source: mainline/uspace/lib/display/test/display.c@ 0e6e77f

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

Window resize by client request

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