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);
t->scroll.direction = -1;
}
continue;
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);
+ dx, dy);
t->scroll.direction = axis;
tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED);
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);
t->scroll.direction = -1;
}
}
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 x, double y)
{
- if (device->scroll.natural_scrolling_enabled)
- value *= -1;
+ if (device->scroll.natural_scrolling_enabled) {
+ x *= -1;
+ y *= -1;
+ }
pointer_notify_axis(&device->base,
time,
- axis,
+ axes,
source,
- value);
+ x, y);
}
static inline void
evdev_notify_axis(
device,
time,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
+ 0,
-1 * e->value * device->scroll.wheel_click_angle);
break;
case REL_HWHEEL:
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 * device->scroll.wheel_click_angle,
+ 0);
break;
}
}
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
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
/* 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);
- }
+ 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);
- }
+ dx,
+ dy);
}
void
enum libinput_pointer_axis_source source)
{
/* terminate scrolling with a zero scroll event */
- if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
- pointer_notify_axis(&device->base,
- time,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- source,
- 0);
- if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
+ if (device->scroll.direction != 0)
pointer_notify_axis(&device->base,
time,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ device->scroll.direction,
source,
- 0);
+ 0.0, 0.0);
device->scroll.buildup_horizontal = 0;
device->scroll.buildup_vertical = 0;
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 x, double y);
void
touch_notify_touch_down(struct libinput_device *device,
#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))
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;
+ uint32_t axes;
};
struct libinput_event_touch {
return event->seat_button_count;
}
-LIBINPUT_EXPORT enum libinput_pointer_axis
-libinput_event_pointer_get_axis(struct libinput_event_pointer *event)
-{
- return event->axis;
+LIBINPUT_EXPORT int
+libinput_event_pointer_has_axis(struct libinput_event_pointer *event,
+ enum libinput_pointer_axis 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 enum libinput_pointer_axis_source
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 x, double y)
{
struct libinput_event_pointer *axis_event;
*axis_event = (struct libinput_event_pointer) {
.time = time,
- .axis = axis,
- .value = value,
+ .x = x,
+ .y = y,
.source = source,
+ .axes = axes,
};
post_device_event(device, time,
/**
* @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
* 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.
*
* @return the axis value of this event
*/
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
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;
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;
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);
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 */
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);
libinput_event_destroy(event);
/* 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);
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);
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
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();
}
}