diff --git a/src/evdev-mt-touchpad-edge-motion.c b/src/evdev-mt-touchpad-edge-motion.c index 4ae28ab5..573d2cd2 100644 --- a/src/evdev-mt-touchpad-edge-motion.c +++ b/src/evdev-mt-touchpad-edge-motion.c @@ -38,27 +38,6 @@ #include "evdev-mt-touchpad.h" -void -tp_edge_motion_init(struct tp_dispatch *tp); - -enum edge_motion_state { STATE_IDLE, STATE_DRAG_ACTIVE, STATE_EDGE_MOTION }; - -struct edge_motion_fsm { - enum edge_motion_state current_state; - usec_t last_motion_time; - uint32_t current_edge; - double motion_dx; - double motion_dy; - uint32_t continuous_motion_count; - struct tp_dispatch *tp; - struct libinput_timer timer; -}; - -static struct edge_motion_fsm fsm = { - .current_state = STATE_IDLE, - .tp = NULL, -}; - #define EDGE_MOTION_CONFIG_SPEED_MM_S 70.0 #define EDGE_MOTION_CONFIG_MIN_INTERVAL_US 8000 #define EDGE_MOTION_CONFIG_EDGE_THRESHOLD_MM 5.0 @@ -89,12 +68,12 @@ calculate_motion_vector(uint32_t edge, double *dx, double *dy) static void inject_accumulated_motion(struct tp_dispatch *tp, usec_t time) { - if (usec_is_zero(fsm.last_motion_time)) { - fsm.last_motion_time = time; + if (usec_is_zero(tp->edge_motion.last_motion_time)) { + tp->edge_motion.last_motion_time = time; return; } - usec_t time_since_last = usec_sub(time, fsm.last_motion_time); + usec_t time_since_last = usec_sub(time, tp->edge_motion.last_motion_time); double dist_mm = EDGE_MOTION_CONFIG_SPEED_MM_S * ((double)usec_as_uint64_t(time_since_last) / 1000000.0); @@ -102,8 +81,8 @@ inject_accumulated_motion(struct tp_dispatch *tp, usec_t time) return; struct device_float_coords raw = { - .x = fsm.motion_dx * dist_mm * tp->accel.x_scale_coeff, - .y = fsm.motion_dy * dist_mm * tp->accel.y_scale_coeff + .x = tp->edge_motion.motion_dx * dist_mm * tp->accel.x_scale_coeff, + .y = tp->edge_motion.motion_dy * dist_mm * tp->accel.y_scale_coeff }; struct normalized_coords delta = @@ -111,8 +90,8 @@ inject_accumulated_motion(struct tp_dispatch *tp, usec_t time) pointer_notify_motion(&tp->device->base, time, &delta, &raw); - fsm.last_motion_time = time; - fsm.continuous_motion_count++; + tp->edge_motion.last_motion_time = time; + tp->edge_motion.continuous_motion_count++; } static uint32_t @@ -138,50 +117,44 @@ detect_touch_edge(const struct tp_dispatch *tp, const struct tp_touch *t) static void tp_edge_motion_handle_timeout(usec_t now, void *data) { - struct edge_motion_fsm *fsm_ptr = data; + struct tp_dispatch *tp = data; - if (fsm_ptr->current_state != STATE_EDGE_MOTION) + if (tp->edge_motion.state != EDGE_MOTION_STATE_EDGE_MOTION) return; - inject_accumulated_motion(fsm_ptr->tp, now); + inject_accumulated_motion(tp, now); libinput_timer_set( - &fsm_ptr->timer, + &tp->edge_motion.timer, usec_add(now, usec_from_uint64_t(EDGE_MOTION_CONFIG_MIN_INTERVAL_US))); } void -tp_edge_motion_init(struct tp_dispatch *tp) +tp_init_edge_motion(struct tp_dispatch *tp) { - if (fsm.tp) - return; + tp->edge_motion.state = EDGE_MOTION_STATE_IDLE; + tp->edge_motion.last_motion_time = usec_from_uint64_t(0); + tp->edge_motion.current_edge = EDGE_NONE; + tp->edge_motion.motion_dx = 0.0; + tp->edge_motion.motion_dy = 0.0; + tp->edge_motion.continuous_motion_count = 0; - memset(&fsm, 0, sizeof(fsm)); - fsm.current_state = STATE_IDLE; - fsm.tp = tp; - - libinput_timer_init(&fsm.timer, + libinput_timer_init(&tp->edge_motion.timer, tp_libinput_context(tp), "edge drag motion", tp_edge_motion_handle_timeout, - &fsm); + tp); } void -tp_edge_motion_cleanup(void) +tp_remove_edge_motion(struct tp_dispatch *tp) { - if (fsm.tp) - libinput_timer_destroy(&fsm.timer); - - memset(&fsm, 0, sizeof(fsm)); - fsm.current_state = STATE_IDLE; + libinput_timer_cancel(&tp->edge_motion.timer); + libinput_timer_destroy(&tp->edge_motion.timer); } int tp_edge_motion_handle_drag_state(struct tp_dispatch *tp, usec_t time) { - if (!fsm.tp) - tp_edge_motion_init(tp); - bool drag_active = false; switch (tp->tap.state) { @@ -209,40 +182,41 @@ tp_edge_motion_handle_drag_state(struct tp_dispatch *tp, usec_t time) } } - enum edge_motion_state next_state = STATE_IDLE; + enum tp_edge_motion_state next_state = EDGE_MOTION_STATE_IDLE; if (drag_active) { - next_state = (detected_edge != EDGE_NONE) ? STATE_EDGE_MOTION - : STATE_DRAG_ACTIVE; + next_state = (detected_edge != EDGE_NONE) ? EDGE_MOTION_STATE_EDGE_MOTION + : EDGE_MOTION_STATE_DRAG_ACTIVE; } - if (next_state != fsm.current_state) { - fsm.current_state = next_state; - fsm.current_edge = detected_edge; + if (next_state != tp->edge_motion.state) { + tp->edge_motion.state = next_state; + tp->edge_motion.current_edge = detected_edge; - if (fsm.current_state != STATE_EDGE_MOTION) - fsm.continuous_motion_count = 0; + if (tp->edge_motion.state != EDGE_MOTION_STATE_EDGE_MOTION) + tp->edge_motion.continuous_motion_count = 0; - switch (fsm.current_state) { - case STATE_IDLE: - case STATE_DRAG_ACTIVE: - libinput_timer_cancel(&fsm.timer); + switch (tp->edge_motion.state) { + case EDGE_MOTION_STATE_IDLE: + case EDGE_MOTION_STATE_DRAG_ACTIVE: + libinput_timer_cancel(&tp->edge_motion.timer); + tp->edge_motion.current_edge = EDGE_NONE; break; - case STATE_EDGE_MOTION: - calculate_motion_vector(fsm.current_edge, - &fsm.motion_dx, - &fsm.motion_dy); - fsm.last_motion_time = time; - tp_edge_motion_handle_timeout(time, &fsm); + case EDGE_MOTION_STATE_EDGE_MOTION: + calculate_motion_vector(tp->edge_motion.current_edge, + &tp->edge_motion.motion_dx, + &tp->edge_motion.motion_dy); + tp->edge_motion.last_motion_time = time; + tp_edge_motion_handle_timeout(time, tp); break; } - } else if (fsm.current_state == STATE_EDGE_MOTION && - detected_edge != fsm.current_edge) { - fsm.current_edge = detected_edge; - calculate_motion_vector(fsm.current_edge, - &fsm.motion_dx, - &fsm.motion_dy); + } else if (tp->edge_motion.state == EDGE_MOTION_STATE_EDGE_MOTION && + detected_edge != tp->edge_motion.current_edge) { + tp->edge_motion.current_edge = detected_edge; + calculate_motion_vector(tp->edge_motion.current_edge, + &tp->edge_motion.motion_dx, + &tp->edge_motion.motion_dy); } - return (fsm.current_state == STATE_EDGE_MOTION); + return (tp->edge_motion.state == EDGE_MOTION_STATE_EDGE_MOTION); } diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index ebde0ab8..5449ecd8 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -1293,7 +1293,7 @@ tp_tap_handle_state(struct tp_dispatch *tp, usec_t time) } /* Log 1-finger drag state changes */ - filter_motion = tp_edge_motion_handle_drag_state(tp, time); + filter_motion |= tp_edge_motion_handle_drag_state(tp, time); /** * In any state where motion exceeding the move threshold would @@ -1597,7 +1597,6 @@ void tp_remove_tap(struct tp_dispatch *tp) { libinput_timer_cancel(&tp->tap.timer); - tp_edge_motion_cleanup(); } void diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index e60ced9b..247cb695 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1960,6 +1960,7 @@ tp_interface_remove(struct evdev_dispatch *dispatch) tp_remove_buttons(tp); tp_remove_sendevents(tp); tp_remove_edge_scroll(tp); + tp_remove_edge_motion(tp); tp_remove_gesture(tp); } @@ -3783,6 +3784,7 @@ tp_init(struct tp_dispatch *tp, struct evdev_device *device) tp_init_palmdetect(tp, device); tp_init_sendevents(tp, device); tp_init_scroll(tp, device); + tp_init_edge_motion(tp); tp_init_gesture(tp); tp_init_thumb(tp); diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 059fac3e..d86ee7a7 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -140,6 +140,12 @@ enum tp_tap_touch_state { TAP_TOUCH_STATE_DEAD, /**< exceeded motion/timeout */ }; +enum tp_edge_motion_state { + EDGE_MOTION_STATE_IDLE, + EDGE_MOTION_STATE_DRAG_ACTIVE, + EDGE_MOTION_STATE_EDGE_MOTION, +}; + /* For edge scrolling, so we only care about right and bottom. For edge motion, we * require all four edges */ enum tp_edge { @@ -565,6 +571,21 @@ struct tp_dispatch { struct evdev_device *tablet_device; bool tablet_left_handed_state; } left_handed; + + struct { + enum tp_edge_motion_state state; + + usec_t last_motion_time; + + uint32_t current_edge; + + double motion_dx; + double motion_dy; + + uint32_t continuous_motion_count; + + struct libinput_timer timer; + } edge_motion; }; static inline struct tp_dispatch * @@ -726,11 +747,14 @@ tp_edge_scroll_touch_active(const struct tp_dispatch *tp, const struct tp_touch uint32_t tp_touch_get_edge(const struct tp_dispatch *tp, const struct tp_touch *t); +void +tp_init_edge_motion(struct tp_dispatch *tp); + int tp_edge_motion_handle_drag_state(struct tp_dispatch *tp, usec_t time); void -tp_edge_motion_cleanup(void); +tp_remove_edge_motion(struct tp_dispatch *tp); void tp_init_gesture(struct tp_dispatch *tp);