[PATCH wayland 2/4] Add a default dispatcher function and related test

Jason Ekstrand jason at jlekstrand.net
Tue Jan 29 07:21:52 PST 2013


Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
 src/connection.c        | 80 +++++++++++++++++++++++++++++++++++++++++
 src/wayland-private.h   |  5 +++
 src/wayland-util.h      | 12 +++++++
 tests/.gitignore        |  1 +
 tests/Makefile.am       |  2 ++
 tests/dispatcher-test.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 196 insertions(+)
 create mode 100644 tests/dispatcher-test.c

diff --git a/src/connection.c b/src/connection.c
index 141875e..76aefb7 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -1039,3 +1039,83 @@ wl_closure_destroy(struct wl_closure *closure)
 {
 	free(closure);
 }
+
+static void
+convert_arguments_to_ffi(const char *signature, union wl_argument *args,
+			 int count, ffi_type **ffi_types, void** ffi_args)
+{
+	int i;
+	const char *sig_iter;
+	struct argument_details arg;
+
+	sig_iter = signature;
+	for (i = 0; i < count; i++) {
+		sig_iter = get_next_argument(sig_iter, &arg);
+
+		switch(arg.type) {
+		case 'i':
+			ffi_types[i] = &ffi_type_sint32;
+			ffi_args[i] = &args[i].i;
+			break;
+		case 'u':
+			ffi_types[i] = &ffi_type_uint32;
+			ffi_args[i] = &args[i].u;
+			break;
+		case 'f':
+			ffi_types[i] = &ffi_type_sint32;
+			ffi_args[i] = &args[i].f;
+			break;
+		case 's':
+			ffi_types[i] = &ffi_type_pointer;
+			ffi_args[i] = &args[i].s;
+			break;
+		case 'o':
+			ffi_types[i] = &ffi_type_pointer;
+			ffi_args[i] = &args[i].o;
+			break;
+		case 'n':
+			ffi_types[i] = &ffi_type_uint32;
+			ffi_args[i] = &args[i].n;
+			break;
+		case 'a':
+			ffi_types[i] = &ffi_type_pointer;
+			ffi_args[i] = &args[i].a;
+			break;
+		case 'h':
+			ffi_types[i] = &ffi_type_sint32;
+			ffi_args[i] = &args[i].h;
+			break;
+		default:
+			printf("unknown type\n");
+			assert(0);
+			break;
+		}
+	}
+}
+
+void
+wl_interface_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;
+	ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2];
+	void * ffi_args[WL_CLOSURE_MAX_ARGS + 2];
+
+	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(message->signature, args, count,
+				 ffi_types + 2, ffi_args + 2);
+
+	ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
+		     count + 2, &ffi_type_void, ffi_types);
+	
+	ffi_call(&cif, target->implementation[opcode], NULL, ffi_args);
+}
+
diff --git a/src/wayland-private.h b/src/wayland-private.h
index ecd7f17..18f280e 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -123,6 +123,11 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
 void
 wl_closure_destroy(struct wl_closure *closure);
 
+void
+wl_interface_default_dispatcher(struct wl_object *target, uint32_t opcode,
+				const struct wl_message *message,
+				void *data, union wl_argument *args);
+
 extern wl_log_func_t wl_log_handler;
 
 void wl_log(const char *fmt, ...);
diff --git a/src/wayland-util.h b/src/wayland-util.h
index 257a5d1..df7b384 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
@@ -198,6 +199,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
diff --git a/tests/.gitignore b/tests/.gitignore
index ccd440a..0e5a973 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -4,6 +4,7 @@
 array-test
 client-test
 connection-test
+dispatcher-test
 display-test
 event-loop-test
 exec-fd-leak-checker
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 54157bc..f9ed1ae 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -3,6 +3,7 @@ TESTS =						\
 	client-test				\
 	display-test				\
 	connection-test				\
+	dispatcher-test				\
 	event-loop-test				\
 	fixed-test				\
 	list-test				\
@@ -25,6 +26,7 @@ array_test_SOURCES = array-test.c $(test_runner_src)
 client_test_SOURCES = client-test.c $(test_runner_src)
 display_test_SOURCES = display-test.c $(test_runner_src)
 connection_test_SOURCES = connection-test.c $(test_runner_src)
+dispatcher_test_SOURCES = dispatcher-test.c $(test_runner_src)
 event_loop_test_SOURCES = event-loop-test.c $(test_runner_src)
 fixed_test_SOURCES = fixed-test.c $(test_runner_src)
 list_test_SOURCES = list-test.c $(test_runner_src)
diff --git a/tests/dispatcher-test.c b/tests/dispatcher-test.c
new file mode 100644
index 0000000..9f96a01
--- /dev/null
+++ b/tests/dispatcher-test.c
@@ -0,0 +1,96 @@
+/*
+ * 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
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "wayland-private.h"
+#include "test-runner.h"
+
+static void
+test_function(void *data, struct wl_object *target, 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)
+{
+	union wl_argument *args;
+
+	args = (union wl_argument *)data;
+	args[0].i = i;
+	args[1].u = u;
+	args[2].f = f;
+	args[3].s = s;
+	args[4].o = o;
+	args[5].n = n;
+	args[6].a = a;
+	args[7].h = h;
+	args[8].o = target;
+}
+
+const struct wl_interface *null_interfaces[8];
+
+struct wl_message test_message = {
+	"test_message", "iuf?sonah", null_interfaces
+};
+
+struct wl_interface test_interface = {
+	"test_interface",
+	1,
+	1, &test_message,
+	1, &test_message
+};
+
+void (* test_function_ptr)(void) = (void (*)(void))&test_function;
+
+TEST(default_dispatcher)
+{
+	struct wl_object target, dummy_obj;
+	struct wl_array arr;
+	union wl_argument args_in[8], args_out[9];
+
+	target.interface = &test_interface;
+	target.implementation = &test_function_ptr;
+	target.id = 7;
+
+	args_in[0].i = -356;
+	args_in[1].u = 42;
+	args_in[2].f = 1007 * 256 + 128; /* 1007.5 */
+	args_in[3].s = "Test String";
+	args_in[4].o = &dummy_obj;
+	args_in[5].n = 75284;
+	args_in[6].a = &arr;
+	args_in[7].h = 37;
+
+	wl_interface_default_dispatcher(&target, 0, &test_message,
+					args_out, args_in);
+
+	assert(args_in[0].i == args_out[0].i);
+	assert(args_in[1].u == args_out[1].u);
+	assert(args_in[2].f == args_out[2].f);
+	assert(args_in[3].s == args_out[3].s);
+	assert(args_in[4].o == args_out[4].o);
+	assert(args_in[5].n == args_out[5].n);
+	assert(args_in[6].a == args_out[6].a);
+	assert(args_in[7].h == args_out[7].h);
+	assert(args_out[8].o == &target);
+}
+
-- 
1.8.1



More information about the wayland-devel mailing list