struct wl_client *client;
void *data;
int version;
+ wl_dispatcher_func_t dispatcher;
};
static int wl_debug = 0;
WL_EXPORT void
-wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
+wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
+ union wl_argument *args)
{
struct wl_closure *closure;
struct wl_object *object = &resource->object;
- va_list ap;
- va_start(ap, opcode);
- closure = wl_closure_vmarshal(object, opcode, ap,
- &object->interface->events[opcode]);
- va_end(ap);
+ closure = wl_closure_marshal(object, opcode, args,
+ &object->interface->events[opcode]);
if (closure == NULL) {
resource->client->error = 1;
wl_closure_destroy(closure);
}
-
WL_EXPORT void
-wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
+wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
{
- struct wl_closure *closure;
+ union wl_argument args[WL_CLOSURE_MAX_ARGS];
struct wl_object *object = &resource->object;
va_list ap;
va_start(ap, opcode);
- closure = wl_closure_vmarshal(object, opcode, ap,
- &object->interface->events[opcode]);
+ wl_argument_from_va_list(object->interface->events[opcode].signature,
+ args, WL_CLOSURE_MAX_ARGS, ap);
va_end(ap);
+ wl_resource_post_event_array(resource, opcode, args);
+}
+
+
+WL_EXPORT void
+wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode,
+ union wl_argument *args)
+{
+ struct wl_closure *closure;
+ struct wl_object *object = &resource->object;
+
+ closure = wl_closure_marshal(object, opcode, args,
+ &object->interface->events[opcode]);
+
if (closure == NULL) {
resource->client->error = 1;
return;
}
WL_EXPORT void
+wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
+{
+ union wl_argument args[WL_CLOSURE_MAX_ARGS];
+ struct wl_object *object = &resource->object;
+ va_list ap;
+
+ va_start(ap, opcode);
+ wl_argument_from_va_list(object->interface->events[opcode].signature,
+ args, WL_CLOSURE_MAX_ARGS, ap);
+ va_end(ap);
+
+ wl_resource_queue_event_array(resource, opcode, args);
+}
+
+WL_EXPORT void
wl_resource_post_error(struct wl_resource *resource,
uint32_t code, const char *msg, ...)
{
if (wl_debug)
wl_closure_print(closure, object, false);
- wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, object,
- opcode, client);
+ if ((resource_flags & WL_MAP_ENTRY_LEGACY) ||
+ resource->dispatcher == NULL) {
+ wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER,
+ object, opcode, client);
+ } else {
+ wl_closure_dispatch(closure, resource->dispatcher,
+ object, opcode);
+ }
wl_closure_destroy(closure);
resource->object.implementation = implementation;
resource->data = data;
resource->destroy = destroy;
+ resource->dispatcher = NULL;
}
+WL_EXPORT void
+wl_resource_set_dispatcher(struct wl_resource *resource,
+ wl_dispatcher_func_t dispatcher,
+ const void *implementation,
+ void *data, wl_resource_destroy_func_t destroy)
+{
+ resource->dispatcher = dispatcher;
+ resource->object.implementation = implementation;
+ resource->data = data;
+ resource->destroy = destroy;
+}
WL_EXPORT struct wl_resource *
wl_resource_create(struct wl_client *client,
resource->client = client;
resource->data = NULL;
resource->version = version;
+ resource->dispatcher = NULL;
if (wl_map_insert_at(&client->objects, 0, resource->object.id, resource) < 0) {
wl_resource_post_error(client->display_resource,
*/
void wl_resource_post_event(struct wl_resource *resource,
uint32_t opcode, ...);
+void wl_resource_post_event_array(struct wl_resource *resource,
+ uint32_t opcode, union wl_argument *args);
void wl_resource_queue_event(struct wl_resource *resource,
uint32_t opcode, ...);
+void wl_resource_queue_event_array(struct wl_resource *resource,
+ uint32_t opcode, union wl_argument *args);
/* msg is a printf format string, variable args are its args. */
void wl_resource_post_error(struct wl_resource *resource,
const void *implementation,
void *data,
wl_resource_destroy_func_t destroy);
+void
+wl_resource_set_dispatcher(struct wl_resource *resource,
+ wl_dispatcher_func_t dispatcher,
+ const void *implementation,
+ void *data,
+ wl_resource_destroy_func_t destroy);
void
wl_resource_destroy(struct wl_resource *resource);
return i * 256;
}
+/**
+ * \brief A union representing all of the basic data types that can be passed
+ * along the wayland wire format.
+ *
+ * This union represents all of the basic data types that can be passed in the
+ * wayland wire format. It is used by dispatchers and runtime-friendly
+ * versions of the event and request marshaling functions.
+ */
+union wl_argument {
+ int32_t i; /**< signed integer */
+ uint32_t u; /**< unsigned integer */
+ wl_fixed_t f; /**< fixed point */
+ const char *s; /**< string */
+ struct wl_object *o; /**< object */
+ uint32_t n; /**< new_id */
+ struct wl_array *a; /**< array */
+ int32_t h; /**< file descriptor */
+};
+
+/**
+ * \brief A function pointer type for a dispatcher.
+ *
+ * A dispatcher is a function that handles the emitting of callbacks in client
+ * code. For programs directly using the C library, this is done by using
+ * libffi to call function pointers. When binding to languages other than C,
+ * dispatchers provide a way to abstract the function calling process to be
+ * friendlier to other function calling systems.
+ *
+ * A dispatcher takes five arguments: The first is the dispatcher-specific
+ * implementation data associated with the target object. The second is the
+ * object on which the callback is being invoked (either wl_proxy or
+ * wl_resource). The third and fourth arguments are the opcode the wl_messsage
+ * structure corresponding to the callback being emitted. The final argument
+ * is an array of arguments recieved from the other process via the wire
+ * protocol.
+ */
+typedef int (*wl_dispatcher_func_t)(const void *, void *, uint32_t,
+ const struct wl_message *,
+ union wl_argument *);
+
typedef void (*wl_log_func_t)(const char *, va_list);
#ifdef __cplusplus