summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocol/wayland.xml31
-rw-r--r--src/wayland-client.c107
-rw-r--r--src/wayland-client.h12
-rw-r--r--src/wayland-server.c69
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)
{