summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/scanner.c43
-rw-r--r--src/wayland-client.c211
-rw-r--r--src/wayland-client.h8
4 files changed, 189 insertions, 75 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4226f63..fb2df1c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,7 +27,7 @@ libwayland_server_la_SOURCES = \
event-loop.c
libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm
-libwayland_client_la_LDFLAGS = -version-info 1:0:1
+libwayland_client_la_LDFLAGS = -version-info 2:0:2
libwayland_client_la_SOURCES = \
wayland-protocol.c \
wayland-client.c
diff --git a/src/scanner.c b/src/scanner.c
index 9624618..a030181 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -699,31 +699,34 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
"{\n");
if (ret) {
printf("\tstruct wl_proxy *%s;\n\n"
- "\t%s = wl_proxy_create("
- "(struct wl_proxy *) %s,\n",
- ret->name, ret->name, interface->name);
+ "\t%s = wl_proxy_marshal_constructor("
+ "(struct wl_proxy *) %s,\n"
+ "\t\t\t %s_%s, ",
+ ret->name, ret->name,
+ interface->name,
+ interface->uppercase_name,
+ m->uppercase_name);
+
if (ret->interface_name == NULL)
- printf("\t\t\t interface);\n");
+ printf("interface");
else
- printf("\t\t\t &%s_interface);\n",
- ret->interface_name);
-
- printf("\tif (!%s)\n"
- "\t\treturn NULL;\n\n",
- ret->name);
+ printf("&%s_interface", ret->interface_name);
+ } else {
+ printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
+ "\t\t\t %s_%s",
+ interface->name,
+ interface->uppercase_name,
+ m->uppercase_name);
}
- printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
- "\t\t\t %s_%s",
- interface->name,
- interface->uppercase_name,
- m->uppercase_name);
-
wl_list_for_each(a, &m->arg_list, link) {
- if (a->type == NEW_ID && a->interface_name == NULL)
- printf(", interface->name, version");
- printf(", ");
- printf("%s", a->name);
+ if (a->type == NEW_ID) {
+ if (a->interface_name == NULL)
+ printf(", interface->name, version");
+ printf(", NULL");
+ } else {
+ printf(", %s", a->name);
+ }
}
printf(");\n");
diff --git a/src/wayland-client.c b/src/wayland-client.c
index e92317a..1486b73 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -194,6 +194,29 @@ wl_display_create_queue(struct wl_display *display)
return queue;
}
+static struct wl_proxy *
+proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
+{
+ struct wl_proxy *proxy;
+ struct wl_display *display = factory->display;
+
+ proxy = malloc(sizeof *proxy);
+ if (proxy == NULL)
+ return NULL;
+
+ proxy->object.interface = interface;
+ proxy->object.implementation = NULL;
+ proxy->dispatcher = NULL;
+ proxy->display = display;
+ proxy->queue = factory->queue;
+ proxy->flags = 0;
+ proxy->refcount = 1;
+
+ proxy->object.id = wl_map_insert_new(&display->objects, 0, proxy);
+
+ return proxy;
+}
+
/** Create a proxy object with a given interface
*
* \param factory Factory proxy object
@@ -216,23 +239,11 @@ wl_display_create_queue(struct wl_display *display)
WL_EXPORT struct wl_proxy *
wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
{
- struct wl_proxy *proxy;
struct wl_display *display = factory->display;
-
- proxy = malloc(sizeof *proxy);
- if (proxy == NULL)
- return NULL;
-
- proxy->object.interface = interface;
- proxy->object.implementation = NULL;
- proxy->dispatcher = NULL;
- proxy->display = display;
- proxy->queue = factory->queue;
- proxy->flags = 0;
- proxy->refcount = 1;
+ struct wl_proxy *proxy;
pthread_mutex_lock(&display->mutex);
- proxy->object.id = wl_map_insert_new(&display->objects, 0, proxy);
+ proxy = proxy_create(factory, interface);
pthread_mutex_unlock(&display->mutex);
return proxy;
@@ -382,27 +393,107 @@ wl_proxy_add_dispatcher(struct wl_proxy *proxy,
return 0;
}
+static struct wl_proxy *
+create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message,
+ union wl_argument *args,
+ const struct wl_interface *interface)
+{
+ int i, count;
+ const char *signature;
+ struct argument_details arg;
+ struct wl_proxy *new_proxy = NULL;
+
+ signature = message->signature;
+ count = arg_count_for_signature(signature);
+ for (i = 0; i < count; i++) {
+ signature = get_next_argument(signature, &arg);
+
+ switch (arg.type) {
+ case 'n':
+ new_proxy = proxy_create(proxy, interface);
+ if (new_proxy == NULL)
+ return NULL;
+
+ args[i].o = &new_proxy->object;
+ break;
+ }
+ }
+
+ return new_proxy;
+}
+
/** Prepare a request to be sent to the compositor
*
* \param proxy The proxy object
* \param opcode Opcode of the request to be sent
- * \param ... Extra arguments for the given request
+ * \param args Extra arguments for the given request
+ * \param iterface The interface to use for the new proxy
*
* Translates the request given by opcode and the extra arguments into the
- * wire format and write it to the connection buffer.
+ * wire format and write it to the connection buffer. This version takes an
+ * array of the union type wl_argument.
*
- * The example below creates a proxy object with the wl_surface_interface
- * using a wl_compositor factory interface and sends the
- * \c compositor.create_surface request using \ref wl_proxy_marshal(). Note
- * the \c id is the extra argument to the request as specified by the
- * protocol.
+ * For new-id arguments, this function will allocate a new wl_proxy
+ * and send the ID to the server. The new wl_proxy will be returned
+ * on success or NULL on errror with errno set accordingly.
+ *
+ * \note This is intended to be used by language bindings and not in
+ * non-generated code.
*
- * \code
- * id = wl_proxy_create((struct wl_proxy *) wl_compositor,
- * &wl_surface_interface);
- * wl_proxy_marshal((struct wl_proxy *) wl_compositor,
- * WL_COMPOSITOR_CREATE_SURFACE, id);
- * \endcode
+ * \sa wl_proxy_marshal()
+ *
+ * \memberof wl_proxy
+ */
+WL_EXPORT struct wl_proxy *
+wl_proxy_marshal_array_constructor(struct wl_proxy *proxy,
+ uint32_t opcode, union wl_argument *args,
+ const struct wl_interface *interface)
+{
+ struct wl_closure *closure;
+ struct wl_proxy *new_proxy = NULL;
+ const struct wl_message *message;
+
+ pthread_mutex_lock(&proxy->display->mutex);
+
+ message = &proxy->object.interface->methods[opcode];
+ if (interface) {
+ new_proxy = create_outgoing_proxy(proxy, message,
+ args, interface);
+ if (new_proxy == NULL)
+ goto err_unlock;
+ }
+
+ closure = wl_closure_marshal(&proxy->object, opcode, args, message);
+ if (closure == NULL) {
+ fprintf(stderr, "Error marshalling request\n");
+ abort();
+ }
+
+ if (wl_debug)
+ wl_closure_print(closure, &proxy->object, true);
+
+ if (wl_closure_send(closure, proxy->display->connection)) {
+ fprintf(stderr, "Error sending request: %m\n");
+ abort();
+ }
+
+ wl_closure_destroy(closure);
+
+ err_unlock:
+ pthread_mutex_unlock(&proxy->display->mutex);
+
+ return new_proxy;
+}
+
+
+/** Prepare a request to be sent to the compositor
+ *
+ * \param proxy The proxy object
+ * \param opcode Opcode of the request to be sent
+ * \param ... Extra arguments for the given request
+ *
+ * This function is similar to wl_proxy_marshal_constructor(), except
+ * it doesn't create proxies for new-id arguments.
*
* \note This should not normally be used by non-generated code.
*
@@ -421,18 +512,52 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
args, WL_CLOSURE_MAX_ARGS, ap);
va_end(ap);
- wl_proxy_marshal_array(proxy, opcode, args);
+ wl_proxy_marshal_array_constructor(proxy, opcode, args, NULL);
}
/** Prepare a request to be sent to the compositor
*
* \param proxy The proxy object
* \param opcode Opcode of the request to be sent
- * \param args Extra arguments for the given request
+ * \param iterface The interface to use for the new proxy
+ * \param ... Extra arguments for the given request
+ * \return A new wl_proxy for the new_id argument or NULL on error
*
* Translates the request given by opcode and the extra arguments into the
- * wire format and write it to the connection buffer. This version takes an
- * array of the union type wl_argument.
+ * wire format and write it to the connection buffer.
+ *
+ * For new-id arguments, this function will allocate a new wl_proxy
+ * and send the ID to the server. The new wl_proxy will be returned
+ * on success or NULL on errror with errno set accordingly.
+ *
+ * \note This should not normally be used by non-generated code.
+ *
+ * \memberof wl_proxy
+ */
+WL_EXPORT struct wl_proxy *
+wl_proxy_marshal_constructor(struct wl_proxy *proxy, uint32_t opcode,
+ const struct wl_interface *interface, ...)
+{
+ union wl_argument args[WL_CLOSURE_MAX_ARGS];
+ va_list ap;
+
+ va_start(ap, interface);
+ wl_argument_from_va_list(proxy->object.interface->methods[opcode].signature,
+ args, WL_CLOSURE_MAX_ARGS, ap);
+ va_end(ap);
+
+ return wl_proxy_marshal_array_constructor(proxy, opcode,
+ args, interface);
+}
+
+/** Prepare a request to be sent to the compositor
+ *
+ * \param proxy The proxy object
+ * \param opcode Opcode of the request to be sent
+ * \param args Extra arguments for the given request
+ *
+ * This function is similar to wl_proxy_marshal_array_constructor(), except
+ * it doesn't create proxies for new-id arguments.
*
* \note This is intended to be used by language bindings and not in
* non-generated code.
@@ -445,29 +570,7 @@ WL_EXPORT void
wl_proxy_marshal_array(struct wl_proxy *proxy, uint32_t opcode,
union wl_argument *args)
{
- struct wl_closure *closure;
-
- pthread_mutex_lock(&proxy->display->mutex);
-
- closure = wl_closure_marshal(&proxy->object, opcode, args,
- &proxy->object.interface->methods[opcode]);
-
- if (closure == NULL) {
- fprintf(stderr, "Error marshalling request\n");
- abort();
- }
-
- if (wl_debug)
- wl_closure_print(closure, &proxy->object, true);
-
- if (wl_closure_send(closure, proxy->display->connection)) {
- fprintf(stderr, "Error sending request: %m\n");
- abort();
- }
-
- wl_closure_destroy(closure);
-
- pthread_mutex_unlock(&proxy->display->mutex);
+ wl_proxy_marshal_array_constructor(proxy, opcode, args, NULL);
}
static void
diff --git a/src/wayland-client.h b/src/wayland-client.h
index 43ba3fc..2a32785 100644
--- a/src/wayland-client.h
+++ b/src/wayland-client.h
@@ -126,6 +126,14 @@ void wl_proxy_marshal_array(struct wl_proxy *p, uint32_t opcode,
union wl_argument *args);
struct wl_proxy *wl_proxy_create(struct wl_proxy *factory,
const struct wl_interface *interface);
+struct wl_proxy *wl_proxy_marshal_constructor(struct wl_proxy *proxy,
+ uint32_t opcode,
+ const struct wl_interface *interface,
+ ...);
+struct wl_proxy *
+wl_proxy_marshal_array_constructor(struct wl_proxy *proxy,
+ uint32_t opcode, union wl_argument *args,
+ const struct wl_interface *interface);
void wl_proxy_destroy(struct wl_proxy *proxy);
int wl_proxy_add_listener(struct wl_proxy *proxy,