mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-06 03:28:00 +02:00
touchpad: hook up the pointer acceleration
Same algorithm as in evdev-touchpad.c Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
e75a0430be
commit
8d867a2b8a
1 changed files with 76 additions and 0 deletions
|
|
@ -27,7 +27,11 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "evdev.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 DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0
|
||||||
#define TOUCHPAD_HISTORY_LENGTH 4
|
#define TOUCHPAD_HISTORY_LENGTH 4
|
||||||
|
|
||||||
|
|
@ -78,6 +82,14 @@ struct tp_dispatch {
|
||||||
int32_t margin_x;
|
int32_t margin_x;
|
||||||
int32_t margin_y;
|
int32_t margin_y;
|
||||||
} hysteresis;
|
} hysteresis;
|
||||||
|
|
||||||
|
struct motion_filter *filter;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
double constant_factor;
|
||||||
|
double min_factor;
|
||||||
|
double max_factor;
|
||||||
|
} accel;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
|
@ -94,6 +106,27 @@ tp_hysteresis(int in, int center, int margin)
|
||||||
return center + diff;
|
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 *
|
static inline struct tp_motion *
|
||||||
tp_motion_history_offset(struct tp_touch *t, int offset)
|
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];
|
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
|
static inline void
|
||||||
tp_motion_history_push(struct tp_touch *t)
|
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)
|
if (tp->nfingers_down != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
if (t->history.count < 4)
|
||||||
|
return;
|
||||||
|
|
||||||
tp_get_delta(t, &dx, &dy);
|
tp_get_delta(t, &dx, &dy);
|
||||||
|
tp_filter_motion(tp, &dx, &dy, time);
|
||||||
|
|
||||||
if (dx != 0 || dy != 0)
|
if (dx != 0 || dy != 0)
|
||||||
pointer_notify_motion(
|
pointer_notify_motion(
|
||||||
|
|
@ -332,6 +385,8 @@ tp_destroy(struct evdev_dispatch *dispatch)
|
||||||
struct tp_dispatch *tp =
|
struct tp_dispatch *tp =
|
||||||
(struct tp_dispatch*)dispatch;
|
(struct tp_dispatch*)dispatch;
|
||||||
|
|
||||||
|
if (tp->filter)
|
||||||
|
tp->filter->interface->destroy(tp->filter);
|
||||||
free(tp->touches);
|
free(tp->touches);
|
||||||
free(tp);
|
free(tp);
|
||||||
}
|
}
|
||||||
|
|
@ -357,6 +412,24 @@ tp_init_slots(struct tp_dispatch *tp,
|
||||||
return 0;
|
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
|
static int
|
||||||
tp_init(struct tp_dispatch *tp,
|
tp_init(struct tp_dispatch *tp,
|
||||||
|
|
@ -380,6 +453,9 @@ tp_init(struct tp_dispatch *tp,
|
||||||
tp->hysteresis.margin_y =
|
tp->hysteresis.margin_y =
|
||||||
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
|
||||||
|
|
||||||
|
if (tp_init_accel(tp, diagonal) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue