[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