source: mainline/uspace/lib/display/test/display.c@ 338d0935

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 338d0935 was 338d0935, checked in by Jiri Svoboda <jiri@…>, 6 years ago

Closing windows

  • Property mode set to 100644
File size: 27.9 KB
Line 
1/*
2 * Copyright (c) 2019 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 <async.h>
30#include <errno.h>
31#include <display.h>
32#include <disp_srv.h>
33#include <fibril_synch.h>
34#include <gfx/color.h>
35#include <gfx/context.h>
36#include <gfx/render.h>
37#include <ipcgfx/server.h>
38#include <loc.h>
39#include <pcut/pcut.h>
40
41PCUT_INIT;
42
43PCUT_TEST_SUITE(display);
44
45static const char *test_display_server = "test-display";
46static const char *test_display_svc = "test/display";
47
48static void test_display_conn(ipc_call_t *, void *);
49
50static void test_close_event(void *);
51static void test_focus_event(void *);
52static void test_kbd_event(void *, kbd_event_t *);
53static void test_pos_event(void *, pos_event_t *);
54static void test_unfocus_event(void *);
55
56static errno_t test_window_create(void *, display_wnd_params_t *, sysarg_t *);
57static errno_t test_window_destroy(void *, sysarg_t);
58static errno_t test_window_resize(void *, sysarg_t, gfx_coord2_t *,
59 gfx_rect_t *);
60static errno_t test_get_event(void *, sysarg_t *, display_wnd_ev_t *);
61
62static errno_t test_gc_set_color(void *, gfx_color_t *);
63
64static display_ops_t test_display_srv_ops = {
65 .window_create = test_window_create,
66 .window_destroy = test_window_destroy,
67 .window_resize = test_window_resize,
68 .get_event = test_get_event
69};
70
71static display_wnd_cb_t test_display_wnd_cb = {
72 .close_event = test_close_event,
73 .focus_event = test_focus_event,
74 .kbd_event = test_kbd_event,
75 .pos_event = test_pos_event,
76 .unfocus_event = test_unfocus_event
77};
78
79static gfx_context_ops_t test_gc_ops = {
80 .set_color = test_gc_set_color
81};
82
83/** Describes to the server how to respond to our request and pass tracking
84 * data back to the client.
85 */
86typedef struct {
87 errno_t rc;
88 sysarg_t wnd_id;
89 display_wnd_ev_t event;
90 display_wnd_ev_t revent;
91 int event_cnt;
92 bool window_create_called;
93 gfx_rect_t create_rect;
94 bool window_destroy_called;
95 sysarg_t destroy_wnd_id;
96
97 bool window_resize_called;
98 gfx_coord2_t resize_offs;
99 gfx_rect_t resize_nbound;
100 sysarg_t resize_wnd_id;
101
102 bool get_event_called;
103 bool set_color_called;
104 bool close_event_called;
105 bool focus_event_called;
106 bool kbd_event_called;
107 bool pos_event_called;
108 bool unfocus_event_called;
109 fibril_condvar_t event_cv;
110 fibril_mutex_t event_lock;
111 display_srv_t *srv;
112} test_response_t;
113
114/** display_open(), display_close() work for valid display service */
115PCUT_TEST(open_close)
116{
117 errno_t rc;
118 service_id_t sid;
119 display_t *disp = NULL;
120 test_response_t resp;
121
122 async_set_fallback_port_handler(test_display_conn, &resp);
123
124 // FIXME This causes this test to be non-reentrant!
125 rc = loc_server_register(test_display_server);
126 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
127
128 rc = loc_service_register(test_display_svc, &sid);
129 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
130
131 rc = display_open(test_display_svc, &disp);
132 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
133 PCUT_ASSERT_NOT_NULL(disp);
134
135 display_close(disp);
136 rc = loc_service_unregister(sid);
137 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
138}
139
140/** display_window_create() with server returning error response works */
141PCUT_TEST(window_create_failure)
142{
143 errno_t rc;
144 service_id_t sid;
145 display_t *disp = NULL;
146 display_wnd_params_t params;
147 display_window_t *wnd;
148 test_response_t resp;
149
150 async_set_fallback_port_handler(test_display_conn, &resp);
151
152 // FIXME This causes this test to be non-reentrant!
153 rc = loc_server_register(test_display_server);
154 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
155
156 rc = loc_service_register(test_display_svc, &sid);
157 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
158
159 rc = display_open(test_display_svc, &disp);
160 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
161 PCUT_ASSERT_NOT_NULL(disp);
162
163 wnd = NULL;
164 resp.rc = ENOMEM;
165 resp.window_create_called = false;
166 display_wnd_params_init(&params);
167 params.rect.p0.x = 0;
168 params.rect.p0.y = 0;
169 params.rect.p0.x = 100;
170 params.rect.p0.y = 100;
171
172 rc = display_window_create(disp, &params, &test_display_wnd_cb,
173 (void *) &resp, &wnd);
174 PCUT_ASSERT_TRUE(resp.window_create_called);
175 PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.create_rect.p0.x);
176 PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.create_rect.p0.y);
177 PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.create_rect.p1.x);
178 PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.create_rect.p1.y);
179 PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
180 PCUT_ASSERT_NULL(wnd);
181
182 display_close(disp);
183 rc = loc_service_unregister(sid);
184 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
185}
186
187/** display_window_create() and display_window_destroy() with success
188 *
189 * with server returning success,
190 */
191PCUT_TEST(window_create_destroy_success)
192{
193 errno_t rc;
194 service_id_t sid;
195 display_t *disp = NULL;
196 display_wnd_params_t params;
197 display_window_t *wnd;
198 test_response_t resp;
199
200 async_set_fallback_port_handler(test_display_conn, &resp);
201
202 // FIXME This causes this test to be non-reentrant!
203 rc = loc_server_register(test_display_server);
204 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
205
206 rc = loc_service_register(test_display_svc, &sid);
207 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
208
209 rc = display_open(test_display_svc, &disp);
210 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
211 PCUT_ASSERT_NOT_NULL(disp);
212
213 wnd = NULL;
214 resp.rc = EOK;
215 resp.window_create_called = false;
216 display_wnd_params_init(&params);
217 params.rect.p0.x = 0;
218 params.rect.p0.y = 0;
219 params.rect.p0.x = 100;
220 params.rect.p0.y = 100;
221
222 rc = display_window_create(disp, &params, &test_display_wnd_cb,
223 (void *) &resp, &wnd);
224 PCUT_ASSERT_TRUE(resp.window_create_called);
225 PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.create_rect.p0.x);
226 PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.create_rect.p0.y);
227 PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.create_rect.p1.x);
228 PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.create_rect.p1.y);
229 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
230 PCUT_ASSERT_NOT_NULL(wnd);
231
232 resp.window_destroy_called = false;
233 rc = display_window_destroy(wnd);
234 PCUT_ASSERT_TRUE(resp.window_destroy_called);
235 PCUT_ASSERT_INT_EQUALS(wnd->id, resp.destroy_wnd_id);
236 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
237
238 display_close(disp);
239 rc = loc_service_unregister(sid);
240 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
241}
242
243/** display_window_create() with server returning error response works. */
244PCUT_TEST(window_destroy_failure)
245{
246 errno_t rc;
247 service_id_t sid;
248 display_t *disp = NULL;
249 display_wnd_params_t params;
250 display_window_t *wnd;
251 test_response_t resp;
252
253 async_set_fallback_port_handler(test_display_conn, &resp);
254
255 // FIXME This causes this test to be non-reentrant!
256 rc = loc_server_register(test_display_server);
257 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
258
259 rc = loc_service_register(test_display_svc, &sid);
260 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
261
262 rc = display_open(test_display_svc, &disp);
263 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
264 PCUT_ASSERT_NOT_NULL(disp);
265
266 resp.rc = EOK;
267 resp.window_create_called = false;
268 display_wnd_params_init(&params);
269 params.rect.p0.x = 0;
270 params.rect.p0.y = 0;
271 params.rect.p0.x = 100;
272 params.rect.p0.y = 100;
273
274 rc = display_window_create(disp, &params, &test_display_wnd_cb,
275 (void *) &resp, &wnd);
276 PCUT_ASSERT_TRUE(resp.window_create_called);
277 PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.create_rect.p0.x);
278 PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.create_rect.p0.y);
279 PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.create_rect.p1.x);
280 PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.create_rect.p1.y);
281 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
282 PCUT_ASSERT_NOT_NULL(wnd);
283
284 resp.rc = EIO;
285 resp.window_destroy_called = false;
286 rc = display_window_destroy(wnd);
287 PCUT_ASSERT_TRUE(resp.window_destroy_called);
288 PCUT_ASSERT_INT_EQUALS(wnd->id, resp.destroy_wnd_id);
289 PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
290
291 display_close(disp);
292 rc = loc_service_unregister(sid);
293 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
294}
295
296/** display_window_resize() with server returning error response works. */
297PCUT_TEST(window_resize_failure)
298{
299 errno_t rc;
300 service_id_t sid;
301 display_t *disp = NULL;
302 display_wnd_params_t params;
303 display_window_t *wnd;
304 gfx_coord2_t offs;
305 gfx_rect_t nrect;
306 test_response_t resp;
307
308 async_set_fallback_port_handler(test_display_conn, &resp);
309
310 // FIXME This causes this test to be non-reentrant!
311 rc = loc_server_register(test_display_server);
312 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
313
314 rc = loc_service_register(test_display_svc, &sid);
315 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
316
317 rc = display_open(test_display_svc, &disp);
318 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
319 PCUT_ASSERT_NOT_NULL(disp);
320
321 resp.rc = EOK;
322 display_wnd_params_init(&params);
323 params.rect.p0.x = 0;
324 params.rect.p0.y = 0;
325 params.rect.p0.x = 100;
326 params.rect.p0.y = 100;
327
328 rc = display_window_create(disp, &params, &test_display_wnd_cb,
329 (void *) &resp, &wnd);
330 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
331 PCUT_ASSERT_NOT_NULL(wnd);
332
333 resp.rc = EIO;
334 resp.window_resize_called = false;
335 offs.x = 11;
336 offs.y = 12;
337 nrect.p0.x = 13;
338 nrect.p0.y = 14;
339 nrect.p1.x = 15;
340 nrect.p1.y = 16;
341
342 rc = display_window_resize(wnd, &offs, &nrect);
343 PCUT_ASSERT_TRUE(resp.window_resize_called);
344 PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
345 PCUT_ASSERT_INT_EQUALS(wnd->id, resp.resize_wnd_id);
346 PCUT_ASSERT_INT_EQUALS(offs.x, resp.resize_offs.x);
347 PCUT_ASSERT_INT_EQUALS(offs.y, resp.resize_offs.y);
348 PCUT_ASSERT_INT_EQUALS(nrect.p0.x, resp.resize_nbound.p0.x);
349 PCUT_ASSERT_INT_EQUALS(nrect.p0.y, resp.resize_nbound.p0.y);
350 PCUT_ASSERT_INT_EQUALS(nrect.p1.x, resp.resize_nbound.p1.x);
351 PCUT_ASSERT_INT_EQUALS(nrect.p1.y, resp.resize_nbound.p1.y);
352
353 display_window_destroy(wnd);
354 display_close(disp);
355 rc = loc_service_unregister(sid);
356 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
357}
358
359/** display_window_resize() with server returning success response works. */
360PCUT_TEST(window_resize_success)
361{
362 errno_t rc;
363 service_id_t sid;
364 display_t *disp = NULL;
365 display_wnd_params_t params;
366 display_window_t *wnd;
367 gfx_coord2_t offs;
368 gfx_rect_t nrect;
369 test_response_t resp;
370
371 async_set_fallback_port_handler(test_display_conn, &resp);
372
373 // FIXME This causes this test to be non-reentrant!
374 rc = loc_server_register(test_display_server);
375 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
376
377 rc = loc_service_register(test_display_svc, &sid);
378 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
379
380 rc = display_open(test_display_svc, &disp);
381 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
382 PCUT_ASSERT_NOT_NULL(disp);
383
384 resp.rc = EOK;
385 display_wnd_params_init(&params);
386 params.rect.p0.x = 0;
387 params.rect.p0.y = 0;
388 params.rect.p0.x = 100;
389 params.rect.p0.y = 100;
390
391 rc = display_window_create(disp, &params, &test_display_wnd_cb,
392 (void *) &resp, &wnd);
393 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
394 PCUT_ASSERT_NOT_NULL(wnd);
395
396 resp.rc = EOK;
397 resp.window_resize_called = false;
398 offs.x = 11;
399 offs.y = 12;
400 nrect.p0.x = 13;
401 nrect.p0.y = 14;
402 nrect.p1.x = 15;
403 nrect.p1.y = 16;
404
405 rc = display_window_resize(wnd, &offs, &nrect);
406 PCUT_ASSERT_TRUE(resp.window_resize_called);
407 PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
408 PCUT_ASSERT_INT_EQUALS(offs.x, resp.resize_offs.x);
409 PCUT_ASSERT_INT_EQUALS(offs.y, resp.resize_offs.y);
410 PCUT_ASSERT_INT_EQUALS(nrect.p0.x, resp.resize_nbound.p0.x);
411 PCUT_ASSERT_INT_EQUALS(nrect.p0.y, resp.resize_nbound.p0.y);
412 PCUT_ASSERT_INT_EQUALS(nrect.p1.x, resp.resize_nbound.p1.x);
413 PCUT_ASSERT_INT_EQUALS(nrect.p1.y, resp.resize_nbound.p1.y);
414
415 display_window_destroy(wnd);
416 display_close(disp);
417 rc = loc_service_unregister(sid);
418 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
419}
420
421/** display_window_get_gc with server returning failure */
422PCUT_TEST(window_get_gc_failure)
423{
424 errno_t rc;
425 service_id_t sid;
426 display_t *disp = NULL;
427 display_wnd_params_t params;
428 display_window_t *wnd;
429 test_response_t resp;
430 gfx_context_t *gc;
431
432 async_set_fallback_port_handler(test_display_conn, &resp);
433
434 // FIXME This causes this test to be non-reentrant!
435 rc = loc_server_register(test_display_server);
436 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
437
438 rc = loc_service_register(test_display_svc, &sid);
439 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
440
441 rc = display_open(test_display_svc, &disp);
442 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
443 PCUT_ASSERT_NOT_NULL(disp);
444
445 wnd = NULL;
446 resp.rc = EOK;
447 display_wnd_params_init(&params);
448 params.rect.p0.x = 0;
449 params.rect.p0.y = 0;
450 params.rect.p0.x = 100;
451 params.rect.p0.y = 100;
452
453 rc = display_window_create(disp, &params, &test_display_wnd_cb,
454 (void *) &resp, &wnd);
455 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
456 PCUT_ASSERT_NOT_NULL(wnd);
457
458 gc = NULL;
459 resp.rc = ENOMEM;
460 rc = display_window_get_gc(wnd, &gc);
461 /* async_connect_me_to() does not return specific error */
462 PCUT_ASSERT_ERRNO_VAL(EIO, rc);
463 PCUT_ASSERT_NULL(gc);
464
465 resp.rc = EOK;
466 rc = display_window_destroy(wnd);
467 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
468
469 display_close(disp);
470 rc = loc_service_unregister(sid);
471 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
472}
473
474/** display_window_get_gc with server returning success */
475PCUT_TEST(window_get_gc_success)
476{
477 errno_t rc;
478 service_id_t sid;
479 display_t *disp = NULL;
480 display_wnd_params_t params;
481 display_window_t *wnd;
482 test_response_t resp;
483 gfx_context_t *gc;
484 gfx_color_t *color;
485
486 async_set_fallback_port_handler(test_display_conn, &resp);
487
488 // FIXME This causes this test to be non-reentrant!
489 rc = loc_server_register(test_display_server);
490 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
491
492 rc = loc_service_register(test_display_svc, &sid);
493 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
494
495 rc = display_open(test_display_svc, &disp);
496 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
497 PCUT_ASSERT_NOT_NULL(disp);
498
499 wnd = NULL;
500 resp.rc = EOK;
501 display_wnd_params_init(&params);
502 params.rect.p0.x = 0;
503 params.rect.p0.y = 0;
504 params.rect.p0.x = 100;
505 params.rect.p0.y = 100;
506
507 rc = display_window_create(disp, &params, &test_display_wnd_cb,
508 (void *) &resp, &wnd);
509 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
510 PCUT_ASSERT_NOT_NULL(wnd);
511
512 gc = NULL;
513 rc = display_window_get_gc(wnd, &gc);
514 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
515 PCUT_ASSERT_NOT_NULL(gc);
516
517 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
518 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
519
520 resp.set_color_called = false;
521 rc = gfx_set_color(gc, color);
522 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
523 PCUT_ASSERT_TRUE(resp.set_color_called);
524
525 gfx_color_delete(color);
526
527 rc = display_window_destroy(wnd);
528 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
529
530 display_close(disp);
531 rc = loc_service_unregister(sid);
532 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
533}
534
535/** Close event can be delivered from server to client callback function */
536PCUT_TEST(close_event_deliver)
537{
538 errno_t rc;
539 service_id_t sid;
540 display_t *disp = NULL;
541 display_wnd_params_t params;
542 display_window_t *wnd;
543 test_response_t resp;
544
545 async_set_fallback_port_handler(test_display_conn, &resp);
546
547 // FIXME This causes this test to be non-reentrant!
548 rc = loc_server_register(test_display_server);
549 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
550
551 rc = loc_service_register(test_display_svc, &sid);
552 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
553
554 rc = display_open(test_display_svc, &disp);
555 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
556 PCUT_ASSERT_NOT_NULL(disp);
557 PCUT_ASSERT_NOT_NULL(resp.srv);
558
559 wnd = NULL;
560 resp.rc = EOK;
561 display_wnd_params_init(&params);
562 params.rect.p0.x = 0;
563 params.rect.p0.y = 0;
564 params.rect.p0.x = 100;
565 params.rect.p0.y = 100;
566
567 rc = display_window_create(disp, &params, &test_display_wnd_cb,
568 (void *) &resp, &wnd);
569 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
570 PCUT_ASSERT_NOT_NULL(wnd);
571
572 resp.event_cnt = 1;
573 resp.event.etype = wev_close;
574 resp.wnd_id = wnd->id;
575 resp.close_event_called = false;
576 fibril_mutex_initialize(&resp.event_lock);
577 fibril_condvar_initialize(&resp.event_cv);
578 display_srv_ev_pending(resp.srv);
579
580 /* Wait for the event handler to be called. */
581 fibril_mutex_lock(&resp.event_lock);
582 while (!resp.close_event_called) {
583 fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
584 }
585 fibril_mutex_unlock(&resp.event_lock);
586
587 /* Verify that the event was delivered correctly */
588 PCUT_ASSERT_EQUALS(resp.event.etype,
589 resp.revent.etype);
590
591 rc = display_window_destroy(wnd);
592 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
593
594 display_close(disp);
595
596 rc = loc_service_unregister(sid);
597 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
598}
599
600/** Focus event can be delivered from server to client callback function */
601PCUT_TEST(focus_event_deliver)
602{
603 errno_t rc;
604 service_id_t sid;
605 display_t *disp = NULL;
606 display_wnd_params_t params;
607 display_window_t *wnd;
608 test_response_t resp;
609
610 async_set_fallback_port_handler(test_display_conn, &resp);
611
612 // FIXME This causes this test to be non-reentrant!
613 rc = loc_server_register(test_display_server);
614 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
615
616 rc = loc_service_register(test_display_svc, &sid);
617 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
618
619 rc = display_open(test_display_svc, &disp);
620 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
621 PCUT_ASSERT_NOT_NULL(disp);
622 PCUT_ASSERT_NOT_NULL(resp.srv);
623
624 wnd = NULL;
625 resp.rc = EOK;
626 display_wnd_params_init(&params);
627 params.rect.p0.x = 0;
628 params.rect.p0.y = 0;
629 params.rect.p0.x = 100;
630 params.rect.p0.y = 100;
631
632 rc = display_window_create(disp, &params, &test_display_wnd_cb,
633 (void *) &resp, &wnd);
634 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
635 PCUT_ASSERT_NOT_NULL(wnd);
636
637 resp.event_cnt = 1;
638 resp.event.etype = wev_focus;
639 resp.wnd_id = wnd->id;
640 resp.focus_event_called = false;
641 fibril_mutex_initialize(&resp.event_lock);
642 fibril_condvar_initialize(&resp.event_cv);
643 display_srv_ev_pending(resp.srv);
644
645 /* Wait for the event handler to be called. */
646 fibril_mutex_lock(&resp.event_lock);
647 while (!resp.focus_event_called) {
648 fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
649 }
650 fibril_mutex_unlock(&resp.event_lock);
651
652 /* Verify that the event was delivered correctly */
653 PCUT_ASSERT_EQUALS(resp.event.etype,
654 resp.revent.etype);
655
656 rc = display_window_destroy(wnd);
657 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
658
659 display_close(disp);
660
661 rc = loc_service_unregister(sid);
662 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
663}
664
665/** Keyboard event can be delivered from server to client callback function */
666PCUT_TEST(kbd_event_deliver)
667{
668 errno_t rc;
669 service_id_t sid;
670 display_t *disp = NULL;
671 display_wnd_params_t params;
672 display_window_t *wnd;
673 test_response_t resp;
674
675 async_set_fallback_port_handler(test_display_conn, &resp);
676
677 // FIXME This causes this test to be non-reentrant!
678 rc = loc_server_register(test_display_server);
679 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
680
681 rc = loc_service_register(test_display_svc, &sid);
682 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
683
684 rc = display_open(test_display_svc, &disp);
685 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
686 PCUT_ASSERT_NOT_NULL(disp);
687 PCUT_ASSERT_NOT_NULL(resp.srv);
688
689 wnd = NULL;
690 resp.rc = EOK;
691 display_wnd_params_init(&params);
692 params.rect.p0.x = 0;
693 params.rect.p0.y = 0;
694 params.rect.p0.x = 100;
695 params.rect.p0.y = 100;
696
697 rc = display_window_create(disp, &params, &test_display_wnd_cb,
698 (void *) &resp, &wnd);
699 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
700 PCUT_ASSERT_NOT_NULL(wnd);
701
702 resp.event_cnt = 1;
703 resp.event.etype = wev_kbd;
704 resp.event.ev.kbd.type = KEY_PRESS;
705 resp.event.ev.kbd.key = KC_ENTER;
706 resp.event.ev.kbd.mods = 0;
707 resp.event.ev.kbd.c = L'\0';
708 resp.wnd_id = wnd->id;
709 resp.kbd_event_called = false;
710 fibril_mutex_initialize(&resp.event_lock);
711 fibril_condvar_initialize(&resp.event_cv);
712 display_srv_ev_pending(resp.srv);
713
714 /* Wait for the event handler to be called. */
715 fibril_mutex_lock(&resp.event_lock);
716 while (!resp.kbd_event_called) {
717 fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
718 }
719 fibril_mutex_unlock(&resp.event_lock);
720
721 /* Verify that the event was delivered correctly */
722 PCUT_ASSERT_EQUALS(resp.event.etype,
723 resp.revent.etype);
724 PCUT_ASSERT_EQUALS(resp.event.ev.kbd.type,
725 resp.revent.ev.kbd.type);
726 PCUT_ASSERT_EQUALS(resp.event.ev.kbd.key,
727 resp.revent.ev.kbd.key);
728 PCUT_ASSERT_EQUALS(resp.event.ev.kbd.mods,
729 resp.revent.ev.kbd.mods);
730 PCUT_ASSERT_EQUALS(resp.event.ev.kbd.c,
731 resp.revent.ev.kbd.c);
732
733 rc = display_window_destroy(wnd);
734 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
735
736 display_close(disp);
737
738 rc = loc_service_unregister(sid);
739 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
740}
741
742/** Position event can be delivered from server to client callback function */
743PCUT_TEST(pos_event_deliver)
744{
745 errno_t rc;
746 service_id_t sid;
747 display_t *disp = NULL;
748 display_wnd_params_t params;
749 display_window_t *wnd;
750 test_response_t resp;
751
752 async_set_fallback_port_handler(test_display_conn, &resp);
753
754 // FIXME This causes this test to be non-reentrant!
755 rc = loc_server_register(test_display_server);
756 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
757
758 rc = loc_service_register(test_display_svc, &sid);
759 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
760
761 rc = display_open(test_display_svc, &disp);
762 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
763 PCUT_ASSERT_NOT_NULL(disp);
764 PCUT_ASSERT_NOT_NULL(resp.srv);
765
766 wnd = NULL;
767 resp.rc = EOK;
768 display_wnd_params_init(&params);
769 params.rect.p0.x = 0;
770 params.rect.p0.y = 0;
771 params.rect.p0.x = 100;
772 params.rect.p0.y = 100;
773
774 rc = display_window_create(disp, &params, &test_display_wnd_cb,
775 (void *) &resp, &wnd);
776 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
777 PCUT_ASSERT_NOT_NULL(wnd);
778
779 resp.event_cnt = 1;
780 resp.event.etype = wev_pos;
781 resp.event.ev.pos.type = POS_PRESS;
782 resp.event.ev.pos.btn_num = 1;
783 resp.event.ev.pos.hpos = 2;
784 resp.event.ev.pos.vpos = 3;
785 resp.wnd_id = wnd->id;
786 resp.pos_event_called = false;
787 fibril_mutex_initialize(&resp.event_lock);
788 fibril_condvar_initialize(&resp.event_cv);
789 display_srv_ev_pending(resp.srv);
790
791 /* Wait for the event handler to be called. */
792 fibril_mutex_lock(&resp.event_lock);
793 while (!resp.pos_event_called) {
794 fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
795 }
796 fibril_mutex_unlock(&resp.event_lock);
797
798 /* Verify that the event was delivered correctly */
799 PCUT_ASSERT_EQUALS(resp.event.etype,
800 resp.revent.etype);
801 PCUT_ASSERT_EQUALS(resp.event.ev.pos.type,
802 resp.revent.ev.pos.type);
803 PCUT_ASSERT_EQUALS(resp.event.ev.pos.btn_num,
804 resp.revent.ev.pos.btn_num);
805 PCUT_ASSERT_EQUALS(resp.event.ev.pos.hpos,
806 resp.revent.ev.pos.hpos);
807 PCUT_ASSERT_EQUALS(resp.event.ev.pos.vpos,
808 resp.revent.ev.pos.vpos);
809
810 rc = display_window_destroy(wnd);
811 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
812
813 display_close(disp);
814
815 rc = loc_service_unregister(sid);
816 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
817}
818
819/** Unfocus event can be delivered from server to client callback function */
820PCUT_TEST(unfocus_event_deliver)
821{
822 errno_t rc;
823 service_id_t sid;
824 display_t *disp = NULL;
825 display_wnd_params_t params;
826 display_window_t *wnd;
827 test_response_t resp;
828
829 async_set_fallback_port_handler(test_display_conn, &resp);
830
831 // FIXME This causes this test to be non-reentrant!
832 rc = loc_server_register(test_display_server);
833 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
834
835 rc = loc_service_register(test_display_svc, &sid);
836 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
837
838 rc = display_open(test_display_svc, &disp);
839 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
840 PCUT_ASSERT_NOT_NULL(disp);
841 PCUT_ASSERT_NOT_NULL(resp.srv);
842
843 wnd = NULL;
844 resp.rc = EOK;
845 display_wnd_params_init(&params);
846 params.rect.p0.x = 0;
847 params.rect.p0.y = 0;
848 params.rect.p0.x = 100;
849 params.rect.p0.y = 100;
850
851 rc = display_window_create(disp, &params, &test_display_wnd_cb,
852 (void *) &resp, &wnd);
853 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
854 PCUT_ASSERT_NOT_NULL(wnd);
855
856 resp.event_cnt = 1;
857 resp.event.etype = wev_unfocus;
858 resp.wnd_id = wnd->id;
859 resp.focus_event_called = false;
860 fibril_mutex_initialize(&resp.event_lock);
861 fibril_condvar_initialize(&resp.event_cv);
862 display_srv_ev_pending(resp.srv);
863
864 /* Wait for the event handler to be called. */
865 fibril_mutex_lock(&resp.event_lock);
866 while (!resp.unfocus_event_called) {
867 fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
868 }
869 fibril_mutex_unlock(&resp.event_lock);
870
871 /* Verify that the event was delivered correctly */
872 PCUT_ASSERT_EQUALS(resp.event.etype,
873 resp.revent.etype);
874
875 rc = display_window_destroy(wnd);
876 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
877
878 display_close(disp);
879
880 rc = loc_service_unregister(sid);
881 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
882}
883
884/** Test display service connection.
885 *
886 * This is very similar to connection handler in the display server.
887 * XXX This should be folded into display_srv, if possible
888 */
889static void test_display_conn(ipc_call_t *icall, void *arg)
890{
891 test_response_t *resp = (test_response_t *) arg;
892 display_srv_t srv;
893 sysarg_t wnd_id;
894 sysarg_t svc_id;
895 gfx_context_t *gc;
896 errno_t rc;
897
898 svc_id = ipc_get_arg2(icall);
899 wnd_id = ipc_get_arg3(icall);
900
901 if (svc_id != 0) {
902 /* Set up protocol structure */
903 display_srv_initialize(&srv);
904 srv.ops = &test_display_srv_ops;
905 srv.arg = arg;
906 resp->srv = &srv;
907
908 /* Handle connection */
909 display_conn(icall, &srv);
910
911 resp->srv = NULL;
912 } else {
913 (void) wnd_id;
914
915 if (resp->rc != EOK) {
916 async_answer_0(icall, resp->rc);
917 return;
918 }
919
920 rc = gfx_context_new(&test_gc_ops, arg, &gc);
921 if (rc != EOK) {
922 async_answer_0(icall, ENOMEM);
923 return;
924 }
925
926 /* Window GC connection */
927 gc_conn(icall, gc);
928 }
929}
930
931static void test_close_event(void *arg)
932{
933 test_response_t *resp = (test_response_t *) arg;
934
935 resp->revent.etype = wev_close;
936
937 fibril_mutex_lock(&resp->event_lock);
938 resp->close_event_called = true;
939 fibril_condvar_broadcast(&resp->event_cv);
940 fibril_mutex_unlock(&resp->event_lock);
941}
942
943static void test_focus_event(void *arg)
944{
945 test_response_t *resp = (test_response_t *) arg;
946
947 resp->revent.etype = wev_focus;
948
949 fibril_mutex_lock(&resp->event_lock);
950 resp->focus_event_called = true;
951 fibril_condvar_broadcast(&resp->event_cv);
952 fibril_mutex_unlock(&resp->event_lock);
953}
954
955static void test_kbd_event(void *arg, kbd_event_t *event)
956{
957 test_response_t *resp = (test_response_t *) arg;
958
959 resp->revent.etype = wev_kbd;
960 resp->revent.ev.kbd = *event;
961
962 fibril_mutex_lock(&resp->event_lock);
963 resp->kbd_event_called = true;
964 fibril_condvar_broadcast(&resp->event_cv);
965 fibril_mutex_unlock(&resp->event_lock);
966}
967
968static void test_pos_event(void *arg, pos_event_t *event)
969{
970 test_response_t *resp = (test_response_t *) arg;
971
972 resp->revent.etype = wev_pos;
973 resp->revent.ev.pos = *event;
974
975 fibril_mutex_lock(&resp->event_lock);
976 resp->pos_event_called = true;
977 fibril_condvar_broadcast(&resp->event_cv);
978 fibril_mutex_unlock(&resp->event_lock);
979}
980
981static void test_unfocus_event(void *arg)
982{
983 test_response_t *resp = (test_response_t *) arg;
984
985 resp->revent.etype = wev_unfocus;
986
987 fibril_mutex_lock(&resp->event_lock);
988 resp->unfocus_event_called = true;
989 fibril_condvar_broadcast(&resp->event_cv);
990 fibril_mutex_unlock(&resp->event_lock);
991}
992
993static errno_t test_window_create(void *arg, display_wnd_params_t *params,
994 sysarg_t *rwnd_id)
995{
996 test_response_t *resp = (test_response_t *) arg;
997
998 resp->window_create_called = true;
999 resp->create_rect = params->rect;
1000 if (resp->rc == EOK)
1001 *rwnd_id = resp->wnd_id;
1002
1003 return resp->rc;
1004}
1005
1006static errno_t test_window_destroy(void *arg, sysarg_t wnd_id)
1007{
1008 test_response_t *resp = (test_response_t *) arg;
1009
1010 resp->window_destroy_called = true;
1011 resp->destroy_wnd_id = wnd_id;
1012 return resp->rc;
1013}
1014
1015static errno_t test_window_resize(void *arg, sysarg_t wnd_id,
1016 gfx_coord2_t *offs, gfx_rect_t *nrect)
1017{
1018 test_response_t *resp = (test_response_t *) arg;
1019
1020 resp->window_resize_called = true;
1021 resp->resize_wnd_id = wnd_id;
1022 resp->resize_offs = *offs;
1023 resp->resize_nbound = *nrect;
1024 return resp->rc;
1025}
1026
1027static errno_t test_get_event(void *arg, sysarg_t *wnd_id, display_wnd_ev_t *event)
1028{
1029 test_response_t *resp = (test_response_t *) arg;
1030
1031 resp->get_event_called = true;
1032 if (resp->event_cnt > 0) {
1033 --resp->event_cnt;
1034 *wnd_id = resp->wnd_id;
1035 *event = resp->event;
1036 return EOK;
1037 }
1038
1039 return ENOENT;
1040}
1041
1042static errno_t test_gc_set_color(void *arg, gfx_color_t *color)
1043{
1044 test_response_t *resp = (test_response_t *) arg;
1045
1046 resp->set_color_called = true;
1047 return resp->rc;
1048}
1049
1050PCUT_EXPORT(display);
Note: See TracBrowser for help on using the repository browser.