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

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

Store dimensions in display server window structure

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