diff options
Diffstat (limited to 'tests/weston-test.c')
-rw-r--r-- | tests/weston-test.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/tests/weston-test.c b/tests/weston-test.c new file mode 100644 index 00000000..bc5b6e9d --- /dev/null +++ b/tests/weston-test.c @@ -0,0 +1,250 @@ +/* + * 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 <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <unistd.h> +#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 weston_pointer *pointer = 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, int32_t width, int32_t height) +{ + struct weston_test_surface *test_surface = surface->configure_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); + + weston_surface_configure(surface, test_surface->x, test_surface->y, + width, height); + + 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 = + wl_resource_get_user_data(surface_resource); + struct weston_test_surface *test_surface; + + surface->configure = test_surface_configure; + if (surface->configure_private == NULL) + surface->configure_private = malloc(sizeof *test_surface); + test_surface = surface->configure_private; + if (test_surface == NULL) { + wl_resource_post_no_memory(resource); + return; + } + + test_surface->surface = surface; + test_surface->test = wl_resource_get_user_data(resource); + 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 = wl_resource_get_user_data(resource); + struct weston_seat *seat = get_seat(test); + struct weston_pointer *pointer = seat->pointer; + + test->compositor->focus = 1; + + notify_motion(seat, 100, + wl_fixed_from_int(x) - pointer->x, + wl_fixed_from_int(y) - pointer->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 = wl_resource_get_user_data(resource); + 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 ? + wl_resource_get_user_data(surface_resource) : NULL; + struct weston_test *test = wl_resource_get_user_data(resource); + 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 = wl_resource_get_user_data(resource); + 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_resource_create(client, &wl_test_interface, 1, id); + wl_resource_set_implementation(resource, + &test_implementation, test, NULL); + + 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, + int *argc, char *argv[]) +{ + struct weston_test *test; + struct wl_event_loop *loop; + + test = zalloc(sizeof *test); + if (test == NULL) + return -1; + + test->compositor = ec; + weston_layer_init(&test->layer, &ec->cursor_layer.link); + + if (wl_global_create(ec->wl_display, &wl_test_interface, 1, + 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; +} |