[RFC wayland 3/4] Add a dispatcher field to wl_object.
Jason Ekstrand
jason at jlekstrand.net
Wed Feb 27 19:29:57 PST 2013
Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
src/connection.c | 25 +++++++++++++++++++------
src/wayland-client.c | 8 ++++++--
src/wayland-private.h | 11 -----------
src/wayland-server.h | 1 +
src/wayland-util.h | 29 ++++++++++++++++++++++++++++-
5 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/src/connection.c b/src/connection.c
index d68f959..3b584ed 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -853,10 +853,10 @@ convert_arguments_to_ffi(const char *signature, union wl_argument *args,
}
}
-
void
-wl_closure_invoke(struct wl_closure *closure,
- struct wl_object *target, uint32_t opcode, void *data)
+wl_object_default_dispatcher(struct wl_object * target, uint32_t opcode,
+ const struct wl_message *message, void *data,
+ union wl_argument *args)
{
int count;
ffi_cif cif;
@@ -864,15 +864,15 @@ wl_closure_invoke(struct wl_closure *closure,
void * ffi_args[WL_CLOSURE_MAX_ARGS + 2];
void (* const *implementation)(void);
- count = arg_count_for_signature(closure->message->signature);
+ count = arg_count_for_signature(message->signature);
ffi_types[0] = &ffi_type_pointer;
ffi_args[0] = &data;
ffi_types[1] = &ffi_type_pointer;
ffi_args[1] = ⌖
- convert_arguments_to_ffi(closure->message->signature, closure->args,
- count, ffi_types + 2, ffi_args + 2);
+ convert_arguments_to_ffi(message->signature, args, count,
+ ffi_types + 2, ffi_args + 2);
ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
count + 2, &ffi_type_void, ffi_types);
@@ -881,6 +881,19 @@ wl_closure_invoke(struct wl_closure *closure,
ffi_call(&cif, implementation[opcode], NULL, ffi_args);
}
+void
+wl_closure_invoke(struct wl_closure *closure, struct wl_object *target,
+ uint32_t opcode, void *data)
+{
+ if (target->dispatcher) {
+ (*target->dispatcher)(target, opcode, closure->message,
+ data, closure->args);
+ } else {
+ wl_object_default_dispatcher(target, opcode, closure->message,
+ data, closure->args);
+ }
+}
+
static int
copy_fds_to_connection(struct wl_closure *closure,
struct wl_connection *connection)
diff --git a/src/wayland-client.c b/src/wayland-client.c
index e8cf7a2..07dd04e 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -220,6 +220,7 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
proxy->object.interface = interface;
proxy->object.implementation = NULL;
+ proxy->object.dispatcher = NULL;
proxy->display = display;
proxy->queue = factory->queue;
proxy->flags = 0;
@@ -247,6 +248,7 @@ wl_proxy_create_for_id(struct wl_proxy *factory,
proxy->object.interface = interface;
proxy->object.implementation = NULL;
+ proxy->object.dispatcher = NULL;
proxy->object.id = id;
proxy->display = display;
proxy->queue = factory->queue;
@@ -311,12 +313,13 @@ WL_EXPORT int
wl_proxy_add_listener(struct wl_proxy *proxy,
void (**implementation)(void), void *data)
{
- if (proxy->object.implementation) {
+ if (proxy->object.implementation || proxy->object.dispatcher) {
fprintf(stderr, "proxy already has listener\n");
return -1;
}
proxy->object.implementation = implementation;
+ proxy->object.dispatcher = NULL;
proxy->user_data = data;
return 0;
@@ -527,6 +530,7 @@ wl_display_connect_to_fd(int fd)
WL_MAP_CLIENT_SIDE, display);
display->proxy.display = display;
display->proxy.object.implementation = (void(**)(void)) &display_listener;
+ display->proxy.object.dispatcher = NULL;
display->proxy.user_data = display;
display->proxy.queue = &display->queue;
display->proxy.flags = 0;
@@ -832,7 +836,7 @@ dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
pthread_mutex_unlock(&display->mutex);
- if (proxy->object.implementation) {
+ if (proxy->object.implementation || proxy->object.dispatcher) {
if (wl_debug)
wl_closure_print(closure, &proxy->object, false);
diff --git a/src/wayland-private.h b/src/wayland-private.h
index cb92e51..fb70e99 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -74,17 +74,6 @@ int wl_connection_write(struct wl_connection *connection, const void *data, size
int wl_connection_queue(struct wl_connection *connection,
const void *data, size_t count);
-union wl_argument {
- int32_t i;
- uint32_t u;
- wl_fixed_t f;
- const char *s;
- struct wl_object *o;
- uint32_t n;
- struct wl_array *a;
- int32_t h;
-};
-
struct wl_closure {
int count;
const struct wl_message *message;
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 38b8303..b720f32 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -198,6 +198,7 @@ wl_resource_init(struct wl_resource *resource,
resource->object.id = id;
resource->object.interface = interface;
resource->object.implementation = implementation;
+ resource->object.dispatcher = NULL;
wl_signal_init(&resource->destroy_signal);
diff --git a/src/wayland-util.h b/src/wayland-util.h
index 257a5d1..0ddb642 100644
--- a/src/wayland-util.h
+++ b/src/wayland-util.h
@@ -1,5 +1,6 @@
/*
* Copyright © 2008 Kristian Høgsberg
+ * Copyright © 2013 Jason Ekstrand
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -54,12 +55,27 @@ struct wl_interface {
const struct wl_message *events;
};
+struct wl_object;
+union wl_argument;
+
+typedef void (*wl_object_dispatcher_func_t)(struct wl_object *, uint32_t,
+ const struct wl_message *,
+ void *, union wl_argument *);
+
struct wl_object {
const struct wl_interface *interface;
- void (* const * implementation)(void);
+ const void *implementation;
uint32_t id;
+
+ /* Added since Wayland version 1.0 */
+ wl_object_dispatcher_func_t dispatcher;
};
+void
+wl_object_default_dispatcher(struct wl_object * target, uint32_t opcode,
+ const struct wl_message *message, void *data,
+ union wl_argument *args);
+
/**
* wl_list - linked list
*
@@ -198,6 +214,17 @@ static inline wl_fixed_t wl_fixed_from_int(int i)
return i * 256;
}
+union wl_argument {
+ int32_t i;
+ uint32_t u;
+ wl_fixed_t f;
+ const char *s;
+ struct wl_object *o;
+ uint32_t n;
+ struct wl_array *a;
+ int32_t h;
+};
+
typedef void (*wl_log_func_t)(const char *, va_list);
#ifdef __cplusplus
--
1.8.1.2
More information about the wayland-devel
mailing list