evdev: convert button scrolling into a state machine

No functional changes, preparation work for adding another state.

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 2017-02-20 13:31:23 +10:00
parent bcf8c222cb
commit 3697b72071
2 changed files with 38 additions and 20 deletions

View file

@ -221,18 +221,18 @@ evdev_button_scroll_timeout(uint64_t time, void *data)
{
struct evdev_device *device = data;
device->scroll.button_scroll_active = true;
device->scroll.button_scroll_state = BUTTONSCROLL_SCROLLING;
}
static void
evdev_button_scroll_button(struct evdev_device *device,
uint64_t time, int is_press)
{
device->scroll.button_scroll_btn_pressed = is_press;
if (is_press) {
enum timer_flags flags = TIMER_FLAG_NONE;
device->scroll.button_scroll_state = BUTTONSCROLL_BUTTON_DOWN;
/* Special case: if middle button emulation is enabled and
* our scroll button is the left or right button, we only
* get here *after* the middle button timeout has expired
@ -254,13 +254,12 @@ evdev_button_scroll_button(struct evdev_device *device,
"btnscroll: down\n");
} else {
libinput_timer_cancel(&device->scroll.timer);
if (device->scroll.button_scroll_active) {
log_debug(evdev_libinput_context(device),
"btnscroll: up\n");
evdev_stop_scroll(device, time,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
device->scroll.button_scroll_active = false;
} else {
switch(device->scroll.button_scroll_state) {
case BUTTONSCROLL_IDLE:
log_bug_libinput(evdev_libinput_context(device),
"invalid state IDLE for button up\n");
break;
case BUTTONSCROLL_BUTTON_DOWN:
log_debug(evdev_libinput_context(device),
"btnscroll: cancel\n");
/* If the button is released quickly enough emit the
@ -272,7 +271,16 @@ evdev_button_scroll_button(struct evdev_device *device,
evdev_pointer_post_button(device, time,
device->scroll.button,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case BUTTONSCROLL_SCROLLING:
log_debug(evdev_libinput_context(device),
"btnscroll: up\n");
evdev_stop_scroll(device, time,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
break;
}
device->scroll.button_scroll_state = BUTTONSCROLL_IDLE;
}
}
@ -381,21 +389,26 @@ evdev_post_trackpoint_scroll(struct evdev_device *device,
struct normalized_coords unaccel,
uint64_t time)
{
if (device->scroll.method != LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN ||
!device->scroll.button_scroll_btn_pressed)
if (device->scroll.method != LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
return false;
if (device->scroll.button_scroll_active)
evdev_post_scroll(device, time,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
&unaccel);
else
switch(device->scroll.button_scroll_state) {
case BUTTONSCROLL_IDLE:
return false;
case BUTTONSCROLL_BUTTON_DOWN:
/* if the button is down but scroll is not active, we're within the
timeout where swallow motion events but don't post scroll buttons */
log_debug(evdev_libinput_context(device),
"btnscroll: discarding\n");
return true;
case BUTTONSCROLL_SCROLLING:
evdev_post_scroll(device, time,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
&unaccel);
return true;
}
return true;
assert(!"invalid scroll button state");
}
static inline bool

View file

@ -129,6 +129,12 @@ enum evdev_device_model {
EVDEV_MODEL_LOGITECH_MARBLE_MOUSE = (1 << 26),
};
enum evdev_button_scroll_state {
BUTTONSCROLL_IDLE,
BUTTONSCROLL_BUTTON_DOWN, /* button is down */
BUTTONSCROLL_SCROLLING, /* scrolling */
};
struct mt_slot {
int32_t seat_slot;
struct device_coords point;
@ -188,8 +194,7 @@ struct evdev_device {
uint32_t want_button;
/* Checks if buttons are down and commits the setting */
void (*change_scroll_method)(struct evdev_device *device);
bool button_scroll_active;
bool button_scroll_btn_pressed;
enum evdev_button_scroll_state button_scroll_state;
double threshold;
double direction_lock_threshold;
uint32_t direction;