summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Glidic <sardemff7+git@sardemff7.net>2016-08-11 18:54:44 +0200
committerQuentin Glidic <sardemff7+git@sardemff7.net>2016-09-27 12:23:07 +0200
commit42ae01dbd82a100d27c27cde6fc8396bebef83eb (patch)
treecf1733918e00088a7bcecaf370c4e4c4dcc301c9
parente338ced1e04bf4b97322d5eed2b5bdf5b052095a (diff)
tests: Add some basic libweston-desktop shells tests
Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
-rw-r--r--Makefile.am29
-rw-r--r--tests/bad-buffer-test.c4
-rw-r--r--tests/event-test.c12
-rw-r--r--tests/reference/wl_shell_toplevel-screenshot-good-00.pngbin0 -> 1644 bytes
-rw-r--r--tests/reference/wl_shell_transient-screenshot-good-00.pngbin0 -> 2911 bytes
-rw-r--r--tests/reference/xdg_shell_v5_popup-screenshot-good-00.pngbin0 -> 1494 bytes
-rw-r--r--tests/reference/xdg_shell_v5_toplevel-screenshot-good-00.pngbin0 -> 1004 bytes
-rw-r--r--tests/reference/xdg_shell_v6_toplevel-screenshot-good-00.pngbin0 -> 1004 bytes
-rw-r--r--tests/weston-test-client-helper.c25
-rw-r--r--tests/weston-test-client-helper.h8
-rw-r--r--tests/weston-test-desktop-shell.c193
-rw-r--r--tests/wl-shell-test.c206
-rw-r--r--tests/xdg-shell-v5-test.c281
-rw-r--r--tests/xdg-shell-v6-test.c438
14 files changed, 1175 insertions, 21 deletions
diff --git a/Makefile.am b/Makefile.am
index 1e63a58c..ce49ad56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1163,6 +1163,9 @@ module_tests = \
surface-global-test.la
weston_tests = \
+ xdg_shell_v6_test.weston \
+ xdg_shell_v5_test.weston \
+ wl_shell_test.weston \
bad_buffer.weston \
keyboard.weston \
event.weston \
@@ -1195,6 +1198,7 @@ export abs_builddir
noinst_LTLIBRARIES += \
weston-test.la \
+ weston-test-desktop-shell.la \
$(module_tests) \
libtest-runner.la \
libtest-client.la
@@ -1232,6 +1236,31 @@ nodist_weston_test_la_SOURCES = \
protocol/weston-test-protocol.c \
protocol/weston-test-server-protocol.h
+weston_test_desktop_shell_la_LIBADD = libshared.la libweston-desktop-@LIBWESTON_MAJOR@.la $(COMPOSITOR_LIBS)
+weston_test_desktop_shell_la_LDFLAGS = $(test_module_ldflags)
+weston_test_desktop_shell_la_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
+weston_test_desktop_shell_la_SOURCES = \
+ tests/weston-test-desktop-shell.c \
+ shared/helpers.h
+
+xdg_shell_v6_test_weston_SOURCES = tests/xdg-shell-v6-test.c
+nodist_xdg_shell_v6_test_weston_SOURCES = protocol/xdg-shell-unstable-v6-protocol.c
+xdg_shell_v6_test_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
+xdg_shell_v6_test_weston_LDADD = libtest-client.la
+
+xdg_shell_v6_test.weston tests/xdg_shell_v6_test_weston-xdg-shell-v6-test.o: protocol/xdg-shell-unstable-v6-client-protocol.h
+
+xdg_shell_v5_test_weston_SOURCES = tests/xdg-shell-v5-test.c
+nodist_xdg_shell_v5_test_weston_SOURCES = protocol/xdg-shell-unstable-v5-protocol.c
+xdg_shell_v5_test_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
+xdg_shell_v5_test_weston_LDADD = libtest-client.la
+
+xdg_shell_v5_test.weston tests/xdg_shell_v5_test_weston-xdg-shell-v5-test.o: protocol/xdg-shell-unstable-v5-client-protocol.h
+
+wl_shell_test_weston_SOURCES = tests/wl-shell-test.c
+wl_shell_test_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
+wl_shell_test_weston_LDADD = libtest-client.la
+
if ENABLE_EGL
weston_test_la_CFLAGS += $(EGL_TESTS_CFLAGS)
weston_test_la_LDFLAGS += $(EGL_TESTS_LIBS)
diff --git a/tests/bad-buffer-test.c b/tests/bad-buffer-test.c
index ee7b2231..4a83210f 100644
--- a/tests/bad-buffer-test.c
+++ b/tests/bad-buffer-test.c
@@ -75,9 +75,9 @@ TEST(test_truncated_shm_file)
wl_surface_attach(surface, bad_buffer, 0, 0);
wl_surface_damage(surface, 0, 0, 200, 200);
- frame_callback_set(surface, &frame);
+ client_set_wait_frame_callback(surface, &frame);
wl_surface_commit(surface);
- frame_callback_wait_nofail(client, &frame);
+ client_wait_nofail(client, &frame);
expect_protocol_error(client, &wl_buffer_interface,
WL_SHM_ERROR_INVALID_FD);
diff --git a/tests/event-test.c b/tests/event-test.c
index 64dd7a0c..a2c577de 100644
--- a/tests/event-test.c
+++ b/tests/event-test.c
@@ -398,25 +398,25 @@ TEST(buffer_release)
wl_surface_attach(surface, buf1->proxy, 0, 0);
wl_surface_attach(surface, buf2->proxy, 0, 0);
- frame_callback_set(surface, &frame);
+ client_set_wait_frame_callback(surface, &frame);
wl_surface_commit(surface);
- frame_callback_wait(client, &frame);
+ client_wait(client, &frame);
assert(buf1_released == 0);
/* buf2 may or may not be released */
assert(buf3_released == 0);
wl_surface_attach(surface, buf3->proxy, 0, 0);
- frame_callback_set(surface, &frame);
+ client_set_wait_frame_callback(surface, &frame);
wl_surface_commit(surface);
- frame_callback_wait(client, &frame);
+ client_wait(client, &frame);
assert(buf1_released == 0);
assert(buf2_released == 1);
/* buf3 may or may not be released */
wl_surface_attach(surface, client->surface->buffer->proxy, 0, 0);
- frame_callback_set(surface, &frame);
+ client_set_wait_frame_callback(surface, &frame);
wl_surface_commit(surface);
- frame_callback_wait(client, &frame);
+ client_wait(client, &frame);
assert(buf1_released == 0);
assert(buf2_released == 1);
assert(buf3_released == 1);
diff --git a/tests/reference/wl_shell_toplevel-screenshot-good-00.png b/tests/reference/wl_shell_toplevel-screenshot-good-00.png
new file mode 100644
index 00000000..a9a5539f
--- /dev/null
+++ b/tests/reference/wl_shell_toplevel-screenshot-good-00.png
Binary files differ
diff --git a/tests/reference/wl_shell_transient-screenshot-good-00.png b/tests/reference/wl_shell_transient-screenshot-good-00.png
new file mode 100644
index 00000000..4e99a5b1
--- /dev/null
+++ b/tests/reference/wl_shell_transient-screenshot-good-00.png
Binary files differ
diff --git a/tests/reference/xdg_shell_v5_popup-screenshot-good-00.png b/tests/reference/xdg_shell_v5_popup-screenshot-good-00.png
new file mode 100644
index 00000000..7684359c
--- /dev/null
+++ b/tests/reference/xdg_shell_v5_popup-screenshot-good-00.png
Binary files differ
diff --git a/tests/reference/xdg_shell_v5_toplevel-screenshot-good-00.png b/tests/reference/xdg_shell_v5_toplevel-screenshot-good-00.png
new file mode 100644
index 00000000..f311c168
--- /dev/null
+++ b/tests/reference/xdg_shell_v5_toplevel-screenshot-good-00.png
Binary files differ
diff --git a/tests/reference/xdg_shell_v6_toplevel-screenshot-good-00.png b/tests/reference/xdg_shell_v6_toplevel-screenshot-good-00.png
new file mode 100644
index 00000000..f311c168
--- /dev/null
+++ b/tests/reference/xdg_shell_v6_toplevel-screenshot-good-00.png
Binary files differ
diff --git a/tests/weston-test-client-helper.c b/tests/weston-test-client-helper.c
index fd6ebaf8..7ff589cb 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -69,7 +69,7 @@ static const struct wl_callback_listener frame_listener = {
};
struct wl_callback *
-frame_callback_set(struct wl_surface *surface, int *done)
+client_set_wait_frame_callback(struct wl_surface *surface, int *done)
{
struct wl_callback *callback;
@@ -81,7 +81,7 @@ frame_callback_set(struct wl_surface *surface, int *done)
}
int
-frame_callback_wait_nofail(struct client *client, int *done)
+client_wait_nofail(struct client *client, int *done)
{
while (!*done) {
if (wl_display_dispatch(client->wl_display) < 0)
@@ -108,11 +108,11 @@ move_client(struct client *client, int x, int y)
wl_surface_damage(surface->wl_surface, 0, 0, surface->width,
surface->height);
- frame_callback_set(surface->wl_surface, &done);
+ client_set_wait_frame_callback(surface->wl_surface, &done);
wl_surface_commit(surface->wl_surface);
- frame_callback_wait(client, &done);
+ client_wait(client, &done);
}
int
@@ -137,12 +137,13 @@ pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
pointer->focus = wl_surface_get_user_data(wl_surface);
else
pointer->focus = NULL;
+ pointer->serial = serial;
pointer->x = wl_fixed_to_int(x);
pointer->y = wl_fixed_to_int(y);
- fprintf(stderr, "test-client: got pointer enter %d %d, surface %p\n",
- pointer->x, pointer->y, pointer->focus);
+ fprintf(stderr, "test-client: got pointer enter [%u] %d %d, surface %p\n",
+ serial, pointer->x, pointer->y, pointer->focus);
}
static void
@@ -152,9 +153,11 @@ pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
struct pointer *pointer = data;
pointer->focus = NULL;
+ pointer->serial = 0;
+ pointer->grab_serial = 0;
- fprintf(stderr, "test-client: got pointer leave, surface %p\n",
- wl_surface ? wl_surface_get_user_data(wl_surface) : NULL);
+ fprintf(stderr, "test-client: got pointer leave [%u], surface %p\n",
+ serial, wl_surface ? wl_surface_get_user_data(wl_surface) : NULL);
}
static void
@@ -177,11 +180,13 @@ pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
{
struct pointer *pointer = data;
+ pointer->serial = serial;
+ pointer->grab_serial = serial;
pointer->button = button;
pointer->state = state;
- fprintf(stderr, "test-client: got pointer button %u %u\n",
- button, state);
+ fprintf(stderr, "test-client: got pointer button [%u] %u %u\n",
+ serial, button, state);
}
static void
diff --git a/tests/weston-test-client-helper.h b/tests/weston-test-client-helper.h
index 8908ae7e..b48af391 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -86,6 +86,8 @@ struct input {
struct pointer {
struct wl_pointer *wl_pointer;
struct surface *focus;
+ uint32_t serial;
+ uint32_t grab_serial;
int x;
int y;
uint32_t button;
@@ -175,12 +177,12 @@ move_client(struct client *client, int x, int y);
} while (0)
struct wl_callback *
-frame_callback_set(struct wl_surface *surface, int *done);
+client_set_wait_frame_callback(struct wl_surface *surface, int *done);
int
-frame_callback_wait_nofail(struct client *client, int *done);
+client_wait_nofail(struct client *client, int *done);
-#define frame_callback_wait(c, d) assert(frame_callback_wait_nofail((c), (d)))
+#define client_wait(c, d) assert(client_wait_nofail((c), (d)))
int
get_n_egl_buffers(struct client *client);
diff --git a/tests/weston-test-desktop-shell.c b/tests/weston-test-desktop-shell.c
new file mode 100644
index 00000000..c2864706
--- /dev/null
+++ b/tests/weston-test-desktop-shell.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright © 2010-2012 Intel Corporation
+ * Copyright © 2011-2012 Collabora, Ltd.
+ * Copyright © 2013 Raspberry Pi Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <assert.h>
+#include <signal.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include "compositor/weston.h"
+#include "shared/config-parser.h"
+#include "shared/helpers.h"
+#include "libweston-desktop/libweston-desktop.h"
+
+#ifndef static_assert
+#define static_assert(cond, msg)
+#endif
+
+static struct weston_desktop *desktop = NULL;
+static struct weston_layer background_layer;
+static struct weston_surface *background_surface = NULL;
+static struct weston_view *background_view = NULL;
+static struct weston_layer layer;
+static struct weston_view *view = NULL;
+/*
+ * libweston-desktop
+ */
+
+static void
+desktop_surface_added(struct weston_desktop_surface *desktop_surface,
+ void *shell)
+{
+
+ assert(!view);
+
+ view = weston_desktop_surface_create_view(desktop_surface);
+
+ assert(view);
+}
+
+static void
+desktop_surface_removed(struct weston_desktop_surface *desktop_surface,
+ void *shell)
+{
+ assert(view);
+
+ weston_desktop_surface_unlink_view(view);
+ weston_view_destroy(view);
+ view = NULL;
+}
+
+static void
+desktop_surface_committed(struct weston_desktop_surface *desktop_surface,
+ int32_t sx, int32_t sy, void *data)
+{
+ struct weston_surface *surface =
+ weston_desktop_surface_get_surface(desktop_surface);
+ struct weston_geometry geometry =
+ weston_desktop_surface_get_geometry(desktop_surface);
+
+ assert(view);
+
+ if (weston_surface_is_mapped(surface))
+ return;
+
+ surface->is_mapped = true;
+ weston_layer_entry_insert(&layer.view_list, &view->layer_link);
+ weston_view_set_position(view, 0 - geometry.x, 0 - geometry.y);
+ weston_view_update_transform(view);
+ view->is_mapped = true;
+}
+
+static void
+desktop_surface_move(struct weston_desktop_surface *desktop_surface,
+ struct weston_seat *seat, uint32_t serial, void *shell)
+{
+}
+
+static void
+desktop_surface_resize(struct weston_desktop_surface *desktop_surface,
+ struct weston_seat *seat, uint32_t serial,
+ enum weston_desktop_surface_edge edges, void *shell)
+{
+}
+
+static void
+desktop_surface_fullscreen_requested(struct weston_desktop_surface *desktop_surface,
+ bool fullscreen,
+ struct weston_output *output, void *shell)
+{
+}
+
+static void
+desktop_surface_maximized_requested(struct weston_desktop_surface *desktop_surface,
+ bool maximized, void *shell)
+{
+}
+
+static void
+desktop_surface_minimized_requested(struct weston_desktop_surface *desktop_surface,
+ void *shell)
+{
+}
+
+static void
+desktop_surface_ping_timeout(struct weston_desktop_client *desktop_client,
+ void *shell)
+{
+}
+
+static void
+desktop_surface_pong(struct weston_desktop_client *desktop_client,
+ void *shell)
+{
+}
+
+static const struct weston_desktop_api shell_desktop_api = {
+ .struct_size = sizeof(struct weston_desktop_api),
+ .surface_added = desktop_surface_added,
+ .surface_removed = desktop_surface_removed,
+ .committed = desktop_surface_committed,
+ .move = desktop_surface_move,
+ .resize = desktop_surface_resize,
+ .fullscreen_requested = desktop_surface_fullscreen_requested,
+ .maximized_requested = desktop_surface_maximized_requested,
+ .minimized_requested = desktop_surface_minimized_requested,
+ .ping_timeout = desktop_surface_ping_timeout,
+ .pong = desktop_surface_pong,
+};
+
+/* ************************ *
+ * end of libweston-desktop *
+ * ************************ */
+
+WL_EXPORT int
+module_init(struct weston_compositor *ec,
+ int *argc, char *argv[])
+{
+ weston_layer_init(&layer, &ec->cursor_layer.link);
+ weston_layer_init(&background_layer, &layer.link);
+
+ background_surface = weston_surface_create(ec);
+ if (background_surface == NULL)
+ return -1;
+ background_view = weston_view_create(background_surface);
+ if (background_view == NULL) {
+ weston_surface_destroy(background_surface);
+ return -1;
+ }
+
+ weston_surface_set_color(background_surface, 0.0, 0.0, 0.0, 1);
+ pixman_region32_fini(&background_surface->opaque);
+ pixman_region32_init_rect(&background_surface->opaque, 0, 0, 2000, 2000);
+ pixman_region32_fini(&background_surface->input);
+ pixman_region32_init_rect(&background_surface->input, 0, 0, 2000, 2000);
+
+ weston_surface_set_size(background_surface, 2000, 2000);
+ weston_view_set_position(background_view, 0, 0);
+ weston_layer_entry_insert(&background_layer.view_list, &background_view->layer_link);
+ weston_view_update_transform(background_view);
+
+ desktop = weston_desktop_create(ec, &shell_desktop_api, NULL);
+ return desktop ? 0 : -1;
+}
diff --git a/tests/wl-shell-test.c b/tests/wl-shell-test.c
new file mode 100644
index 00000000..26c5a5f8
--- /dev/null
+++ b/tests/wl-shell-test.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright © 2015 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "weston-test-client-helper.h"
+
+char *server_parameters="--use-pixman --width=320 --height=240 --shell=weston-test-desktop-shell.so";
+
+static struct wl_shell *
+client_get_wl_shell(struct client *client)
+{
+ struct global *global;
+
+ wl_list_for_each(global, &client->global_list, link) {
+ if (strcmp(global->interface, "wl_shell") != 0)
+ continue;
+ return wl_registry_bind(client->wl_registry, global->name,
+ &wl_shell_interface, global->version);
+ }
+ return NULL;
+}
+
+static void
+draw_stuff(pixman_image_t *image)
+{
+ int w, h;
+ int stride; /* bytes */
+ int x, y;
+ uint8_t r, g, b;
+ uint32_t *pixels;
+ uint32_t *pixel;
+ pixman_format_code_t fmt;
+
+ fmt = pixman_image_get_format(image);
+ w = pixman_image_get_width(image);
+ h = pixman_image_get_height(image);
+ stride = pixman_image_get_stride(image);
+ pixels = pixman_image_get_data(image);
+
+ assert(PIXMAN_FORMAT_BPP(fmt) == 32);
+
+ for (x = 0; x < w; x++)
+ for (y = 0; y < h; y++) {
+ r = (double) x / w * 0xff;
+ g = (double) (x+y) / (w+h) * 0xff;
+ b = (double) y / w * 0xff;
+ pixel = pixels + (y * stride / 4) + x;
+ *pixel = (255 << 24) | (r << 16) | (g << 8) | b;
+ }
+}
+
+static void
+wl_shell_test_run(char *basename, void(*run)(struct client *client, struct wl_shell *shell, struct wl_surface *surface, struct wl_shell_surface *shell_surface))
+{
+ char basename_good[100];
+ char basename_error[100];
+ char basename_result[100];
+ struct buffer *buf;
+ struct client *client;
+ struct wl_shell *shell;
+ struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
+ struct buffer *screenshot = NULL;
+ pixman_image_t *reference_good = NULL;
+ pixman_image_t *diffimg;
+ struct rectangle clip;
+ const char *fname;
+ bool match = false;
+ bool dump_all_images = true;
+
+ snprintf(basename_good, sizeof(basename_good),
+ "%s-screenshot-good", basename);
+ snprintf(basename_error, sizeof(basename_error),
+ "%s-screenshot-error", basename);
+ snprintf(basename_result, sizeof(basename_result),
+ "%s-screenshot", basename);
+
+ /* Create the client */
+ printf("Creating client for test\n");
+ client = create_client();
+ assert(client);
+ shell = client_get_wl_shell(client);
+ assert(shell);
+
+ surface = wl_compositor_create_surface(client->wl_compositor);
+ shell_surface = wl_shell_get_shell_surface(shell, surface);
+ run(client, shell, surface, shell_surface);
+
+ buf = create_shm_buffer_a8r8g8b8(client, 100, 100);
+ draw_stuff(buf->image);
+ wl_surface_attach(surface, buf->proxy, 0, 0);
+ wl_surface_damage(surface, 0, 0, 100, 100);
+ wl_surface_commit(surface);
+
+ wl_display_flush(client->wl_display);
+
+ /* Take a snapshot. Result will be in screenshot->wl_buffer. */
+ printf("Taking a screenshot\n");
+ screenshot = capture_screenshot_of_output(client);
+ assert(screenshot);
+
+ /* Load good reference image */
+ fname = screenshot_reference_filename(basename_good, 0);
+ printf("Loading good reference image %s\n", fname);
+ reference_good = load_image_from_png(fname);
+ assert(reference_good);
+
+ /* Test check_images_match() with clip.
+ * Alpha-blending and other effects can cause irrelevant discrepancies, so look only
+ * at a small portion of the solid-colored background
+ */
+ clip.x = 0;
+ clip.y = 0;
+ clip.width = 100;
+ clip.height = 100;
+ printf("Clip: %d,%d %d x %d\n", clip.x, clip.y, clip.width, clip.height);
+ match = check_images_match(screenshot->image, reference_good, &clip);
+ printf("Screenshot %s reference image in clipped area\n", match? "matches" : "doesn't match");
+ if (!match) {
+ diffimg = visualize_image_difference(screenshot->image, reference_good, &clip);
+ fname = screenshot_output_filename(basename_error, 0);
+ write_image_as_png(diffimg, fname);
+ pixman_image_unref(diffimg);
+ }
+ pixman_image_unref(reference_good);
+
+ /* Test dumping of non-matching images */
+ if (!match || dump_all_images) {
+ fname = screenshot_output_filename(basename_result, 0);
+ write_image_as_png(screenshot->image, fname);
+ }
+
+ buffer_destroy(screenshot);
+
+ printf("Test complete\n");
+ assert(match);
+}
+
+static void
+wl_shell_toplevel_run(struct client *client, struct wl_shell *shell, struct wl_surface *surface, struct wl_shell_surface *shell_surface)
+{
+ wl_shell_surface_set_toplevel(shell_surface);
+ wl_surface_commit(surface);
+}
+
+TEST(wl_shell_toplevel)
+{
+ wl_shell_test_run("wl_shell_toplevel", wl_shell_toplevel_run);
+}
+
+static void
+wl_shell_transient_run(struct client *client, struct wl_shell *shell,
+ struct wl_surface *parent_surface,
+ struct wl_shell_surface *parent_shell_surface)
+{
+ struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
+ struct buffer *buf;
+
+ wl_shell_surface_set_toplevel(parent_shell_surface);
+ wl_surface_commit(parent_surface);
+
+ surface = wl_compositor_create_surface(client->wl_compositor);
+ shell_surface = wl_shell_get_shell_surface(shell, surface);
+ wl_shell_surface_set_transient(shell_surface, parent_surface, 25, 25,
+ WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
+ wl_surface_commit(surface);
+
+ buf = create_shm_buffer_a8r8g8b8(client, 50, 50);
+ draw_stuff(buf->image);
+ wl_surface_attach(surface, buf->proxy, 0, 0);
+ wl_surface_damage(surface, 0, 0, 50, 50);
+ wl_surface_commit(surface);
+}
+
+TEST(wl_shell_transient)
+{
+ wl_shell_test_run("wl_shell_transient", wl_shell_transient_run);
+}
diff --git a/tests/xdg-shell-v5-test.c b/tests/xdg-shell-v5-test.c
new file mode 100644
index 00000000..35e6da43
--- /dev/null
+++ b/tests/xdg-shell-v5-test.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright © 2015 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "weston-test-client-helper.h"
+#include "xdg-shell-unstable-v5-client-protocol.h"
+
+char *server_parameters="--use-pixman --width=320 --height=240 --shell=weston-test-desktop-shell.so";
+
+static void
+ping(void *data, struct xdg_shell *shell, uint32_t serial)
+{
+ xdg_shell_pong(shell, serial);
+}
+
+static struct xdg_shell_listener shell_listener = {
+ ping
+};
+
+static struct xdg_shell *
+client_get_xdg_shell_v5(struct client *client)
+{
+ struct global *global;
+ struct xdg_shell *xdg_shell_v5;
+
+ wl_list_for_each(global, &client->global_list, link) {
+ if (strcmp(global->interface, "xdg_shell") != 0)
+ continue;
+ xdg_shell_v5 = wl_registry_bind(client->wl_registry,
+ global->name,
+ &xdg_shell_interface,
+ global->version);
+ xdg_shell_use_unstable_version(xdg_shell_v5, 5);
+ xdg_shell_add_listener(xdg_shell_v5, &shell_listener, xdg_shell_v5);
+ return xdg_shell_v5;
+ }
+ return NULL;
+}
+
+static void
+draw_stuff(pixman_image_t *image, int border)
+{
+ int w, h;
+ int stride; /* bytes */
+ int x, y;
+ uint8_t a, r, g, b;
+ uint32_t *pixels;
+ uint32_t *pixel;
+ pixman_format_code_t fmt;
+
+ fmt = pixman_image_get_format(image);
+ w = pixman_image_get_width(image);
+ h = pixman_image_get_height(image);
+ stride = pixman_image_get_stride(image);
+ pixels = pixman_image_get_data(image);
+
+ assert(PIXMAN_FORMAT_BPP(fmt) == 32);
+
+ for (x = 0; x < w; x++)
+ for (y = 0; y < h; y++) {
+ a = 0xff;
+ if (x < border || x > w - border ||
+ y < border || y > h - border)
+ a = 0x80;
+ r = (double) x / w * a;
+ g = (double) (x+y) / (w+h) * a;
+ b = (double) y / w * a;
+ pixel = pixels + (y * stride / 4) + x;
+ *pixel = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+}
+
+static void
+handle_surface_configure(void *data, struct xdg_surface *xdg_surface,
+ int32_t width, int32_t height,
+ struct wl_array *states, uint32_t serial)
+{
+ xdg_surface_ack_configure(xdg_surface, serial);
+}
+
+static void
+handle_surface_delete(void *data, struct xdg_surface *xdg_surface)
+{
+ xdg_surface_destroy(xdg_surface);
+}
+
+static const struct xdg_surface_listener xdg_surface_listener = {
+ handle_surface_configure,
+ handle_surface_delete,
+};
+
+static void
+popup_done(void *data, struct xdg_popup *xdg_popup)
+{
+ int *ready = data;
+
+ xdg_popup_destroy(xdg_popup);
+ *ready = 1;
+}
+
+static const struct xdg_popup_listener xdg_popup_listener = {
+ popup_done
+};
+
+static void
+xdg_shell_v5_create_xdg_surface(struct client *client, struct xdg_shell *shell, struct wl_surface **surface, struct xdg_surface **xdg_surface, int width, int height, int border)
+{
+ struct buffer *buf;
+ int ready;
+
+ *surface = wl_compositor_create_surface(client->wl_compositor);
+ *xdg_surface = xdg_shell_get_xdg_surface(shell, *surface);
+ xdg_surface_set_window_geometry(*xdg_surface, border, border, width, height);
+ xdg_surface_add_listener(*xdg_surface, &xdg_surface_listener, NULL);
+
+ buf = create_shm_buffer_a8r8g8b8(client, width + border * 2, height + border * 2);
+ draw_stuff(buf->image, border);
+ wl_surface_attach(*surface, buf->proxy, 0, 0);
+ wl_surface_damage(*surface, 0, 0, width + border * 2, height + border * 2);
+
+ client_set_wait_frame_callback(*surface, &ready);
+ wl_surface_commit(*surface);
+ client_wait(client, &ready);
+}
+
+static void
+xdg_shell_v5_test_run(char *basename, void (*run)(struct client *client, struct xdg_shell *shell, struct wl_surface *surface, struct xdg_surface *xdg_surface))
+{
+ char basename_good[100];
+ char basename_error[100];
+ char basename_result[100];
+ int width = 200;
+ int height = 80;
+ int border = 10;
+ struct client *client;
+ struct xdg_shell *shell;
+ struct wl_surface *surface;
+ struct xdg_surface *xdg_surface;
+ struct buffer *screenshot = NULL;
+ pixman_image_t *reference_good = NULL;
+ pixman_image_t *diffimg;
+ struct rectangle clip;
+ const char *fname;
+ bool match = false;
+ bool dump_all_images = true;
+
+ snprintf(basename_good, sizeof(basename_good),
+ "%s-screenshot-good", basename);
+ snprintf(basename_error, sizeof(basename_error),
+ "%s-screenshot-error", basename);
+ snprintf(basename_result, sizeof(basename_result),
+ "%s-screenshot", basename);
+
+ /* Create the client */
+ printf("Creating client for test\n");
+ client = create_client();
+ assert(client);
+ shell = client_get_xdg_shell_v5(client);
+ assert(shell);
+
+ weston_test_move_pointer(client->test->weston_test, 100, 100);
+ xdg_shell_v5_create_xdg_surface(client, shell, &surface, &xdg_surface, width, height, border);
+ run(client, shell, surface, xdg_surface);
+
+ /* Take a snapshot. Result will be in screenshot->wl_buffer. */
+ printf("Taking a screenshot\n");
+ screenshot = capture_screenshot_of_output(client);
+ assert(screenshot);
+
+ /* Load good reference image */
+ fname = screenshot_reference_filename(basename_good, 0);
+ printf("Loading good reference image %s\n", fname);
+ reference_good = load_image_from_png(fname);
+ assert(reference_good);
+
+ /* Test check_images_match() with clip.
+ * Alpha-blending and other effects can cause irrelevant discrepancies, so look only
+ * at a small portion of the solid-colored background
+ */
+ clip.x = 0;
+ clip.y = 0;
+ clip.width = width;
+ clip.height = height;
+ printf("Clip: %d,%d %d x %d\n", clip.x, clip.y, clip.width, clip.height);
+ match = check_images_match(screenshot->image, reference_good, &clip);
+ printf("Screenshot %s reference image in clipped area\n", match? "matches" : "doesn't match");
+ if (!match) {
+ diffimg = visualize_image_difference(screenshot->image, reference_good, &clip);
+ fname = screenshot_output_filename(basename_error, 0);
+ write_image_as_png(diffimg, fname);
+ pixman_image_unref(diffimg);
+ }
+ pixman_image_unref(reference_good);
+
+ /* Test dumping of non-matching images */
+ if (!match || dump_all_images) {
+ fname = screenshot_output_filename(basename_result, 0);
+ write_image_as_png(screenshot->image, fname);
+ }
+
+ buffer_destroy(screenshot);
+
+ printf("Test complete\n");
+ assert(match);
+}
+
+static void
+xdg_shell_v5_toplevel_run(struct client *client, struct xdg_shell *shell, struct wl_surface *surface, struct xdg_surface *xdg_surface)
+{
+}
+
+TEST(xdg_shell_v5_toplevel)
+{
+ xdg_shell_v5_test_run("xdg_shell_v5_toplevel", xdg_shell_v5_toplevel_run);
+}
+
+static void
+xdg_shell_v5_popup_run(struct client *client, struct xdg_shell *shell,
+ struct wl_surface *parent_surface,
+ struct xdg_surface *parent_xdg_surface)
+{
+ struct wl_surface *surface;
+ uint32_t serial;
+ struct xdg_popup *xdg_popup;
+ int ready;
+ struct buffer *buf;
+
+ weston_test_move_pointer(client->test->weston_test, 50, 50);
+ weston_test_send_button(client->test->weston_test, 1,
+ WL_POINTER_BUTTON_STATE_PRESSED);
+ client_roundtrip(client);
+ serial = client->input->pointer->grab_serial;
+ assert(serial != 0);
+
+ surface = wl_compositor_create_surface(client->wl_compositor);
+ client_set_wait_frame_callback(surface, &ready);
+ xdg_popup = xdg_shell_get_xdg_popup(shell, surface, parent_surface,
+ client->input->wl_seat, serial,
+ 25, 25);
+ xdg_popup_add_listener(xdg_popup, &xdg_popup_listener, &ready);
+
+ buf = create_shm_buffer_a8r8g8b8(client, 50, 50);
+ draw_stuff(buf->image, 0);
+ wl_surface_attach(surface, buf->proxy, 0, 0);
+ wl_surface_damage(surface, 0, 0, 50, 50);
+
+ wl_surface_commit(surface);
+ client_wait(client, &ready);
+}
+
+TEST(xdg_shell_v5_popup)
+{
+ xdg_shell_v5_test_run("xdg_shell_v5_popup", xdg_shell_v5_popup_run);
+}
diff --git a/tests/xdg-shell-v6-test.c b/tests/xdg-shell-v6-test.c
new file mode 100644
index 00000000..643a165b
--- /dev/null
+++ b/tests/xdg-shell-v6-test.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright © 2015 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "weston-test-client-helper.h"
+#include "xdg-shell-unstable-v6-client-protocol.h"
+
+char *server_parameters="--use-pixman --width=320 --height=240 --shell=weston-test-desktop-shell.so";
+
+static void
+ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial)
+{
+ zxdg_shell_v6_pong(shell, serial);
+}
+
+static struct zxdg_shell_v6_listener shell_listener = {
+ ping
+};
+
+static struct zxdg_shell_v6 *
+client_get_xdg_shell_v6(struct client *client)
+{
+ struct global *global;
+ struct zxdg_shell_v6 *xdg_shell_v6;
+
+ wl_list_for_each(global, &client->global_list, link) {
+ if (strcmp(global->interface, "zxdg_shell_v6") != 0)
+ continue;
+ xdg_shell_v6 = wl_registry_bind(client->wl_registry,
+ global->name,
+ &zxdg_shell_v6_interface,
+ global->version);
+ zxdg_shell_v6_add_listener(xdg_shell_v6, &shell_listener, xdg_shell_v6);
+ return xdg_shell_v6;
+ }
+ return NULL;
+}
+
+static void
+draw_stuff(pixman_image_t *image, int border)
+{
+ int w, h;
+ int stride; /* bytes */
+ int x, y;
+ uint8_t a, r, g, b;
+ uint32_t *pixels;
+ uint32_t *pixel;
+ pixman_format_code_t fmt;
+
+ fmt = pixman_image_get_format(image);
+ w = pixman_image_get_width(image);
+ h = pixman_image_get_height(image);
+ stride = pixman_image_get_stride(image);
+ pixels = pixman_image_get_data(image);
+
+ assert(PIXMAN_FORMAT_BPP(fmt) == 32);
+
+ for (x = 0; x < w; x++)
+ for (y = 0; y < h; y++) {
+ a = 0xff;
+ if (x < border || x > w - border ||
+ y < border || y > h - border)
+ a = 0x80;
+ r = (double) x / w * a;
+ g = (double) (x+y) / (w+h) * a;
+ b = (double) y / w * a;
+ pixel = pixels + (y * stride / 4) + x;
+ *pixel = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+}
+
+static void
+handle_surface_configure(void *data, struct zxdg_surface_v6 *xdg_surface,
+ uint32_t serial)
+{
+ int *ready = data;
+
+ zxdg_surface_v6_ack_configure(xdg_surface, serial);
+ *ready = 1;
+}
+
+static const struct zxdg_surface_v6_listener xdg_surface_listener = {
+ handle_surface_configure,
+};
+
+static void
+handle_toplevel_configure(void *data, struct zxdg_toplevel_v6 *xdg_toplevel,
+ int32_t width, int32_t height,
+ struct wl_array *states)
+{
+}
+
+static void
+handle_toplevel_close(void *data, struct zxdg_toplevel_v6 *xdg_toplevel)
+{
+ int *ready = data;
+ struct zxdg_surface_v6 *xdg_surface =
+ zxdg_toplevel_v6_get_user_data(xdg_toplevel);
+
+ zxdg_toplevel_v6_destroy(xdg_toplevel);
+ zxdg_surface_v6_destroy(xdg_surface);
+ *ready = 1;
+}
+
+static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = {
+ handle_toplevel_configure,
+ handle_toplevel_close,
+};
+
+static void
+handle_popup_configure(void *data, struct zxdg_popup_v6 *xdg_popup,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ int *ready = data;
+
+ *ready = 1;
+}
+
+static void
+handle_popup_done(void *data, struct zxdg_popup_v6 *xdg_popup)
+{
+ int *ready = data;
+ struct zxdg_surface_v6 *xdg_surface =
+ zxdg_popup_v6_get_user_data(xdg_popup);
+
+ zxdg_popup_v6_destroy(xdg_popup);
+ zxdg_surface_v6_destroy(xdg_surface);
+ *ready = 1;
+}
+
+static const struct zxdg_popup_v6_listener xdg_popup_listener = {
+ handle_popup_configure,
+ handle_popup_done,
+};
+
+static void *
+xdg_shell_v6_create_xdg_surface(struct client *client, struct zxdg_shell_v6 *shell,
+ int width, int height, int border,
+ void *(*setup)(struct client *client, struct zxdg_shell_v6 *shell, struct zxdg_surface_v6 *xdg_surface, int32_t width, int32_t height, int32_t border, void *data),
+ struct wl_surface **surface,
+ struct zxdg_surface_v6 **xdg_surface,
+ void *data)
+{
+ struct buffer *buf;
+ int ready = 0;
+ void *ret;
+
+ *surface = wl_compositor_create_surface(client->wl_compositor);
+ *xdg_surface = zxdg_shell_v6_get_xdg_surface(shell, *surface);
+ zxdg_surface_v6_add_listener(*xdg_surface, &xdg_surface_listener, &ready);
+ ret = setup(client, shell, *xdg_surface, width, height, border, data);
+ zxdg_surface_v6_set_window_geometry(*xdg_surface, border, border, width, height);
+ wl_surface_commit(*surface);
+
+ client_wait(client, &ready);
+
+ buf = create_shm_buffer_a8r8g8b8(client, width + border * 2, height + border * 2);
+ draw_stuff(buf->image, border);
+ wl_surface_attach(*surface, buf->proxy, 0, 0);
+ wl_surface_damage(*surface, 0, 0, width + border * 2, height + border * 2);
+
+ client_set_wait_frame_callback(*surface, &ready);
+ wl_surface_commit(*surface);
+ client_wait(client, &ready);
+
+ return ret;
+}
+
+static void *
+xdg_shell_v6_toplevel_setup(struct client *client, struct zxdg_shell_v6 *shell, struct zxdg_surface_v6 *xdg_surface, int32_t width, int32_t height, int32_t border, void *data)
+{
+ struct zxdg_toplevel_v6 *xdg_toplevel;
+
+ xdg_toplevel = zxdg_surface_v6_get_toplevel(xdg_surface);
+ zxdg_toplevel_v6_add_listener(xdg_toplevel, &xdg_toplevel_listener, data);
+
+ return xdg_toplevel;
+}
+
+static void
+xdg_shell_v6_test_run(char *basename, void (*run)(struct client *client, struct zxdg_shell_v6 *shell, struct zxdg_surface_v6 *xdg_surface))
+{
+ char basename_good[100];
+ char basename_error[100];
+ char basename_result[100];
+ int width = 200;
+ int height = 80;
+ int border = 10;
+ struct client *client;
+ struct zxdg_shell_v6 *shell;
+ struct wl_surface *surface;
+ struct zxdg_surface_v6 *xdg_surface;
+ struct buffer *screenshot = NULL;
+ pixman_image_t *reference_good = NULL;
+ pixman_image_t *diffimg;
+ struct rectangle clip;
+ const char *fname;
+ bool match = false;
+ bool dump_all_images = true;
+
+ snprintf(basename_good, sizeof(basename_good),
+ "%s-screenshot-good", basename);
+ snprintf(basename_error, sizeof(basename_error),
+ "%s-screenshot-error", basename);
+ snprintf(basename_result, sizeof(basename_result),
+ "%s-screenshot", basename);
+
+ /* Create the client */
+ printf("Creating client for test\n");
+ client = create_client();
+ assert(client);
+ shell = client_get_xdg_shell_v6(client);
+ assert(shell);
+
+ weston_test_move_pointer(client->test->weston_test, 100, 100);
+ xdg_shell_v6_create_xdg_surface(client, shell, width, height, border, xdg_shell_v6_toplevel_setup, &surface, &xdg_surface, NULL);
+ run(client, shell, xdg_surface);
+
+ /* Take a snapshot. Result will be in screenshot->wl_buffer. */
+ printf("Taking a screenshot\n");
+ screenshot = capture_screenshot_of_output(client);
+ assert(screenshot);
+
+ /* Load good reference image */
+ fname = screenshot_reference_filename(basename_good, 0);
+ printf("Loading good reference image %s\n", fname);
+ reference_good = load_image_from_png(fname);
+ assert(reference_good);
+
+ /* Test check_images_match() with clip.
+ * Alpha-blending and other effects can cause irrelevant discrepancies, so look only
+ * at a small portion of the solid-colored background
+ */
+ clip.x = 0;
+ clip.y = 0;
+ clip.width = width;
+ clip.height = height;
+ printf("Clip: %d,%d %d x %d\n", clip.x, clip.y, clip.width, clip.height);
+ match = check_images_match(screenshot->image, reference_good, &clip);
+ printf("Screenshot %s reference image in clipped area\n", match? "matches" : "doesn't match");
+ if (!match) {
+ diffimg = visualize_image_difference(screenshot->image, reference_good, &clip);
+ fname = screenshot_output_filename(basename_error, 0);
+ write_image_as_png(diffimg, fname);
+ pixman_image_unref(diffimg);
+ }
+ pixman_image_unref(reference_good);
+
+ /* Test dumping of non-matching images */
+ if (!match || dump_all_images) {
+ fname = screenshot_output_filename(basename_result, 0);
+ write_image_as_png(screenshot->image, fname);
+ }
+
+ buffer_destroy(screenshot);
+
+ printf("Test complete\n");
+ assert(match);
+}
+
+static void
+xdg_shell_v6_test_run_error(void (*run)(struct client *client, struct zxdg_shell_v6 *shell), const struct wl_interface *intf, uint32_t code)
+{
+ struct client *client;
+ struct zxdg_shell_v6 *shell;
+
+ client = create_client();
+ assert(client);
+ shell = client_get_xdg_shell_v6(client);
+ assert(shell);
+
+ run(client, shell);
+
+ expect_protocol_error(client, intf, code);
+}
+
+static void
+xdg_shell_v6_toplevel_run(struct client *client, struct zxdg_shell_v6 *shell, struct zxdg_surface_v6 *xdg_surface)
+{
+}
+
+TEST(xdg_shell_v6_toplevel)
+{
+ xdg_shell_v6_test_run("xdg_shell_v6_toplevel", xdg_shell_v6_toplevel_run);
+}
+
+struct popup_data {
+ struct zxdg_surface_v6 *parent_xdg_surface;
+ int *ready;
+};
+
+static void *
+xdg_shell_v6_popup_setup(struct client *client, struct zxdg_shell_v6 *shell,
+ struct zxdg_surface_v6 *xdg_surface,
+ int32_t width, int32_t height, int32_t border,
+ void *data)
+{
+ struct zxdg_positioner_v6 *xdg_positioner;
+ struct zxdg_popup_v6 *xdg_popup;
+ struct popup_data *popup_data = data;
+
+ xdg_positioner = zxdg_shell_v6_create_positioner(shell);
+ zxdg_positioner_v6_set_size(xdg_positioner, width, height);
+ zxdg_positioner_v6_set_anchor_rect(xdg_positioner, 25, 25, 1, 1);
+ zxdg_positioner_v6_set_anchor(xdg_positioner, ZXDG_POSITIONER_V6_ANCHOR_TOP|ZXDG_POSITIONER_V6_ANCHOR_LEFT);
+ zxdg_positioner_v6_set_gravity(xdg_positioner, ZXDG_POSITIONER_V6_GRAVITY_BOTTOM|ZXDG_POSITIONER_V6_GRAVITY_RIGHT);
+
+ xdg_popup = zxdg_surface_v6_get_popup(xdg_surface, popup_data->parent_xdg_surface, xdg_positioner);
+ zxdg_positioner_v6_destroy(xdg_positioner);
+
+ zxdg_popup_v6_add_listener(xdg_popup, &xdg_popup_listener, popup_data->ready);
+
+ return xdg_popup;
+}
+
+static void
+xdg_shell_v6_popup_run(struct client *client, struct zxdg_shell_v6 *shell,
+ struct zxdg_surface_v6 *parent_xdg_surface)
+{
+ struct wl_surface *surface;
+ int width = 200;
+ int height = 80;
+ int border = 10;
+ struct zxdg_surface_v6 *xdg_surface;
+ struct zxdg_popup_v6 *xdg_popup;
+ int ready = 0;
+ struct popup_data popup_data = {
+ .parent_xdg_surface = parent_xdg_surface,
+ .ready = &ready,
+ };
+
+ xdg_popup = xdg_shell_v6_create_xdg_surface(client, shell, width, height, border, xdg_shell_v6_popup_setup, &surface, &xdg_surface, &popup_data);
+ client_wait(client, &ready);
+}
+
+TEST(xdg_shell_v6_popup)
+{
+ xdg_shell_v6_test_run("xdg_shell_v6_popup", xdg_shell_v6_popup_run);
+}
+
+static void
+xdg_shell_v6_surface_no_role_error_run(struct client *client, struct zxdg_shell_v6 *shell)
+{
+ struct wl_surface *surface;
+ struct zxdg_surface_v6 *xdg_surface;
+
+ surface = wl_compositor_create_surface(client->wl_compositor);
+ xdg_surface = zxdg_shell_v6_get_xdg_surface(shell, surface);
+ wl_surface_commit(surface);
+}
+
+TEST(xdg_shell_v6_surface_errors)
+{
+ xdg_shell_v6_test_run_error(xdg_shell_v6_surface_no_role_error_run,
+ &zxdg_surface_v6_interface,
+ ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED);
+}
+
+static void
+xdg_shell_v6_positioner_invalid_size_run(struct client *client, struct zxdg_shell_v6 *shell)
+{
+ struct zxdg_positioner_v6 *xdg_positioner;
+
+ xdg_positioner = zxdg_shell_v6_create_positioner(shell);
+ zxdg_positioner_v6_set_size(xdg_positioner, -1, -1);
+}
+
+static void
+xdg_shell_v6_positioner_invalid_anchor_run(struct client *client, struct zxdg_shell_v6 *shell)
+{
+ struct zxdg_positioner_v6 *xdg_positioner;
+
+ xdg_positioner = zxdg_shell_v6_create_positioner(shell);
+ zxdg_positioner_v6_set_anchor(xdg_positioner,
+ ZXDG_POSITIONER_V6_ANCHOR_BOTTOM|ZXDG_POSITIONER_V6_ANCHOR_TOP);
+}
+
+static void
+xdg_shell_v6_positioner_invalid_anchor_rect_run(struct client *client, struct zxdg_shell_v6 *shell)
+{
+ struct zxdg_positioner_v6 *xdg_positioner;
+
+ xdg_positioner = zxdg_shell_v6_create_positioner(shell);
+ zxdg_positioner_v6_set_anchor_rect(xdg_positioner, 0, 0, 0, 0);
+}
+
+static void
+xdg_shell_v6_positioner_invalid_gravity_run(struct client *client, struct zxdg_shell_v6 *shell)
+{
+ struct zxdg_positioner_v6 *xdg_positioner;
+
+ xdg_positioner = zxdg_shell_v6_create_positioner(shell);
+ zxdg_positioner_v6_set_gravity(xdg_positioner,
+ ZXDG_POSITIONER_V6_GRAVITY_BOTTOM|ZXDG_POSITIONER_V6_GRAVITY_TOP);
+}
+
+TEST(xdg_shell_v6_positioner_errors)
+{
+ xdg_shell_v6_test_run_error(xdg_shell_v6_positioner_invalid_size_run,
+ &zxdg_positioner_v6_interface,
+ ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT);
+ xdg_shell_v6_test_run_error(xdg_shell_v6_positioner_invalid_anchor_run,
+ &zxdg_positioner_v6_interface,
+ ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT);
+ xdg_shell_v6_test_run_error(xdg_shell_v6_positioner_invalid_anchor_rect_run,
+ &zxdg_positioner_v6_interface,
+ ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT);
+ xdg_shell_v6_test_run_error(xdg_shell_v6_positioner_invalid_gravity_run,
+ &zxdg_positioner_v6_interface,
+ ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT);
+}