source: mainline/uspace/srv/hid/display/test/display.c@ 0da03df

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

Clean up debug messages and logging

  • Property mode set to 100644
File size: 10.2 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 <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(display);
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/** Display creation and destruction. */
56PCUT_TEST(display_create_destroy)
57{
58 ds_display_t *disp;
59 errno_t rc;
60
61 rc = ds_display_create(NULL, df_none, &disp);
62 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
63
64 ds_display_destroy(disp);
65}
66
67/** Basic client operation. */
68PCUT_TEST(display_client)
69{
70 ds_display_t *disp;
71 ds_client_t *client;
72 ds_client_t *c0, *c1;
73 errno_t rc;
74
75 rc = ds_display_create(NULL, df_none, &disp);
76 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
77
78 rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
79 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
80
81 c0 = ds_display_first_client(disp);
82 PCUT_ASSERT_EQUALS(c0, client);
83
84 c1 = ds_display_next_client(c0);
85 PCUT_ASSERT_NULL(c1);
86
87 ds_client_destroy(client);
88 ds_display_destroy(disp);
89}
90
91/** Test ds_display_find_window(). */
92PCUT_TEST(display_find_window)
93{
94 ds_display_t *disp;
95 ds_client_t *client;
96 ds_window_t *w0;
97 ds_window_t *w1;
98 ds_window_t *wnd;
99 display_wnd_params_t params;
100 errno_t rc;
101
102 rc = ds_display_create(NULL, df_none, &disp);
103 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
104
105 rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
106 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
107
108 display_wnd_params_init(&params);
109 params.rect.p0.x = params.rect.p0.y = 0;
110 params.rect.p1.x = params.rect.p1.y = 1;
111
112 rc = ds_window_create(client, &params, &w1);
113 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
114
115 rc = ds_window_create(client, &params, &w0);
116 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
117
118 wnd = ds_display_first_window(disp);
119 PCUT_ASSERT_EQUALS(w0, wnd);
120
121 wnd = ds_display_next_window(wnd);
122 PCUT_ASSERT_EQUALS(w1, wnd);
123
124 wnd = ds_display_next_window(wnd);
125 PCUT_ASSERT_NULL(wnd);
126
127 wnd = ds_display_last_window(disp);
128 PCUT_ASSERT_EQUALS(w1, wnd);
129
130 wnd = ds_display_prev_window(wnd);
131 PCUT_ASSERT_EQUALS(w0, wnd);
132
133 wnd = ds_display_prev_window(wnd);
134 PCUT_ASSERT_NULL(wnd);
135
136 wnd = ds_display_find_window(disp, w0->id);
137 PCUT_ASSERT_EQUALS(w0, wnd);
138
139 wnd = ds_display_find_window(disp, w1->id);
140 PCUT_ASSERT_EQUALS(w1, wnd);
141
142 wnd = ds_display_find_window(disp, 0);
143 PCUT_ASSERT_NULL(wnd);
144
145 wnd = ds_display_find_window(disp, w0->id + 1);
146 PCUT_ASSERT_NULL(wnd);
147
148 ds_window_destroy(w0);
149 ds_window_destroy(w1);
150 ds_client_destroy(client);
151 ds_display_destroy(disp);
152}
153
154/** Test ds_display_window_by_pos(). */
155PCUT_TEST(display_window_by_pos)
156{
157 ds_display_t *disp;
158 ds_client_t *client;
159 ds_window_t *w0;
160 ds_window_t *w1;
161 ds_window_t *wnd;
162 display_wnd_params_t params;
163 gfx_coord2_t pos;
164 errno_t rc;
165
166 rc = ds_display_create(NULL, df_none, &disp);
167 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
168
169 rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
170 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
171
172 display_wnd_params_init(&params);
173 params.rect.p0.x = params.rect.p0.y = 0;
174 params.rect.p1.x = params.rect.p1.y = 100;
175
176 rc = ds_window_create(client, &params, &w0);
177 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
178
179 rc = ds_window_create(client, &params, &w1);
180 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
181
182 w0->dpos.x = 10;
183 w0->dpos.y = 10;
184
185 w1->dpos.x = 400;
186 w1->dpos.y = 400;
187
188 pos.x = 10;
189 pos.y = 10;
190 wnd = ds_display_window_by_pos(disp, &pos);
191 PCUT_ASSERT_EQUALS(w0, wnd);
192
193 pos.x = 400;
194 pos.y = 400;
195 wnd = ds_display_window_by_pos(disp, &pos);
196 PCUT_ASSERT_EQUALS(w1, wnd);
197
198 ds_window_destroy(w0);
199 ds_window_destroy(w1);
200 ds_client_destroy(client);
201 ds_display_destroy(disp);
202}
203
204/** Basic seat operation. */
205PCUT_TEST(display_seat)
206{
207 ds_display_t *disp;
208 ds_seat_t *seat;
209 ds_seat_t *s0, *s1;
210 errno_t rc;
211
212 rc = ds_display_create(NULL, df_none, &disp);
213 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
214
215 rc = ds_seat_create(disp, &seat);
216 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
217
218 s0 = ds_display_first_seat(disp);
219 PCUT_ASSERT_EQUALS(s0, seat);
220
221 s1 = ds_display_next_seat(s0);
222 PCUT_ASSERT_NULL(s1);
223
224 ds_seat_destroy(seat);
225 ds_display_destroy(disp);
226}
227
228/** Test ds_display_post_kbd_event() delivers event to client callback.
229 */
230PCUT_TEST(display_post_kbd_event)
231{
232 ds_display_t *disp;
233 ds_seat_t *seat;
234 ds_client_t *client;
235 ds_window_t *wnd;
236 display_wnd_params_t params;
237 kbd_event_t event;
238 bool called_cb = false;
239 errno_t rc;
240
241 rc = ds_display_create(NULL, df_none, &disp);
242 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
243
244 rc = ds_seat_create(disp, &seat);
245 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
246
247 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
248 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
249
250 display_wnd_params_init(&params);
251 params.rect.p0.x = params.rect.p0.y = 0;
252 params.rect.p1.x = params.rect.p1.y = 1;
253
254 rc = ds_window_create(client, &params, &wnd);
255 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
256
257 ds_seat_set_focus(seat, wnd);
258
259 event.type = KEY_PRESS;
260 event.key = KC_ENTER;
261 event.mods = 0;
262 event.c = L'\0';
263
264 called_cb = false;
265
266 rc = ds_display_post_kbd_event(disp, &event);
267 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
268 PCUT_ASSERT_TRUE(called_cb);
269
270 ds_window_destroy(wnd);
271 ds_client_destroy(client);
272 ds_seat_destroy(seat);
273 ds_display_destroy(disp);
274}
275
276/** Test ds_display_post_kbd_event() with Alt-Tab switches focus.
277 */
278PCUT_TEST(display_post_kbd_event_alt_tab)
279{
280 ds_display_t *disp;
281 ds_seat_t *seat;
282 ds_client_t *client;
283 ds_window_t *w0, *w1;
284 display_wnd_params_t params;
285 kbd_event_t event;
286 bool called_cb = false;
287 errno_t rc;
288
289 rc = ds_display_create(NULL, df_none, &disp);
290 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
291
292 rc = ds_seat_create(disp, &seat);
293 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
294
295 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
296 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
297
298 display_wnd_params_init(&params);
299 params.rect.p0.x = params.rect.p0.y = 0;
300 params.rect.p1.x = params.rect.p1.y = 1;
301
302 rc = ds_window_create(client, &params, &w0);
303 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
304
305 rc = ds_window_create(client, &params, &w1);
306 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
307
308 ds_seat_set_focus(seat, w0);
309
310 event.type = KEY_PRESS;
311 event.key = KC_TAB;
312 event.mods = KM_ALT;
313 event.c = L'\0';
314
315 called_cb = false;
316
317 rc = ds_display_post_kbd_event(disp, &event);
318 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
319
320 /* Got gocus/unfocus events */
321 PCUT_ASSERT_TRUE(called_cb);
322
323 /* Next window should be focused */
324 PCUT_ASSERT_EQUALS(w1, seat->focus);
325
326 called_cb = false;
327
328 rc = ds_display_post_kbd_event(disp, &event);
329 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
330
331 /* Got gocus/unfocus events */
332 PCUT_ASSERT_TRUE(called_cb);
333
334 /* Focus should be back to the first window */
335 PCUT_ASSERT_EQUALS(w0, seat->focus);
336
337 ds_window_destroy(w0);
338 ds_window_destroy(w1);
339 ds_client_destroy(client);
340 ds_seat_destroy(seat);
341 ds_display_destroy(disp);
342}
343
344/** Test ds_display_post_ptd_event() with click on window switches focus
345 */
346PCUT_TEST(display_post_ptd_event_wnd_switch)
347{
348 ds_display_t *disp;
349 ds_seat_t *seat;
350 ds_client_t *client;
351 ds_window_t *w0, *w1;
352 display_wnd_params_t params;
353 ptd_event_t event;
354 bool called_cb = false;
355 errno_t rc;
356
357 rc = ds_display_create(NULL, df_none, &disp);
358 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
359
360 rc = ds_seat_create(disp, &seat);
361 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
362
363 rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
364 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
365
366 /*
367 * For PTD_MOVE to work we need to set display dimensions (as pointer
368 * move is clipped to the display rectangle. Here we do it directly
369 * instead of adding a display device.
370 */
371 disp->rect.p0.x = 0;
372 disp->rect.p0.y = 0;
373 disp->rect.p1.x = 500;
374 disp->rect.p1.y = 500;
375
376 display_wnd_params_init(&params);
377 params.rect.p0.x = params.rect.p0.y = 0;
378 params.rect.p1.x = params.rect.p1.y = 1;
379
380 rc = ds_window_create(client, &params, &w0);
381 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
382
383 rc = ds_window_create(client, &params, &w1);
384 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
385
386 w0->dpos.x = 10;
387 w0->dpos.y = 10;
388
389 w1->dpos.x = 400;
390 w1->dpos.y = 400;
391
392 ds_seat_set_focus(seat, w0);
393
394 event.type = PTD_MOVE;
395 event.dmove.x = 400;
396 event.dmove.y = 400;
397 rc = ds_display_post_ptd_event(disp, &event);
398 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
399
400 event.type = PTD_PRESS;
401 event.btn_num = 1;
402 rc = ds_display_post_ptd_event(disp, &event);
403 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
404
405 PCUT_ASSERT_EQUALS(w1, seat->focus);
406
407 event.type = PTD_RELEASE;
408 event.btn_num = 1;
409 rc = ds_display_post_ptd_event(disp, &event);
410 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
411
412 event.type = PTD_MOVE;
413 event.dmove.x = -400 + 10;
414 event.dmove.y = -400 + 10;
415 rc = ds_display_post_ptd_event(disp, &event);
416 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
417
418 event.type = PTD_PRESS;
419 event.btn_num = 1;
420 rc = ds_display_post_ptd_event(disp, &event);
421 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
422
423 PCUT_ASSERT_EQUALS(w0, seat->focus);
424
425 ds_window_destroy(w0);
426 ds_window_destroy(w1);
427 ds_client_destroy(client);
428 ds_seat_destroy(seat);
429 ds_display_destroy(disp);
430}
431
432PCUT_EXPORT(display);
Note: See TracBrowser for help on using the repository browser.