summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/connection.c30
-rw-r--r--src/connection.h2
-rw-r--r--src/wayland-client.c4
-rw-r--r--src/wayland-server.c26
-rw-r--r--src/wayland-server.h2
5 files changed, 56 insertions, 8 deletions
diff --git a/src/connection.c b/src/connection.c
index 4230f7d..5a7ec2e 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -65,6 +65,7 @@ struct wl_connection {
void *data;
wl_connection_update_func_t update;
struct wl_closure receive_closure, send_closure;
+ int write_signalled;
};
union wl_value {
@@ -285,10 +286,13 @@ wl_connection_data(struct wl_connection *connection, uint32_t mask)
close_fds(&connection->fds_out);
connection->out.tail += len;
- if (connection->out.tail == connection->out.head)
+ if (connection->out.tail == connection->out.head &&
+ connection->write_signalled) {
connection->update(connection,
WL_CONNECTION_READABLE,
connection->data);
+ connection->write_signalled = 0;
+ }
}
if (mask & WL_CONNECTION_READABLE) {
@@ -334,11 +338,24 @@ wl_connection_write(struct wl_connection *connection,
wl_buffer_put(&connection->out, data, count);
- if (connection->out.head - connection->out.tail == count)
+ if (!connection->write_signalled) {
connection->update(connection,
WL_CONNECTION_READABLE |
WL_CONNECTION_WRITABLE,
connection->data);
+ connection->write_signalled = 1;
+ }
+}
+
+static void
+wl_connection_queue(struct wl_connection *connection,
+ const void *data, size_t count)
+{
+ if (connection->out.head - connection->out.tail +
+ count > ARRAY_LENGTH(connection->out.data))
+ wl_connection_data(connection, WL_CONNECTION_WRITABLE);
+
+ wl_buffer_put(&connection->out, data, count);
}
static int
@@ -704,6 +721,15 @@ wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
}
void
+wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
+{
+ uint32_t size;
+
+ size = closure->start[1] >> 16;
+ wl_connection_queue(connection, closure->start, size);
+}
+
+void
wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
{
union wl_value *value;
diff --git a/src/connection.h b/src/connection.h
index 1c733ff..4f7c928 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -61,6 +61,8 @@ wl_closure_invoke(struct wl_closure *closure,
void
wl_closure_send(struct wl_closure *closure, struct wl_connection *connection);
void
+wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection);
+void
wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send);
void
wl_closure_destroy(struct wl_closure *closure);
diff --git a/src/wayland-client.c b/src/wayland-client.c
index 8f3e106..5845698 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -469,10 +469,6 @@ wl_display_iterate(struct wl_display *display, uint32_t mask)
len = wl_connection_data(display->connection, mask);
- if (wl_debug && (mask & WL_DISPLAY_READABLE))
- fprintf(stderr,
- "[-----------] wakeup, read %d bytes\n", len);
-
while (len > 0) {
if (len < sizeof p)
break;
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 0004c15..f3d8050 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -108,6 +108,28 @@ wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
wl_closure_destroy(closure);
}
+
+WL_EXPORT void
+wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
+{
+ struct wl_closure *closure;
+ struct wl_object *object = &resource->object;
+ va_list ap;
+
+ va_start(ap, opcode);
+ closure = wl_connection_vmarshal(resource->client->connection,
+ object, opcode, ap,
+ &object->interface->events[opcode]);
+ va_end(ap);
+
+ wl_closure_queue(closure, resource->client->connection);
+
+ if (wl_debug)
+ wl_closure_print(closure, object, true);
+
+ wl_closure_destroy(closure);
+}
+
WL_EXPORT void
wl_resource_post_error(struct wl_resource *resource,
uint32_t code, const char *msg, ...)
@@ -314,8 +336,8 @@ wl_resource_destroy(struct wl_resource *resource, uint32_t time)
{
struct wl_client *client = resource->client;
- wl_resource_post_event(resource->client->display_resource,
- WL_DISPLAY_DELETE_ID, resource->object.id);
+ wl_resource_queue_event(resource->client->display_resource,
+ WL_DISPLAY_DELETE_ID, resource->object.id);
wl_map_insert_at(&client->objects, resource->object.id, NULL);
destroy_resource(resource, &time);
}
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 9f5e8c3..ead95cc 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -216,6 +216,8 @@ struct wl_selection {
void wl_resource_post_event(struct wl_resource *resource,
uint32_t opcode, ...);
+void wl_resource_queue_event(struct wl_resource *resource,
+ uint32_t opcode, ...);
void wl_resource_post_error(struct wl_resource *resource,
uint32_t code, const char *msg, ...);
void wl_resource_post_no_memory(struct wl_resource *resource);