diff options
-rw-r--r-- | protocol/wayland.xml | 31 | ||||
-rw-r--r-- | src/wayland-client.c | 107 | ||||
-rw-r--r-- | src/wayland-client.h | 12 | ||||
-rw-r--r-- | src/wayland-server.c | 69 |
4 files changed, 43 insertions, 176 deletions
diff --git a/protocol/wayland.xml b/protocol/wayland.xml index 92377c4..f1dd78e 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -42,16 +42,7 @@ The key argument can be used to correlate between multiple sync invocations. --> <request name="sync"> - <arg name="key" type="uint"/> - </request> - - <!-- Request notification when the next frame is displayed. - Useful for throttling redrawing operations, and driving - animations. The notification will only be posted for one - frame unless requested again. --> - <request name="frame"> - <arg name="surface" type="object" interface="wl_surface"/> - <arg name="key" type="uint"/> + <arg name="callback" type="new_id" interface="wl_callback"/> </request> <!-- A fatal error has occurred. --> @@ -92,19 +83,14 @@ <event name="range"> <arg name="base" type="uint"/> </event> + </interface> - <!-- A reply to the frame or sync request. The key is the one - used in the request. time is in millisecond units, and - denotes the time when the frame was posted on the - display. time can be used to estimate frame rate, determine - how much to advance animations and compensate for jitter. --> - <event name="key"> - <arg name="key" type="uint"/> + <interface name="wl_callback" version="1"> + <event name="done"> <arg name="time" type="uint"/> </event> </interface> - <!-- A compositor. This object is a global. The compositor is in charge of combining the contents of multiple surfaces into one displayable output. --> @@ -423,6 +409,15 @@ <arg name="width" type="int"/> <arg name="height" type="int"/> </request> + + <!-- Request notification when the next frame is displayed. + Useful for throttling redrawing operations, and driving + animations. The notification will only be posted for one + frame unless requested again. --> + <request name="frame"> + <arg name="callback" type="new_id" interface="wl_callback"/> + </request> + </interface> diff --git a/src/wayland-client.c b/src/wayland-client.c index 9d1f66b..a7b118b 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -51,21 +51,6 @@ struct wl_proxy { void *user_data; }; -struct wl_sync_handler { - wl_display_sync_func_t func; - uint32_t key; - void *data; - struct wl_list link; -}; - -struct wl_frame_handler { - wl_display_frame_func_t func; - uint32_t key; - void *data; - struct wl_surface *surface; - struct wl_list link; -}; - struct wl_global { uint32_t id; char *interface; @@ -88,9 +73,6 @@ struct wl_display { wl_display_global_func_t global_handler; void *global_handler_data; - - struct wl_list sync_list, frame_list; - uint32_t key; }; static int wl_debug = 0; @@ -278,42 +260,11 @@ display_handle_range(void *data, display->next_range = range; } -static void -display_handle_key(void *data, - struct wl_display *display, uint32_t key, uint32_t time) -{ - struct wl_sync_handler *sync_handler; - struct wl_frame_handler *frame_handler; - - sync_handler = container_of(display->sync_list.next, - struct wl_sync_handler, link); - if (!wl_list_empty(&display->sync_list) && sync_handler->key == key) { - wl_list_remove(&sync_handler->link); - sync_handler->func(sync_handler->data); - free(sync_handler); - return; - } - - frame_handler = container_of(display->frame_list. next, - struct wl_frame_handler, link); - if (!wl_list_empty(&display->frame_list) && - frame_handler->key == key) { - wl_list_remove(&frame_handler->link); - frame_handler->func(frame_handler->surface, - frame_handler->data, time); - free(frame_handler); - return; - } - - fprintf(stderr, "unsolicited sync event, client gone?\n"); -} - static const struct wl_display_listener display_listener = { display_handle_error, display_handle_global, display_handle_global_remove, display_handle_range, - display_handle_key }; static int @@ -402,9 +353,6 @@ wl_display_connect(const char *name) display->proxy.object.id = 1; display->proxy.display = display; - wl_list_init(&display->sync_list); - wl_list_init(&display->frame_list); - display->proxy.object.implementation = (void(**)(void)) &display_listener; display->proxy.user_data = display; @@ -455,46 +403,31 @@ wl_display_get_fd(struct wl_display *display, return display->fd; } -WL_EXPORT int -wl_display_sync_callback(struct wl_display *display, - wl_display_sync_func_t func, void *data) +static void +sync_callback(void *data, struct wl_callback *callback, uint32_t time) { - struct wl_sync_handler *handler; - - handler = malloc(sizeof *handler); - if (handler == NULL) - return -1; + int *done = data; - handler->func = func; - handler->key = display->key++; - handler->data = data; - - wl_list_insert(display->sync_list.prev, &handler->link); - wl_display_sync(display, handler->key); - - return 0; + *done = 1; + wl_callback_destroy(callback); } -WL_EXPORT int -wl_display_frame_callback(struct wl_display *display, - struct wl_surface *surface, - wl_display_frame_func_t func, void *data) -{ - struct wl_frame_handler *handler; - - handler = malloc(sizeof *handler); - if (handler == NULL) - return -1; - - handler->func = func; - handler->key = display->key++; - handler->data = data; - handler->surface = surface; - - wl_list_insert(display->frame_list.prev, &handler->link); - wl_display_frame(display, handler->surface, handler->key); +static const struct wl_callback_listener sync_listener = { + sync_callback +}; - return 0; +WL_EXPORT void +wl_display_roundtrip(struct wl_display *display) +{ + struct wl_callback *callback; + int done; + + done = 0; + callback = wl_display_sync(display); + wl_callback_add_listener(callback, &sync_listener, &done); + wl_display_flush(display); + while (!done) + wl_display_iterate(display, WL_DISPLAY_READABLE); } static void diff --git a/src/wayland-client.h b/src/wayland-client.h index 385dc16..b00b0ae 100644 --- a/src/wayland-client.h +++ b/src/wayland-client.h @@ -50,9 +50,7 @@ void *wl_proxy_get_user_data(struct wl_proxy *proxy); #define WL_DISPLAY_WRITABLE 0x02 typedef int (*wl_display_update_func_t)(uint32_t mask, void *data); -typedef void (*wl_display_sync_func_t)(void *data); -typedef void (*wl_display_frame_func_t)(struct wl_surface *surface, - void *data, uint32_t time); +typedef void (*wl_callback_func_t)(void *data, uint32_t time); struct wl_display *wl_display_connect(const char *name); void wl_display_destroy(struct wl_display *display); @@ -61,11 +59,7 @@ int wl_display_get_fd(struct wl_display *display, uint32_t wl_display_allocate_id(struct wl_display *display); void wl_display_iterate(struct wl_display *display, uint32_t mask); void wl_display_flush(struct wl_display *display); -int wl_display_sync_callback(struct wl_display *display, - wl_display_sync_func_t func, void *data); -int wl_display_frame_callback(struct wl_display *display, - struct wl_surface *surface, - wl_display_frame_func_t func, void *data); +void wl_display_roundtrip(struct wl_display *display); struct wl_global_listener; typedef void (*wl_display_global_func_t)(struct wl_display *display, @@ -79,7 +73,7 @@ wl_display_remove_global_listener(struct wl_display *display, struct wl_global_listener * wl_display_add_global_listener(struct wl_display *display, wl_display_global_func_t handler, void *data); -WL_EXPORT uint32_t +uint32_t wl_display_get_global(struct wl_display *display, const char *interface, uint32_t version); diff --git a/src/wayland-server.c b/src/wayland-server.c index 2019cb4..c6ec2f1 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -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) -{ - wl_client_post_event(client, &display->object, WL_DISPLAY_KEY, key, 0); -} - -static void -destroy_frame_listener(struct wl_resource *resource, struct wl_client *client) + struct wl_display *display, uint32_t id) { - struct wl_frame_listener *listener = - container_of(resource, struct wl_frame_listener, resource); - - 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; + struct wl_object object; - listener = malloc(sizeof *listener); - if (listener == NULL) { - wl_client_post_no_memory(client); - return; - } + object.interface = &wl_callback_interface; + object.id = id; - /* 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) { |