struct wl_signal destroy_signal;
struct ucred ucred;
int error;
+ struct wl_signal resource_created_signal;
};
struct wl_display {
if (client == NULL)
return NULL;
+ wl_signal_init(&client->resource_created_signal);
client->display = display;
client->source = wl_event_loop_add_fd(display->loop, fd,
WL_EVENT_READABLE,
wl_event_source_remove(client->source);
close(wl_connection_destroy(client->connection));
wl_list_remove(&client->link);
+ wl_list_remove(&client->resource_created_signal.listener_list);
free(client);
}
resource->destroy = destroy;
}
+/** Create a new resource object
+ *
+ * \param client The client owner of the new resource.
+ * \param interface The interface of the new resource.
+ * \param version The version of the new resource.
+ * \param id The id of the new resource. If 0, an available id will be used.
+ *
+ * Listeners added with \a wl_client_add_resource_created_listener will be
+ * notified at the end of this function.
+ *
+ * \memberof wl_resource
+ */
WL_EXPORT struct wl_resource *
wl_resource_create(struct wl_client *client,
const struct wl_interface *interface,
return NULL;
}
+ wl_signal_emit(&client->resource_created_signal, resource);
return resource;
}
return container_of(link, struct wl_client, link);
}
+/** Add a listener for the client's resource creation signal
+ *
+ * \param client The client object
+ * \param listener The listener to be added
+ *
+ * When a new resource is created for this client the listener
+ * will be notified, carrying the new resource as the data argument.
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT void
+wl_client_add_resource_created_listener(struct wl_client *client,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&client->resource_created_signal, listener);
+}
+
/** \cond */ /* Deprecated functions below. */
uint32_t
assert(compositor->client == client);
}
+static const char *
+setup_compositor(struct compositor *compositor)
+{
+ const char *socket;
+
+ require_xdg_runtime_dir();
+
+ compositor->display = wl_display_create();
+ socket = wl_display_add_socket_auto(compositor->display);
+
+ compositor->listener.notify = client_created;
+ wl_display_add_client_created_listener(compositor->display, &compositor->listener);
+
+ return socket;
+}
+
+static void
+cleanup_compositor(struct compositor *compositor)
+{
+ wl_client_destroy(compositor->client);
+ wl_display_destroy(compositor->display);
+}
+
TEST(new_client_connect)
{
const char *socket;
struct wl_display *display;
} client;
- require_xdg_runtime_dir();
-
- compositor.display = wl_display_create();
- socket = wl_display_add_socket_auto(compositor.display);
-
- compositor.listener.notify = client_created;
- wl_display_add_client_created_listener(compositor.display, &compositor.listener);
+ socket = setup_compositor(&compositor);
client.display = wl_display_connect(socket);
check_client_list(&compositor);
+
+
+ wl_display_disconnect(client.display);
+ cleanup_compositor(&compositor);
+}
+
+struct resource_listener {
+ struct wl_listener listener;
+ int count;
+};
+
+static void
+resource_created(struct wl_listener *listener, void *data)
+{
+ struct resource_listener *l;
+ l = wl_container_of(listener, l, listener);
+ l->count++;
+}
+
+TEST(new_resource)
+{
+ const char *socket;
+ struct compositor compositor = { 0 };
+ struct {
+ struct wl_display *display;
+ struct wl_callback *cb;
+ } client;
+ struct resource_listener resource_listener;
+
+ socket = setup_compositor(&compositor);
+ client.display = wl_display_connect(socket);
+ wl_event_loop_dispatch(wl_display_get_event_loop(compositor.display), 100);
+
+ resource_listener.count = 0;
+ resource_listener.listener.notify = resource_created;
+ wl_client_add_resource_created_listener(compositor.client,
+ &resource_listener.listener);
+
+ client.cb = wl_display_sync(client.display);
+ wl_display_flush(client.display);
+ wl_event_loop_dispatch(wl_display_get_event_loop(compositor.display), 100);
+
+ assert(resource_listener.count == 1);
+
+ wl_callback_destroy(client.cb);
wl_display_disconnect(client.display);
+ cleanup_compositor(&compositor);
- wl_client_destroy(compositor.client);
- wl_display_destroy(compositor.display);
+ /* This is defined to be safe also after client destruction */
+ wl_list_remove(&resource_listener.listener.link);
}