Use a callback object instead of ad-hoc lists for sync and frame events

So obvious in retrospect.  The object system can do all the work for us
and keep track of pending calls as regular objects and we don't need to
abuse the resource system to get them cleaned up on client exit.  We
don't need the custom key management or (broken) lookup, we just sue
object IDs.  And last but not least, anybody can receive the callback,
not just display listeners.
This commit is contained in:
Kristian Høgsberg 2011-07-29 19:51:22 -07:00
parent 1648109c84
commit 0af17ed98c
4 changed files with 42 additions and 175 deletions

View file

@ -69,7 +69,7 @@ struct wl_display {
struct wl_hash_table *objects;
int run;
struct wl_list frame_list;
struct wl_list callback_list;
uint32_t client_id_range;
uint32_t id;
@ -78,14 +78,6 @@ struct wl_display {
struct wl_list client_list;
};
struct wl_frame_listener {
struct wl_resource resource;
struct wl_client *client;
uint32_t key;
struct wl_surface *surface;
struct wl_list link;
};
struct wl_global {
struct wl_object *object;
wl_global_bind_func_t func;
@ -531,51 +523,19 @@ display_bind(struct wl_client *client,
static void
display_sync(struct wl_client *client,
struct wl_display *display, uint32_t key)
struct wl_display *display, uint32_t id)
{
wl_client_post_event(client, &display->object, WL_DISPLAY_KEY, key, 0);
}
struct wl_object object;
static void
destroy_frame_listener(struct wl_resource *resource, struct wl_client *client)
{
struct wl_frame_listener *listener =
container_of(resource, struct wl_frame_listener, resource);
object.interface = &wl_callback_interface;
object.id = id;
wl_list_remove(&listener->link);
free(listener);
}
static void
display_frame(struct wl_client *client,
struct wl_display *display,
struct wl_surface *surface,
uint32_t key)
{
struct wl_frame_listener *listener;
listener = malloc(sizeof *listener);
if (listener == NULL) {
wl_client_post_no_memory(client);
return;
}
/* The listener is a resource so we destroy it when the client
* goes away. */
listener->resource.destroy = destroy_frame_listener;
listener->resource.object.id = 0;
listener->client = client;
listener->key = key;
listener->surface = surface;
wl_list_init(&listener->resource.destroy_listener_list);
wl_list_insert(client->resource_list.prev, &listener->resource.link);
wl_list_insert(display->frame_list.prev, &listener->link);
wl_client_post_event(client, &object, WL_CALLBACK_DONE, 0);
}
struct wl_display_interface display_interface = {
display_bind,
display_sync,
display_frame
};
@ -606,7 +566,7 @@ wl_display_create(void)
return NULL;
}
wl_list_init(&display->frame_list);
wl_list_init(&display->callback_list);
wl_list_init(&display->global_list);
wl_list_init(&display->socket_list);
wl_list_init(&display->client_list);
@ -698,21 +658,6 @@ wl_display_remove_global(struct wl_display *display,
return 0;
}
WL_EXPORT void
wl_display_post_frame(struct wl_display *display, struct wl_surface *surface,
uint32_t time)
{
struct wl_frame_listener *listener, *next;
wl_list_for_each_safe(listener, next, &display->frame_list, link) {
if (listener->surface != surface)
continue;
wl_client_post_event(listener->client, &display->object,
WL_DISPLAY_KEY, listener->key, time);
wl_resource_destroy(&listener->resource, listener->client, 0);
}
}
WL_EXPORT struct wl_event_loop *
wl_display_get_event_loop(struct wl_display *display)
{