From 8474d03e03cc4fbb72912613b3eeafd15e0f132f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 3 Mar 2022 14:42:49 +1000 Subject: [PATCH] test: add test cases for eis -> ei events Copy/paste from the normal test-cases, with the appropriate switching of server vs client and s/eis/ei/ --- test/eierpecken.c | 17 ++ test/eierpecken.h | 12 + test/test-ei-device.c | 682 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 711 insertions(+) diff --git a/test/eierpecken.c b/test/eierpecken.c index 5391857..cc90214 100644 --- a/test/eierpecken.c +++ b/test/eierpecken.c @@ -999,6 +999,23 @@ _peck_eis_touch_event(struct eis *eis, enum eis_event_type type, double x, doubl return event; } +struct ei_event * +_peck_ei_touch_event(struct ei *ei, enum ei_event_type type, double x, double y, int lineno) +{ + assert(type == EI_EVENT_TOUCH_DOWN || type == EI_EVENT_TOUCH_MOTION); + + struct ei_event *event = _peck_ei_next_event(ei, type, lineno); + double ex = ei_event_touch_get_x(event); + double ey = ei_event_touch_get_y(event); + + if (fabs(ex - x) > 1e-3 || fabs(ey - y) > 1e-3) { + munit_errorf("Touch coordinate mismatch: have (%.2f/%.2f) need (%.2f/%.2f)\n", + ex, ey, x, y); + } + + return event; +} + const char * peck_ei_event_name(struct ei_event *e) { diff --git a/test/eierpecken.h b/test/eierpecken.h index e7672dd..cd0fbd0 100644 --- a/test/eierpecken.h +++ b/test/eierpecken.h @@ -277,6 +277,17 @@ struct eis_event * _peck_eis_touch_event(struct eis *eis, enum eis_event_type type, double x, double y, int lineno); +#define peck_ei_touch_down(_ei, _x, _y) \ + _peck_ei_touch_event(_ei, EI_EVENT_TOUCH_DOWN, _x, _y, __LINE__) +#define peck_ei_touch_motion(_ei, _x, _y) \ + _peck_ei_touch_event(_ei, EI_EVENT_TOUCH_MOTION, _x, _y, __LINE__) +#define peck_ei_touch_up(_ei) \ + _peck_ei_next_event(_ei, EI_EVENT_TOUCH_UP, __LINE__) + +struct ei_event * +_peck_ei_touch_event(struct ei *ei, enum ei_event_type type, + double x, double y, int lineno); + const char * peck_ei_event_name(struct ei_event *e); @@ -304,6 +315,7 @@ DEFINE_UNREF_CLEANUP_FUNC(eis); DEFINE_UNREF_CLEANUP_FUNC(eis_client); DEFINE_UNREF_CLEANUP_FUNC(eis_event); DEFINE_UNREF_CLEANUP_FUNC(eis_device); +DEFINE_UNREF_CLEANUP_FUNC(eis_touch); DEFINE_UNREF_CLEANUP_FUNC(eis_keymap); DEFINE_UNREF_CLEANUP_FUNC(eis_seat); DEFINE_UNREF_CLEANUP_FUNC(eis_region); diff --git a/test/test-ei-device.c b/test/test-ei-device.c index 6854940..461c773 100644 --- a/test/test-ei-device.c +++ b/test/test-ei-device.c @@ -1101,3 +1101,685 @@ MUNIT_TEST(test_ei_keyboard_modifiers) return MUNIT_OK; } + +MUNIT_TEST(test_passive_ei_device_start_stop_emulating) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE); + + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSEAT); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_RESUMED); + + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_start_emulating(device); + eis_device_stop_emulating(device); + } + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *start = + peck_ei_next_event(ei, EI_EVENT_DEVICE_START_EMULATING); + _unref_(ei_event) *stop = + peck_ei_next_event(ei, EI_EVENT_DEVICE_STOP_EMULATING); + } + + return MUNIT_OK; +} + +MUNIT_TEST(test_passive_ei_device_stop_emulating_when_removing) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE); + + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSEAT); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_RESUMED); + + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_start_emulating(device); + eis_device_remove(device); + } + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *start = + peck_ei_next_event(ei, EI_EVENT_DEVICE_START_EMULATING); + _unref_(ei_event) *stop = + peck_ei_next_event(ei, EI_EVENT_DEVICE_STOP_EMULATING); + _unref_(ei_event) *close = + peck_ei_next_event(ei, EI_EVENT_DEVICE_REMOVED); + } + + return MUNIT_OK; +} + +/* Same as test_passive_ei_device_pointer_rel() but for a passive context */ +MUNIT_TEST(test_passive_ei_device_keyboard_key) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_keyboard(peck); + eis_device_keyboard_key(device, KEY_Q, true); + eis_device_frame(device); + eis_device_keyboard_key(device, KEY_Q, false); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *press = + peck_ei_next_event(ei, EI_EVENT_KEYBOARD_KEY); + munit_assert_int(ei_event_keyboard_get_key(press), ==, KEY_Q); + munit_assert_true(ei_event_keyboard_get_key_is_press(press)); + + _unref_(ei_event) *release = + peck_ei_next_event(ei, EI_EVENT_KEYBOARD_KEY); + munit_assert_int(ei_event_keyboard_get_key(release), ==, KEY_Q); + munit_assert_false(ei_event_keyboard_get_key_is_press(release)); + } + + return MUNIT_OK; +} + +/* Same as test_ei_device_pointer_rel() but for a passive context */ +MUNIT_TEST(test_passive_ei_device_pointer_rel) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_pointer_motion(device, 1, 2); + eis_device_frame(device); + eis_device_pointer_motion(device, 0.3, 1.4); + eis_device_frame(device); + eis_device_pointer_motion(device, 100, 200); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *first = + peck_ei_next_event(ei, EI_EVENT_POINTER_MOTION); + munit_assert_double_equal(ei_event_pointer_get_dx(first), 1.0, 2 /* precision */); + munit_assert_double_equal(ei_event_pointer_get_dy(first), 2.0, 2 /* precision */); + + _unref_(ei_event) *second = + peck_ei_next_event(ei, EI_EVENT_POINTER_MOTION); + munit_assert_double_equal(ei_event_pointer_get_dx(second), 0.3, 2 /* precision */); + munit_assert_double_equal(ei_event_pointer_get_dy(second), 1.4, 2 /* precision */); + + _unref_(ei_event) *third = + peck_ei_next_event(ei, EI_EVENT_POINTER_MOTION); + munit_assert_double_equal(ei_event_pointer_get_dx(third), 100, 2 /* precision */); + munit_assert_double_equal(ei_event_pointer_get_dy(third), 200, 2 /* precision */); + } + + return MUNIT_OK; +} + +/* Same as test_ei_device_pointer_abs() but for a passive context */ +MUNIT_TEST(test_passive_ei_device_pointer_abs) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + struct eis_device *device = NULL; + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + with_server(peck) { + device = peck_eis_get_default_pointer_absolute(peck); + + for (int i = 0; i < 10; i++) { + eis_device_pointer_motion_absolute(device, 1 * i , 2 + i); + eis_device_frame(device); + } + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + for (int i = 0; i < 10; i++) { + _unref_(ei_event) *e = + peck_ei_next_event(ei, EI_EVENT_POINTER_MOTION_ABSOLUTE); + munit_assert_double_equal(ei_event_pointer_get_absolute_x(e), 1.0 * i, 2 /* precision */); + munit_assert_double_equal(ei_event_pointer_get_absolute_y(e), 2.0 + i, 2 /* precision */); + } + } + + with_server(peck) { + /* We know our default device has one region */ + struct eis_region *r = eis_device_get_region(device, 0); + uint32_t maxx = eis_region_get_x(r) + eis_region_get_width(r); + uint32_t maxy = eis_region_get_y(r) + eis_region_get_height(r); + + /* outside of pointer range, expect to be discarded */ + eis_device_pointer_motion_absolute(device, maxx + 1, maxy/2); + eis_device_frame(device); + eis_device_pointer_motion_absolute(device, maxx/2 , maxy + 1); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + peck_assert_no_ei_events(ei); + } + + with_server(peck) { + eis_device_remove(device); + /* absmotion after remove must not trigger an event */ + eis_device_pointer_motion_absolute(device, 100, 200); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *stop = + peck_ei_next_event(ei, EI_EVENT_DEVICE_STOP_EMULATING); + _unref_(ei_event) *closed = + peck_ei_next_event(ei, EI_EVENT_DEVICE_REMOVED); + peck_assert_no_ei_events(ei); + } + + return MUNIT_OK; +} + +/* same as test_ei_device_pointer_scroll but for a passive context */ +MUNIT_TEST(test_passive_ei_device_pointer_scroll) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_pointer_scroll(device, 1.1, 2.2); + eis_device_frame(device); + eis_device_pointer_scroll_discrete(device, 3, 4); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *first = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + munit_assert_double_equal(ei_event_pointer_get_scroll_x(first), 1.1, 2 /* precision */); + munit_assert_double_equal(ei_event_pointer_get_scroll_y(first), 2.2, 2 /* precision */); + + _unref_(ei_event) *second = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_DISCRETE); + munit_assert_int(ei_event_pointer_get_scroll_discrete_x(second), ==, 3); + munit_assert_int(ei_event_pointer_get_scroll_discrete_y(second), ==, 4); + } + + return MUNIT_OK; +} + +/* same as test_ei_device_pointer_scroll_stop but for a passive context */ +MUNIT_TEST(test_passive_ei_device_pointer_scroll_stop) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_pointer_scroll(device, 1.1, 2.2); + eis_device_frame(device); + eis_device_pointer_scroll_stop(device, true, false); + eis_device_frame(device); + eis_device_pointer_scroll_stop(device, false, true); + eis_device_frame(device); + + /* This should not generate an event */ + eis_device_pointer_scroll_stop(device, true, true); + eis_device_frame(device); + + /* But scrolling again will re-enable stopping */ + eis_device_pointer_scroll(device, 3.3, 4.4); + eis_device_frame(device); + eis_device_pointer_scroll_stop(device, true, true); + eis_device_frame(device); + + eis_device_pointer_scroll(device, 3.3, 4.4); + /* This one is a client bug and shouldn't trigger an event */ + eis_device_pointer_scroll_stop(device, false, false); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *scroll = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + + _unref_(ei_event) *first = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_STOP); + munit_assert(ei_event_pointer_get_scroll_stop_x(first)); + munit_assert(!ei_event_pointer_get_scroll_stop_y(first)); + + _unref_(ei_event) *second = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_STOP); + munit_assert(!ei_event_pointer_get_scroll_stop_x(second)); + munit_assert(ei_event_pointer_get_scroll_stop_y(second)); + + /* third one doesn't trigger an event */ + + _unref_(ei_event) *again = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + + _unref_(ei_event) *fourth = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_STOP); + munit_assert(ei_event_pointer_get_scroll_stop_x(fourth)); + munit_assert(ei_event_pointer_get_scroll_stop_y(fourth)); + + _unref_(ei_event) *again_again = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + + peck_assert_no_ei_events(ei); + } + + return MUNIT_OK; +} + +/* same as test_ei_device_pointer_scroll_cancel but for a passive context */ +MUNIT_TEST(test_passive_ei_device_pointer_scroll_cancel) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_pointer_scroll(device, 1.1, 2.2); + eis_device_frame(device); + eis_device_pointer_scroll_cancel(device, true, false); + eis_device_frame(device); + eis_device_pointer_scroll_cancel(device, false, true); + eis_device_frame(device); + + /* This should not generate an event */ + eis_device_pointer_scroll_cancel(device, true, true); + eis_device_frame(device); + + /* But scrolling again will re-enable stopping */ + eis_device_pointer_scroll(device, 3.3, 4.4); + eis_device_frame(device); + eis_device_pointer_scroll_cancel(device, true, true); + eis_device_frame(device); + + eis_device_pointer_scroll(device, 3.3, 4.4); + /* This one is a client bug and shouldn't trigger an event */ + eis_device_pointer_scroll_cancel(device, false, false); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *scroll = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + + _unref_(ei_event) *first = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_CANCEL); + munit_assert(ei_event_pointer_get_scroll_stop_x(first)); + munit_assert(!ei_event_pointer_get_scroll_stop_y(first)); + + _unref_(ei_event) *second = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_CANCEL); + munit_assert(!ei_event_pointer_get_scroll_stop_x(second)); + munit_assert(ei_event_pointer_get_scroll_stop_y(second)); + + /* third one doesn't trigger an event */ + + _unref_(ei_event) *again = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + + _unref_(ei_event) *fourth = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_CANCEL); + munit_assert(ei_event_pointer_get_scroll_stop_x(fourth)); + munit_assert(ei_event_pointer_get_scroll_stop_y(fourth)); + + _unref_(ei_event) *again_again = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + + peck_assert_no_ei_events(ei); + } + + return MUNIT_OK; +} + +/* same as test_ei_device_pointer_scroll_stop_cancel but for a passive context */ +MUNIT_TEST(test_passive_ei_device_pointer_scroll_stop_cancel) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + /* cancel after stop is fine, stop after cancel is ignored */ + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_pointer_scroll(device, 1.1, 2.2); + eis_device_frame(device); + peck_mark(peck); + eis_device_pointer_scroll_stop(device, true, false); + peck_mark(peck); + eis_device_frame(device); + eis_device_pointer_scroll_cancel(device, true, false); + peck_mark(peck); + eis_device_frame(device); + eis_device_pointer_scroll_cancel(device, false, true); + eis_device_frame(device); + peck_mark(peck); + + /* This should not generate an event */ + eis_device_pointer_scroll_stop(device, true, true); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *scroll = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL); + + _unref_(ei_event) *stop = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_STOP); + munit_assert(ei_event_pointer_get_scroll_stop_x(stop)); + munit_assert(!ei_event_pointer_get_scroll_stop_y(stop)); + + _unref_(ei_event) *first = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_CANCEL); + munit_assert(ei_event_pointer_get_scroll_stop_x(first)); + munit_assert(!ei_event_pointer_get_scroll_stop_y(first)); + + _unref_(ei_event) *second = + peck_ei_next_event(ei, EI_EVENT_POINTER_SCROLL_CANCEL); + munit_assert(!ei_event_pointer_get_scroll_stop_x(second)); + munit_assert(ei_event_pointer_get_scroll_stop_y(second)); + + /* third one doesn't trigger an event */ + peck_assert_no_ei_events(ei); + } + + return MUNIT_OK; +} + +/* same as test_ei_device_touch but for a passive context */ +MUNIT_TEST(test_passive_ei_device_touch) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + struct eis_device *device = NULL; + uint32_t maxx = 0, maxy = 0; + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_TOUCH); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + with_server(peck) { + device = peck_eis_get_default_touch(peck); + /* We know our default device has one region */ + + struct eis_region *r = eis_device_get_region(device, 0); + maxx = eis_region_get_x(r) + eis_region_get_width(r); + maxy = eis_region_get_y(r) + eis_region_get_height(r); + + _unref_(eis_touch) *t = eis_device_touch_new(device); + eis_touch_down(t, 1, 2); + eis_device_frame(device); + eis_touch_motion(t, 200, 500); + eis_device_frame(device); + eis_touch_up(t); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *down = peck_ei_touch_down(ei, 1, 2); + uint32_t tid = ei_event_touch_get_id(down); + + _unref_(ei_event) *motion = peck_ei_touch_motion(ei, 200, 500); + munit_assert_uint32(ei_event_touch_get_id(motion), ==, tid); + + _unref_(ei_event) *up = peck_ei_touch_up(ei); + munit_assert_uint32(ei_event_touch_get_id(up), ==, tid); + } + + with_server(peck) { + _unref_(eis_touch) *t = eis_device_touch_new(device); + /* outside clip range, expect touch to be dropped */ + eis_touch_down(t, maxx + 1, maxy/2); + eis_device_frame(device); + eis_touch_motion(t, maxx + 1, maxy/3); + eis_device_frame(device); + eis_touch_up(t); + eis_device_frame(device); + + /* outside clip range, expect touch to be dropped */ + eis_touch_down(t, maxx/2, maxy + 1); + eis_device_frame(device); + eis_touch_motion(t, maxx/3, maxy + 1); + eis_device_frame(device); + eis_touch_up(t); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + peck_assert_no_ei_events(ei); + } + + with_server(peck) { + _unref_(eis_touch) *t = eis_device_touch_new(device); + eis_touch_down(t, 100, 200); + eis_device_frame(device); + /* outside allowed range, generates a touch up */ + eis_touch_motion(t, maxx + 1, 200); + eis_device_frame(device); + eis_touch_up(t); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *down = peck_ei_touch_down(ei, 100, 200); + _unref_(ei_event) *up = peck_ei_touch_up(ei); + } + + with_server(peck) { + _unref_(eis_touch) *t = eis_device_touch_new(device); + eis_touch_down(t, 100, 100); + eis_device_frame(device); + /* client forgets to touch up, touch_unref takes care of it */ + /* FIXME: this doesn't work with frames */ + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *down = peck_ei_touch_down(ei, 100, 100); + _unref_(ei_event) *up = peck_ei_touch_up(ei); + } + + with_server(peck) { + /* touch only allocated, not actually set down */ + _unref_(eis_touch) *t1 = eis_device_touch_new(device); + + /* touch never set down */ + _unref_(eis_touch) *t2 = eis_device_touch_new(device); + eis_touch_up(t2); + eis_device_frame(device); + + /* touch never set down */ + _unref_(eis_touch) *t3 = eis_device_touch_new(device); + eis_touch_motion(t3, 100, 200); + eis_device_frame(device); + eis_touch_up(t3); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + with_client(peck) { + peck_assert_no_ei_events(ei); + } + + with_server(peck) { + /* touch re-used */ + _unref_(eis_touch) *t = eis_device_touch_new(device); + eis_touch_down(t, 100, 200); + eis_device_frame(device); + eis_touch_up(t); + eis_device_frame(device); + eis_touch_down(t, 200, 300); + eis_device_frame(device); + eis_touch_motion(t, 300, 400); + eis_device_frame(device); + eis_touch_up(t); + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *down = peck_ei_touch_down(ei, 100, 200); + _unref_(ei_event) *up = peck_ei_touch_up(ei); + peck_assert_no_ei_events(ei); + } + + with_server(peck) { + /* double-down, double-up */ + _unref_(eis_touch) *t = eis_device_touch_new(device); + eis_touch_down(t, 100, 200); + eis_device_frame(device); + eis_touch_down(t, 200, 300); /* ignored */ + eis_device_frame(device); + eis_touch_motion(t, 300, 400); + eis_device_frame(device); + eis_touch_up(t); + eis_device_frame(device); + eis_touch_up(t); /* ignored */ + eis_device_frame(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *down = peck_ei_touch_down(ei, 100, 200); + _unref_(ei_event) *motion = peck_ei_touch_motion(ei, 300, 400); + _unref_(ei_event) *up = peck_ei_touch_up(ei); + peck_assert_no_ei_events(ei); + } + + return MUNIT_OK; +} + +/* same as test_ei_device_multitouch but for a passive context */ +MUNIT_TEST(test_passive_ei_device_multitouch) +{ + _unref_(peck) *peck = peck_new_context(PECK_EI_PASSIVE); + struct ei_device *device = NULL; + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_TOUCH); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES); + peck_dispatch_until_stable(peck); + + peck_dispatch_until_stable(peck); + + with_client(peck) { + device = peck_ei_get_default_touch(peck); + _unref_(ei_touch) *t1 = ei_device_touch_new(device); + _unref_(ei_touch) *t2 = ei_device_touch_new(device); + ei_touch_down(t1, 1, 2); + ei_device_frame(device); + ei_touch_motion(t1, 2, 3); + ei_device_frame(device); + + ei_touch_down(t2, 3, 4); + ei_device_frame(device); + ei_touch_motion(t2, 4, 5); + ei_device_frame(device); + + ei_touch_up(t2); + ei_touch_up(t1); + } + + peck_dispatch_until_stable(peck); + + with_server(peck) { + _unref_(eis_event) *down1 = peck_eis_touch_down(eis, 1, 2); + uint32_t tid1 = eis_event_touch_get_id(down1); + + _unref_(eis_event) *motion1 = peck_eis_touch_motion(eis, 2, 3); + munit_assert_uint32(eis_event_touch_get_id(motion1), ==, tid1); + + _unref_(eis_event) *down2 = peck_eis_touch_down(eis, 3, 4); + uint32_t tid2 = eis_event_touch_get_id(down2); + munit_assert_uint32(tid2, !=, tid1); + + _unref_(eis_event) *motion2 = peck_eis_touch_motion(eis, 4, 5); + munit_assert_uint32(eis_event_touch_get_id(motion2), ==, tid2); + + _unref_(eis_event) *up2 = peck_eis_touch_up(eis); + munit_assert_uint32(eis_event_touch_get_id(up2), ==, tid2); + + _unref_(eis_event) *up1 = peck_eis_touch_up(eis); + munit_assert_uint32(eis_event_touch_get_id(up1), ==, tid1); + } + + return MUNIT_OK; +}