From 7fbb08e0ca7a4565bd8262e6b7e1fce57fd511e8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 26 Jun 2014 21:31:53 -0400 Subject: [PATCH] tablet: copy the axis state into the tablet event The tablet state updates with each event during libinput_dispatch(), but the state in the event must reflect the state at the time of the event. Signed-off-by: Peter Hutterer Signed-off-by: Stephen Chandler Paul --- src/libinput.c | 4 +-- test/tablet.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/libinput.c b/src/libinput.c index 7d9d6a0f..ecbe33fc 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -86,7 +86,7 @@ struct libinput_event_tablet { enum libinput_button_state state; uint32_t seat_button_count; uint32_t time; - double *axes; + double axes[LIBINPUT_TABLET_AXIS_CNT]; unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_AXIS_CNT)]; struct libinput_tool *tool; }; @@ -1243,12 +1243,12 @@ tablet_notify_axis(struct libinput_device *device, *axis_event = (struct libinput_event_tablet) { .time = time, .tool = tool, - .axes = axes, }; memcpy(axis_event->changed_axes, changed_axes, sizeof(axis_event->changed_axes)); + memcpy(axis_event->axes, axes, sizeof(axis_event->axes)); post_device_event(device, LIBINPUT_EVENT_TABLET_AXIS, diff --git a/test/tablet.c b/test/tablet.c index 0e92c36c..70690743 100644 --- a/test/tablet.c +++ b/test/tablet.c @@ -239,6 +239,88 @@ START_TEST(motion) } END_TEST +START_TEST(motion_event_state) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_tablet *tablet_event; + int test_x, test_y; + double last_x, last_y; + + struct axis_replacement axes[] = { + { ABS_DISTANCE, 10 }, + { -1, -1 } + }; + + litest_drain_events(li); + litest_tablet_proximity_in(dev, 5, 100, axes); + litest_drain_events(li); + + /* couple of events that go left/bottom to right/top */ + for (test_x = 0, test_y = 100; test_x < 100; test_x += 10, test_y -= 10) + litest_tablet_proximity_in(dev, test_x, test_y, axes); + + libinput_dispatch(li); + + while ((event = libinput_get_event(li))) { + if (libinput_event_get_type(event) == LIBINPUT_EVENT_TABLET_AXIS) + break; + libinput_event_destroy(event); + } + + /* pop the first event off */ + ck_assert_notnull(event); + tablet_event = libinput_event_get_tablet_event(event); + ck_assert_notnull(tablet_event); + + last_x = libinput_event_tablet_get_axis_value(tablet_event, + LIBINPUT_TABLET_AXIS_X); + last_y = libinput_event_tablet_get_axis_value(tablet_event, + LIBINPUT_TABLET_AXIS_Y); + + /* mark with a button event, then go back to bottom/left */ + litest_event(dev, EV_KEY, BTN_STYLUS, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + + for (test_x = 100, test_y = 0; test_x > 0; test_x -= 10, test_y += 10) + litest_tablet_proximity_in(dev, test_x, test_y, axes); + + libinput_event_destroy(event); + libinput_dispatch(li); + ck_assert_int_eq(libinput_next_event_type(li), + LIBINPUT_EVENT_TABLET_AXIS); + + /* we expect all events up to the button event to go from + bottom/left to top/right */ + while ((event = libinput_get_event(li))) { + double x, y; + + if (libinput_event_get_type(event) != LIBINPUT_EVENT_TABLET_AXIS) + break; + + tablet_event = libinput_event_get_tablet_event(event); + ck_assert_notnull(tablet_event); + + x = libinput_event_tablet_get_axis_value(tablet_event, + LIBINPUT_TABLET_AXIS_X); + y = libinput_event_tablet_get_axis_value(tablet_event, + LIBINPUT_TABLET_AXIS_Y); + + ck_assert(x > last_x); + ck_assert(y < last_y); + + last_x = x; + last_y = y; + libinput_event_destroy(event); + } + + ck_assert_int_eq(libinput_event_get_type(event), + LIBINPUT_EVENT_TABLET_BUTTON); + libinput_event_destroy(event); +} +END_TEST + START_TEST(bad_distance_events) { struct litest_device *dev = litest_current_device(); @@ -610,6 +692,7 @@ main(int argc, char **argv) litest_add("tablet:proximity", proximity_in_out, LITEST_TABLET, LITEST_ANY); litest_add("tablet:proximity", bad_distance_events, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY); litest_add("tablet:motion", motion, LITEST_TABLET, LITEST_ANY); + litest_add("tablet:motion", motion_event_state, LITEST_TABLET, LITEST_ANY); litest_add("tablet:normalization", normalization, LITEST_TABLET, LITEST_ANY); litest_add("tablet:pad", pad_buttons_ignored, LITEST_TABLET, LITEST_ANY);