diff --git a/meson.build b/meson.build
index b73bca8..2280113 100644
--- a/meson.build
+++ b/meson.build
@@ -83,6 +83,7 @@ src_libei = files(
'src/libei-fd.c',
'src/libei-keyboard.c',
'src/libei-log.c',
+ 'src/libei-pingpong.c',
'src/libei-pointer.c',
'src/libei-region.c',
'src/libei-region.c',
@@ -132,6 +133,7 @@ src_libeis = files(
'src/libeis-fd.c',
'src/libeis-keyboard.c',
'src/libeis-log.c',
+ 'src/libeis-pingpong.c',
'src/libeis-pointer.c',
'src/libeis-region.c',
'src/libeis-seat.c',
diff --git a/proto/protocol.xml b/proto/protocol.xml
index d6eb1f4..4d09683 100644
--- a/proto/protocol.xml
+++ b/proto/protocol.xml
@@ -366,7 +366,7 @@
a protocol violation to send this event to a client without the
"ei_callback" interface.
-
@@ -382,6 +382,31 @@
support for this interface in ei_connection_setup.interface.
+
+
+
+
+ Notify the client when the related request is done. Immediately after this event
+ the ei_callback object is destroyed by the EIS implementation and as such the
+ client must not attempt to use it after that point.
+
+ This event may only be sent on an ei_callback object that was created by the
+ client.
+
+
+
+
+
+
+
+ Interface for ensuring a roundtrip to the client implementation.
+ This interface is identical to ei_callback but is intended for
+ the EIS implementation to enforce a roundtrip to the client.
+
+ Note that for a client to receive objects of this type, it must announce
+ support for this interface in ei_connection_setup.interface.
+
+
@@ -397,18 +422,6 @@
-
-
-
- Notify the client when the related request is done. Immediately after this event
- the ei_callback object is destroyed by the EIS implementation and as such the
- client must not attempt to use it after that point.
-
- This event may only be sent on an ei_callback object that was created by the
- client.
-
-
-
diff --git a/src/libei-connection-setup.c b/src/libei-connection-setup.c
index 9d682d1..6a85bb5 100644
--- a/src/libei-connection-setup.c
+++ b/src/libei-connection-setup.c
@@ -86,6 +86,7 @@ ei_connection_setup_initialize(struct ei_connection_setup *setup, uint32_t versi
ei_connection_setup_request_interface_version(setup, "ei_connection_setup", VERSION_V(1));
ei_connection_setup_request_interface_version(setup, "ei_connection", VERSION_V(1));
ei_connection_setup_request_interface_version(setup, "ei_callback", VERSION_V(1));
+ ei_connection_setup_request_interface_version(setup, "ei_pingpong", VERSION_V(1));
ei_connection_setup_request_interface_version(setup, "ei_seat", VERSION_V(1));
ei_connection_setup_request_interface_version(setup, "ei_device", VERSION_V(1));
ei_connection_setup_request_interface_version(setup, "ei_pointer", VERSION_V(1));
diff --git a/src/libei-pingpong.c b/src/libei-pingpong.c
new file mode 100644
index 0000000..2b22e99
--- /dev/null
+++ b/src/libei-pingpong.c
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include
+#include
+
+#include "util-bits.h"
+#include "util-macros.h"
+#include "util-mem.h"
+#include "util-io.h"
+#include "util-strings.h"
+#include "util-version.h"
+
+#include "libei-private.h"
+#include "ei-proto.h"
+
+static void
+ei_pingpong_destroy(struct ei_pingpong *pingpong)
+{
+ struct ei *ei = ei_pingpong_get_context(pingpong);
+ ei_unregister_object(ei, &pingpong->proto_object);
+}
+
+OBJECT_IMPLEMENT_REF(ei_pingpong);
+OBJECT_IMPLEMENT_UNREF_CLEANUP(ei_pingpong);
+OBJECT_IMPLEMENT_GETTER(ei_pingpong, user_data, void*);
+OBJECT_IMPLEMENT_SETTER(ei_pingpong, user_data, void*);
+OBJECT_IMPLEMENT_GETTER_AS_REF(ei_pingpong, proto_object, const struct brei_object*);
+
+static
+OBJECT_IMPLEMENT_CREATE(ei_pingpong);
+static
+OBJECT_IMPLEMENT_PARENT(ei_pingpong, ei);
+
+struct ei*
+ei_pingpong_get_context(struct ei_pingpong *pingpong)
+{
+ assert(pingpong);
+ return ei_pingpong_parent(pingpong);
+}
+
+uint32_t
+ei_pingpong_get_id(struct ei_pingpong *pingpong)
+{
+ return pingpong->proto_object.id;
+}
+
+static const struct ei_pingpong_interface interface = {
+};
+
+const struct ei_pingpong_interface *
+ei_pingpong_get_interface(struct ei_pingpong *pingpong) {
+ return &interface;
+}
+
+struct ei_pingpong *
+ei_pingpong_new(struct ei *ei, ei_pingpong_func func, void *pingpong_data)
+{
+ struct ei_pingpong *pingpong = ei_pingpong_create(&ei->object);
+
+ pingpong->proto_object.id = ei_get_new_id(ei);
+ pingpong->proto_object.implementation = pingpong;
+ pingpong->proto_object.interface = &ei_pingpong_proto_interface;
+ pingpong->proto_object.version = VERSION_V(1);
+ pingpong->pingpong_data = pingpong_data;
+ ei_register_object(ei, &pingpong->proto_object);
+
+ pingpong->func = func;
+ list_init(&pingpong->link);
+
+ return pingpong; /* ref owned by caller */
+}
+
+struct ei_pingpong *
+ei_pingpong_new_for_id(struct ei *ei, uint32_t id, uint32_t version)
+{
+ struct ei_pingpong *pingpong = ei_pingpong_create(&ei->object);
+
+ pingpong->proto_object.id = id;
+ pingpong->proto_object.implementation = pingpong;
+ pingpong->proto_object.interface = &ei_pingpong_proto_interface;
+ pingpong->proto_object.version = version; /* FIXME */
+ ei_register_object(ei, &pingpong->proto_object);
+ list_init(&pingpong->link);
+
+ return pingpong; /* ref owned by caller */
+}
diff --git a/src/libei-pingpong.h b/src/libei-pingpong.h
new file mode 100644
index 0000000..388c91d
--- /dev/null
+++ b/src/libei-pingpong.h
@@ -0,0 +1,62 @@
+
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "util-object.h"
+#include "util-list.h"
+#include "brei-shared.h"
+
+struct ei;
+struct ei_pingpong;
+
+typedef void (*ei_pingpong_func)(struct ei_pingpong *pingpong, void *pingpong_data, uint32_t proto_data);
+
+/* This is a protocol-only object, not exposed in the API */
+struct ei_pingpong {
+ struct object object;
+ struct brei_object proto_object;
+ void *user_data; /* Note: user-data is attached to the object */
+
+ struct list link; /* for use by the callers, if needed */
+
+ ei_pingpong_func func;
+ void *pingpong_data; /* Note: pingpong-data is attached to the pingpong */
+};
+
+OBJECT_DECLARE_GETTER(ei_pingpong, context, struct ei*);
+OBJECT_DECLARE_GETTER(ei_pingpong, proto_object, const struct brei_object *);
+OBJECT_DECLARE_GETTER(ei_pingpong, id, uint32_t);
+OBJECT_DECLARE_GETTER(ei_pingpong, interface, const struct ei_pingpong_interface *);
+OBJECT_DECLARE_GETTER(ei_pingpong, user_data, void *);
+OBJECT_DECLARE_SETTER(ei_pingpong, user_data, void *);
+OBJECT_DECLARE_REF(ei_pingpong);
+OBJECT_DECLARE_UNREF(ei_pingpong);
+
+struct ei_pingpong *
+ei_pingpong_new(struct ei *ei, ei_pingpong_func func, void *pingpong_data);
+
+struct ei_pingpong *
+ei_pingpong_new_for_id(struct ei *ei, uint32_t id, uint32_t version);
diff --git a/src/libei-private.h b/src/libei-private.h
index 3a7ad53..cd700da 100644
--- a/src/libei-private.h
+++ b/src/libei-private.h
@@ -42,6 +42,7 @@
#include "libei-device.h"
#include "libei-keyboard.h"
#include "libei-event.h"
+#include "libei-pingpong.h"
#include "libei-pointer.h"
#include "libei-region.h"
#include "libei-touchscreen.h"
diff --git a/src/libei.c b/src/libei.c
index 9a7423f..5c15ef2 100644
--- a/src/libei.c
+++ b/src/libei.c
@@ -83,7 +83,7 @@ OBJECT_IMPLEMENT_GETTER(ei, connection, struct ei_connection *);
DEFINE_UNREF_CLEANUP_FUNC(ei_device);
DEFINE_UNREF_CLEANUP_FUNC(ei_region);
-DEFINE_UNREF_CLEANUP_FUNC(ei_callback);
+DEFINE_UNREF_CLEANUP_FUNC(ei_pingpong);
struct ei *
ei_get_context(struct ei *ei)
@@ -675,9 +675,9 @@ static int
handle_msg_ping(struct ei_connection *connection, uint32_t id, uint32_t version)
{
struct ei *ei = ei_connection_get_context(connection);
- _unref_(ei_callback) *callback = ei_callback_new_for_id(ei, id, version);
+ _unref_(ei_pingpong) *pingpong = ei_pingpong_new_for_id(ei, id, version);
- ei_callback_request_done(callback, 0);
+ ei_pingpong_request_done(pingpong, 0);
return 0;
}
diff --git a/src/libeis-callback.c b/src/libeis-callback.c
index a651a3f..a7c5549 100644
--- a/src/libeis-callback.c
+++ b/src/libeis-callback.c
@@ -80,15 +80,7 @@ eis_callback_get_version(struct eis_callback *callback)
return callback->proto_object.version;
}
-static int
-client_msg_done(struct eis_callback *callback, uint32_t callback_data)
-{
- callback->func(callback, callback->callback_data, callback_data);
- return 0;
-}
-
static const struct eis_callback_interface interface = {
- .done = client_msg_done,
};
const struct eis_callback_interface *
@@ -111,21 +103,3 @@ eis_callback_new(struct eis_client *client, uint32_t new_id, uint32_t version)
return callback; /* ref owned by caller */
}
-
-struct eis_callback *
-eis_callback_new_with_callback(struct eis_client *client, eis_callback_func func, void *callback_data)
-{
- struct eis_callback *callback = eis_callback_create(&client->object);
-
- callback->proto_object.id = eis_client_get_new_id(client);
- callback->proto_object.implementation = callback;
- callback->proto_object.interface = &eis_callback_proto_interface;
- callback->proto_object.version = VERSION_V(1); /* FIXME */
- callback->callback_data = callback_data;
- eis_client_register_object(client, &callback->proto_object);
-
- callback->func = func;
- list_init(&callback->link);
-
- return callback; /* ref owned by caller */
-}
diff --git a/src/libeis-client.c b/src/libeis-client.c
index bfb9096..5e6dad0 100644
--- a/src/libeis-client.c
+++ b/src/libeis-client.c
@@ -382,6 +382,7 @@ eis_client_new(struct eis *eis, int fd)
.ei_connection = VERSION_V(1),
.ei_connection_setup = VERSION_V(1),
.ei_callback = VERSION_V(1),
+ .ei_pingpong = VERSION_V(1),
.ei_seat = VERSION_V(1),
.ei_device = VERSION_V(1),
.ei_pointer = VERSION_V(1),
diff --git a/src/libeis-client.h b/src/libeis-client.h
index a7890ad..a7a6209 100644
--- a/src/libeis-client.h
+++ b/src/libeis-client.h
@@ -41,6 +41,7 @@ struct eis_client_interface_versions {
uint32_t ei_connection;
uint32_t ei_connection_setup;
uint32_t ei_callback;
+ uint32_t ei_pingpong;
uint32_t ei_seat;
uint32_t ei_device;
uint32_t ei_pointer;
diff --git a/src/libeis-connection-setup.c b/src/libeis-connection-setup.c
index 87edc54..0cdcee0 100644
--- a/src/libeis-connection-setup.c
+++ b/src/libeis-connection-setup.c
@@ -145,6 +145,7 @@ client_msg_interface_version(struct eis_connection_setup *setup, const char *nam
.server_version = &setup->server_versions.name_, \
}
VERSION_ENTRY(ei_callback),
+ VERSION_ENTRY(ei_pingpong),
VERSION_ENTRY(ei_connection),
VERSION_ENTRY(ei_connection_setup),
VERSION_ENTRY(ei_seat),
diff --git a/src/libeis-connection.c b/src/libeis-connection.c
index 05c222a..c734e35 100644
--- a/src/libeis-connection.c
+++ b/src/libeis-connection.c
@@ -43,11 +43,11 @@ eis_connection_destroy(struct eis_connection *connection)
struct eis_client *client = eis_connection_get_client(connection);
eis_client_unregister_object(client, &connection->proto_object);
- struct eis_callback *cb;
- list_for_each_safe(cb, &connection->pending_callbacks, link) {
+ struct eis_pingpong *cb;
+ list_for_each_safe(cb, &connection->pending_pingpongs, link) {
list_remove(&cb->link);
- free(eis_callback_get_user_data(cb));
- eis_callback_unref(cb);
+ free(eis_pingpong_get_user_data(cb));
+ eis_pingpong_unref(cb);
}
}
@@ -102,29 +102,29 @@ eis_connection_new(struct eis_client *client)
connection->proto_object.version = client->interface_versions.ei_connection;
eis_client_register_object(client, &connection->proto_object);
- list_init(&connection->pending_callbacks);
+ list_init(&connection->pending_pingpongs);
return connection; /* ref owned by caller */
}
-struct callback_user_data {
+struct pingpong_user_data {
eis_connection_ping_callback_t cb;
void *user_data;
};
static void
-ping_callback(struct eis_callback *callback, void *callback_data, uint32_t proto_data)
+ping_pingpong(struct eis_pingpong *pingpong, void *pingpong_data, uint32_t proto_data)
{
- struct eis_connection *connection = callback_data;
+ struct eis_connection *connection = pingpong_data;
- _cleanup_free_ struct callback_user_data *data = eis_callback_get_user_data(callback);
+ _cleanup_free_ struct pingpong_user_data *data = eis_pingpong_get_user_data(pingpong);
if (data->cb)
data->cb(connection, data->user_data);
/* remove from pending callbacks */
- list_remove(&callback->link);
- eis_callback_unref(callback);
+ list_remove(&pingpong->link);
+ eis_pingpong_unref(pingpong);
}
void
@@ -138,13 +138,13 @@ eis_connection_ping(struct eis_connection *connection, eis_connection_ping_callb
* then we extract the user_data on the object and call into the
* cb supplied to this function.
*/
- struct eis_callback *callback = eis_callback_new_with_callback(client, ping_callback, connection);
- struct callback_user_data *data = xalloc(sizeof *data);
+ struct eis_pingpong *pingpong = eis_pingpong_new(client, ping_pingpong, connection);
+ struct pingpong_user_data *data = xalloc(sizeof *data);
data->cb = cb;
data->user_data = user_data;
- eis_callback_set_user_data(callback, data);
- list_append(&connection->pending_callbacks, &callback->link);
+ eis_pingpong_set_user_data(pingpong, data);
+ list_append(&connection->pending_pingpongs, &pingpong->link);
- eis_connection_event_ping(connection, eis_callback_get_id(callback),
- eis_callback_get_version(callback));
+ eis_connection_event_ping(connection, eis_pingpong_get_id(pingpong),
+ eis_pingpong_get_version(pingpong));
}
diff --git a/src/libeis-connection.h b/src/libeis-connection.h
index 57576a7..684ccdb 100644
--- a/src/libeis-connection.h
+++ b/src/libeis-connection.h
@@ -36,7 +36,7 @@ struct eis_connection {
struct object object;
struct brei_object proto_object;
- struct list pending_callbacks;
+ struct list pending_pingpongs;
};
OBJECT_DECLARE_GETTER(eis_connection, context, struct eis *);
diff --git a/src/libeis-pingpong.c b/src/libeis-pingpong.c
new file mode 100644
index 0000000..2d57c2b
--- /dev/null
+++ b/src/libeis-pingpong.c
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include
+#include
+
+#include "util-bits.h"
+#include "util-macros.h"
+#include "util-mem.h"
+#include "util-io.h"
+#include "util-strings.h"
+#include "util-version.h"
+
+#include "libeis-private.h"
+#include "eis-proto.h"
+
+static void
+eis_pingpong_destroy(struct eis_pingpong *pingpong)
+{
+ struct eis_client * client = eis_pingpong_get_client(pingpong);
+ eis_client_unregister_object(client, &pingpong->proto_object);
+}
+
+OBJECT_IMPLEMENT_REF(eis_pingpong);
+OBJECT_IMPLEMENT_UNREF_CLEANUP(eis_pingpong);
+OBJECT_IMPLEMENT_GETTER_AS_REF(eis_pingpong, proto_object, const struct brei_object *);
+OBJECT_IMPLEMENT_GETTER(eis_pingpong, user_data, void *);
+OBJECT_IMPLEMENT_SETTER(eis_pingpong, user_data, void *);
+
+static
+OBJECT_IMPLEMENT_CREATE(eis_pingpong);
+static
+OBJECT_IMPLEMENT_PARENT(eis_pingpong, eis_client);
+
+struct eis_client*
+eis_pingpong_get_client(struct eis_pingpong *pingpong)
+{
+ return eis_pingpong_parent(pingpong);
+}
+
+struct eis*
+eis_pingpong_get_context(struct eis_pingpong *pingpong)
+{
+ struct eis_client *client = eis_pingpong_parent(pingpong);
+ return eis_client_get_context(client);
+}
+
+uint32_t
+eis_pingpong_get_id(struct eis_pingpong *pingpong)
+{
+ return pingpong->proto_object.id;
+}
+
+uint32_t
+eis_pingpong_get_version(struct eis_pingpong *pingpong)
+{
+ return pingpong->proto_object.version;
+}
+
+static int
+client_msg_done(struct eis_pingpong *pingpong, uint32_t pingpong_data)
+{
+ pingpong->func(pingpong, pingpong->pingpong_data, pingpong_data);
+ return 0;
+}
+
+static const struct eis_pingpong_interface interface = {
+ .done = client_msg_done,
+};
+
+const struct eis_pingpong_interface *
+eis_pingpong_get_interface(struct eis_pingpong *pingpong) {
+ return &interface;
+}
+
+struct eis_pingpong *
+eis_pingpong_new(struct eis_client *client, eis_pingpong_func func, void *pingpong_data)
+{
+ struct eis_pingpong *pingpong = eis_pingpong_create(&client->object);
+
+ pingpong->proto_object.id = eis_client_get_new_id(client);
+ pingpong->proto_object.implementation = pingpong;
+ pingpong->proto_object.interface = &eis_pingpong_proto_interface;
+ pingpong->proto_object.version = VERSION_V(1); /* FIXME */
+ pingpong->pingpong_data = pingpong_data;
+ eis_client_register_object(client, &pingpong->proto_object);
+
+ pingpong->func = func;
+ list_init(&pingpong->link);
+
+ return pingpong; /* ref owned by caller */
+}
diff --git a/src/libeis-pingpong.h b/src/libeis-pingpong.h
new file mode 100644
index 0000000..3b4d3f3
--- /dev/null
+++ b/src/libeis-pingpong.h
@@ -0,0 +1,61 @@
+
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "util-object.h"
+#include "brei-shared.h"
+
+struct eis;
+struct eis_client;
+struct eis_pingpong;
+
+typedef void (*eis_pingpong_func)(struct eis_pingpong *pingpong, void *pingpong_data, uint32_t proto_data);
+
+/* This is a protocol-only object, not exposed in the API */
+struct eis_pingpong {
+ struct object object;
+ struct brei_object proto_object;
+ void *user_data; /* Note: user-data is attached to the object */
+
+ struct list link; /* for use by the callers, if needed */
+
+ eis_pingpong_func func;
+ void *pingpong_data; /* Note: pingpong-data is attached to the pingpong */
+};
+
+OBJECT_DECLARE_GETTER(eis_pingpong, context, struct eis *);
+OBJECT_DECLARE_GETTER(eis_pingpong, client, struct eis_client *);
+OBJECT_DECLARE_GETTER(eis_pingpong, id, uint32_t);
+OBJECT_DECLARE_GETTER(eis_pingpong, version, uint32_t);
+OBJECT_DECLARE_GETTER(eis_pingpong, proto_object, const struct brei_object *);
+OBJECT_DECLARE_GETTER(eis_pingpong, interface, const struct eis_pingpong_interface *);
+OBJECT_DECLARE_GETTER(eis_pingpong, user_data, void*);
+OBJECT_DECLARE_SETTER(eis_pingpong, user_data, void*);
+OBJECT_DECLARE_REF(eis_pingpong);
+OBJECT_DECLARE_UNREF(eis_pingpong);
+
+struct eis_pingpong *
+eis_pingpong_new(struct eis_client *eis_client, eis_pingpong_func func, void *pingpong_data);
diff --git a/src/libeis-private.h b/src/libeis-private.h
index 9d4f251..d7e4712 100644
--- a/src/libeis-private.h
+++ b/src/libeis-private.h
@@ -41,7 +41,9 @@
#include "libeis-connection-setup.h"
#include "libeis-device.h"
#include "libeis-event.h"
+#include "libeis-pingpong.h"
#include "libeis-keyboard.h"
+#include "libeis-pingpong.h"
#include "libeis-pointer.h"
#include "libeis-region.h"
#include "libeis-seat.h"