source: mainline/uspace/srv/hid/display/test/client.c@ 7cc30e9

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7cc30e9 was 98735eb, checked in by jxsvoboda <5887334+jxsvoboda@…>, 4 years ago

Purge events from client event queue when destroying window

If the client had events queued for a particular window and that got
destroyed, later these events, pointing to freed (and reused) memory
would be handed to the client with the wrong window ID (which was
read from the wrong/recycled memory block).

  • Property mode set to 100644
File size: 16.3 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <disp_srv.h>
30#include <errno.h>
31#include <pcut/pcut.h>
32#include <str.h>
33
34#include "../client.h"
35#include "../display.h"
36#include "../seat.h"
37#include "../window.h"
38
39PCUT_INIT;
40
41PCUT_TEST_SUITE(client);
42
43static void test_ds_ev_pending(void *);
44
45static ds_client_cb_t test_ds_client_cb = {
46 .ev_pending = test_ds_ev_pending
47};
48
49static void test_ds_ev_pending(void *arg)
50{
51 bool *called_cb = (bool *) arg;
52 *called_cb = true;
53}
54
55/** Client creation and destruction. */
56PCUT_TEST(client_create_destroy)
57{
58 ds_display_t *disp;
59 ds_client_t *client;
60 errno_t rc;
61
62 rc = ds_display_create(NULL, df_none, &disp);
63 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
64
65 rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
66 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
67
68 ds_client_destroy(client);
69 ds_display_destroy(disp);
70}
71
72/** Test ds_client_find_window().
73 *
74 * ds_client_add_window() and ds_client_remove_window() are indirectly
75 * tested too as part of creating and destroying the window
76 */
77PCUT_TEST(client_find_window)
78{
79 ds_display_t *disp;
80 ds_client_t *client;
81 ds_seat_t *seat;
82 ds_window_t *w0;
83 ds_window_t *w1;
84 ds_window_t *wnd;
85 display_wnd_params_t params;
86 bool called_cb = NULL;
87 errno_t rc;
88
89 rc = ds_display_create(NULL, df_none, &disp);
90 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
91
92 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
93 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
94
95 rc = ds_seat_create(disp, &seat);
96 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
97
98 display_wnd_params_init(&params);
99 params.rect.p0.x = params.rect.p0.y = 0;
100 params.rect.p1.x = params.rect.p1.y = 1;
101
102 rc = ds_window_create(client, &params, &w0);
103 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
104
105 rc = ds_window_create(client, &params, &w1);
106 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
107
108 wnd = ds_client_find_window(client, w0->id);
109 PCUT_ASSERT_EQUALS(w0, wnd);
110
111 wnd = ds_client_find_window(client, w1->id);
112 PCUT_ASSERT_EQUALS(w1, wnd);
113
114 wnd = ds_client_find_window(client, 0);
115 PCUT_ASSERT_NULL(wnd);
116
117 wnd = ds_client_find_window(client, w1->id + 1);
118 PCUT_ASSERT_NULL(wnd);
119
120 ds_window_destroy(w0);
121 ds_window_destroy(w1);
122 ds_seat_destroy(seat);
123 ds_client_destroy(client);
124 ds_display_destroy(disp);
125}
126
127/** Test ds_client_first_window() / ds_client_next_window. */
128PCUT_TEST(client_first_next_window)
129{
130 ds_display_t *disp;
131 ds_client_t *client;
132 ds_seat_t *seat;
133 ds_window_t *w0;
134 ds_window_t *w1;
135 ds_window_t *wnd;
136 display_wnd_params_t params;
137 bool called_cb = NULL;
138 errno_t rc;
139
140 rc = ds_display_create(NULL, df_none, &disp);
141 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
142
143 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
144 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
145
146 rc = ds_seat_create(disp, &seat);
147 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
148
149 display_wnd_params_init(&params);
150 params.rect.p0.x = params.rect.p0.y = 0;
151 params.rect.p1.x = params.rect.p1.y = 1;
152
153 rc = ds_window_create(client, &params, &w0);
154 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
155
156 rc = ds_window_create(client, &params, &w1);
157 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
158
159 wnd = ds_client_first_window(client);
160 PCUT_ASSERT_EQUALS(w0, wnd);
161
162 wnd = ds_client_next_window(w0);
163 PCUT_ASSERT_EQUALS(w1, wnd);
164
165 wnd = ds_client_next_window(w1);
166 PCUT_ASSERT_NULL(wnd);
167
168 ds_window_destroy(w0);
169 ds_window_destroy(w1);
170 ds_seat_destroy(seat);
171 ds_client_destroy(client);
172 ds_display_destroy(disp);
173}
174
175/** Test ds_client_get_event(), ds_client_post_close_event(). */
176PCUT_TEST(client_get_post_close_event)
177{
178 ds_display_t *disp;
179 ds_client_t *client;
180 ds_seat_t *seat;
181 ds_window_t *wnd;
182 display_wnd_params_t params;
183 ds_window_t *rwindow;
184 display_wnd_ev_t revent;
185 bool called_cb = NULL;
186 errno_t rc;
187
188 rc = ds_display_create(NULL, df_none, &disp);
189 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
190
191 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
192 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
193
194 rc = ds_seat_create(disp, &seat);
195 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
196
197 display_wnd_params_init(&params);
198 params.rect.p0.x = params.rect.p0.y = 0;
199 params.rect.p1.x = params.rect.p1.y = 1;
200
201 rc = ds_window_create(client, &params, &wnd);
202 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
203
204 /* New window gets focused event */
205 PCUT_ASSERT_TRUE(called_cb);
206
207 rc = ds_client_get_event(client, &rwindow, &revent);
208 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
209
210 called_cb = false;
211
212 rc = ds_client_get_event(client, &rwindow, &revent);
213 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
214
215 rc = ds_client_post_close_event(client, wnd);
216 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
217 PCUT_ASSERT_TRUE(called_cb);
218
219 rc = ds_client_get_event(client, &rwindow, &revent);
220 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
221 PCUT_ASSERT_EQUALS(wnd, rwindow);
222 PCUT_ASSERT_EQUALS(wev_close, revent.etype);
223
224 rc = ds_client_get_event(client, &rwindow, &revent);
225 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
226
227 ds_window_destroy(wnd);
228 ds_seat_destroy(seat);
229 ds_client_destroy(client);
230 ds_display_destroy(disp);
231}
232
233/** Test ds_client_get_event(), ds_client_post_focus_event(). */
234PCUT_TEST(client_get_post_focus_event)
235{
236 ds_display_t *disp;
237 ds_client_t *client;
238 ds_seat_t *seat;
239 ds_window_t *wnd;
240 display_wnd_params_t params;
241 ds_window_t *rwindow;
242 display_wnd_ev_t revent;
243 bool called_cb = NULL;
244 errno_t rc;
245
246 rc = ds_display_create(NULL, df_none, &disp);
247 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
248
249 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
250 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
251
252 rc = ds_seat_create(disp, &seat);
253 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
254
255 display_wnd_params_init(&params);
256 params.rect.p0.x = params.rect.p0.y = 0;
257 params.rect.p1.x = params.rect.p1.y = 1;
258
259 rc = ds_window_create(client, &params, &wnd);
260 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
261
262 /* New window gets focused event */
263 PCUT_ASSERT_TRUE(called_cb);
264
265 rc = ds_client_get_event(client, &rwindow, &revent);
266 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
267
268 called_cb = false;
269
270 rc = ds_client_get_event(client, &rwindow, &revent);
271 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
272
273 rc = ds_client_post_focus_event(client, wnd);
274 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
275 PCUT_ASSERT_TRUE(called_cb);
276
277 rc = ds_client_get_event(client, &rwindow, &revent);
278 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
279 PCUT_ASSERT_EQUALS(wnd, rwindow);
280 PCUT_ASSERT_EQUALS(wev_focus, revent.etype);
281
282 rc = ds_client_get_event(client, &rwindow, &revent);
283 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
284
285 ds_window_destroy(wnd);
286 ds_seat_destroy(seat);
287 ds_client_destroy(client);
288 ds_display_destroy(disp);
289}
290
291/** Test ds_client_get_event(), ds_client_post_kbd_event(). */
292PCUT_TEST(client_get_post_kbd_event)
293{
294 ds_display_t *disp;
295 ds_client_t *client;
296 ds_seat_t *seat;
297 ds_window_t *wnd;
298 display_wnd_params_t params;
299 kbd_event_t event;
300 ds_window_t *rwindow;
301 display_wnd_ev_t revent;
302 bool called_cb = NULL;
303 errno_t rc;
304
305 rc = ds_display_create(NULL, df_none, &disp);
306 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
307
308 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
309 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
310
311 rc = ds_seat_create(disp, &seat);
312 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
313
314 display_wnd_params_init(&params);
315 params.rect.p0.x = params.rect.p0.y = 0;
316 params.rect.p1.x = params.rect.p1.y = 1;
317
318 rc = ds_window_create(client, &params, &wnd);
319 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
320
321 /* New window gets focused event */
322 PCUT_ASSERT_TRUE(called_cb);
323
324 rc = ds_client_get_event(client, &rwindow, &revent);
325 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
326
327 called_cb = false;
328
329 rc = ds_client_get_event(client, &rwindow, &revent);
330 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
331
332 event.type = KEY_PRESS;
333 event.key = KC_ENTER;
334 event.mods = 0;
335 event.c = L'\0';
336
337 rc = ds_client_post_kbd_event(client, wnd, &event);
338 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
339 PCUT_ASSERT_TRUE(called_cb);
340
341 rc = ds_client_get_event(client, &rwindow, &revent);
342 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
343 PCUT_ASSERT_EQUALS(wnd, rwindow);
344 PCUT_ASSERT_EQUALS(wev_kbd, revent.etype);
345 PCUT_ASSERT_EQUALS(event.type, revent.ev.kbd.type);
346 PCUT_ASSERT_EQUALS(event.key, revent.ev.kbd.key);
347 PCUT_ASSERT_EQUALS(event.mods, revent.ev.kbd.mods);
348 PCUT_ASSERT_EQUALS(event.c, revent.ev.kbd.c);
349
350 rc = ds_client_get_event(client, &rwindow, &revent);
351 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
352
353 ds_window_destroy(wnd);
354 ds_seat_destroy(seat);
355 ds_client_destroy(client);
356 ds_display_destroy(disp);
357}
358
359/** Test ds_client_get_event(), ds_client_post_pos_event(). */
360PCUT_TEST(client_get_post_pos_event)
361{
362 ds_display_t *disp;
363 ds_client_t *client;
364 ds_seat_t *seat;
365 ds_window_t *wnd;
366 display_wnd_params_t params;
367 pos_event_t event;
368 ds_window_t *rwindow;
369 display_wnd_ev_t revent;
370 bool called_cb = NULL;
371 errno_t rc;
372
373 rc = ds_display_create(NULL, df_none, &disp);
374 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
375
376 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
377 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
378
379 rc = ds_seat_create(disp, &seat);
380 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
381
382 display_wnd_params_init(&params);
383 params.rect.p0.x = params.rect.p0.y = 0;
384 params.rect.p1.x = params.rect.p1.y = 1;
385
386 rc = ds_window_create(client, &params, &wnd);
387 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
388
389 /* New window gets focused event */
390 PCUT_ASSERT_TRUE(called_cb);
391
392 rc = ds_client_get_event(client, &rwindow, &revent);
393 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
394
395 called_cb = false;
396
397 PCUT_ASSERT_FALSE(called_cb);
398
399 rc = ds_client_get_event(client, &rwindow, &revent);
400 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
401
402 event.type = POS_PRESS;
403 event.hpos = 1;
404 event.vpos = 2;
405
406 rc = ds_client_post_pos_event(client, wnd, &event);
407 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
408 PCUT_ASSERT_TRUE(called_cb);
409
410 rc = ds_client_get_event(client, &rwindow, &revent);
411 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
412 PCUT_ASSERT_EQUALS(wnd, rwindow);
413 PCUT_ASSERT_EQUALS(wev_pos, revent.etype);
414 PCUT_ASSERT_EQUALS(event.type, revent.ev.pos.type);
415 PCUT_ASSERT_EQUALS(event.hpos, revent.ev.pos.hpos);
416 PCUT_ASSERT_EQUALS(event.vpos, revent.ev.pos.vpos);
417
418 rc = ds_client_get_event(client, &rwindow, &revent);
419 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
420
421 ds_window_destroy(wnd);
422 ds_seat_destroy(seat);
423 ds_client_destroy(client);
424 ds_display_destroy(disp);
425}
426
427/** Test ds_client_get_event(), ds_client_post_resize_event(). */
428PCUT_TEST(client_get_post_resize_event)
429{
430 ds_display_t *disp;
431 ds_client_t *client;
432 ds_seat_t *seat;
433 ds_window_t *wnd;
434 display_wnd_params_t params;
435 gfx_rect_t rect;
436 ds_window_t *rwindow;
437 display_wnd_ev_t revent;
438 bool called_cb = NULL;
439 errno_t rc;
440
441 rc = ds_display_create(NULL, df_none, &disp);
442 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
443
444 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
445 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
446
447 rc = ds_seat_create(disp, &seat);
448 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
449
450 display_wnd_params_init(&params);
451 params.rect.p0.x = params.rect.p0.y = 0;
452 params.rect.p1.x = params.rect.p1.y = 1;
453
454 rc = ds_window_create(client, &params, &wnd);
455 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
456
457 /* New window gets focused event */
458 PCUT_ASSERT_TRUE(called_cb);
459
460 rc = ds_client_get_event(client, &rwindow, &revent);
461 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
462
463 called_cb = false;
464
465 PCUT_ASSERT_FALSE(called_cb);
466
467 rc = ds_client_get_event(client, &rwindow, &revent);
468 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
469
470 rect.p0.x = 1;
471 rect.p0.y = 2;
472 rect.p1.x = 3;
473 rect.p1.y = 4;
474
475 rc = ds_client_post_resize_event(client, wnd, &rect);
476 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
477 PCUT_ASSERT_TRUE(called_cb);
478
479 rc = ds_client_get_event(client, &rwindow, &revent);
480 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
481 PCUT_ASSERT_EQUALS(wnd, rwindow);
482 PCUT_ASSERT_EQUALS(wev_resize, revent.etype);
483 PCUT_ASSERT_EQUALS(rect.p0.x, revent.ev.resize.rect.p0.x);
484 PCUT_ASSERT_EQUALS(rect.p0.y, revent.ev.resize.rect.p0.y);
485 PCUT_ASSERT_EQUALS(rect.p1.x, revent.ev.resize.rect.p1.x);
486 PCUT_ASSERT_EQUALS(rect.p1.y, revent.ev.resize.rect.p1.y);
487
488 rc = ds_client_get_event(client, &rwindow, &revent);
489 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
490
491 ds_window_destroy(wnd);
492 ds_seat_destroy(seat);
493 ds_client_destroy(client);
494 ds_display_destroy(disp);
495}
496
497/** Test ds_client_get_event(), ds_client_post_unfocus_event(). */
498PCUT_TEST(client_get_post_unfocus_event)
499{
500 ds_display_t *disp;
501 ds_client_t *client;
502 ds_seat_t *seat;
503 ds_window_t *wnd;
504 display_wnd_params_t params;
505 ds_window_t *rwindow;
506 display_wnd_ev_t revent;
507 bool called_cb = NULL;
508 errno_t rc;
509
510 rc = ds_display_create(NULL, df_none, &disp);
511 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
512
513 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
514 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
515
516 rc = ds_seat_create(disp, &seat);
517 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
518
519 display_wnd_params_init(&params);
520 params.rect.p0.x = params.rect.p0.y = 0;
521 params.rect.p1.x = params.rect.p1.y = 1;
522
523 rc = ds_window_create(client, &params, &wnd);
524 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
525
526 /* New window gets focused event */
527 PCUT_ASSERT_TRUE(called_cb);
528
529 rc = ds_client_get_event(client, &rwindow, &revent);
530 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
531
532 called_cb = false;
533
534 rc = ds_client_get_event(client, &rwindow, &revent);
535 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
536
537 rc = ds_client_post_unfocus_event(client, wnd);
538 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
539 PCUT_ASSERT_TRUE(called_cb);
540
541 rc = ds_client_get_event(client, &rwindow, &revent);
542 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
543 PCUT_ASSERT_EQUALS(wnd, rwindow);
544 PCUT_ASSERT_EQUALS(wev_unfocus, revent.etype);
545
546 rc = ds_client_get_event(client, &rwindow, &revent);
547 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
548
549 ds_window_destroy(wnd);
550 ds_seat_destroy(seat);
551 ds_client_destroy(client);
552 ds_display_destroy(disp);
553}
554
555/** Test ds_client_purge_window_events() */
556PCUT_TEST(client_purge_window_events)
557{
558 ds_display_t *disp;
559 ds_client_t *client;
560 ds_seat_t *seat;
561 ds_window_t *wnd;
562 display_wnd_params_t params;
563 ds_window_t *rwindow;
564 display_wnd_ev_t revent;
565 bool called_cb = NULL;
566 errno_t rc;
567
568 rc = ds_display_create(NULL, df_none, &disp);
569 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
570
571 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
572 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
573
574 rc = ds_seat_create(disp, &seat);
575 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
576
577 display_wnd_params_init(&params);
578 params.rect.p0.x = params.rect.p0.y = 0;
579 params.rect.p1.x = params.rect.p1.y = 1;
580
581 rc = ds_window_create(client, &params, &wnd);
582 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
583
584 /* New window gets focused event */
585 PCUT_ASSERT_TRUE(called_cb);
586
587 /* Purge it */
588 ds_client_purge_window_events(client, wnd);
589
590 /* The queue should be empty now */
591 rc = ds_client_get_event(client, &rwindow, &revent);
592 PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
593
594 ds_window_destroy(wnd);
595 ds_seat_destroy(seat);
596 ds_client_destroy(client);
597 ds_display_destroy(disp);
598}
599
600/** Test client being destroyed while still having a window.
601 *
602 * This can happen if client forgets to destroy window or if the client
603 * is disconnected (or terminated).
604 */
605PCUT_TEST(client_leftover_window)
606{
607 ds_display_t *disp;
608 ds_client_t *client;
609 ds_seat_t *seat;
610 ds_window_t *wnd;
611 display_wnd_params_t params;
612 errno_t rc;
613
614 rc = ds_display_create(NULL, df_none, &disp);
615 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
616
617 rc = ds_client_create(disp, NULL, NULL, &client);
618 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
619
620 rc = ds_seat_create(disp, &seat);
621 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
622
623 display_wnd_params_init(&params);
624 params.rect.p0.x = params.rect.p0.y = 0;
625 params.rect.p1.x = params.rect.p1.y = 1;
626
627 rc = ds_window_create(client, &params, &wnd);
628 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
629
630 ds_seat_destroy(seat);
631 ds_client_destroy(client);
632 ds_display_destroy(disp);
633}
634
635PCUT_EXPORT(client);
Note: See TracBrowser for help on using the repository browser.