6 #include "weston-test-client-helper.h"
7 #include "weston-test-fixture-compositor.h"
9 #include "agl-shell-client-protocol.h"
10 #include "xdg-shell-client-protocol.h"
12 #include "test-config.h"
14 #define WINDOW_WIDTH_SIZE 200
15 #define WINDOW_HEIGHT_SIZE 200
25 pixman_color_t bg_color = {
32 pixman_color_t panel_top_color = {
39 pixman_color_t panel_bottom_color = {
47 struct agl_shell *agl_shell;
48 struct xdg_wm_base *wm_base;
49 struct client *client;
50 struct wl_list win_list;
54 struct display *display;
55 struct xdg_toplevel *xdg_toplevel;
56 struct xdg_surface *xdg_surface;
57 struct wl_surface *surface;
58 struct buffer *buffer;
60 bool wait_for_configure;
66 enum window_type w_type;
71 static enum test_result_code
72 fixture_setup(struct weston_test_harness *harness)
74 struct compositor_setup setup;
76 compositor_setup_defaults(&setup);
77 setup.renderer = RENDERER_PIXMAN;
81 return weston_test_harness_execute_as_client(harness, &setup);
84 DECLARE_FIXTURE_SETUP(fixture_setup);
86 static struct window *
87 create_window(int width, int height)
89 struct window *window = calloc(1, sizeof(*window));
91 window->width = width;
92 window->height = height;
97 static struct display *
98 create_display(struct client *client, struct xdg_wm_base *wm_base, struct agl_shell *agl_shell)
100 struct display *display = calloc(1, sizeof(*display));
102 display->client = client;
103 display->wm_base = wm_base;
104 display->agl_shell = agl_shell;
110 xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
112 xdg_wm_base_pong(shell, serial);
115 static const struct xdg_wm_base_listener xdg_wm_base_listener = {
120 draw(struct window *window, pixman_color_t color)
122 struct client *client = window->display->client;
124 testlog("Creating a buffer with %dx%d\n", window->width, window->height);
126 create_shm_buffer_a8r8g8b8(client, window->width, window->height);
127 fill_image_with_color(window->buffer->image, &color);
129 wl_surface_attach(window->surface, window->buffer->proxy, 0, 0);
130 wl_surface_damage(window->surface, 0, 0, window->width, window->height);
132 wl_surface_commit(window->surface);
136 handle_xdg_surface_configure(void *data, struct xdg_surface *surface, uint32_t serial)
138 struct window *window = data;
139 xdg_surface_ack_configure(surface, serial);
141 if (window->wait_for_configure) {
142 switch (window->w_type) {
144 draw(window, bg_color);
147 draw(window, panel_top_color);
150 draw(window, panel_bottom_color);
156 window->wait_for_configure = false;
160 static const struct xdg_surface_listener xdg_surface_listener = {
161 handle_xdg_surface_configure,
165 handle_xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
166 int32_t width, int32_t height, struct wl_array *states)
168 struct window *window = data;
171 window->fullscreen = 0;
172 window->maximized = 0;
174 wl_array_for_each(p, states) {
177 case XDG_TOPLEVEL_STATE_FULLSCREEN:
178 window->fullscreen = 1;
180 case XDG_TOPLEVEL_STATE_MAXIMIZED:
181 window->maximized = 1;
186 if (width > 0 && height > 0) {
187 if (!window->fullscreen && !window->maximized) {
188 window->width = width;
189 window->height = height;
191 window->width = width;
192 window->height = height;
193 } else if (!window->fullscreen && !window->maximized) {
195 window->width = WINDOW_WIDTH_SIZE;
197 window->width = width;
200 window->height = WINDOW_HEIGHT_SIZE;
202 window->height = height;
205 /* if we've been resized set wait_for_configure to adjust the fb size
206 * in the frame callback handler, which will also clear this up */
207 if ((window->width > 0 && window->width != WINDOW_WIDTH_SIZE) &&
208 (window->height > 0 && window->height != WINDOW_HEIGHT_SIZE)) {
209 window->wait_for_configure = true;
214 handle_xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
218 static const struct xdg_toplevel_listener xdg_toplevel_listener = {
219 handle_xdg_toplevel_configure,
220 handle_xdg_toplevel_close,
224 static struct window *
225 setup_agl_shell_client_bg(struct display *display)
227 struct window *window;
228 window = create_window(200, 200);
230 window->display = display;
232 xdg_wm_base_add_listener(display->wm_base, &xdg_wm_base_listener, display);
235 wl_compositor_create_surface(display->client->wl_compositor);
236 window->xdg_surface =
237 xdg_wm_base_get_xdg_surface(display->wm_base, window->surface);
238 assert(window->xdg_surface);
240 xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, window);
241 window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface);
242 assert(window->xdg_toplevel);
244 xdg_toplevel_add_listener(window->xdg_toplevel, &xdg_toplevel_listener, window);
246 xdg_toplevel_set_title(window->xdg_toplevel, "bg");
247 xdg_toplevel_set_app_id(window->xdg_toplevel, "bg");
249 wl_surface_commit(window->surface);
251 window->wait_for_configure = true;
253 agl_shell_set_background(display->agl_shell, window->surface,
254 display->client->output->wl_output);
256 window->w_type = BACKGROUND;
260 static struct window *
261 setup_agl_shell_client_panel(struct display *display, enum agl_shell_edge edge)
263 struct window *window;
264 window = create_window(200, 200);
266 window->display = display;
268 xdg_wm_base_add_listener(display->wm_base,
269 &xdg_wm_base_listener, display);
272 wl_compositor_create_surface(display->client->wl_compositor);
273 window->xdg_surface =
274 xdg_wm_base_get_xdg_surface(display->wm_base, window->surface);
275 assert(window->xdg_surface);
277 xdg_surface_add_listener(window->xdg_surface,
278 &xdg_surface_listener, window);
279 window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface);
280 assert(window->xdg_toplevel);
282 xdg_toplevel_add_listener(window->xdg_toplevel,
283 &xdg_toplevel_listener, window);
286 case AGL_SHELL_EDGE_TOP:
287 xdg_toplevel_set_title(window->xdg_toplevel, "panel top");
288 xdg_toplevel_set_app_id(window->xdg_toplevel, "panel top");
290 case AGL_SHELL_EDGE_BOTTOM:
291 xdg_toplevel_set_title(window->xdg_toplevel, "panel bottom");
292 xdg_toplevel_set_app_id(window->xdg_toplevel, "panel bottom");
294 case AGL_SHELL_EDGE_LEFT:
295 case AGL_SHELL_EDGE_RIGHT:
299 wl_surface_commit(window->surface);
301 window->wait_for_configure = true;
303 agl_shell_set_panel(display->agl_shell, window->surface,
304 display->client->output->wl_output, edge);
306 window->w_type = (enum window_type) edge;
310 static struct display *
311 setup_agl_shell_client(struct client *client)
313 struct display *display;
314 struct agl_shell *agl_shell;
315 struct xdg_wm_base *wm_base;
317 wm_base = bind_to_singleton_global(client, &xdg_wm_base_interface, 1);
320 agl_shell = bind_to_singleton_global(client, &agl_shell_interface, 1);
323 display = create_display(client, wm_base, agl_shell);
324 wl_list_init(&display->win_list);
326 struct window *win_bg = setup_agl_shell_client_bg(display);
327 wl_list_insert(&display->win_list, &win_bg->link);
329 struct window *win_panel_top =
330 setup_agl_shell_client_panel(display, AGL_SHELL_EDGE_TOP);
331 wl_list_insert(&display->win_list, &win_panel_top->link);
333 struct window *win_panel_bottom =
334 setup_agl_shell_client_panel(display, AGL_SHELL_EDGE_BOTTOM);
335 wl_list_insert(&display->win_list, &win_panel_bottom->link);
337 client_roundtrip(client);
340 agl_shell_ready(agl_shell);
345 display_destroy(struct display *display)
347 struct window *win, *win_next;
349 wl_list_for_each_safe(win, win_next, &display->win_list, link) {
350 wl_list_remove(&win->link);
355 TEST(agl_client_shell)
357 struct display *display;
358 struct client *client = create_client();
363 /* Create the client */
364 testlog("Creating client shell for agl-shell\n");
365 display = setup_agl_shell_client(client);
367 client_roundtrip(client);
369 /* take a screenshot and compare it with reference ->
370 * agl-shell client shell works */
371 match = verify_screen_content(client, "agl_client_shell", 0, NULL, 0);
374 client_destroy(client);
375 display_destroy(display);