Same algorithm as in evdev-touchpad.c Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- src/evdev-mt-touchpad.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index f625814..1968199 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -27,7 +27,11 @@ #include <stdbool.h> #include "evdev.h" +#include "filter.h" +#define DEFAULT_CONSTANT_ACCEL_NUMERATOR 50 +#define DEFAULT_MIN_ACCEL_FACTOR 0.16 +#define DEFAULT_MAX_ACCEL_FACTOR 1.0 #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0 #define TOUCHPAD_HISTORY_LENGTH 4 @@ -78,6 +82,14 @@ struct tp_dispatch { int32_t margin_x; int32_t margin_y; } hysteresis; + + struct motion_filter *filter; + + struct { + double constant_factor; + double min_factor; + double max_factor; + } accel; }; static inline int @@ -94,6 +106,27 @@ tp_hysteresis(int in, int center, int margin) return center + diff; } +static double +tp_accel_profile(struct motion_filter *filter, + void *data, + double velocity, + uint32_t time) +{ + struct tp_dispatch *tp = + (struct tp_dispatch *) data; + + double accel_factor; + + accel_factor = velocity * tp->accel.constant_factor; + + if (accel_factor > tp->accel.max_factor) + accel_factor = tp->accel.max_factor; + else if (accel_factor < tp->accel.min_factor) + accel_factor = tp->accel.min_factor; + + return accel_factor; +} + static inline struct tp_motion * tp_motion_history_offset(struct tp_touch *t, int offset) { @@ -104,6 +137,21 @@ tp_motion_history_offset(struct tp_touch *t, int offset) return &t->history.samples[offset_index]; } +static void +tp_filter_motion(struct tp_dispatch *tp, + double *dx, double *dy, uint32_t time) +{ + struct motion_params motion; + + motion.dx = *dx; + motion.dy = *dy; + + filter_dispatch(tp->filter, &motion, tp, time); + + *dx = motion.dx; + *dy = motion.dy; +} + static inline void tp_motion_history_push(struct tp_touch *t) { @@ -292,7 +340,12 @@ tp_post_events(struct tp_dispatch *tp, uint32_t time) if (tp->nfingers_down != 1) return; + + if (t->history.count < 4) + return; + tp_get_delta(t, &dx, &dy); + tp_filter_motion(tp, &dx, &dy, time); if (dx != 0 || dy != 0) pointer_notify_motion( @@ -332,6 +385,8 @@ tp_destroy(struct evdev_dispatch *dispatch) struct tp_dispatch *tp = (struct tp_dispatch*)dispatch; + if (tp->filter) + tp->filter->interface->destroy(tp->filter); free(tp->touches); free(tp); } @@ -357,6 +412,24 @@ tp_init_slots(struct tp_dispatch *tp, return 0; } +static int +tp_init_accel(struct tp_dispatch *touchpad, double diagonal) +{ + struct motion_filter *accel; + + touchpad->accel.constant_factor = + DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal; + touchpad->accel.min_factor = DEFAULT_MIN_ACCEL_FACTOR; + touchpad->accel.max_factor = DEFAULT_MAX_ACCEL_FACTOR; + + accel = create_pointer_accelator_filter(tp_accel_profile); + if (accel == NULL) + return -1; + + touchpad->filter = accel; + + return 0; +} static int tp_init(struct tp_dispatch *tp, @@ -380,6 +453,9 @@ tp_init(struct tp_dispatch *tp, tp->hysteresis.margin_y = diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR; + if (tp_init_accel(tp, diagonal) != 0) + return -1; + return 0; } -- 1.8.4.2 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel