touchpad: switch touch point, hysteresis, initial coords to typesafe coords

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Peter Hutterer 2015-03-11 09:24:52 +10:00
parent dd3a2ea7d9
commit 614dc10fd1
5 changed files with 51 additions and 67 deletions

View file

@ -80,14 +80,14 @@ button_event_to_str(enum button_event event) {
static inline bool
is_inside_bottom_button_area(struct tp_dispatch *tp, struct tp_touch *t)
{
return t->y >= tp->buttons.bottom_area.top_edge;
return t->point.y >= tp->buttons.bottom_area.top_edge;
}
static inline bool
is_inside_bottom_right_area(struct tp_dispatch *tp, struct tp_touch *t)
{
return is_inside_bottom_button_area(tp, t) &&
t->x > tp->buttons.bottom_area.rightbutton_left_edge;
t->point.x > tp->buttons.bottom_area.rightbutton_left_edge;
}
static inline bool
@ -100,29 +100,29 @@ is_inside_bottom_left_area(struct tp_dispatch *tp, struct tp_touch *t)
static inline bool
is_inside_top_button_area(struct tp_dispatch *tp, struct tp_touch *t)
{
return t->y <= tp->buttons.top_area.bottom_edge;
return t->point.y <= tp->buttons.top_area.bottom_edge;
}
static inline bool
is_inside_top_right_area(struct tp_dispatch *tp, struct tp_touch *t)
{
return is_inside_top_button_area(tp, t) &&
t->x > tp->buttons.top_area.rightbutton_left_edge;
t->point.x > tp->buttons.top_area.rightbutton_left_edge;
}
static inline bool
is_inside_top_left_area(struct tp_dispatch *tp, struct tp_touch *t)
{
return is_inside_top_button_area(tp, t) &&
t->x < tp->buttons.top_area.leftbutton_right_edge;
t->point.x < tp->buttons.top_area.leftbutton_right_edge;
}
static inline bool
is_inside_top_middle_area(struct tp_dispatch *tp, struct tp_touch *t)
{
return is_inside_top_button_area(tp, t) &&
t->x >= tp->buttons.top_area.leftbutton_right_edge &&
t->x <= tp->buttons.top_area.rightbutton_left_edge;
t->point.x >= tp->buttons.top_area.leftbutton_right_edge &&
t->point.x <= tp->buttons.top_area.rightbutton_left_edge;
}
static void

View file

@ -52,10 +52,10 @@ tp_touch_get_edge(struct tp_dispatch *tp, struct tp_touch *t)
if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE)
return EDGE_NONE;
if (t->x > tp->scroll.right_edge)
if (t->point.x > tp->scroll.right_edge)
edge |= EDGE_RIGHT;
if (t->y > tp->scroll.bottom_edge)
if (t->point.y > tp->scroll.bottom_edge)
edge |= EDGE_BOTTOM;
return edge;
@ -76,8 +76,7 @@ tp_edge_scroll_set_state(struct tp_dispatch *tp,
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
t->scroll.edge = tp_touch_get_edge(tp, t);
t->scroll.initial_x = t->x;
t->scroll.initial_y = t->y;
t->scroll.initial = t->point;
libinput_timer_set(&t->scroll.timer,
t->millis + DEFAULT_SCROLL_LOCK_TIMEOUT);
break;
@ -359,8 +358,8 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
t->scroll.edge_state);
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
initial_dx = t->x - t->scroll.initial_x;
initial_dy = t->y - t->scroll.initial_y;
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);

View file

@ -533,8 +533,8 @@ tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp,
int threshold = DEFAULT_TAP_MOVE_THRESHOLD;
double dx, dy;
dx = abs(t->tap.initial_x - t->x);
dy = abs(t->tap.initial_y - t->y);
dx = abs(t->tap.initial.x - t->point.x);
dy = abs(t->tap.initial.y - t->point.y);
tp_normalize_delta(tp, &dx, &dy);
return dx * dx + dy * dy > threshold * threshold;
@ -571,8 +571,7 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
if (t->state == TOUCH_BEGIN) {
t->tap.state = TAP_TOUCH_STATE_TOUCH;
t->tap.initial_x = t->x;
t->tap.initial_y = t->y;
t->tap.initial = t->point;
tp_tap_handle_event(tp, t, TAP_EVENT_TOUCH, time);
} else if (t->state == TOUCH_END) {
tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);

View file

@ -87,8 +87,7 @@ tp_motion_history_push(struct tp_touch *t)
if (t->history.count < TOUCHPAD_HISTORY_LENGTH)
t->history.count++;
t->history.samples[motion_index].x = t->x;
t->history.samples[motion_index].y = t->y;
t->history.samples[motion_index] = t->point;
t->history.index = motion_index;
}
@ -96,23 +95,22 @@ static inline void
tp_motion_hysteresis(struct tp_dispatch *tp,
struct tp_touch *t)
{
int x = t->x,
y = t->y;
int x = t->point.x,
y = t->point.y;
if (t->history.count == 0) {
t->hysteresis.center_x = t->x;
t->hysteresis.center_y = t->y;
t->hysteresis_center = t->point;
} else {
x = tp_hysteresis(x,
t->hysteresis.center_x,
tp->hysteresis.margin_x);
t->hysteresis_center.x,
tp->hysteresis_margin.x);
y = tp_hysteresis(y,
t->hysteresis.center_y,
tp->hysteresis.margin_y);
t->hysteresis.center_x = x;
t->hysteresis.center_y = y;
t->x = x;
t->y = y;
t->hysteresis_center.y,
tp->hysteresis_margin.y);
t->hysteresis_center.x = x;
t->hysteresis_center.y = y;
t->point.x = x;
t->point.y = y;
}
}
@ -281,13 +279,13 @@ tp_process_absolute(struct tp_dispatch *tp,
switch(e->code) {
case ABS_MT_POSITION_X:
t->x = e->value;
t->point.x = e->value;
t->millis = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
break;
case ABS_MT_POSITION_Y:
t->y = e->value;
t->point.y = e->value;
t->millis = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
@ -312,13 +310,13 @@ tp_process_absolute_st(struct tp_dispatch *tp,
switch(e->code) {
case ABS_X:
t->x = e->value;
t->point.x = e->value;
t->millis = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
break;
case ABS_Y:
t->y = e->value;
t->point.y = e->value;
t->millis = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
@ -418,8 +416,8 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
if (!t->pinned.is_pinned)
return;
xdist = abs(t->x - t->pinned.center_x);
ydist = abs(t->y - t->pinned.center_y);
xdist = abs(t->point.x - t->pinned.center.x);
ydist = abs(t->point.y - t->pinned.center.y);
if (xdist * xdist + ydist * ydist >=
tp->buttons.motion_dist * tp->buttons.motion_dist) {
@ -428,8 +426,8 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
}
/* The finger may slowly drift, adjust the center */
t->pinned.center_x = t->x + t->pinned.center_x / 2;
t->pinned.center_y = t->y + t->pinned.center_y / 2;
t->pinned.center.x = t->point.x + t->pinned.center.x / 2;
t->pinned.center.y = t->point.y + t->pinned.center.y / 2;
}
static void
@ -439,8 +437,7 @@ tp_pin_fingers(struct tp_dispatch *tp)
tp_for_each_touch(tp, t) {
t->pinned.is_pinned = true;
t->pinned.center_x = t->x;
t->pinned.center_y = t->y;
t->pinned.center = t->point;
}
}
@ -466,8 +463,9 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
*/
if (t->palm.is_palm) {
if (time < t->palm.time + PALM_TIMEOUT &&
(t->x > tp->palm.left_edge && t->x < tp->palm.right_edge)) {
int dirs = vector_get_direction(t->x - t->palm.x, t->y - t->palm.y);
(t->point.x > tp->palm.left_edge && t->point.x < tp->palm.right_edge)) {
int dirs = vector_get_direction(t->point.x - t->palm.first.x,
t->point.y - t->palm.first.y);
if ((dirs & DIRECTIONS) && !(dirs & ~DIRECTIONS)) {
t->palm.is_palm = false;
}
@ -478,7 +476,7 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
/* palm must start in exclusion zone, it's ok to move into
the zone without being a palm */
if (t->state != TOUCH_BEGIN ||
(t->x > tp->palm.left_edge && t->x < tp->palm.right_edge))
(t->point.x > tp->palm.left_edge && t->point.x < tp->palm.right_edge))
return;
/* don't detect palm in software button areas, it's
@ -490,8 +488,7 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->palm.is_palm = true;
t->palm.time = time;
t->palm.x = t->x;
t->palm.y = t->y;
t->palm.first = t->point;
}
static void
@ -566,8 +563,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
tp_motion_history_reset(t);
if (i >= tp->real_touches && t->state != TOUCH_NONE) {
t->x = first->x;
t->y = first->y;
t->point = first->point;
if (!t->dirty)
t->dirty = first->dirty;
}
@ -1155,9 +1151,9 @@ tp_init(struct tp_dispatch *tp,
device->abs.absinfo_y->minimum);
diagonal = sqrt(width*width + height*height);
tp->hysteresis.margin_x =
tp->hysteresis_margin.x =
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
tp->hysteresis.margin_y =
tp->hysteresis_margin.y =
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
if (tp_init_accel(tp, diagonal) != 0)

View file

@ -127,8 +127,7 @@ struct tp_touch {
enum touch_state state;
bool has_ended; /* TRACKING_ID == -1 */
bool dirty;
int32_t x; /* in device coordinates */
int32_t y; /* in device coordinates */
struct device_coords point;
uint64_t millis;
struct {
@ -137,10 +136,7 @@ struct tp_touch {
unsigned int count;
} history;
struct {
int32_t center_x; /* in device coordinates */
int32_t center_y; /* in device coordinates */
} hysteresis;
struct device_coords hysteresis_center;
/* A pinned touchpoint is the one that pressed the physical button
* on a clickpad. After the release, it won't move until the center
@ -148,8 +144,7 @@ struct tp_touch {
*/
struct {
bool is_pinned;
int32_t center_x; /* in device coordinates */
int32_t center_y; /* in device coordinates */
struct device_coords center;
} pinned;
/* Software-button state and timeout if applicable */
@ -162,7 +157,7 @@ struct tp_touch {
struct {
enum tp_tap_touch_state state;
int32_t initial_x, initial_y; /* in device coordinates */
struct device_coords initial;
} tap;
struct {
@ -170,14 +165,12 @@ struct tp_touch {
uint32_t edge;
int direction;
struct libinput_timer timer;
int32_t initial_x; /* in device coordinates */
int32_t initial_y; /* in device coordinates */
struct device_coords initial;
} scroll;
struct {
bool is_palm;
int32_t x, y; /* first coordinates if is_palm == true,
in device coordinates */
struct device_coords first; /* first coordinates if is_palm == true */
uint32_t time; /* first timestamp if is_palm == true */
} palm;
};
@ -202,10 +195,7 @@ struct tp_dispatch {
*/
unsigned int fake_touches;
struct {
int32_t margin_x; /* in device coordiantes */
int32_t margin_y; /* in device coordiantes */
} hysteresis;
struct device_coords hysteresis_margin;
struct {
double x_scale_coeff;