diff --git a/src/libei-private.h b/src/libei-private.h index 10133c9..02791a8 100644 --- a/src/libei-private.h +++ b/src/libei-private.h @@ -131,9 +131,6 @@ ei_get_interface(struct ei *ei); int ei_set_socket(struct ei *ei, int fd); -void -ei_disconnect(struct ei *ei); - struct ei * ei_get_context(struct ei *ei); diff --git a/src/libei.c b/src/libei.c index c80018b..286e062 100644 --- a/src/libei.c +++ b/src/libei.c @@ -580,7 +580,7 @@ ei_queue_touch_up_event(struct ei_device *device, uint32_t touchid) queue_event(ei_device_get_context(device), e); } -void +_public_ void ei_disconnect(struct ei *ei) { if (ei->state == EI_STATE_DISCONNECTED || diff --git a/src/libei.h b/src/libei.h index 8375de1..a9588dd 100644 --- a/src/libei.h +++ b/src/libei.h @@ -849,6 +849,24 @@ ei_peek_event(struct ei *ei); uint64_t ei_now(struct ei *ei); +/** + * Disconnect the current ei context from the EIS implementation. + * + * After a call to ei_disconnect(), ei_get_event() will return + * events to remove resources (e.g. seats and devices) as if they + * had been removed by the EIS implementation. The last event + * returned by ei_get_event() is @ref EI_EVENT_DISCONNECT after + * which the context should be considered inert and any + * remaining resources released with ei_unref(). + * + * This does not free the resources associated with the ei context, use + * ei_unref(). + * + * @since 1.4 + */ +void +ei_disconnect(struct ei *ei); + /** * @ingroup libei-seat * diff --git a/test/test-ei.c b/test/test-ei.c index 711e0d3..697011e 100644 --- a/test/test-ei.c +++ b/test/test-ei.c @@ -67,7 +67,7 @@ MUNIT_TEST(test_ei_disconnect_immediately) return MUNIT_OK; } -MUNIT_TEST(test_ei_disconnect_self_immediately) +MUNIT_TEST(test_ei_unref_self_immediately) { _unref_(peck) *peck = peck_new(); @@ -93,6 +93,30 @@ MUNIT_TEST(test_ei_disconnect_self_immediately) return MUNIT_OK; } +MUNIT_TEST(test_ei_disconnect_self_immediately) +{ + _unref_(peck) *peck = peck_new(); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE); + peck_dispatch_until_stable(peck); + + /* Disconnect before server processed CONNECT */ + with_client(peck) { + ei_disconnect(ei); + } + + peck_dispatch_until_stable(peck); + + /* Expect the client to get a disconnect event */ + with_server(peck) { + _unref_(eis_event) *connect = + peck_eis_next_event(eis, EIS_EVENT_CLIENT_CONNECT); + _unref_(eis_event) *disconnect = + peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT); + } + + return MUNIT_OK; +} MUNIT_TEST(test_ei_disconnect_after_connect) { @@ -130,7 +154,7 @@ MUNIT_TEST(test_ei_disconnect_after_connect) return MUNIT_OK; } -MUNIT_TEST(test_ei_disconnect_self_after_connect) +MUNIT_TEST(test_ei_unref_self_after_connect) { _unref_(peck) *peck = peck_new(); @@ -154,6 +178,29 @@ MUNIT_TEST(test_ei_disconnect_self_after_connect) return MUNIT_OK; } +MUNIT_TEST(test_ei_disconnect_self_after_connect) +{ + _unref_(peck) *peck = peck_new(); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE); + peck_dispatch_until_stable(peck); + + with_client(peck) { + ei_disconnect(ei); + } + + peck_dispatch_until_stable(peck); + + with_server(peck) { + _unref_(eis_event) *connect = + peck_eis_next_event(eis, EIS_EVENT_CLIENT_CONNECT); + _unref_(eis_event) *disconnect = + peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT); + } + + return MUNIT_OK; +} + MUNIT_TEST(test_ei_disconnect_after_seat) { _unref_(peck) *peck = peck_new(); @@ -203,9 +250,8 @@ MUNIT_TEST(test_ei_disconnect_self_after_seat) peck_ei_next_event(ei, EI_EVENT_CONNECT); _unref_(ei_event) *seat = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED); - peck_drop_ei(peck); /* Disconnect from client */ - ei_unref(ei); + ei_disconnect(ei); /* There is no way to disconnect from the server without * destroying the context, so we don't care about the actual @@ -274,8 +320,7 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_before_received) struct ei_seat *seat = ei_event_get_seat(event); ei_seat_bind_capabilities(seat, EI_DEVICE_CAP_POINTER, NULL); /* Disconnect before the server can process the bind event */ - peck_drop_ei(peck); - ei_unref(ei); + ei_disconnect(ei); } peck_dispatch_eis(peck); @@ -354,8 +399,7 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_after_received) peck_dispatch_eis(peck); with_client(peck) { - peck_drop_ei(peck); - ei_unref(ei); + ei_disconnect(ei); } peck_dispatch_eis(peck);