mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-02-05 04:06:20 -05:00
Merge branch 'event-dispatch-listener' into 'main'
wayland-server: Add wl_client_add_event_dispatch_listener See merge request wayland/wayland!358
This commit is contained in:
commit
650a3c6d63
3 changed files with 80 additions and 5 deletions
|
|
@ -342,6 +342,10 @@ struct wl_listener *
|
|||
wl_client_get_destroy_late_listener(struct wl_client *client,
|
||||
wl_notify_func_t notify);
|
||||
|
||||
void
|
||||
wl_client_add_event_dispatch_listener(struct wl_client *client,
|
||||
struct wl_listener *listener);
|
||||
|
||||
struct wl_resource *
|
||||
wl_client_get_object(struct wl_client *client, uint32_t id);
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ struct wl_client {
|
|||
struct wl_map objects;
|
||||
struct wl_priv_signal destroy_signal;
|
||||
struct wl_priv_signal destroy_late_signal;
|
||||
struct wl_priv_signal event_dispatch_signal;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
|
|
@ -214,12 +215,13 @@ handle_array(struct wl_resource *resource, uint32_t opcode,
|
|||
{
|
||||
struct wl_closure *closure;
|
||||
struct wl_object *object = &resource->object;
|
||||
struct wl_client *client = resource->client;
|
||||
|
||||
if (resource->client->error)
|
||||
if (client->error)
|
||||
return;
|
||||
|
||||
if (!verify_objects(resource, opcode, args)) {
|
||||
resource->client->error = true;
|
||||
client->error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -227,14 +229,17 @@ handle_array(struct wl_resource *resource, uint32_t opcode,
|
|||
&object->interface->events[opcode]);
|
||||
|
||||
if (closure == NULL) {
|
||||
resource->client->error = true;
|
||||
client->error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
log_closure(resource, closure, true);
|
||||
|
||||
if (send_func(closure, resource->client->connection))
|
||||
resource->client->error = true;
|
||||
if (send_func(closure, client->connection)) {
|
||||
client->error = true;
|
||||
} else {
|
||||
wl_priv_signal_final_emit(&client->event_dispatch_signal, client);
|
||||
}
|
||||
|
||||
wl_closure_destroy(closure);
|
||||
}
|
||||
|
|
@ -551,6 +556,7 @@ wl_client_create(struct wl_display *display, int fd)
|
|||
|
||||
wl_priv_signal_init(&client->destroy_signal);
|
||||
wl_priv_signal_init(&client->destroy_late_signal);
|
||||
wl_priv_signal_init(&client->event_dispatch_signal);
|
||||
if (bind_display(client, display) < 0)
|
||||
goto err_map;
|
||||
|
||||
|
|
@ -930,6 +936,27 @@ wl_client_get_destroy_late_listener(struct wl_client *client,
|
|||
return wl_priv_signal_get(&client->destroy_late_signal, notify);
|
||||
}
|
||||
|
||||
/** Add a listener to be called after successful event dispatch.
|
||||
*
|
||||
* \param client The client object.
|
||||
* \param listener The listener to be added.
|
||||
*
|
||||
* After an event has been dispatched to this client, the listener will
|
||||
* be notified.
|
||||
*
|
||||
* There is no requirement to remove the link of the wl_listener when the
|
||||
* signal is emitted.
|
||||
*
|
||||
* \memberof wl_client
|
||||
* \since 1.22.0
|
||||
*/
|
||||
WL_EXPORT void
|
||||
wl_client_add_event_dispatch_listener(struct wl_client *client,
|
||||
struct wl_listener *listener)
|
||||
{
|
||||
wl_priv_signal_add(&client->event_dispatch_signal, listener);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
wl_client_destroy(struct wl_client *client)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -158,3 +158,47 @@ TEST(client_destroy_listener)
|
|||
wl_display_destroy(display);
|
||||
}
|
||||
|
||||
struct event_dispatch_listener {
|
||||
struct wl_listener listener;
|
||||
bool done;
|
||||
};
|
||||
|
||||
static void
|
||||
event_dispatch_notify(struct wl_listener *l, void *data)
|
||||
{
|
||||
struct event_dispatch_listener *listener =
|
||||
wl_container_of(l, listener, listener);
|
||||
listener->done = true;
|
||||
}
|
||||
|
||||
TEST(event_dispatch_listener)
|
||||
{
|
||||
struct wl_display *display;
|
||||
struct wl_client *client;
|
||||
struct wl_resource *resource;
|
||||
struct event_dispatch_listener dispatch_listener;
|
||||
int s[2];
|
||||
|
||||
assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
|
||||
display = wl_display_create();
|
||||
assert(display);
|
||||
client = wl_client_create(display, s[0]);
|
||||
assert(client);
|
||||
|
||||
dispatch_listener.listener.notify = event_dispatch_notify;
|
||||
dispatch_listener.done = false;
|
||||
wl_client_add_event_dispatch_listener(client, &dispatch_listener.listener);
|
||||
|
||||
resource = wl_resource_create(client, &wl_seat_interface, 4, 0);
|
||||
assert(resource);
|
||||
wl_seat_send_name(resource, "default");
|
||||
|
||||
wl_event_loop_dispatch(wl_display_get_event_loop(display), 0);
|
||||
|
||||
assert(dispatch_listener.done);
|
||||
|
||||
close(s[1]);
|
||||
wl_client_destroy(client);
|
||||
wl_display_destroy(display);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue