From 65e7e7a65bf17f7b886653bfee850ff728bbd904 Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Fri, 7 Dec 2012 13:50:29 -0800 Subject: [PATCH] tests: Define and implement a test protocol extension. The weston test extension, called weston-test.so, can be loaded from the "modules" configuration option on the command line or in the .ini file. Clients can bind to the "wl_test" interface to interact with the weston test extension. Signed-off-by: U. Artie Eoff --- protocol/Makefile.am | 3 +- protocol/wayland-test.xml | 55 +++++++++ tests/.gitignore | 3 + tests/Makefile.am | 35 +++++- tests/weston-test.c | 248 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 338 insertions(+), 6 deletions(-) create mode 100644 protocol/wayland-test.xml create mode 100644 tests/weston-test.c diff --git a/protocol/Makefile.am b/protocol/Makefile.am index c68e4c1c..8c1803c8 100644 --- a/protocol/Makefile.am +++ b/protocol/Makefile.am @@ -5,4 +5,5 @@ EXTRA_DIST = \ xserver.xml \ text.xml \ input-method.xml \ - workspaces.xml + workspaces.xml \ + wayland-test.xml diff --git a/protocol/wayland-test.xml b/protocol/wayland-test.xml new file mode 100644 index 00000000..2993f087 --- /dev/null +++ b/protocol/wayland-test.xml @@ -0,0 +1,55 @@ + + + + + Copyright © 2012 Intel Corporation + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/.gitignore b/tests/.gitignore index f46c8d2e..26bf83db 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -2,3 +2,6 @@ matrix-test setbacklight test-client test-text-client +wayland-test-client-protocol.h +wayland-test-protocol.c +wayland-test-server-protocol.h diff --git a/tests/Makefile.am b/tests/Makefile.am index b1b76ba8..7dd02ca4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -7,13 +7,22 @@ TESTS_ENVIRONMENT = $(SHELL) $(top_srcdir)/tests/weston-test export abs_builddir -AM_CFLAGS = $(GCC_CFLAGS) -AM_CPPFLAGS = -I$(top_srcdir)/src -DUNIT_TEST $(COMPOSITOR_CFLAGS) +noinst_LTLIBRARIES = \ + $(weston_test) +noinst_PROGRAMS = \ + $(setbacklight) \ + matrix-test -check_LTLIBRARIES = $(TESTS) -check_PROGRAMS = test-client test-text-client +check_LTLIBRARIES = \ + $(TESTS) +check_PROGRAMS = \ + test-client \ + test-text-client + +AM_CFLAGS = $(GCC_CFLAGS) +AM_CPPFLAGS = -I$(top_srcdir)/src -DUNIT_TEST $(COMPOSITOR_CFLAGS) AM_LDFLAGS = -module -avoid-version -rpath $(libdir) test_runner_src = test-runner.c test-runner.h @@ -32,7 +41,14 @@ test_client_LDADD = $(SIMPLE_CLIENT_LIBS) test_text_client_SOURCES = test-text-client.c ../clients/text-protocol.c test_text_client_LDADD = $(SIMPLE_CLIENT_LIBS) -noinst_PROGRAMS = $(setbacklight) matrix-test +weston_test = weston-test.la +weston_test_la_LIBADD = $(COMPOSITOR_LIBS) \ + ../shared/libshared.la +weston_test_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) +weston_test_la_SOURCES = \ + weston-test.c \ + wayland-test-protocol.c \ + wayland-test-server-protocol.h matrix_test_SOURCES = \ matrix-test.c \ @@ -53,3 +69,12 @@ setbacklight = setbacklight endif EXTRA_DIST = weston-test + +BUILT_SOURCES = \ + wayland-test-protocol.c \ + wayland-test-server-protocol.h \ + wayland-test-client-protocol.h + +CLEANFILES = $(BUILT_SOURCES) + +@wayland_scanner_rules@ diff --git a/tests/weston-test.c b/tests/weston-test.c new file mode 100644 index 00000000..be635fa4 --- /dev/null +++ b/tests/weston-test.c @@ -0,0 +1,248 @@ +/* + * Copyright © 2012 Intel Corporation + * + * 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 +#include +#include +#include +#include +#include "../src/compositor.h" +#include "wayland-test-server-protocol.h" + +struct weston_test { + struct weston_compositor *compositor; + struct weston_layer layer; + struct weston_process process; +}; + +struct weston_test_surface { + struct weston_surface *surface; + int32_t x, y; + struct weston_test *test; +}; + +static void +test_client_sigchld(struct weston_process *process, int status) +{ + struct weston_test *test = + container_of(process, struct weston_test, process); + + assert(status == 0); + + wl_display_terminate(test->compositor->wl_display); +} + +static struct weston_seat * +get_seat(struct weston_test *test) +{ + struct wl_list *seat_list; + struct weston_seat *seat; + + seat_list = &test->compositor->seat_list; + assert(wl_list_length(seat_list) == 1); + seat = container_of(seat_list->next, struct weston_seat, link); + + return seat; +} + +static void +notify_pointer_position(struct weston_test *test, struct wl_resource *resource) +{ + struct weston_seat *seat = get_seat(test); + struct wl_pointer *pointer = seat->seat.pointer; + + wl_test_send_pointer_position(resource, pointer->x, pointer->y); +} + +static void +test_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy) +{ + struct weston_test_surface *test_surface = surface->private; + struct weston_test *test = test_surface->test; + + if (wl_list_empty(&surface->layer_link)) + wl_list_insert(&test->layer.surface_list, + &surface->layer_link); + + surface->geometry.x = test_surface->x; + surface->geometry.y = test_surface->y; + surface->geometry.width = surface->buffer_ref.buffer->width; + surface->geometry.height = surface->buffer_ref.buffer->height; + surface->geometry.dirty = 1; + + if (!weston_surface_is_mapped(surface)) + weston_surface_update_transform(surface); +} + +static void +move_surface(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *surface_resource, + int32_t x, int32_t y) +{ + struct weston_surface *surface = surface_resource->data; + struct weston_test_surface *test_surface; + + surface->configure = test_surface_configure; + if (surface->private == NULL) + surface->private = malloc(sizeof *test_surface); + test_surface = surface->private; + if (test_surface == NULL) { + wl_resource_post_no_memory(resource); + return; + } + + test_surface->surface = surface; + test_surface->test = resource->data; + test_surface->x = x; + test_surface->y = y; +} + +static void +move_pointer(struct wl_client *client, struct wl_resource *resource, + int32_t x, int32_t y) +{ + struct weston_test *test = resource->data; + struct weston_seat *seat = get_seat(test); + + test->compositor->focus = 1; + + notify_motion(seat, 100, wl_fixed_from_int(x), wl_fixed_from_int(y)); + + notify_pointer_position(test, resource); +} + +static void +send_button(struct wl_client *client, struct wl_resource *resource, + int32_t button, uint32_t state) +{ + struct weston_test *test = resource->data; + struct weston_seat *seat = get_seat(test); + + test->compositor->focus = 1; + + notify_button(seat, 100, button, state); +} + +static void +activate_surface(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct weston_surface *surface = surface_resource ? + surface_resource->data : NULL; + struct weston_test *test = resource->data; + struct weston_seat *seat; + + seat = get_seat(test); + + if (surface) { + weston_surface_activate(surface, seat); + notify_keyboard_focus_in(seat, &seat->keyboard.keys, + STATE_UPDATE_AUTOMATIC); + } + else { + notify_keyboard_focus_out(seat); + weston_surface_activate(surface, seat); + } +} + +static void +send_key(struct wl_client *client, struct wl_resource *resource, + uint32_t key, enum wl_keyboard_key_state state) +{ + struct weston_test *test = resource->data; + struct weston_seat *seat = get_seat(test); + + test->compositor->focus = 1; + + notify_key(seat, 100, key, state, STATE_UPDATE_AUTOMATIC); +} + +static const struct wl_test_interface test_implementation = { + move_surface, + move_pointer, + send_button, + activate_surface, + send_key +}; + +static void +bind_test(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct weston_test *test = data; + struct wl_resource *resource; + + resource = wl_client_add_object(client, &wl_test_interface, + &test_implementation, id, test); + + notify_pointer_position(test, resource); +} + +static void +idle_launch_client(void *data) +{ + struct weston_test *test = data; + pid_t pid; + sigset_t allsigs; + char *path; + + path = getenv("WESTON_TEST_CLIENT_PATH"); + if (path == NULL) + exit(EXIT_FAILURE); + pid = fork(); + if (pid == -1) + exit(EXIT_FAILURE); + if (pid == 0) { + sigfillset(&allsigs); + sigprocmask(SIG_UNBLOCK, &allsigs, NULL); + execl(path, path, NULL); + weston_log("compositor: executing '%s' failed: %m\n", path); + exit(EXIT_FAILURE); + } + + test->process.pid = pid; + test->process.cleanup = test_client_sigchld; + weston_watch_process(&test->process); +} + +WL_EXPORT int +module_init(struct weston_compositor *ec) +{ + struct weston_test *test; + struct wl_event_loop *loop; + + test = malloc(sizeof *test); + if (test == NULL) + return -1; + + memset(test, 0, sizeof *test); + test->compositor = ec; + weston_layer_init(&test->layer, &ec->cursor_layer.link); + + if (wl_display_add_global(ec->wl_display, &wl_test_interface, + test, bind_test) == NULL) + return -1; + + loop = wl_display_get_event_loop(ec->wl_display); + wl_event_loop_add_idle(loop, idle_launch_client, test); + + return 0; +}