Commit 9de9e39f authored by Kristian Høgsberg's avatar Kristian Høgsberg

Allocate client proxy automatically for new objects

When the server send a new object ID, the client used to have to allocate
the proxy manually and without type-safety.  We now allocate the proxy
in a client-side post-processing step on the incoming closure.
parent c30ad0d9
......@@ -375,6 +375,7 @@ wl_message_size_extra(const struct wl_message *message)
switch (message->signature[i]) {
case 's':
case 'o':
case 'n':
extra += sizeof (void *);
break;
case 'a':
......@@ -574,7 +575,7 @@ wl_connection_demarshal(struct wl_connection *connection,
struct wl_map *objects,
const struct wl_message *message)
{
uint32_t *p, *next, *end, length;
uint32_t *p, *next, *end, length, **id;
int *fd;
char *extra, **s;
unsigned int i, count, extra_space;
......@@ -690,8 +691,12 @@ wl_connection_demarshal(struct wl_connection *connection,
p++;
break;
case 'n':
closure->types[i] = &ffi_type_uint32;
closure->args[i] = p;
closure->types[i] = &ffi_type_pointer;
id = (uint32_t **) extra;
extra += sizeof *id;
closure->args[i] = id;
*id = p;
object = wl_map_lookup(objects, *p);
if (object != NULL) {
printf("not a new object (%d), "
......
......@@ -769,6 +769,8 @@ emit_structs(struct wl_list *message_list, struct interface *interface)
if (is_interface && a->type == OBJECT)
printf("struct wl_resource *");
else if (!is_interface && a->type == NEW_ID)
printf("struct %s *", a->interface_name);
else
emit_type(a);
......
......@@ -462,6 +462,31 @@ wl_display_roundtrip(struct wl_display *display)
wl_display_iterate(display, WL_DISPLAY_READABLE);
}
static int
create_proxies(struct wl_display *display, struct wl_closure *closure)
{
struct wl_proxy *proxy;
const char *signature;
uint32_t id;
int i;
signature = closure->message->signature;
for (i = 0; signature[i]; i++) {
switch (signature[i]) {
case 'n':
id = **(uint32_t **) closure->args[i + 2];
proxy = wl_proxy_create_for_id(&display->proxy, id,
closure->message->types[i]);
if (proxy == NULL)
return -1;
*(void **) closure->args[i + 2] = proxy;
break;
}
}
return 0;
}
static void
handle_event(struct wl_display *display,
uint32_t id, uint32_t opcode, uint32_t size)
......@@ -484,7 +509,7 @@ handle_event(struct wl_display *display,
closure = wl_connection_demarshal(display->connection, size,
&display->objects, message);
if (closure == NULL) {
if (closure == NULL || create_proxies(display, closure) < 0) {
fprintf(stderr, "Error demarshalling event\n");
abort();
}
......
......@@ -178,6 +178,25 @@ wl_resource_post_error(struct wl_resource *resource,
WL_DISPLAY_ERROR, resource, code, buffer);
}
static void
deref_new_objects(struct wl_closure *closure)
{
const char *signature;
int i;
signature = closure->message->signature;
for (i = 0; signature[i]; i++) {
switch (signature[i]) {
case 'n':
closure->args[i + 2] = *(uint32_t **) closure->args[i + 2];
closure->types[i] = &ffi_type_uint32;
break;
}
}
}
static int
wl_client_connection_data(int fd, uint32_t mask, void *data)
{
......@@ -247,6 +266,8 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
break;
}
deref_new_objects(closure);
if (wl_debug)
wl_closure_print(closure, object, false);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment