Add client side demarshalling for events.
authorKristian Høgsberg <krh@redhat.com>
Thu, 25 Dec 2008 00:30:25 +0000 (19:30 -0500)
committerKristian Høgsberg <krh@redhat.com>
Thu, 25 Dec 2008 00:31:58 +0000 (19:31 -0500)
This also consolidates the marshalling code in connection.c and
uses the same functions in the server and client for marshalling.

Makefile.in
connection.c
connection.h
wayland-client.c
wayland-protocol.c
wayland-system-compositor.c
wayland.c

index 5910911..09cd2b7 100644 (file)
@@ -16,16 +16,14 @@ libwayland-server.so :                              \
        wayland-util.o                          \
        wayland-protocol.o
 
-libwayland-server.so : CFLAGS += @FFI_CFLAGS@
-libwayland-server.so : LDLIBS += @FFI_LIBS@ -ldl -rdynamic
-
 libwayland.so :                                        \
        wayland-client.o                        \
        connection.o                            \
        wayland-util.o                          \
        wayland-protocol.o
 
-$(libs) : CFLAGS += -fPIC
+$(libs) : CFLAGS += -fPIC @FFI_CFLAGS@
+$(libs) : LDLIBS += @FFI_LIBS@
 $(libs) :
        gcc -shared $^ $(LDLIBS)  -o $@
 
index 5430963..be9c88b 100644 (file)
@@ -26,6 +26,8 @@
 #include <stdio.h>
 #include <errno.h>
 #include <sys/uio.h>
+#include <ffi.h>
+#include <assert.h>
 
 #include "wayland-util.h"
 #include "connection.h"
@@ -218,3 +220,145 @@ wl_connection_write(struct wl_connection *connection, const void *data, size_t c
                                   WL_CONNECTION_WRITABLE,
                                   connection->data);
 }
+
+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_object *object;
+       uint32_t args[32], length, *p, size;
+       const char *s;
+       int i, count;
+
+       count = strlen(message->signature);
+       assert(count <= ARRAY_LENGTH(args));
+
+       p = &args[2];
+       for (i = 0; i < count; i++) {
+               switch (message->signature[i]) {
+               case 'u':
+               case 'i':
+                       *p++ = va_arg(ap, uint32_t);
+                       break;
+               case 's':
+                       s = va_arg(ap, const char *);
+                       length = strlen(s);
+                       *p++ = length;
+                       memcpy(p, s, length);
+                       p += DIV_ROUNDUP(length, sizeof(*p));
+                       break;
+               case 'o':
+               case 'n':
+                       object = va_arg(ap, struct wl_object *);
+                       *p++ = object->id;
+                       break;
+               default:
+                       assert(0);
+                       break;
+               }
+       }
+
+       size = (p - args) * sizeof *p;
+       args[0] = sender->id;
+       args[1] = opcode | (size << 16);
+       wl_connection_write(connection, args, size);
+}
+
+void
+wl_connection_demarshal(struct wl_connection *connection,
+                       uint32_t size,
+                       struct wl_hash *objects,
+                       void (*func)(void),
+                       void *data, struct wl_object *target,
+                       const struct wl_message *message)
+{
+       ffi_type *types[20];
+       ffi_cif cif;
+       uint32_t *p, result, length;
+       int i, count;
+       union {
+               uint32_t uint32;
+               char *string;
+               void *object;
+               uint32_t new_id;
+       } values[20];
+       void *args[20];
+       struct wl_object *object;
+       uint32_t buffer[64];
+
+       count = strlen(message->signature) + 2;
+       if (count > ARRAY_LENGTH(types)) {
+               printf("too many args (%d)\n", count);
+               return;
+       }
+
+       if (sizeof buffer < size) {
+               printf("request too big, should malloc tmp buffer here\n");
+               return;
+       }
+
+       types[0] = &ffi_type_pointer;
+       values[0].object = data;
+       args[0] =  &values[0];
+
+       types[1] = &ffi_type_pointer;
+       values[1].object = target;
+       args[1] =  &values[1];
+
+       wl_connection_copy(connection, buffer, size);
+       p = &buffer[2];
+       for (i = 2; i < count; i++) {
+               switch (message->signature[i - 2]) {
+               case 'u':
+               case 'i':
+                       types[i] = &ffi_type_uint32;
+                       values[i].uint32 = *p++;
+                       break;
+               case 's':
+                       types[i] = &ffi_type_pointer;
+                       length = *p++;
+                       values[i].string = malloc(length + 1);
+                       if (values[i].string == NULL) {
+                               /* FIXME: Send NO_MEMORY */
+                               return;
+                       }
+                       memcpy(values[i].string, p, length);
+                       values[i].string[length] = '\0';
+                       p += DIV_ROUNDUP(length, sizeof *p);
+                       break;
+               case 'o':
+                       types[i] = &ffi_type_pointer;
+                       object = wl_hash_lookup(objects, *p);
+                       if (object == NULL)
+                               printf("unknown object (%d)\n", *p);
+                       values[i].object = object;
+                       p++;
+                       break;
+               case 'n':
+                       types[i] = &ffi_type_uint32;
+                       values[i].new_id = *p;
+                       object = wl_hash_lookup(objects, *p);
+                       if (object != NULL)
+                               printf("object already exists (%d)\n", *p);
+                       p++;
+                       break;
+               default:
+                       printf("unknown type\n");
+                       break;
+               }
+               args[i] = &values[i];
+       }
+
+       ffi_prep_cif(&cif, FFI_DEFAULT_ABI, count, &ffi_type_uint32, types);
+       ffi_call(&cif, func, &result, args);
+
+       for (i = 2; i < count; i++) {
+               switch (message->signature[i - 2]) {
+               case 's':
+                       free(values[i].string);
+                       break;
+               }
+       }
+}
index 68d6396..3db07ee 100644 (file)
@@ -24,6 +24,7 @@
 #define _CONNECTION_H_
 
 #include <stdarg.h>
+#include "wayland-util.h"
 
 struct wl_connection;
 
@@ -41,7 +42,17 @@ void wl_connection_copy(struct wl_connection *connection, void *data, size_t siz
 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, uint32_t id,
-                           uint32_t opcode, const char *signature, va_list ap);
+
+void wl_connection_vmarshal(struct wl_connection *connection,
+                           struct wl_object *sender,
+                           uint32_t opcode, va_list ap,
+                           const struct wl_message *message);
+
+void wl_connection_demarshal(struct wl_connection *connection,
+                            uint32_t size,
+                            struct wl_hash *objects,
+                            void (*func)(void),
+                            void *data, struct wl_object *target,
+                            const struct wl_message *message);
 
 #endif
index 2087a92..3d82c50 100644 (file)
@@ -103,6 +103,41 @@ connection_update(struct wl_connection *connection,
        return 0;
 }
 
+static void
+output_handle_geometry(struct wl_display *display,
+                      struct wl_output *output, int32_t width, int32_t height)
+{
+       output->width = width;
+       output->height = height;
+}
+
+struct wl_output_listener {
+       void (*geometry)(struct wl_display *display,
+                        struct wl_output *output,
+                        int32_t width, int32_t height);
+};
+
+static const struct wl_output_listener output_listener = {
+       output_handle_geometry
+};
+
+static void
+add_output(struct wl_display *display, struct wl_global *global)
+{
+       struct wl_output *output;
+
+       output = malloc(sizeof *output);
+       if (output == NULL)
+               return;
+
+       output->proxy.base.interface = &wl_output_interface;
+       output->proxy.base.implementation = (void(**)(void)) &output_listener;
+       output->proxy.base.id = global->id;
+       output->proxy.display = display;
+       display->output = output;
+       wl_hash_insert(display->objects, &output->proxy.base);
+}
+
 WL_EXPORT void
 wl_display_get_geometry(struct wl_display *display, int32_t *width, int32_t *height)
 {
@@ -150,6 +185,79 @@ wl_display_get_rgb_visual(struct wl_display *display)
                            struct wl_visual, link);
 }
 
+static void
+display_handle_invalid_object(struct wl_display *display,
+                             struct wl_object *object, uint32_t id)
+{
+       fprintf(stderr, "sent request to invalid object\n");
+}
+                             
+static void
+display_handle_invalid_method(struct wl_display *display,
+                             struct wl_object *object,
+                             uint32_t id, uint32_t opcode)
+{
+       fprintf(stderr, "sent invalid request opcode\n");
+}
+
+static void
+display_handle_no_memory(struct wl_display *display,
+                        struct wl_object *object)
+{
+       fprintf(stderr, "server out of memory\n");
+}
+
+static void
+display_handle_global(struct wl_display *display,
+                     struct wl_object *object,
+                     uint32_t id, const char *interface, uint32_t version)
+{
+       struct wl_global *global;
+
+       global = malloc(sizeof *global);
+       if (global == NULL)
+               return;
+
+       global->id = id;
+       global->interface = strdup(interface);
+       global->version = version;
+       wl_list_insert(display->global_list.prev, &global->link);
+       if (strcmp(global->interface, "display") == 0)
+               wl_hash_insert(display->objects, &display->proxy.base);
+       if (strcmp(global->interface, "visual") == 0)
+               add_visual(display, global);
+       else if (strcmp(global->interface, "output") == 0)
+               add_output(display, global);
+}
+
+static void
+display_handle_range(struct wl_display *display,
+                    struct wl_object *object, uint32_t range)
+{
+       display->next_range = range;
+}
+
+struct wl_display_listener {
+       void (*invalid_object)(struct wl_display *display,
+                              struct wl_object *object, uint32_t id);
+       void (*invalid_method)(struct wl_display *display,
+                              struct wl_object *object,
+                              uint32_t id, uint32_t opcode);
+       void (*no_memory)(struct wl_display *display, struct wl_object *object);
+       void (*global)(struct wl_display *display, struct wl_object *object,
+                      uint32_t id, const char *interface, uint32_t version);
+       void (*range)(struct wl_display *display,
+                     struct wl_object *object, uint32_t range);
+};
+
+static const struct wl_display_listener display_listener = {
+       display_handle_invalid_object,
+       display_handle_invalid_method,
+       display_handle_no_memory,
+       display_handle_global,
+       display_handle_range
+};
+
 WL_EXPORT struct wl_display *
 wl_display_create(const char *name, size_t name_size)
 {
@@ -184,10 +292,9 @@ wl_display_create(const char *name, size_t name_size)
        wl_list_init(&display->visual_list);
 
        display->proxy.base.interface = &wl_display_interface;
-       display->proxy.base.implementation = NULL;
+       display->proxy.base.implementation = (void(**)(void)) &display_listener;
        display->proxy.base.id = 1;
        display->proxy.display = display;
-       wl_hash_insert(display->objects, &display->proxy.base);
 
        display->connection = wl_connection_create(display->fd,
                                                   connection_update,
@@ -239,100 +346,6 @@ wl_display_get_fd(struct wl_display *display,
        return display->fd;
 }
 
-struct wl_output_listener {
-       void (*geometry)(struct wl_display *display,
-                        struct wl_output *output,
-                        int32_t width, int32_t height);
-};
-
-static void
-handle_geometry(struct wl_display *display,
-               struct wl_output *output, int32_t width, int32_t height)
-{
-       output->width = width;
-       output->height = height;
-}
-
-static const struct wl_output_listener output_listener = {
-       handle_geometry
-};
-
-static void
-add_output(struct wl_display *display, struct wl_global *global)
-{
-       struct wl_output *output;
-
-       output = malloc(sizeof *output);
-       if (output == NULL)
-               return;
-
-       output->proxy.base.interface = &wl_output_interface;
-       output->proxy.base.implementation = (void(**)(void)) &output_listener;
-       output->proxy.base.id = global->id;
-       output->proxy.display = display;
-       display->output = output;
-       wl_hash_insert(display->objects, &output->proxy.base);
-}
-
-static void
-handle_display_event(struct wl_display *display,
-                    uint32_t opcode, uint32_t *p, uint32_t size)
-{
-       struct wl_global *global;
-       uint32_t length;
-
-       switch (opcode) {
-       case WL_DISPLAY_INVALID_OBJECT:
-               fprintf(stderr, "sent request to invalid object\n");
-               break;
-
-       case WL_DISPLAY_INVALID_METHOD:
-               fprintf(stderr, "sent invalid request opcode\n");
-               break;
-
-       case WL_DISPLAY_NO_MEMORY:
-               fprintf(stderr, "server out of memory\n");
-               break;
-
-       case WL_DISPLAY_GLOBAL:
-               global = malloc(sizeof *global);
-               if (global == NULL)
-                       return;
-
-               global->id = p[0];
-               length = p[1];
-               global->interface = malloc(length + 1);
-               if (global->interface == NULL) {
-                       free(global);
-                       return;
-               }
-               memcpy(global->interface, &p[2], length);
-               global->interface[length] = '\0';
-               global->version = p[2 + DIV_ROUNDUP(length, sizeof *p)];
-               wl_list_insert(display->global_list.prev, &global->link);
-               if (strcmp(global->interface, "visual") == 0)
-                       add_visual(display, global);
-               else if (strcmp(global->interface, "output") == 0)
-                       add_output(display, global);
-               break;
-
-       case WL_DISPLAY_RANGE:
-               display->next_range = p[0];
-               break;
-       }
-}
-
-static void
-handle_output_event(struct wl_display *display,
-                   uint32_t opcode, uint32_t *p, uint32_t size)
-{
-       switch (opcode) {
-       case WL_OUTPUT_GEOMETRY:
-               handle_geometry(display, display->output, p[0], p[1]);
-               break;
-       }
-}
-
 static void
 handle_event(struct wl_display *display,
             uint32_t id, uint32_t opcode, uint32_t size)
@@ -341,15 +354,24 @@ handle_event(struct wl_display *display,
        struct wl_object *object;
 
        wl_connection_copy(display->connection, p, size);
-       object = wl_hash_lookup(display->objects, id);
-
-       if (object == &display->proxy.base)
-               handle_display_event(display, opcode, p + 2, size);
-       else if (object == &display->output->proxy.base && opcode == 0)
-               handle_output_event(display, opcode, p + 2, size);
+       if (id == 1)
+               object = &display->proxy.base;
+       else
+               object = wl_hash_lookup(display->objects, id);
+
+       if (object != NULL)
+               wl_connection_demarshal(display->connection,
+                                       size,
+                                       display->objects,
+                                       object->implementation[opcode],
+                                       display,
+                                       object, 
+                                       &object->interface->events[opcode]);
        else if (display->event_handler != NULL)
-               display->event_handler(display, id, opcode, size, p + 2,
+               display->event_handler(display, id,
+                                      opcode, size, p + 2,
                                       display->event_handler_data);
+
        wl_connection_consume(display->connection, size);
 }
 
@@ -429,56 +451,16 @@ wl_display_get_compositor(struct wl_display *display)
 }
 
 static void
-wl_proxy_vmarshal(struct wl_proxy *target, uint32_t opcode, va_list ap)
-{
-       struct wl_object *object;
-       uint32_t args[32], length, *p, size;
-       const char *s, *signature;
-       int i, count;
-
-       signature = target->base.interface->methods[opcode].signature;
-       count = strlen(signature);
-       /* FIXME: Make sure we don't overwrite args array. */
-
-       p = &args[2];
-       for (i = 0; i < count; i++) {
-               switch (signature[i]) {
-               case 'u':
-               case 'i':
-                       *p++ = va_arg(ap, uint32_t);
-                       break;
-               case 's':
-                       s = va_arg(ap, const char *);
-                       length = strlen(s);
-                       *p++ = length;
-                       memcpy(p, s, length);
-                       p += DIV_ROUNDUP(length, sizeof(*p));
-                       break;
-               case 'n':
-               case 'o':
-                       object = va_arg(ap, struct wl_object *);
-                       *p++ = object->id;
-                       break;
-               default:
-                       assert(0);
-                       break;
-               }
-       }
-
-       size = (p - args) * sizeof *p;
-       args[0] = target->base.id;
-       args[1] = opcode | (size << 16);
-       wl_connection_write(target->display->connection, args, size);
-}
-
-static void
 wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
 {
        va_list ap;
 
        va_start(ap, opcode);
-       wl_proxy_vmarshal(proxy, opcode, ap);
+       wl_connection_vmarshal(proxy->display->connection,
+                              &proxy->base, opcode, ap,
+                              &proxy->base.interface->methods[opcode]);
        va_end(ap);
+
 }
 
 WL_EXPORT struct wl_surface *
index 2c7ba99..308cc70 100644 (file)
@@ -29,7 +29,7 @@ static const struct wl_message display_events[] = {
        { "invalid_object", "u" },
        { "invalid_method", "uu" },
        { "no_memory", "" },
-       { "global", "osu" },
+       { "global", "nsu" },
        { "range", "u" },
 };
 
index 77c6bfe..09daebf 100644 (file)
@@ -702,7 +702,9 @@ create_input_device(struct egl_compositor *ec, const char *glob)
 
        memset(device, 0, sizeof *device);
        device->base.interface = &wl_input_device_interface;
+       device->base.implementation = NULL;
        wl_display_add_object(ec->wl_display, &device->base);
+       wl_display_add_global(ec->wl_display, &device->base, NULL);
        device->x = 100;
        device->y = 100;
        device->pointer_surface =
index 0fe2a8d..98cb341 100644 (file)
--- a/wayland.c
+++ b/wayland.c
@@ -73,61 +73,6 @@ struct wl_global {
 void
 wl_client_destroy(struct wl_client *client);
 
-static void
-wl_client_vmarshal(struct wl_client *client, struct wl_object *sender,
-                  uint32_t opcode, va_list ap)
-{
-       const struct wl_message *event;
-       struct wl_object *object;
-       uint32_t args[32], length, *p, size;
-       const char *s;
-       int i, count;
-
-       event = &sender->interface->events[opcode];
-       count = strlen(event->signature);
-       assert(count <= ARRAY_LENGTH(args));
-
-       p = &args[2];
-       for (i = 0; i < count; i++) {
-               switch (event->signature[i]) {
-               case 'u':
-               case 'i':
-                       *p++ = va_arg(ap, uint32_t);
-                       break;
-               case 's':
-                       s = va_arg(ap, const char *);
-                       length = strlen(s);
-                       *p++ = length;
-                       memcpy(p, s, length);
-                       p += DIV_ROUNDUP(length, sizeof(*p));
-                       break;
-               case 'o':
-                       object = va_arg(ap, struct wl_object *);
-                       *p++ = object->id;
-                       break;
-               default:
-                       assert(0);
-                       break;
-               }
-       }
-
-       size = (p - args) * sizeof *p;
-       args[0] = sender->id;
-       args[1] = opcode | (size << 16);
-       wl_connection_write(client->connection, args, size);
-}
-
-static void
-wl_client_marshal(struct wl_client *client, struct wl_object *sender,
-                 uint32_t opcode, ...)
-{
-       va_list ap;
-
-       va_start(ap, opcode);
-       wl_client_vmarshal(client, sender, opcode, ap);
-       va_end(ap);
-}
-
 WL_EXPORT void
 wl_client_post_event(struct wl_client *client, struct wl_object *sender,
                     uint32_t opcode, ...)
@@ -135,94 +80,13 @@ wl_client_post_event(struct wl_client *client, struct wl_object *sender,
        va_list ap;
 
        va_start(ap, opcode);
-       wl_client_vmarshal(client, sender, opcode, ap);
+       wl_connection_vmarshal(client->connection,
+                              sender, opcode, ap,
+                              &sender->interface->events[opcode]);
        va_end(ap);
 }
 
 static void
-wl_client_demarshal(struct wl_client *client, struct wl_object *target,
-                   uint32_t opcode, size_t size)
-{
-       const struct wl_message *method;
-       ffi_type *types[20];
-       ffi_cif cif;
-       uint32_t *p, result;
-       int i, count;
-       union {
-               uint32_t uint32;
-               const char *string;
-               void *object;
-               uint32_t new_id;
-       } values[20];
-       void *args[20];
-       struct wl_object *object;
-       uint32_t data[64];
-       void (*func)(void);
-
-       method = &target->interface->methods[opcode];
-       count = strlen(method->signature) + 2;
-       if (count > ARRAY_LENGTH(types)) {
-               printf("too many args (%d)\n", count);
-               return;
-       }
-
-       if (sizeof data < size) {
-               printf("request too big, should malloc tmp buffer here\n");
-               return;
-       }
-
-       types[0] = &ffi_type_pointer;
-       values[0].object = client;
-       args[0] =  &values[0];
-
-       types[1] = &ffi_type_pointer;
-       values[1].object = target;
-       args[1] =  &values[1];
-
-       wl_connection_copy(client->connection, data, size);
-       p = &data[2];
-       for (i = 2; i < count; i++) {
-               switch (method->signature[i - 2]) {
-               case 'u':
-               case 'i':
-                       types[i] = &ffi_type_uint32;
-                       values[i].uint32 = *p;
-                       p++;
-                       break;
-               case 's':
-                       types[i] = &ffi_type_pointer;
-                       /* FIXME */
-                       values[i].uint32 = *p++;
-                       break;
-               case 'o':
-                       types[i] = &ffi_type_pointer;
-                       object = wl_hash_lookup(client->display->objects, *p);
-                       if (object == NULL)
-                               printf("unknown object (%d)\n", *p);
-                       values[i].object = object;
-                       p++;
-                       break;
-               case 'n':
-                       types[i] = &ffi_type_uint32;
-                       values[i].new_id = *p;
-                       object = wl_hash_lookup(client->display->objects, *p);
-                       if (object != NULL)
-                               printf("object already exists (%d)\n", *p);
-                       p++;
-                       break;
-               default:
-                       printf("unknown type\n");
-                       break;
-               }
-               args[i] = &values[i];
-       }
-
-       func = target->implementation[opcode];
-       ffi_prep_cif(&cif, FFI_DEFAULT_ABI, count, &ffi_type_uint32, types);
-       ffi_call(&cif, func, &result, args);
-}
-
-static void
 wl_client_connection_data(int fd, uint32_t mask, void *data)
 {
        struct wl_client *client = data;
@@ -252,22 +116,29 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
 
                object = wl_hash_lookup(client->display->objects, p[0]);
                if (object == NULL) {
-                       wl_client_marshal(client, &client->display->base,
-                                         WL_DISPLAY_INVALID_OBJECT, p[0]);
+                       wl_client_post_event(client, &client->display->base,
+                                            WL_DISPLAY_INVALID_OBJECT, p[0]);
                        wl_connection_consume(connection, size);
                        len -= size;
                        continue;
                }
                                
                if (opcode >= object->interface->method_count) {
-                       wl_client_marshal(client, &client->display->base,
-                                         WL_DISPLAY_INVALID_METHOD, p[0], opcode);
+                       wl_client_post_event(client, &client->display->base,
+                                            WL_DISPLAY_INVALID_METHOD, p[0], opcode);
                        wl_connection_consume(connection, size);
                        len -= size;
                        continue;
                }
                                
-               wl_client_demarshal(client, object, opcode, size);
+               wl_connection_demarshal(client->connection,
+                                       size,
+                                       client->display->objects,
+                                       object->implementation[opcode],
+                                       client,
+                                       object, 
+                                       &object->interface->methods[opcode]);
+
                wl_connection_consume(connection, size);
                len -= size;
        }
@@ -291,8 +162,8 @@ wl_client_connection_update(struct wl_connection *connection,
 static void
 wl_display_post_range(struct wl_display *display, struct wl_client *client)
 {
-       wl_client_marshal(client, &client->display->base,
-                         WL_DISPLAY_RANGE, display->client_id_range);
+       wl_client_post_event(client, &client->display->base,
+                            WL_DISPLAY_RANGE, display->client_id_range);
        display->client_id_range += 256;
        client->id_count += 256;
 }
@@ -323,11 +194,11 @@ wl_client_create(struct wl_display *display, int fd)
        global = container_of(display->global_list.next,
                              struct wl_global, link);
        while (&global->link != &display->global_list) {
-               wl_client_marshal(client, &client->display->base,
-                                 WL_DISPLAY_GLOBAL,
-                                 global->object,
-                                 global->object->interface->name,
-                                 global->object->interface->version);
+               wl_client_post_event(client, &client->display->base,
+                                    WL_DISPLAY_GLOBAL,
+                                    global->object,
+                                    global->object->interface->name,
+                                    global->object->interface->version);
                global = container_of(global->link.next,
                                      struct wl_global, link);
        }
@@ -395,8 +266,8 @@ wl_client_add_surface(struct wl_client *client,
 
        ref = malloc(sizeof *ref);
        if (ref == NULL) {
-               wl_client_marshal(client, &display->base,
-                                 WL_DISPLAY_NO_MEMORY);
+               wl_client_post_event(client, &display->base,
+                                    WL_DISPLAY_NO_MEMORY);
                return -1;
        }
 
@@ -415,8 +286,8 @@ wl_client_send_acknowledge(struct wl_client *client,
        wl_list_remove(&client->link);
        wl_list_insert(client->display->pending_frame_list.prev,
                       &client->link);
-       wl_client_marshal(client, &compositor->base,
-                         WL_COMPOSITOR_ACKNOWLEDGE, key, frame);
+       wl_client_post_event(client, &compositor->base,
+                            WL_COMPOSITOR_ACKNOWLEDGE, key, frame);
 }
 
 WL_EXPORT int
@@ -505,7 +376,9 @@ wl_surface_post_event(struct wl_surface *surface,
        va_list ap;
 
        va_start(ap, event);
-       wl_client_vmarshal(surface->client, sender, event, ap);
+       wl_connection_vmarshal(surface->client->connection,
+                              sender, event, ap,
+                              &sender->interface->events[event]);
        va_end(ap);
 }
 
@@ -520,8 +393,8 @@ wl_display_post_frame(struct wl_display *display,
                              struct wl_client, link);
 
        while (&client->link != &display->pending_frame_list) {
-               wl_client_marshal(client, &compositor->base,
-                                 WL_COMPOSITOR_FRAME, frame, msecs);
+               wl_client_post_event(client, &compositor->base,
+                                    WL_COMPOSITOR_FRAME, frame, msecs);
                client = container_of(client->link.next,
                                      struct wl_client, link);
        }