diff --git a/connection.c b/connection.c index 530e23fe..53e265a9 100644 --- a/connection.c +++ b/connection.c @@ -52,6 +52,7 @@ struct wl_closure { ffi_cif cif; void *args[20]; uint32_t buffer[64]; + uint32_t *start; }; struct wl_connection { @@ -357,7 +358,7 @@ wl_message_size_extra(const struct wl_message *message) return extra; } -void +struct wl_closure * wl_connection_vmarshal(struct wl_connection *connection, struct wl_object *sender, uint32_t opcode, va_list ap, @@ -466,7 +467,9 @@ wl_connection_vmarshal(struct wl_connection *connection, size = (p - start) * sizeof *p; start[0] = sender->id; start[1] = opcode | (size << 16); - wl_connection_write(connection, start, size); + closure->start = start; + + return closure; } struct wl_closure * @@ -651,6 +654,15 @@ wl_closure_invoke(struct wl_closure *closure, ffi_call(&closure->cif, func, &result, closure->args); } +void +wl_closure_send(struct wl_closure *closure, struct wl_connection *connection) +{ + uint32_t size; + + size = closure->start[1] >> 16; + wl_connection_write(connection, closure->start, size); +} + void wl_closure_print(struct wl_closure *closure, struct wl_object *target) { diff --git a/connection.h b/connection.h index c087d82a..413977df 100644 --- a/connection.h +++ b/connection.h @@ -44,10 +44,11 @@ void wl_connection_consume(struct wl_connection *connection, size_t size); int wl_connection_data(struct wl_connection *connection, uint32_t mask); void wl_connection_write(struct wl_connection *connection, const void *data, size_t count); -void wl_connection_vmarshal(struct wl_connection *connection, - struct wl_object *sender, - uint32_t opcode, va_list ap, - const struct wl_message *message); +struct wl_closure * +wl_connection_vmarshal(struct wl_connection *connection, + struct wl_object *sender, + uint32_t opcode, va_list ap, + const struct wl_message *message); struct wl_closure * wl_connection_demarshal(struct wl_connection *connection, @@ -58,6 +59,8 @@ void wl_closure_invoke(struct wl_closure *closure, struct wl_object *target, void (*func)(void), void *data); void +wl_closure_send(struct wl_closure *closure, struct wl_connection *connection); +void wl_closure_print(struct wl_closure *closure, struct wl_object *target); void wl_closure_destroy(struct wl_closure *closure); diff --git a/wayland-client.c b/wayland-client.c index 2d731b00..9715307b 100644 --- a/wayland-client.c +++ b/wayland-client.c @@ -195,13 +195,17 @@ wl_proxy_add_listener(struct wl_proxy *proxy, WL_EXPORT void wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...) { + struct wl_closure *closure; va_list ap; va_start(ap, opcode); - wl_connection_vmarshal(proxy->display->connection, - &proxy->base, opcode, ap, - &proxy->base.interface->methods[opcode]); + closure = wl_connection_vmarshal(proxy->display->connection, + &proxy->base, opcode, ap, + &proxy->base.interface->methods[opcode]); va_end(ap); + + wl_closure_send(closure, proxy->display->connection); + wl_closure_destroy(closure); } static void diff --git a/wayland-server.c b/wayland-server.c index 8f618743..5c9cc581 100644 --- a/wayland-server.c +++ b/wayland-server.c @@ -79,6 +79,7 @@ WL_EXPORT void wl_client_post_event(struct wl_client *client, struct wl_object *sender, uint32_t opcode, ...) { + struct wl_closure *closure; va_list ap; if (client == NULL) @@ -86,10 +87,13 @@ wl_client_post_event(struct wl_client *client, struct wl_object *sender, return; va_start(ap, opcode); - wl_connection_vmarshal(client->connection, - sender, opcode, ap, - &sender->interface->events[opcode]); + closure = wl_connection_vmarshal(client->connection, + sender, opcode, ap, + &sender->interface->events[opcode]); va_end(ap); + + wl_closure_send(closure, client->connection); + wl_closure_destroy(closure); } static void @@ -163,7 +167,6 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) object->implementation[opcode], client); wl_closure_destroy(closure); - } }