Re: [PATCH v2 libinput] Fix premature flushing of evdev event on mx4 touchscreen
sorry for the delay, travelling and only slowly catching up with email. On Mon, Sep 07, 2015 at 09:57:44PM +0200, Andreas Pokorny wrote: > The mx4 touchscreen driver emits BTN_TOUCH and BTN_TOOL_FINGER key events > on a new contact. Prior to this patch only the BTN_TOUCH event was filtered > out. Now the whole range of BTN_ events for tool types and certain builtin > multi finger gestures are marked as non-key type. > > Signed-off-by: Andreas Pokorny Reviewed-by: Peter Hutterer Cheers, Peter > --- > src/evdev.c | 10 +++--- > test/touch.c | 110 > +++ > 2 files changed, 115 insertions(+), 5 deletions(-) > > diff --git a/src/evdev.c b/src/evdev.c > index 04df275..3e22aa9 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -557,7 +557,7 @@ evdev_flush_pending_event(struct evdev_device *device, > uint64_t time) > static enum evdev_key_type > get_key_type(uint16_t code) > { > - if (code == BTN_TOUCH) > + if (code >= BTN_DIGI && code <= BTN_TOOL_QUADTAP) > return EVDEV_KEY_TYPE_NONE; > > if (code >= KEY_ESC && code <= KEY_MICMUTE) > @@ -630,16 +630,16 @@ evdev_process_key(struct evdev_device *device, > if (e->value == 2) > return; > > - if (e->code == BTN_TOUCH) { > - if (!device->is_mt) > + type = get_key_type(e->code); > + > + if (type == EVDEV_KEY_TYPE_NONE) { > + if (e->code == BTN_TOUCH && !device->is_mt) > evdev_process_touch_button(device, time, e->value); > return; > } > > evdev_flush_pending_event(device, time); > > - type = get_key_type(e->code); > - > /* Ignore key release events from the kernel for keys that libinput >* never got a pressed event for. */ > if (e->value == 0) { > diff --git a/test/touch.c b/test/touch.c > index 875d94d..0e7f893 100644 > --- a/test/touch.c > +++ b/test/touch.c > @@ -912,6 +912,114 @@ START_TEST(touch_point_no_minor_or_orientation) > } > END_TEST > > +START_TEST(touchscreen_with_btn_tool_finger_on_down) > +{ > + struct libevdev_uinput *uinput; > + struct libinput *li; > + struct libinput_device *device; > + struct libinput_event *event; > + struct libinput_event_touch *tev; > + const struct input_absinfo abs[] = { > + { ABS_X, 0, 1152, 0, 0, 0 }, > + { ABS_Y, 0, 1920, 0, 0, 0 }, > + { ABS_MT_SLOT, 0, 9, 0, 0, 0 }, > + { ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 }, > + { ABS_MT_POSITION_X, 0, 1152, 0, 0, 0 }, > + { ABS_MT_POSITION_Y, 0, 1920, 0, 0, 0 }, > + { ABS_MT_TOUCH_MAJOR, 0, 23, 0, 0, 0 }, > + { ABS_MT_TOUCH_MINOR, 0, 23, 0, 0, 0 }, > + { -1, -1, -1, -1, -1, -1 } > + }; > + const struct input_event input_sequence[] = { > + { {0}, EV_ABS, ABS_MT_SLOT, 0}, > + { {0}, EV_ABS, ABS_MT_TRACKING_ID, 9}, > + { {0}, EV_KEY, BTN_TOUCH, 1}, > + { {0}, EV_KEY, BTN_TOOL_FINGER, 1}, > + { {0}, EV_ABS, ABS_MT_POSITION_X, 128}, > + { {0}, EV_ABS, ABS_MT_POSITION_Y, 240}, > + { {0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 5}, > + { {0}, EV_ABS, ABS_MT_TOUCH_MINOR, 4}, > + { {0}, EV_SYN, SYN_REPORT, 0}, > + { {0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 6}, > + { {0}, EV_SYN, SYN_REPORT, 0}, > + { {0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, > + { {0}, EV_KEY, BTN_TOUCH, 0}, > + { {0}, EV_KEY, BTN_TOOL_FINGER, 0}, > + { {0}, EV_SYN, SYN_REPORT, 0} > + }; > + const int num_events = ARRAY_LENGTH(input_sequence); > + const int width = 1152; > + const int height = 1920; > + int x, y, major, minor; > + > + uinput = litest_create_uinput_abs_device( > + "test device", > + NULL, abs, > + EV_KEY, BTN_TOUCH, > + EV_KEY, BTN_TOOL_FINGER, > + INPUT_PROP_MAX, INPUT_PROP_DIRECT, > + -1, -1); > + > + li = litest_create_context(); > + device = libinput_path_add_device(li, > + libevdev_uinput_get_devnode(uinput)); > + ck_assert(device != NULL); > + device = libinput_device_ref(device); > + litest_drain_events(li); > + > + for (int i = 0; i!=num_events; ++i) > + libevdev_uinput_write_event(uinput, > + input_sequence[i].type, > + input_sequence[i].code, > + input_sequence[i].value); > + > + litest_wait_for_event(li); > + > + event = libinput_get_event(li); > + tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN); > + x = round(libinput_event_touch_get_x_transformed(tev, width)); > + y = round(libinput_event_touch_get_y_transformed(tev, height)), > + major = round( >
[PATCH v2 libinput] Fix premature flushing of evdev event on mx4 touchscreen
The mx4 touchscreen driver emits BTN_TOUCH and BTN_TOOL_FINGER key events on a new contact. Prior to this patch only the BTN_TOUCH event was filtered out. Now the whole range of BTN_ events for tool types and certain builtin multi finger gestures are marked as non-key type. Signed-off-by: Andreas Pokorny --- src/evdev.c | 10 +++--- test/touch.c | 110 +++ 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 04df275..3e22aa9 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -557,7 +557,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) static enum evdev_key_type get_key_type(uint16_t code) { - if (code == BTN_TOUCH) + if (code >= BTN_DIGI && code <= BTN_TOOL_QUADTAP) return EVDEV_KEY_TYPE_NONE; if (code >= KEY_ESC && code <= KEY_MICMUTE) @@ -630,16 +630,16 @@ evdev_process_key(struct evdev_device *device, if (e->value == 2) return; - if (e->code == BTN_TOUCH) { - if (!device->is_mt) + type = get_key_type(e->code); + + if (type == EVDEV_KEY_TYPE_NONE) { + if (e->code == BTN_TOUCH && !device->is_mt) evdev_process_touch_button(device, time, e->value); return; } evdev_flush_pending_event(device, time); - type = get_key_type(e->code); - /* Ignore key release events from the kernel for keys that libinput * never got a pressed event for. */ if (e->value == 0) { diff --git a/test/touch.c b/test/touch.c index 875d94d..0e7f893 100644 --- a/test/touch.c +++ b/test/touch.c @@ -912,6 +912,114 @@ START_TEST(touch_point_no_minor_or_orientation) } END_TEST +START_TEST(touchscreen_with_btn_tool_finger_on_down) +{ + struct libevdev_uinput *uinput; + struct libinput *li; + struct libinput_device *device; + struct libinput_event *event; + struct libinput_event_touch *tev; + const struct input_absinfo abs[] = { + { ABS_X, 0, 1152, 0, 0, 0 }, + { ABS_Y, 0, 1920, 0, 0, 0 }, + { ABS_MT_SLOT, 0, 9, 0, 0, 0 }, + { ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 }, + { ABS_MT_POSITION_X, 0, 1152, 0, 0, 0 }, + { ABS_MT_POSITION_Y, 0, 1920, 0, 0, 0 }, + { ABS_MT_TOUCH_MAJOR, 0, 23, 0, 0, 0 }, + { ABS_MT_TOUCH_MINOR, 0, 23, 0, 0, 0 }, + { -1, -1, -1, -1, -1, -1 } + }; + const struct input_event input_sequence[] = { + { {0}, EV_ABS, ABS_MT_SLOT, 0}, + { {0}, EV_ABS, ABS_MT_TRACKING_ID, 9}, + { {0}, EV_KEY, BTN_TOUCH, 1}, + { {0}, EV_KEY, BTN_TOOL_FINGER, 1}, + { {0}, EV_ABS, ABS_MT_POSITION_X, 128}, + { {0}, EV_ABS, ABS_MT_POSITION_Y, 240}, + { {0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 5}, + { {0}, EV_ABS, ABS_MT_TOUCH_MINOR, 4}, + { {0}, EV_SYN, SYN_REPORT, 0}, + { {0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 6}, + { {0}, EV_SYN, SYN_REPORT, 0}, + { {0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, + { {0}, EV_KEY, BTN_TOUCH, 0}, + { {0}, EV_KEY, BTN_TOOL_FINGER, 0}, + { {0}, EV_SYN, SYN_REPORT, 0} + }; + const int num_events = ARRAY_LENGTH(input_sequence); + const int width = 1152; + const int height = 1920; + int x, y, major, minor; + + uinput = litest_create_uinput_abs_device( + "test device", + NULL, abs, + EV_KEY, BTN_TOUCH, + EV_KEY, BTN_TOOL_FINGER, + INPUT_PROP_MAX, INPUT_PROP_DIRECT, + -1, -1); + + li = litest_create_context(); + device = libinput_path_add_device(li, + libevdev_uinput_get_devnode(uinput)); + ck_assert(device != NULL); + device = libinput_device_ref(device); + litest_drain_events(li); + + for (int i = 0; i!=num_events; ++i) + libevdev_uinput_write_event(uinput, + input_sequence[i].type, + input_sequence[i].code, + input_sequence[i].value); + + litest_wait_for_event(li); + + event = libinput_get_event(li); + tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN); + x = round(libinput_event_touch_get_x_transformed(tev, width)); + y = round(libinput_event_touch_get_y_transformed(tev, height)), + major = round( + libinput_event_touch_get_major_transformed(tev, width, height)); + minor = round( + libinput_event_touch_get_minor_transformed(tev, width, height)); + ck_assert_int_eq(x, 128); + ck_assert_int_eq(y, 240); + ck_assert_int_