blob: ad4f3779020ac25bf46f2434a319771fb05b1479 [file] [log] [blame]
Pekka Paalanen82d95a62016-04-19 17:20:42 +03001/*
2 * Copyright © 2014, 2016 Collabora, Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26#include "config.h"
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <assert.h>
32#include <time.h>
33
34#include "shared/helpers.h"
35#include "shared/xalloc.h"
36#include "weston-test-client-helper.h"
37#include "viewporter-client-protocol.h"
Pekka Paalanen701676d2019-11-13 15:45:10 +020038#include "weston-test-fixture-compositor.h"
39
40static enum test_result_code
41fixture_setup(struct weston_test_harness *harness)
42{
43 struct compositor_setup setup;
44
45 compositor_setup_defaults(&setup);
46
47 return weston_test_harness_execute_as_client(harness, &setup);
48}
49DECLARE_FIXTURE_SETUP(fixture_setup);
Pekka Paalanen82d95a62016-04-19 17:20:42 +030050
51static struct wp_viewporter *
52get_viewporter(struct client *client)
53{
54 struct global *g;
55 struct global *global_wpr = NULL;
Pekka Paalanen40588282019-11-05 15:40:25 +020056 struct wp_viewporter *wpr;
Pekka Paalanen82d95a62016-04-19 17:20:42 +030057
58 wl_list_for_each(g, &client->global_list, link) {
59 if (strcmp(g->interface, wp_viewporter_interface.name))
60 continue;
61
62 if (global_wpr)
63 assert(0 && "multiple wp_viewporter objects");
64
65 global_wpr = g;
66 }
67
68 assert(global_wpr && "no wp_viewporter found");
69
70 assert(global_wpr->version == 1);
71
72 wpr = wl_registry_bind(client->wl_registry, global_wpr->name,
73 &wp_viewporter_interface, 1);
74 assert(wpr);
75
76 return wpr;
77}
78
79static struct wp_viewport *
80create_viewport(struct client *client)
81{
82 struct wp_viewporter *viewporter;
83 struct wp_viewport *viewport;
84
85 viewporter = get_viewporter(client);
86 viewport = wp_viewporter_get_viewport(viewporter,
87 client->surface->wl_surface);
88 assert(viewport);
89
90 return viewport;
91}
92
93static void
94set_source(struct wp_viewport *vp, int x, int y, int w, int h)
95{
96 wp_viewport_set_source(vp, wl_fixed_from_int(x), wl_fixed_from_int(y),
97 wl_fixed_from_int(w), wl_fixed_from_int(h));
98}
99
100TEST(test_viewporter_double_create)
101{
102 struct wp_viewporter *viewporter;
103 struct client *client;
104
105 client = create_client_and_test_surface(100, 50, 123, 77);
106
107 viewporter = get_viewporter(client);
108 wp_viewporter_get_viewport(viewporter, client->surface->wl_surface);
109 wp_viewporter_get_viewport(viewporter, client->surface->wl_surface);
110
111 expect_protocol_error(client, &wp_viewporter_interface,
112 WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS);
113}
114
115struct bad_source_rect_args {
116 int x, y, w, h;
117};
118
119static const struct bad_source_rect_args bad_source_rect_args[] = {
120 { -5, 0, 20, 10 },
121 { 0, -5, 20, 10 },
122 { 5, 6, 0, 10 },
123 { 5, 6, 20, 0 },
124 { 5, 6, -20, 10 },
125 { 5, 6, 20, -10 },
126 { -1, -1, 20, 10 },
127 { 5, 6, -1, -1 },
128};
129
130TEST_P(test_viewporter_bad_source_rect, bad_source_rect_args)
131{
132 const struct bad_source_rect_args *args = data;
133 struct client *client;
134 struct wp_viewport *vp;
135
136 client = create_client_and_test_surface(100, 50, 123, 77);
137
138 vp = create_viewport(client);
139
Pekka Paalanen12a138d2019-11-06 15:59:33 +0200140 testlog("wp_viewport.set_source x=%d, y=%d, w=%d, h=%d\n",
Pekka Paalanen82d95a62016-04-19 17:20:42 +0300141 args->x, args->y, args->w, args->h);
142 set_source(vp, args->x, args->y, args->w, args->h);
143
144 expect_protocol_error(client, &wp_viewport_interface,
145 WP_VIEWPORT_ERROR_BAD_VALUE);
146}
147
148TEST(test_viewporter_unset_source_rect)
149{
150 struct client *client;
151 struct wp_viewport *vp;
152
153 client = create_client_and_test_surface(100, 50, 123, 77);
154
155 vp = create_viewport(client);
156 set_source(vp, -1, -1, -1, -1);
157 wl_surface_commit(client->surface->wl_surface);
158
159 client_roundtrip(client);
160}
161
162struct bad_destination_args {
163 int w, h;
164};
165
166static const struct bad_destination_args bad_destination_args[] = {
167 { 0, 10 },
168 { 20, 0 },
169 { -20, 10 },
170 { -1, 10 },
171 { 20, -10 },
172 { 20, -1 },
173};
174
175TEST_P(test_viewporter_bad_destination_size, bad_destination_args)
176{
177 const struct bad_destination_args *args = data;
178 struct client *client;
179 struct wp_viewport *vp;
180
181 client = create_client_and_test_surface(100, 50, 123, 77);
182
183 vp = create_viewport(client);
184
Pekka Paalanen12a138d2019-11-06 15:59:33 +0200185 testlog("wp_viewport.set_destination w=%d, h=%d\n", args->w, args->h);
Pekka Paalanen82d95a62016-04-19 17:20:42 +0300186 wp_viewport_set_destination(vp, args->w, args->h);
187
188 expect_protocol_error(client, &wp_viewport_interface,
189 WP_VIEWPORT_ERROR_BAD_VALUE);
190}
191
192TEST(test_viewporter_unset_destination_size)
193{
194 struct client *client;
195 struct wp_viewport *vp;
196
197 client = create_client_and_test_surface(100, 50, 123, 77);
198
199 vp = create_viewport(client);
200 wp_viewport_set_destination(vp, -1, -1);
201 wl_surface_commit(client->surface->wl_surface);
202
203 client_roundtrip(client);
204}
205
206struct nonint_destination_args {
207 wl_fixed_t w, h;
208};
209
210static const struct nonint_destination_args nonint_destination_args[] = {
211#define F(i,f) ((i) * 256 + (f))
212 { F(20, 0), F(10, 1) },
213 { F(20, 0), F(10, -1) },
214 { F(20, 1), F(10, 0) },
215 { F(20, -1), F(10, 0) },
216 { F(20, 128), F(10, 128) },
217#undef F
218};
219
220TEST_P(test_viewporter_non_integer_destination_size, nonint_destination_args)
221{
222 const struct nonint_destination_args *args = data;
223 struct client *client;
224 struct wp_viewport *vp;
225
226 client = create_client_and_test_surface(100, 50, 123, 77);
227
228 vp = create_viewport(client);
229
Pekka Paalanen12a138d2019-11-06 15:59:33 +0200230 testlog("non-integer size w=%f, h=%f\n",
Pekka Paalanen82d95a62016-04-19 17:20:42 +0300231 wl_fixed_to_double(args->w), wl_fixed_to_double(args->h));
232 wp_viewport_set_source(vp, 5, 6, args->w, args->h);
233 wp_viewport_set_destination(vp, -1, -1);
234 wl_surface_commit(client->surface->wl_surface);
235
236 expect_protocol_error(client, &wp_viewport_interface,
237 WP_VIEWPORT_ERROR_BAD_SIZE);
238}
239
240struct source_buffer_args {
241 wl_fixed_t x, y;
242 wl_fixed_t w, h;
243 int buffer_scale;
244 enum wl_output_transform buffer_transform;
245};
246
247static int
248get_surface_width(struct surface *surface,
249 int buffer_scale,
250 enum wl_output_transform buffer_transform)
251{
252 switch (buffer_transform) {
253 case WL_OUTPUT_TRANSFORM_NORMAL:
254 case WL_OUTPUT_TRANSFORM_180:
255 case WL_OUTPUT_TRANSFORM_FLIPPED:
256 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
257 return surface->width / buffer_scale;
258 case WL_OUTPUT_TRANSFORM_90:
259 case WL_OUTPUT_TRANSFORM_270:
260 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
261 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
262 return surface->height / buffer_scale;
263 }
264
265 return -1;
266}
267
268static int
269get_surface_height(struct surface *surface,
270 int buffer_scale,
271 enum wl_output_transform buffer_transform)
272{
273 switch (buffer_transform) {
274 case WL_OUTPUT_TRANSFORM_NORMAL:
275 case WL_OUTPUT_TRANSFORM_180:
276 case WL_OUTPUT_TRANSFORM_FLIPPED:
277 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
278 return surface->height / buffer_scale;
279 case WL_OUTPUT_TRANSFORM_90:
280 case WL_OUTPUT_TRANSFORM_270:
281 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
282 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
283 return surface->width / buffer_scale;
284 }
285
286 return -1;
287}
288
289static void
290setup_source_vs_buffer(struct client *client,
291 const struct source_buffer_args *args)
292{
293 struct wl_surface *surf;
294 struct wp_viewport *vp;
295
296 surf = client->surface->wl_surface;
297 vp = create_viewport(client);
298
Pekka Paalanen12a138d2019-11-06 15:59:33 +0200299 testlog("surface %dx%d\n",
Pekka Paalanen82d95a62016-04-19 17:20:42 +0300300 get_surface_width(client->surface,
301 args->buffer_scale, args->buffer_transform),
302 get_surface_height(client->surface,
303 args->buffer_scale, args->buffer_transform));
Pekka Paalanen12a138d2019-11-06 15:59:33 +0200304 testlog("source x=%f, y=%f, w=%f, h=%f; "
Pekka Paalanen82d95a62016-04-19 17:20:42 +0300305 "buffer scale=%d, transform=%d\n",
306 wl_fixed_to_double(args->x), wl_fixed_to_double(args->y),
307 wl_fixed_to_double(args->w), wl_fixed_to_double(args->h),
308 args->buffer_scale, args->buffer_transform);
309
310 wl_surface_set_buffer_scale(surf, args->buffer_scale);
311 wl_surface_set_buffer_transform(surf, args->buffer_transform);
Pekka Paalanen924cd942016-05-20 17:25:38 +0300312 wl_surface_attach(surf, client->surface->buffer->proxy, 0, 0);
Pekka Paalanen82d95a62016-04-19 17:20:42 +0300313 wp_viewport_set_source(vp, args->x, args->y, args->w, args->h);
314 wp_viewport_set_destination(vp, 99, 99);
315 wl_surface_commit(surf);
316}
317
318/* buffer dimensions */
319#define WIN_W 124
320#define WIN_H 78
321
322/* source rect base size */
323#define SRC_W 20
324#define SRC_H 10
325
326/* margin */
327#define MRG 10
328/* epsilon of wl_fixed_t */
329#define EPS 1
330
331TEST(test_viewporter_source_buffer_params)
332{
333 const int max_scale = 2;
334
335 /* buffer_scale requirement */
336 assert(WIN_W % max_scale == 0);
337 assert(WIN_H % max_scale == 0);
338
339 /* source rect must fit inside regardless of scale and transform */
340 assert(SRC_W < WIN_W / max_scale);
341 assert(SRC_H < WIN_H / max_scale);
342 assert(SRC_W < WIN_H / max_scale);
343 assert(SRC_H < WIN_W / max_scale);
344
345 /* If buffer scale was ignored, source rect should be inside instead */
346 assert(WIN_W / max_scale + SRC_W + MRG < WIN_W);
347 assert(WIN_H / max_scale + SRC_H + MRG < WIN_H);
348 assert(WIN_W / max_scale + SRC_H + MRG < WIN_W);
349 assert(WIN_H / max_scale + SRC_W + MRG < WIN_H);
350}
351
352static const struct source_buffer_args bad_source_buffer_args[] = {
353#define F(i) ((i) * 256)
354
355/* Flush right-top, but epsilon too far right. */
356 { F(WIN_W - SRC_W) + EPS, F(0), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
357 { F(WIN_W - SRC_W), F(0), F(SRC_W) + EPS, F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
358/* Flush left-bottom, but epsilon too far down. */
359 { F(0), F(WIN_H - SRC_H) + EPS, F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
360 { F(0), F(WIN_H - SRC_H), F(SRC_W), F(SRC_H) + EPS, 1, WL_OUTPUT_TRANSFORM_NORMAL },
361/* Completely outside on the right. */
362 { F(WIN_W + MRG), F(0), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
363/* Competely outside on the bottom. */
364 { F(0), F(WIN_H + MRG), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
365
366/*
367 * buffer_scale=2, so the surface size will be halved.
368 * If buffer_scale was not taken into account, these would all be inside.
369 * These are the same as above, but adapted to buffer_scale=2.
370 */
371 { F(WIN_W / 2 - SRC_W) + EPS, F(0), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
372 { F(WIN_W / 2 - SRC_W), F(0), F(SRC_W) + EPS, F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
373
374 { F(0), F(WIN_H / 2 - SRC_H) + EPS, F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
375 { F(0), F(WIN_H / 2 - SRC_H), F(SRC_W), F(SRC_H) + EPS, 2, WL_OUTPUT_TRANSFORM_NORMAL },
376
377 { F(WIN_W / 2 + MRG), F(0), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
378
379 { F(0), F(WIN_H / 2 + MRG), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
380
381/* Exceeding bottom-right corner by epsilon: */
382/* non-dimension-swapping transforms */
383 { F(WIN_W - SRC_W), F(WIN_H - SRC_H), F(SRC_W), F(SRC_H) + EPS, 1, WL_OUTPUT_TRANSFORM_FLIPPED_180 },
384 { F(WIN_W - SRC_W), F(WIN_H - SRC_H) + EPS, F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_FLIPPED },
385 { F(WIN_W - SRC_W), F(WIN_H - SRC_H), F(SRC_W) + EPS, F(SRC_H), 1, WL_OUTPUT_TRANSFORM_180 },
386
387/* dimension-swapping transforms */
388 { F(WIN_H - SRC_W) + EPS, F(WIN_W - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_90 },
389 { F(WIN_H - SRC_W), F(WIN_W - SRC_H) + EPS, F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_270 },
390 { F(WIN_H - SRC_W), F(WIN_W - SRC_H), F(SRC_W) + EPS, F(SRC_H), 1, WL_OUTPUT_TRANSFORM_FLIPPED_90 },
391 { F(WIN_H - SRC_W), F(WIN_W - SRC_H), F(SRC_W), F(SRC_H) + EPS, 1, WL_OUTPUT_TRANSFORM_FLIPPED_270 },
392
393/* non-dimension-swapping transforms, buffer_scale=2 */
394 { F(WIN_W / 2 - SRC_W), F(WIN_H / 2 - SRC_H) + EPS, F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_FLIPPED_180 },
395 { F(WIN_W / 2 - SRC_W), F(WIN_H / 2 - SRC_H), F(SRC_W) + EPS, F(SRC_H), 2, WL_OUTPUT_TRANSFORM_FLIPPED },
396 { F(WIN_W / 2 - SRC_W), F(WIN_H / 2 - SRC_H), F(SRC_W), F(SRC_H) + EPS, 2, WL_OUTPUT_TRANSFORM_180 },
397
398/* dimension-swapping transforms, buffer_scale=2 */
399 { F(WIN_H / 2 - SRC_W) + EPS, F(WIN_W / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_90 },
400 { F(WIN_H / 2 - SRC_W), F(WIN_W / 2 - SRC_H) + EPS, F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_270 },
401 { F(WIN_H / 2 - SRC_W), F(WIN_W / 2 - SRC_H), F(SRC_W) + EPS, F(SRC_H), 2, WL_OUTPUT_TRANSFORM_FLIPPED_90 },
402 { F(WIN_H / 2 - SRC_W), F(WIN_W / 2 - SRC_H), F(SRC_W), F(SRC_H) + EPS, 2, WL_OUTPUT_TRANSFORM_FLIPPED_270 },
403
404#undef F
405};
406
407TEST_P(test_viewporter_source_outside_buffer, bad_source_buffer_args)
408{
409 const struct source_buffer_args *args = data;
410 struct client *client;
411
412 client = create_client_and_test_surface(100, 50, WIN_W, WIN_H);
413 setup_source_vs_buffer(client, args);
414
415 expect_protocol_error(client, &wp_viewport_interface,
416 WP_VIEWPORT_ERROR_OUT_OF_BUFFER);
417}
418
419static const struct source_buffer_args good_source_buffer_args[] = {
420#define F(i) ((i) * 256)
421
422/* top-left, top-right, bottom-left, and bottom-right corner */
423 { F(0), F(0), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
424 { F(WIN_W - SRC_W), F(0), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
425 { F(0), F(WIN_H - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
426 { F(WIN_W - SRC_W), F(WIN_H - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_NORMAL },
427
428/* buffer_scale=2, so the surface size will be halved */
429 { F(0), F(0), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
430 { F(WIN_W / 2 - SRC_W), F(0), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
431 { F(0), F(WIN_H / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
432 { F(WIN_W / 2 - SRC_W), F(WIN_H / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_NORMAL },
433
434/* with half pixel offset */
435 { F(WIN_W / 2 - SRC_W) + 128, F(WIN_H / 2 - SRC_H) + 128, F(SRC_W) - 128, F(SRC_H) - 128, 2, WL_OUTPUT_TRANSFORM_NORMAL },
436
437/* Flushed to bottom-right corner: */
438/* non-dimension-swapping transforms */
439 { F(WIN_W - SRC_W), F(WIN_H - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_FLIPPED_180 },
440 { F(WIN_W - SRC_W), F(WIN_H - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_FLIPPED },
441 { F(WIN_W - SRC_W), F(WIN_H - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_180 },
442
443/* dimension-swapping transforms */
444 { F(WIN_H - SRC_W), F(WIN_W - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_90 },
445 { F(WIN_H - SRC_W), F(WIN_W - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_270 },
446 { F(WIN_H - SRC_W), F(WIN_W - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_FLIPPED_90 },
447 { F(WIN_H - SRC_W), F(WIN_W - SRC_H), F(SRC_W), F(SRC_H), 1, WL_OUTPUT_TRANSFORM_FLIPPED_270 },
448
449/* non-dimension-swapping transforms, buffer_scale=2 */
450 { F(WIN_W / 2 - SRC_W), F(WIN_H / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_FLIPPED_180 },
451 { F(WIN_W / 2 - SRC_W), F(WIN_H / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_FLIPPED },
452 { F(WIN_W / 2 - SRC_W), F(WIN_H / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_180 },
453
454/* dimension-swapping transforms, buffer_scale=2 */
455 { F(WIN_H / 2 - SRC_W), F(WIN_W / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_90 },
456 { F(WIN_H / 2 - SRC_W), F(WIN_W / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_270 },
457 { F(WIN_H / 2 - SRC_W), F(WIN_W / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_FLIPPED_90 },
458 { F(WIN_H / 2 - SRC_W), F(WIN_W / 2 - SRC_H), F(SRC_W), F(SRC_H), 2, WL_OUTPUT_TRANSFORM_FLIPPED_270 },
459
460#undef F
461};
462
463TEST_P(test_viewporter_source_inside_buffer, good_source_buffer_args)
464{
465 const struct source_buffer_args *args = data;
466 struct client *client;
467
468 client = create_client_and_test_surface(100, 50, WIN_W, WIN_H);
469 setup_source_vs_buffer(client, args);
470 client_roundtrip(client);
471}
472
473#undef WIN_W
474#undef WIN_H
475#undef SRC_W
476#undef SRC_H
477#undef MRG
478#undef EPS
479
480TEST(test_viewporter_outside_null_buffer)
481{
482 struct client *client;
483 struct wp_viewport *vp;
484 struct wl_surface *surf;
485
486 client = create_client_and_test_surface(100, 50, 123, 77);
487 surf = client->surface->wl_surface;
488
489 /* If buffer is NULL, does not matter what the source rect is. */
490 vp = create_viewport(client);
491 wl_surface_attach(surf, NULL, 0, 0);
492 set_source(vp, 1000, 1000, 20, 10);
493 wp_viewport_set_destination(vp, 99, 99);
494 wl_surface_commit(surf);
495 client_roundtrip(client);
496
497 /* Try again, with all old values. */
498 wl_surface_commit(surf);
499 client_roundtrip(client);
500
501 /* Try once more with old NULL buffer. */
502 set_source(vp, 1200, 1200, 20, 10);
503 wl_surface_commit(surf);
504 client_roundtrip(client);
505
506 /* When buffer comes back, source rect matters again. */
Pekka Paalanen924cd942016-05-20 17:25:38 +0300507 wl_surface_attach(surf, client->surface->buffer->proxy, 0, 0);
Pekka Paalanen82d95a62016-04-19 17:20:42 +0300508 wl_surface_commit(surf);
509 expect_protocol_error(client, &wp_viewport_interface,
510 WP_VIEWPORT_ERROR_OUT_OF_BUFFER);
511}
512
513TEST(test_viewporter_no_surface_set_source)
514{
515 struct client *client;
516 struct wp_viewport *vp;
517
518 client = create_client_and_test_surface(100, 50, 123, 77);
519 vp = create_viewport(client);
520 wl_surface_destroy(client->surface->wl_surface);
521 client->surface->wl_surface = NULL;
522
523 /* But the wl_surface does not exist anymore. */
524 set_source(vp, 1000, 1000, 20, 10);
525
526 expect_protocol_error(client, &wp_viewport_interface,
527 WP_VIEWPORT_ERROR_NO_SURFACE);
528}
529
530TEST(test_viewporter_no_surface_set_destination)
531{
532 struct client *client;
533 struct wp_viewport *vp;
534
535 client = create_client_and_test_surface(100, 50, 123, 77);
536 vp = create_viewport(client);
537 wl_surface_destroy(client->surface->wl_surface);
538 client->surface->wl_surface = NULL;
539
540 /* But the wl_surface does not exist anymore. */
541 wp_viewport_set_destination(vp, 99, 99);
542
543 expect_protocol_error(client, &wp_viewport_interface,
544 WP_VIEWPORT_ERROR_NO_SURFACE);
545}
546
547TEST(test_viewporter_no_surface_destroy)
548{
549 struct client *client;
550 struct wp_viewport *vp;
551
552 client = create_client_and_test_surface(100, 50, 123, 77);
553 vp = create_viewport(client);
554 wl_surface_destroy(client->surface->wl_surface);
555 client->surface->wl_surface = NULL;
556
557 /* But the wl_surface does not exist anymore. */
558 wp_viewport_destroy(vp);
559
560 client_roundtrip(client);
561}