mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-22 18:20:06 +01:00
touchpad: switch delta handling to typesafe coordinates
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
614dc10fd1
commit
8101e43774
5 changed files with 73 additions and 65 deletions
|
|
@ -311,8 +311,9 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
struct libinput_device *device = &tp->device->base;
|
||||
struct tp_touch *t;
|
||||
enum libinput_pointer_axis axis;
|
||||
double dx, dy, *delta;
|
||||
double *delta;
|
||||
double initial_dx, initial_dy, *initial_delta;
|
||||
struct normalized_coords normalized;
|
||||
|
||||
if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE)
|
||||
return 0;
|
||||
|
|
@ -335,20 +336,21 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
continue;
|
||||
case EDGE_RIGHT:
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
|
||||
delta = &dy;
|
||||
delta = &normalized.y;
|
||||
initial_delta = &initial_dy;
|
||||
break;
|
||||
case EDGE_BOTTOM:
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
|
||||
delta = &dx;
|
||||
delta = &normalized.x;
|
||||
initial_delta = &initial_dx;
|
||||
break;
|
||||
default: /* EDGE_RIGHT | EDGE_BOTTOM */
|
||||
continue; /* Don't know direction yet, skip */
|
||||
}
|
||||
|
||||
tp_get_delta(t, &dx, &dy);
|
||||
tp_filter_motion(tp, &dx, &dy, NULL, NULL, time);
|
||||
normalized = tp_get_delta(t);
|
||||
tp_filter_motion(tp, &normalized.x, &normalized.y,
|
||||
NULL, NULL, time);
|
||||
|
||||
switch (t->scroll.edge_state) {
|
||||
case EDGE_SCROLL_TOUCH_STATE_NONE:
|
||||
|
|
@ -361,14 +363,12 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
initial_dx = t->point.x - t->scroll.initial.x;
|
||||
initial_dy = t->point.y - t->scroll.initial.y;
|
||||
tp_normalize_delta(tp,
|
||||
&initial_dx,
|
||||
&initial_dy);
|
||||
initial_dx,
|
||||
initial_dy,
|
||||
&normalized);
|
||||
if (fabs(*initial_delta) < DEFAULT_SCROLL_THRESHOLD) {
|
||||
dx = 0.0;
|
||||
dy = 0.0;
|
||||
} else {
|
||||
dx = initial_dx;
|
||||
dy = initial_dy;
|
||||
normalized.x = 0.0;
|
||||
normalized.y = 0.0;
|
||||
}
|
||||
break;
|
||||
case EDGE_SCROLL_TOUCH_STATE_EDGE:
|
||||
|
|
@ -381,7 +381,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
pointer_notify_axis(device, time,
|
||||
AS_MASK(axis),
|
||||
LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
|
||||
dx, dy,
|
||||
normalized.x, normalized.y,
|
||||
0, 0);
|
||||
t->scroll.direction = axis;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,45 +31,45 @@
|
|||
|
||||
#define DEFAULT_GESTURE_SWITCH_TIMEOUT 100 /* ms */
|
||||
|
||||
static void
|
||||
tp_get_touches_delta(struct tp_dispatch *tp, double *dx, double *dy, bool average)
|
||||
static struct normalized_coords
|
||||
tp_get_touches_delta(struct tp_dispatch *tp, bool average)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
unsigned int i, nchanged = 0;
|
||||
double tmpx, tmpy;
|
||||
|
||||
*dx = 0.0;
|
||||
*dy = 0.0;
|
||||
struct normalized_coords normalized;
|
||||
struct normalized_coords delta = {0.0, 0.0};
|
||||
|
||||
for (i = 0; i < tp->real_touches; i++) {
|
||||
t = &tp->touches[i];
|
||||
|
||||
if (tp_touch_active(tp, t) && t->dirty) {
|
||||
nchanged++;
|
||||
tp_get_delta(t, &tmpx, &tmpy);
|
||||
normalized = tp_get_delta(t);
|
||||
|
||||
*dx += tmpx;
|
||||
*dy += tmpy;
|
||||
delta.x += normalized.x;
|
||||
delta.y += normalized.y;
|
||||
}
|
||||
}
|
||||
|
||||
if (!average || nchanged == 0)
|
||||
return;
|
||||
return delta;
|
||||
|
||||
*dx /= nchanged;
|
||||
*dy /= nchanged;
|
||||
delta.x /= nchanged;
|
||||
delta.y /= nchanged;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_get_combined_touches_delta(struct tp_dispatch *tp, double *dx, double *dy)
|
||||
static inline struct normalized_coords
|
||||
tp_get_combined_touches_delta(struct tp_dispatch *tp)
|
||||
{
|
||||
tp_get_touches_delta(tp, dx, dy, false);
|
||||
return tp_get_touches_delta(tp, false);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_get_average_touches_delta(struct tp_dispatch *tp, double *dx, double *dy)
|
||||
static inline struct normalized_coords
|
||||
tp_get_average_touches_delta(struct tp_dispatch *tp)
|
||||
{
|
||||
tp_get_touches_delta(tp, dx, dy, true);
|
||||
return tp_get_touches_delta(tp, true);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -89,39 +89,41 @@ tp_gesture_start(struct tp_dispatch *tp, uint64_t time)
|
|||
static void
|
||||
tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
double dx = 0.0, dy = 0.0;
|
||||
double dx_unaccel, dy_unaccel;
|
||||
struct normalized_coords delta;
|
||||
|
||||
/* When a clickpad is clicked, combine motion of all active touches */
|
||||
if (tp->buttons.is_clickpad && tp->buttons.state)
|
||||
tp_get_combined_touches_delta(tp, &dx, &dy);
|
||||
delta = tp_get_combined_touches_delta(tp);
|
||||
else
|
||||
tp_get_average_touches_delta(tp, &dx, &dy);
|
||||
delta = tp_get_average_touches_delta(tp);
|
||||
|
||||
tp_filter_motion(tp, &dx, &dy, &dx_unaccel, &dy_unaccel, time);
|
||||
tp_filter_motion(tp, &delta.x, &delta.y, &dx_unaccel, &dy_unaccel, time);
|
||||
|
||||
if (dx != 0.0 || dy != 0.0 || dx_unaccel != 0.0 || dy_unaccel != 0.0) {
|
||||
if (delta.x != 0.0 || delta.y != 0.0 ||
|
||||
dx_unaccel != 0.0 || dy_unaccel != 0.0) {
|
||||
pointer_notify_motion(&tp->device->base, time,
|
||||
dx, dy, dx_unaccel, dy_unaccel);
|
||||
delta.x, delta.y,
|
||||
dx_unaccel, dy_unaccel);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
double dx = 0, dy =0;
|
||||
struct normalized_coords delta;
|
||||
|
||||
tp_get_average_touches_delta(tp, &dx, &dy);
|
||||
tp_filter_motion(tp, &dx, &dy, NULL, NULL, time);
|
||||
delta = tp_get_average_touches_delta(tp);
|
||||
tp_filter_motion(tp, &delta.x, &delta.y, NULL, NULL, time);
|
||||
|
||||
if (dx == 0.0 && dy == 0.0)
|
||||
if (delta.x == 0.0 && delta.y == 0.0)
|
||||
return;
|
||||
|
||||
tp_gesture_start(tp, time);
|
||||
evdev_post_scroll(tp->device,
|
||||
time,
|
||||
LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
|
||||
dx, dy);
|
||||
delta.x, delta.y);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -532,12 +532,14 @@ tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp,
|
|||
{
|
||||
int threshold = DEFAULT_TAP_MOVE_THRESHOLD;
|
||||
double dx, dy;
|
||||
struct normalized_coords normalized;
|
||||
|
||||
dx = abs(t->tap.initial.x - t->point.x);
|
||||
dy = abs(t->tap.initial.y - t->point.y);
|
||||
tp_normalize_delta(tp, &dx, &dy);
|
||||
tp_normalize_delta(tp, dx, dy, &normalized);
|
||||
|
||||
return dx * dx + dy * dy > threshold * threshold;
|
||||
return normalized.x * normalized.x + normalized.y * normalized.y
|
||||
> threshold * threshold;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -250,24 +250,26 @@ tp_estimate_delta(int x0, int x1, int x2, int x3)
|
|||
return (x0 + x1 - x2 - x3) / 4.0;
|
||||
}
|
||||
|
||||
void
|
||||
tp_get_delta(struct tp_touch *t, double *dx, double *dy)
|
||||
struct normalized_coords
|
||||
tp_get_delta(struct tp_touch *t)
|
||||
{
|
||||
if (t->history.count < TOUCHPAD_MIN_SAMPLES) {
|
||||
*dx = 0;
|
||||
*dy = 0;
|
||||
return;
|
||||
}
|
||||
double dx, dy; /* in device coords */
|
||||
struct normalized_coords normalized = { 0.0, 0.0 };
|
||||
|
||||
*dx = tp_estimate_delta(tp_motion_history_offset(t, 0)->x,
|
||||
tp_motion_history_offset(t, 1)->x,
|
||||
tp_motion_history_offset(t, 2)->x,
|
||||
tp_motion_history_offset(t, 3)->x);
|
||||
*dy = tp_estimate_delta(tp_motion_history_offset(t, 0)->y,
|
||||
tp_motion_history_offset(t, 1)->y,
|
||||
tp_motion_history_offset(t, 2)->y,
|
||||
tp_motion_history_offset(t, 3)->y);
|
||||
tp_normalize_delta(t->tp, dx, dy);
|
||||
if (t->history.count < TOUCHPAD_MIN_SAMPLES)
|
||||
return normalized;
|
||||
|
||||
dx = tp_estimate_delta(tp_motion_history_offset(t, 0)->x,
|
||||
tp_motion_history_offset(t, 1)->x,
|
||||
tp_motion_history_offset(t, 2)->x,
|
||||
tp_motion_history_offset(t, 3)->x);
|
||||
dy = tp_estimate_delta(tp_motion_history_offset(t, 0)->y,
|
||||
tp_motion_history_offset(t, 1)->y,
|
||||
tp_motion_history_offset(t, 2)->y,
|
||||
tp_motion_history_offset(t, 3)->y);
|
||||
tp_normalize_delta(t->tp, dx, dy, &normalized);
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -277,14 +277,16 @@ struct tp_dispatch {
|
|||
for (unsigned int _i = 0; _i < (_tp)->ntouches && (_t = &(_tp)->touches[_i]); _i++)
|
||||
|
||||
static inline void
|
||||
tp_normalize_delta(struct tp_dispatch *tp, double *dx, double *dy)
|
||||
tp_normalize_delta(struct tp_dispatch *tp,
|
||||
double dx, double dy,
|
||||
struct normalized_coords *normalized)
|
||||
{
|
||||
*dx = *dx * tp->accel.x_scale_coeff;
|
||||
*dy = *dy * tp->accel.y_scale_coeff;
|
||||
normalized->x = dx * tp->accel.x_scale_coeff;
|
||||
normalized->y = dy * tp->accel.y_scale_coeff;
|
||||
}
|
||||
|
||||
void
|
||||
tp_get_delta(struct tp_touch *t, double *dx, double *dy);
|
||||
struct normalized_coords
|
||||
tp_get_delta(struct tp_touch *t);
|
||||
|
||||
void
|
||||
tp_filter_motion(struct tp_dispatch *tp,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue