source: mainline/uspace/lib/ui/test/wdecor.c@ b0ae23f

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

Change the correct pointer's shape when resizing window

The request to resize a window originates from the client. The display
server forces the cursor to a double-arrow shape regardless of whether
it is over the window or not, until the resize is done. This is to
make sure the cursor keeps that shape even if it moves outside of
the current boundaries of the window. With multiple pointers we need
to know which one to change. This is done by passing the pos_id from
button press event that starts the resize all the way to
ds_window_start_resize(). Then it needs to be stored in the window
structure for use when it is time to restore the cursor.

  • Property mode set to 100644
File size: 28.0 KB
Line 
1/*
2 * Copyright (c) 2023 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 <gfx/context.h>
30#include <gfx/coord.h>
31#include <mem.h>
32#include <pcut/pcut.h>
33#include <stdbool.h>
34#include <ui/pbutton.h>
35#include <ui/resource.h>
36#include <ui/wdecor.h>
37#include "../private/wdecor.h"
38
39PCUT_INIT;
40
41PCUT_TEST_SUITE(wdecor);
42
43static errno_t testgc_set_clip_rect(void *, gfx_rect_t *);
44static errno_t testgc_set_color(void *, gfx_color_t *);
45static errno_t testgc_fill_rect(void *, gfx_rect_t *);
46static errno_t testgc_update(void *);
47static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
48 gfx_bitmap_alloc_t *, void **);
49static errno_t testgc_bitmap_destroy(void *);
50static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
51static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
52
53static gfx_context_ops_t ops = {
54 .set_clip_rect = testgc_set_clip_rect,
55 .set_color = testgc_set_color,
56 .fill_rect = testgc_fill_rect,
57 .update = testgc_update,
58 .bitmap_create = testgc_bitmap_create,
59 .bitmap_destroy = testgc_bitmap_destroy,
60 .bitmap_render = testgc_bitmap_render,
61 .bitmap_get_alloc = testgc_bitmap_get_alloc
62};
63
64static void test_wdecor_minimize(ui_wdecor_t *, void *);
65static void test_wdecor_maximize(ui_wdecor_t *, void *);
66static void test_wdecor_unmaximize(ui_wdecor_t *, void *);
67static void test_wdecor_close(ui_wdecor_t *, void *);
68static void test_wdecor_move(ui_wdecor_t *, void *, gfx_coord2_t *);
69static void test_wdecor_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
70 gfx_coord2_t *, sysarg_t);
71static void test_wdecor_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
72
73static ui_wdecor_cb_t test_wdecor_cb = {
74 .minimize = test_wdecor_minimize,
75 .maximize = test_wdecor_maximize,
76 .unmaximize = test_wdecor_unmaximize,
77 .close = test_wdecor_close,
78 .move = test_wdecor_move,
79 .resize = test_wdecor_resize,
80 .set_cursor = test_wdecor_set_cursor
81};
82
83static ui_wdecor_cb_t dummy_wdecor_cb = {
84};
85
86typedef struct {
87 bool bm_created;
88 bool bm_destroyed;
89 gfx_bitmap_params_t bm_params;
90 void *bm_pixels;
91 gfx_rect_t bm_srect;
92 gfx_coord2_t bm_offs;
93 bool bm_rendered;
94 bool bm_got_alloc;
95} test_gc_t;
96
97typedef struct {
98 test_gc_t *tgc;
99 gfx_bitmap_alloc_t alloc;
100 bool myalloc;
101} testgc_bitmap_t;
102
103typedef struct {
104 bool minimize;
105 bool maximize;
106 bool unmaximize;
107 bool close;
108 bool move;
109 gfx_coord2_t pos;
110 sysarg_t pos_id;
111 bool resize;
112 ui_wdecor_rsztype_t rsztype;
113 bool set_cursor;
114 ui_stock_cursor_t cursor;
115} test_cb_resp_t;
116
117/** Create and destroy button */
118PCUT_TEST(create_destroy)
119{
120 ui_wdecor_t *wdecor = NULL;
121 errno_t rc;
122
123 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
124 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
125 PCUT_ASSERT_NOT_NULL(wdecor);
126
127 ui_wdecor_destroy(wdecor);
128}
129
130/** ui_wdecor_destroy() can take NULL argument (no-op) */
131PCUT_TEST(destroy_null)
132{
133 ui_wdecor_destroy(NULL);
134}
135
136/** Set window decoration rectangle sets internal field */
137PCUT_TEST(set_rect)
138{
139 ui_wdecor_t *wdecor;
140 gfx_rect_t rect;
141 errno_t rc;
142
143 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
144 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
145
146 rect.p0.x = 1;
147 rect.p0.y = 2;
148 rect.p1.x = 3;
149 rect.p1.y = 4;
150
151 ui_wdecor_set_rect(wdecor, &rect);
152 PCUT_ASSERT_INT_EQUALS(rect.p0.x, wdecor->rect.p0.x);
153 PCUT_ASSERT_INT_EQUALS(rect.p0.y, wdecor->rect.p0.y);
154 PCUT_ASSERT_INT_EQUALS(rect.p1.x, wdecor->rect.p1.x);
155 PCUT_ASSERT_INT_EQUALS(rect.p1.y, wdecor->rect.p1.y);
156
157 ui_wdecor_destroy(wdecor);
158}
159
160/** Set window decoration active sets internal field */
161PCUT_TEST(set_active)
162{
163 ui_wdecor_t *wdecor;
164 errno_t rc;
165
166 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
167 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
168
169 PCUT_ASSERT_TRUE(wdecor->active);
170
171 ui_wdecor_set_active(wdecor, false);
172 PCUT_ASSERT_FALSE(wdecor->active);
173
174 ui_wdecor_set_active(wdecor, true);
175 PCUT_ASSERT_TRUE(wdecor->active);
176
177 ui_wdecor_destroy(wdecor);
178}
179
180/** Set window decoration maximized sets internal field */
181PCUT_TEST(set_maximized)
182{
183 ui_wdecor_t *wdecor;
184 errno_t rc;
185
186 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
187 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
188
189 PCUT_ASSERT_TRUE(wdecor->active);
190
191 ui_wdecor_set_maximized(wdecor, false);
192 PCUT_ASSERT_FALSE(wdecor->maximized);
193
194 ui_wdecor_set_maximized(wdecor, true);
195 PCUT_ASSERT_TRUE(wdecor->maximized);
196
197 ui_wdecor_destroy(wdecor);
198}
199
200/** Paint button */
201PCUT_TEST(paint)
202{
203 errno_t rc;
204 gfx_context_t *gc = NULL;
205 test_gc_t tgc;
206 ui_resource_t *resource = NULL;
207 ui_wdecor_t *wdecor;
208
209 memset(&tgc, 0, sizeof(tgc));
210 rc = gfx_context_new(&ops, &tgc, &gc);
211 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
212
213 rc = ui_resource_create(gc, false, &resource);
214 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
215 PCUT_ASSERT_NOT_NULL(resource);
216
217 rc = ui_wdecor_create(resource, "Hello", ui_wds_none, &wdecor);
218 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
219
220 rc = ui_wdecor_paint(wdecor);
221 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
222
223 ui_wdecor_destroy(wdecor);
224 ui_resource_destroy(resource);
225
226 rc = gfx_context_delete(gc);
227 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
228}
229
230/** Test ui_wdecor_minimize() */
231PCUT_TEST(minimize)
232{
233 errno_t rc;
234 ui_wdecor_t *wdecor;
235 test_cb_resp_t resp;
236
237 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
238 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
239
240 /* Minimize callback with no callbacks set */
241 ui_wdecor_minimize(wdecor);
242
243 /* Minimize callback with minimize callback not implemented */
244 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
245 ui_wdecor_minimize(wdecor);
246
247 /* Minimize callback with real callback set */
248 resp.minimize = false;
249 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
250 ui_wdecor_minimize(wdecor);
251 PCUT_ASSERT_TRUE(resp.minimize);
252
253 ui_wdecor_destroy(wdecor);
254}
255
256/** Test ui_wdecor_maximize() */
257PCUT_TEST(maximize)
258{
259 errno_t rc;
260 ui_wdecor_t *wdecor;
261 test_cb_resp_t resp;
262
263 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
264 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
265
266 /* Maximize callback with no callbacks set */
267 ui_wdecor_maximize(wdecor);
268
269 /* Maxmimize callback with maximize callback not implemented */
270 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
271 ui_wdecor_maximize(wdecor);
272
273 /* Maximize callback with real callback set */
274 resp.maximize = false;
275 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
276 ui_wdecor_maximize(wdecor);
277 PCUT_ASSERT_TRUE(resp.maximize);
278
279 ui_wdecor_destroy(wdecor);
280}
281
282/** Test ui_wdecor_unmaximize() */
283PCUT_TEST(unmaximize)
284{
285 errno_t rc;
286 ui_wdecor_t *wdecor;
287 test_cb_resp_t resp;
288
289 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
290 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
291
292 /* Unmaximize callback with no callbacks set */
293 ui_wdecor_unmaximize(wdecor);
294
295 /* Unmaximize callback with unmaximize callback not implemented */
296 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
297 ui_wdecor_unmaximize(wdecor);
298
299 /* Unmaximize callback with real callback set */
300 resp.unmaximize = false;
301 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
302 ui_wdecor_unmaximize(wdecor);
303 PCUT_ASSERT_TRUE(resp.unmaximize);
304
305 ui_wdecor_destroy(wdecor);
306}
307
308/** Test ui_wdecor_close() */
309PCUT_TEST(close)
310{
311 errno_t rc;
312 ui_wdecor_t *wdecor;
313 test_cb_resp_t resp;
314
315 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
316 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
317
318 /* Close callback with no callbacks set */
319 ui_wdecor_close(wdecor);
320
321 /* Close callback with close callback not implemented */
322 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
323 ui_wdecor_close(wdecor);
324
325 /* Close callback with real callback set */
326 resp.close = false;
327 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
328 ui_wdecor_close(wdecor);
329 PCUT_ASSERT_TRUE(resp.close);
330
331 ui_wdecor_destroy(wdecor);
332}
333
334/** Test ui_wdecor_move() */
335PCUT_TEST(move)
336{
337 errno_t rc;
338 ui_wdecor_t *wdecor;
339 test_cb_resp_t resp;
340 gfx_coord2_t pos;
341
342 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
343 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
344
345 pos.x = 3;
346 pos.y = 4;
347
348 /* Move callback with no callbacks set */
349 ui_wdecor_move(wdecor, &pos);
350
351 /* Move callback with move callback not implemented */
352 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
353 ui_wdecor_move(wdecor, &pos);
354
355 /* Move callback with real callback set */
356 resp.move = false;
357 resp.pos.x = 0;
358 resp.pos.y = 0;
359 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
360 ui_wdecor_move(wdecor, &pos);
361 PCUT_ASSERT_TRUE(resp.move);
362 PCUT_ASSERT_INT_EQUALS(pos.x, resp.pos.x);
363 PCUT_ASSERT_INT_EQUALS(pos.y, resp.pos.y);
364
365 ui_wdecor_destroy(wdecor);
366}
367
368/** Test ui_wdecor_resize() */
369PCUT_TEST(resize)
370{
371 errno_t rc;
372 ui_wdecor_t *wdecor;
373 test_cb_resp_t resp;
374 ui_wdecor_rsztype_t rsztype;
375 gfx_coord2_t pos;
376 sysarg_t pos_id;
377
378 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
379 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
380
381 rsztype = ui_wr_bottom;
382 pos.x = 3;
383 pos.y = 4;
384 pos_id = 5;
385
386 /* Resize callback with no callbacks set */
387 ui_wdecor_resize(wdecor, rsztype, &pos, pos_id);
388
389 /* Resize callback with move callback not implemented */
390 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
391 ui_wdecor_resize(wdecor, rsztype, &pos, pos_id);
392
393 /* Resize callback with real callback set */
394 resp.resize = false;
395 resp.rsztype = ui_wr_none;
396 resp.pos.x = 0;
397 resp.pos.y = 0;
398 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
399 ui_wdecor_resize(wdecor, rsztype, &pos, pos_id);
400 PCUT_ASSERT_TRUE(resp.resize);
401 PCUT_ASSERT_INT_EQUALS(rsztype, resp.rsztype);
402 PCUT_ASSERT_INT_EQUALS(pos.x, resp.pos.x);
403 PCUT_ASSERT_INT_EQUALS(pos.y, resp.pos.y);
404 PCUT_ASSERT_INT_EQUALS(pos_id, resp.pos_id);
405
406 ui_wdecor_destroy(wdecor);
407}
408
409/** Test ui_wdecor_set_cursor() */
410PCUT_TEST(set_cursor)
411{
412 errno_t rc;
413 ui_wdecor_t *wdecor;
414 test_cb_resp_t resp;
415 ui_stock_cursor_t cursor;
416
417 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
418 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
419
420 cursor = ui_curs_size_uldr;
421
422 /* Set cursor callback with no callbacks set */
423 ui_wdecor_set_cursor(wdecor, cursor);
424
425 /* Set cursor callback with move callback not implemented */
426 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
427 ui_wdecor_set_cursor(wdecor, cursor);
428
429 /* Set cursor callback with real callback set */
430 resp.set_cursor = false;
431 resp.cursor = ui_curs_arrow;
432 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
433 ui_wdecor_set_cursor(wdecor, cursor);
434 PCUT_ASSERT_TRUE(resp.set_cursor);
435 PCUT_ASSERT_INT_EQUALS(cursor, resp.cursor);
436
437 ui_wdecor_destroy(wdecor);
438}
439
440/** Clicking the close button generates close callback */
441PCUT_TEST(close_btn_clicked)
442{
443 ui_wdecor_t *wdecor;
444 gfx_rect_t rect;
445 test_cb_resp_t resp;
446 errno_t rc;
447
448 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
449 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
450
451 rect.p0.x = 10;
452 rect.p0.y = 20;
453 rect.p1.x = 100;
454 rect.p1.y = 200;
455
456 ui_wdecor_set_rect(wdecor, &rect);
457
458 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, (void *) &resp);
459
460 resp.close = false;
461
462 ui_pbutton_clicked(wdecor->btn_close);
463 PCUT_ASSERT_TRUE(resp.close);
464
465 ui_wdecor_destroy(wdecor);
466}
467
468/** Button press on title bar generates move callback */
469PCUT_TEST(pos_event_move)
470{
471 errno_t rc;
472 gfx_rect_t rect;
473 pos_event_t event;
474 gfx_context_t *gc = NULL;
475 test_gc_t tgc;
476 test_cb_resp_t resp;
477 ui_resource_t *resource = NULL;
478 ui_wdecor_t *wdecor;
479
480 memset(&tgc, 0, sizeof(tgc));
481 rc = gfx_context_new(&ops, &tgc, &gc);
482 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
483
484 rc = ui_resource_create(gc, false, &resource);
485 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
486 PCUT_ASSERT_NOT_NULL(resource);
487
488 rc = ui_wdecor_create(resource, "Hello", ui_wds_decorated, &wdecor);
489 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
490
491 rect.p0.x = 10;
492 rect.p0.y = 20;
493 rect.p1.x = 100;
494 rect.p1.y = 200;
495
496 ui_wdecor_set_rect(wdecor, &rect);
497
498 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, (void *) &resp);
499
500 resp.move = false;
501 resp.pos.x = 0;
502 resp.pos.y = 0;
503
504 event.type = POS_PRESS;
505 event.hpos = 50;
506 event.vpos = 25;
507 ui_wdecor_pos_event(wdecor, &event);
508
509 PCUT_ASSERT_TRUE(resp.move);
510 PCUT_ASSERT_INT_EQUALS(event.hpos, resp.pos.x);
511 PCUT_ASSERT_INT_EQUALS(event.vpos, resp.pos.y);
512
513 ui_wdecor_destroy(wdecor);
514 ui_resource_destroy(resource);
515
516 rc = gfx_context_delete(gc);
517 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
518}
519
520/** ui_wdecor_get_geom() with ui_wds_none produces the correct geometry */
521PCUT_TEST(get_geom_none)
522{
523 gfx_context_t *gc = NULL;
524 test_gc_t tgc;
525 ui_resource_t *resource = NULL;
526 ui_wdecor_t *wdecor;
527 gfx_rect_t rect;
528 ui_wdecor_geom_t geom;
529 errno_t rc;
530
531 memset(&tgc, 0, sizeof(tgc));
532 rc = gfx_context_new(&ops, &tgc, &gc);
533 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
534
535 rc = ui_resource_create(gc, false, &resource);
536 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
537 PCUT_ASSERT_NOT_NULL(resource);
538
539 rc = ui_wdecor_create(resource, "Hello", ui_wds_none, &wdecor);
540 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
541
542 rect.p0.x = 10;
543 rect.p0.y = 20;
544 rect.p1.x = 100;
545 rect.p1.y = 200;
546
547 ui_wdecor_set_rect(wdecor, &rect);
548 ui_wdecor_get_geom(wdecor, &geom);
549
550 PCUT_ASSERT_INT_EQUALS(10, geom.interior_rect.p0.x);
551 PCUT_ASSERT_INT_EQUALS(20, geom.interior_rect.p0.y);
552 PCUT_ASSERT_INT_EQUALS(100, geom.interior_rect.p1.x);
553 PCUT_ASSERT_INT_EQUALS(200, geom.interior_rect.p1.y);
554
555 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.x);
556 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.y);
557 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.x);
558 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.y);
559
560 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.x);
561 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.y);
562 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.x);
563 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.y);
564
565 PCUT_ASSERT_INT_EQUALS(10, geom.app_area_rect.p0.x);
566 PCUT_ASSERT_INT_EQUALS(20, geom.app_area_rect.p0.y);
567 PCUT_ASSERT_INT_EQUALS(100, geom.app_area_rect.p1.x);
568 PCUT_ASSERT_INT_EQUALS(200, geom.app_area_rect.p1.y);
569
570 ui_wdecor_destroy(wdecor);
571 ui_resource_destroy(resource);
572
573 rc = gfx_context_delete(gc);
574 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
575}
576
577/** ui_wdecor_get_geom() with ui_wds_frame produces the correct geometry */
578PCUT_TEST(get_geom_frame)
579{
580 gfx_context_t *gc = NULL;
581 test_gc_t tgc;
582 ui_resource_t *resource = NULL;
583 ui_wdecor_t *wdecor;
584 gfx_rect_t rect;
585 ui_wdecor_geom_t geom;
586 errno_t rc;
587
588 memset(&tgc, 0, sizeof(tgc));
589 rc = gfx_context_new(&ops, &tgc, &gc);
590 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
591
592 rc = ui_resource_create(gc, false, &resource);
593 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
594 PCUT_ASSERT_NOT_NULL(resource);
595
596 rc = ui_wdecor_create(resource, "Hello", ui_wds_frame, &wdecor);
597 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
598
599 rect.p0.x = 10;
600 rect.p0.y = 20;
601 rect.p1.x = 100;
602 rect.p1.y = 200;
603
604 ui_wdecor_set_rect(wdecor, &rect);
605 ui_wdecor_get_geom(wdecor, &geom);
606
607 PCUT_ASSERT_INT_EQUALS(14, geom.interior_rect.p0.x);
608 PCUT_ASSERT_INT_EQUALS(24, geom.interior_rect.p0.y);
609 PCUT_ASSERT_INT_EQUALS(96, geom.interior_rect.p1.x);
610 PCUT_ASSERT_INT_EQUALS(196, geom.interior_rect.p1.y);
611
612 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.x);
613 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.y);
614 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.x);
615 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.y);
616
617 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.x);
618 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.y);
619 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.x);
620 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.y);
621
622 PCUT_ASSERT_INT_EQUALS(14, geom.app_area_rect.p0.x);
623 PCUT_ASSERT_INT_EQUALS(24, geom.app_area_rect.p0.y);
624 PCUT_ASSERT_INT_EQUALS(96, geom.app_area_rect.p1.x);
625 PCUT_ASSERT_INT_EQUALS(196, geom.app_area_rect.p1.y);
626
627 ui_wdecor_destroy(wdecor);
628 ui_resource_destroy(resource);
629
630 rc = gfx_context_delete(gc);
631 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
632}
633
634/** ui_wdecor_get_geom() with ui_wds_frame | ui_wds_titlebar */
635PCUT_TEST(get_geom_frame_titlebar)
636{
637 gfx_context_t *gc = NULL;
638 test_gc_t tgc;
639 ui_resource_t *resource = NULL;
640 ui_wdecor_t *wdecor;
641 gfx_rect_t rect;
642 ui_wdecor_geom_t geom;
643 errno_t rc;
644
645 memset(&tgc, 0, sizeof(tgc));
646 rc = gfx_context_new(&ops, &tgc, &gc);
647 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
648
649 rc = ui_resource_create(gc, false, &resource);
650 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
651 PCUT_ASSERT_NOT_NULL(resource);
652
653 rc = ui_wdecor_create(resource, "Hello", ui_wds_frame | ui_wds_titlebar,
654 &wdecor);
655 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
656
657 rect.p0.x = 10;
658 rect.p0.y = 20;
659 rect.p1.x = 100;
660 rect.p1.y = 200;
661
662 ui_wdecor_set_rect(wdecor, &rect);
663 ui_wdecor_get_geom(wdecor, &geom);
664
665 PCUT_ASSERT_INT_EQUALS(14, geom.interior_rect.p0.x);
666 PCUT_ASSERT_INT_EQUALS(24, geom.interior_rect.p0.y);
667 PCUT_ASSERT_INT_EQUALS(96, geom.interior_rect.p1.x);
668 PCUT_ASSERT_INT_EQUALS(196, geom.interior_rect.p1.y);
669
670 PCUT_ASSERT_INT_EQUALS(14, geom.title_bar_rect.p0.x);
671 PCUT_ASSERT_INT_EQUALS(24, geom.title_bar_rect.p0.y);
672 PCUT_ASSERT_INT_EQUALS(96, geom.title_bar_rect.p1.x);
673 PCUT_ASSERT_INT_EQUALS(46, geom.title_bar_rect.p1.y);
674
675 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.x);
676 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.y);
677 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.x);
678 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.y);
679
680 PCUT_ASSERT_INT_EQUALS(14, geom.app_area_rect.p0.x);
681 PCUT_ASSERT_INT_EQUALS(46, geom.app_area_rect.p0.y);
682 PCUT_ASSERT_INT_EQUALS(96, geom.app_area_rect.p1.x);
683 PCUT_ASSERT_INT_EQUALS(196, geom.app_area_rect.p1.y);
684
685 ui_wdecor_destroy(wdecor);
686 ui_resource_destroy(resource);
687
688 rc = gfx_context_delete(gc);
689 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
690}
691
692/** ui_wdecor_get_geom() with ui_wds_decorated produces the correct geometry */
693PCUT_TEST(get_geom_decorated)
694{
695 gfx_context_t *gc = NULL;
696 test_gc_t tgc;
697 ui_resource_t *resource = NULL;
698 ui_wdecor_t *wdecor;
699 gfx_rect_t rect;
700 ui_wdecor_geom_t geom;
701 errno_t rc;
702
703 memset(&tgc, 0, sizeof(tgc));
704 rc = gfx_context_new(&ops, &tgc, &gc);
705 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
706
707 rc = ui_resource_create(gc, false, &resource);
708 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
709 PCUT_ASSERT_NOT_NULL(resource);
710
711 rc = ui_wdecor_create(resource, "Hello", ui_wds_decorated, &wdecor);
712 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
713
714 rect.p0.x = 10;
715 rect.p0.y = 20;
716 rect.p1.x = 100;
717 rect.p1.y = 200;
718
719 ui_wdecor_set_rect(wdecor, &rect);
720 ui_wdecor_get_geom(wdecor, &geom);
721
722 PCUT_ASSERT_INT_EQUALS(14, geom.interior_rect.p0.x);
723 PCUT_ASSERT_INT_EQUALS(24, geom.interior_rect.p0.y);
724 PCUT_ASSERT_INT_EQUALS(96, geom.interior_rect.p1.x);
725 PCUT_ASSERT_INT_EQUALS(196, geom.interior_rect.p1.y);
726
727 PCUT_ASSERT_INT_EQUALS(14, geom.title_bar_rect.p0.x);
728 PCUT_ASSERT_INT_EQUALS(24, geom.title_bar_rect.p0.y);
729 PCUT_ASSERT_INT_EQUALS(96, geom.title_bar_rect.p1.x);
730 PCUT_ASSERT_INT_EQUALS(46, geom.title_bar_rect.p1.y);
731
732 PCUT_ASSERT_INT_EQUALS(75, geom.btn_close_rect.p0.x);
733 PCUT_ASSERT_INT_EQUALS(25, geom.btn_close_rect.p0.y);
734 PCUT_ASSERT_INT_EQUALS(95, geom.btn_close_rect.p1.x);
735 PCUT_ASSERT_INT_EQUALS(45, geom.btn_close_rect.p1.y);
736
737 PCUT_ASSERT_INT_EQUALS(14, geom.app_area_rect.p0.x);
738 PCUT_ASSERT_INT_EQUALS(46, geom.app_area_rect.p0.y);
739 PCUT_ASSERT_INT_EQUALS(96, geom.app_area_rect.p1.x);
740 PCUT_ASSERT_INT_EQUALS(196, geom.app_area_rect.p1.y);
741
742 ui_wdecor_destroy(wdecor);
743 ui_resource_destroy(resource);
744
745 rc = gfx_context_delete(gc);
746 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
747}
748
749/** ui_wdecor_rect_from_app() correctly converts application to window rect */
750PCUT_TEST(rect_from_app)
751{
752 gfx_rect_t arect;
753 gfx_rect_t rect;
754
755 arect.p0.x = 14;
756 arect.p0.y = 46;
757 arect.p1.x = 96;
758 arect.p1.y = 196;
759
760 ui_wdecor_rect_from_app(ui_wds_none, &arect, &rect);
761
762 PCUT_ASSERT_INT_EQUALS(14, rect.p0.x);
763 PCUT_ASSERT_INT_EQUALS(46, rect.p0.y);
764 PCUT_ASSERT_INT_EQUALS(96, rect.p1.x);
765 PCUT_ASSERT_INT_EQUALS(196, rect.p1.y);
766
767 ui_wdecor_rect_from_app(ui_wds_frame, &arect, &rect);
768
769 PCUT_ASSERT_INT_EQUALS(10, rect.p0.x);
770 PCUT_ASSERT_INT_EQUALS(42, rect.p0.y);
771 PCUT_ASSERT_INT_EQUALS(100, rect.p1.x);
772 PCUT_ASSERT_INT_EQUALS(200, rect.p1.y);
773
774 ui_wdecor_rect_from_app(ui_wds_decorated, &arect, &rect);
775
776 PCUT_ASSERT_INT_EQUALS(10, rect.p0.x);
777 PCUT_ASSERT_INT_EQUALS(20, rect.p0.y);
778 PCUT_ASSERT_INT_EQUALS(100, rect.p1.x);
779 PCUT_ASSERT_INT_EQUALS(200, rect.p1.y);
780
781}
782
783/** Test ui_wdecor_get_rsztype() */
784PCUT_TEST(get_rsztype)
785{
786 ui_wdecor_t *wdecor;
787 gfx_rect_t rect;
788 ui_wdecor_rsztype_t rsztype;
789 gfx_coord2_t pos;
790 errno_t rc;
791
792 rc = ui_wdecor_create(NULL, "Hello", ui_wds_resizable, &wdecor);
793 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
794
795 rect.p0.x = 10;
796 rect.p0.y = 20;
797 rect.p1.x = 100;
798 rect.p1.y = 200;
799
800 ui_wdecor_set_rect(wdecor, &rect);
801
802 /* Outside of the window */
803 pos.x = 0;
804 pos.y = -1;
805 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
806 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
807
808 /* Middle of the window */
809 pos.x = 50;
810 pos.y = 100;
811 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
812 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
813
814 /* Top-left corner, but not on edge */
815 pos.x = 20;
816 pos.y = 30;
817 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
818 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
819
820 /* Top-left corner on top edge */
821 pos.x = 20;
822 pos.y = 20;
823 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
824 PCUT_ASSERT_EQUALS(ui_wr_top_left, rsztype);
825
826 /* Top-left corner on left edge */
827 pos.x = 10;
828 pos.y = 30;
829 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
830 PCUT_ASSERT_EQUALS(ui_wr_top_left, rsztype);
831
832 /* Top-right corner on top edge */
833 pos.x = 90;
834 pos.y = 20;
835 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
836 PCUT_ASSERT_EQUALS(ui_wr_top_right, rsztype);
837
838 /* Top-right corner on right edge */
839 pos.x = 99;
840 pos.y = 30;
841 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
842 PCUT_ASSERT_EQUALS(ui_wr_top_right, rsztype);
843
844 /* Top edge */
845 pos.x = 50;
846 pos.y = 20;
847 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
848 PCUT_ASSERT_EQUALS(ui_wr_top, rsztype);
849
850 /* Bottom edge */
851 pos.x = 50;
852 pos.y = 199;
853 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
854 PCUT_ASSERT_EQUALS(ui_wr_bottom, rsztype);
855
856 /* Left edge */
857 pos.x = 10;
858 pos.y = 100;
859 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
860 PCUT_ASSERT_EQUALS(ui_wr_left, rsztype);
861
862 /* Right edge */
863 pos.x = 99;
864 pos.y = 100;
865 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
866 PCUT_ASSERT_EQUALS(ui_wr_right, rsztype);
867
868 ui_wdecor_destroy(wdecor);
869
870 /* Non-resizable window */
871
872 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
873 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
874
875 rect.p0.x = 10;
876 rect.p0.y = 20;
877 rect.p1.x = 100;
878 rect.p1.y = 200;
879
880 ui_wdecor_set_rect(wdecor, &rect);
881
882 pos.x = 10;
883 pos.y = 20;
884 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
885 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
886
887 ui_wdecor_destroy(wdecor);
888}
889
890/** Test ui_wdecor_cursor_from_rsztype() */
891PCUT_TEST(cursor_from_rsztype)
892{
893 PCUT_ASSERT_EQUALS(ui_curs_arrow,
894 ui_wdecor_cursor_from_rsztype(ui_wr_none));
895 PCUT_ASSERT_EQUALS(ui_curs_size_ud,
896 ui_wdecor_cursor_from_rsztype(ui_wr_top));
897 PCUT_ASSERT_EQUALS(ui_curs_size_ud,
898 ui_wdecor_cursor_from_rsztype(ui_wr_bottom));
899 PCUT_ASSERT_EQUALS(ui_curs_size_lr,
900 ui_wdecor_cursor_from_rsztype(ui_wr_left));
901 PCUT_ASSERT_EQUALS(ui_curs_size_lr,
902 ui_wdecor_cursor_from_rsztype(ui_wr_right));
903 PCUT_ASSERT_EQUALS(ui_curs_size_uldr,
904 ui_wdecor_cursor_from_rsztype(ui_wr_top_left));
905 PCUT_ASSERT_EQUALS(ui_curs_size_uldr,
906 ui_wdecor_cursor_from_rsztype(ui_wr_bottom_right));
907 PCUT_ASSERT_EQUALS(ui_curs_size_urdl,
908 ui_wdecor_cursor_from_rsztype(ui_wr_top_right));
909 PCUT_ASSERT_EQUALS(ui_curs_size_urdl,
910 ui_wdecor_cursor_from_rsztype(ui_wr_bottom_left));
911}
912
913/** Test ui_wdecor_frame_pos_event() */
914PCUT_TEST(frame_pos_event)
915{
916 ui_wdecor_t *wdecor;
917 gfx_rect_t rect;
918 test_cb_resp_t resp;
919 pos_event_t event;
920 errno_t rc;
921
922 rc = ui_wdecor_create(NULL, "Hello", ui_wds_resizable, &wdecor);
923 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
924
925 rect.p0.x = 10;
926 rect.p0.y = 20;
927 rect.p1.x = 100;
928 rect.p1.y = 200;
929
930 ui_wdecor_set_rect(wdecor, &rect);
931 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
932
933 /* Release on window border should do nothing */
934 resp.resize = false;
935 event.type = POS_RELEASE;
936 event.hpos = 10;
937 event.vpos = 10;
938 ui_wdecor_frame_pos_event(wdecor, &event);
939 PCUT_ASSERT_FALSE(resp.resize);
940
941 /* Press in the middle of the window should do nothing */
942 resp.resize = false;
943 event.type = POS_PRESS;
944 event.hpos = 50;
945 event.vpos = 100;
946 ui_wdecor_frame_pos_event(wdecor, &event);
947 PCUT_ASSERT_FALSE(resp.resize);
948
949 /* Press on window border should cause resize to be called */
950 resp.resize = false;
951 event.type = POS_PRESS;
952 event.hpos = 10;
953 event.vpos = 20;
954 ui_wdecor_frame_pos_event(wdecor, &event);
955 PCUT_ASSERT_TRUE(resp.resize);
956
957 ui_wdecor_destroy(wdecor);
958}
959
960static errno_t testgc_set_clip_rect(void *arg, gfx_rect_t *rect)
961{
962 (void) arg;
963 (void) rect;
964 return EOK;
965}
966
967static errno_t testgc_set_color(void *arg, gfx_color_t *color)
968{
969 (void) arg;
970 (void) color;
971 return EOK;
972}
973
974static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
975{
976 (void) arg;
977 (void) rect;
978 return EOK;
979}
980
981static errno_t testgc_update(void *arg)
982{
983 (void) arg;
984 return EOK;
985}
986
987static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
988 gfx_bitmap_alloc_t *alloc, void **rbm)
989{
990 test_gc_t *tgc = (test_gc_t *) arg;
991 testgc_bitmap_t *tbm;
992
993 tbm = calloc(1, sizeof(testgc_bitmap_t));
994 if (tbm == NULL)
995 return ENOMEM;
996
997 if (alloc == NULL) {
998 tbm->alloc.pitch = (params->rect.p1.x - params->rect.p0.x) *
999 sizeof(uint32_t);
1000 tbm->alloc.off0 = 0;
1001 tbm->alloc.pixels = calloc(sizeof(uint32_t),
1002 (params->rect.p1.x - params->rect.p0.x) *
1003 (params->rect.p1.y - params->rect.p0.y));
1004 tbm->myalloc = true;
1005 if (tbm->alloc.pixels == NULL) {
1006 free(tbm);
1007 return ENOMEM;
1008 }
1009 } else {
1010 tbm->alloc = *alloc;
1011 }
1012
1013 tbm->tgc = tgc;
1014 tgc->bm_created = true;
1015 tgc->bm_params = *params;
1016 tgc->bm_pixels = tbm->alloc.pixels;
1017 *rbm = (void *)tbm;
1018 return EOK;
1019}
1020
1021static errno_t testgc_bitmap_destroy(void *bm)
1022{
1023 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
1024 if (tbm->myalloc)
1025 free(tbm->alloc.pixels);
1026 tbm->tgc->bm_destroyed = true;
1027 free(tbm);
1028 return EOK;
1029}
1030
1031static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
1032 gfx_coord2_t *offs)
1033{
1034 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
1035 tbm->tgc->bm_rendered = true;
1036 tbm->tgc->bm_srect = *srect;
1037 tbm->tgc->bm_offs = *offs;
1038 return EOK;
1039}
1040
1041static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
1042{
1043 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
1044 *alloc = tbm->alloc;
1045 tbm->tgc->bm_got_alloc = true;
1046 return EOK;
1047}
1048
1049static void test_wdecor_minimize(ui_wdecor_t *wdecor, void *arg)
1050{
1051 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1052
1053 resp->minimize = true;
1054}
1055
1056static void test_wdecor_maximize(ui_wdecor_t *wdecor, void *arg)
1057{
1058 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1059
1060 resp->maximize = true;
1061}
1062
1063static void test_wdecor_unmaximize(ui_wdecor_t *wdecor, void *arg)
1064{
1065 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1066
1067 resp->unmaximize = true;
1068}
1069
1070static void test_wdecor_close(ui_wdecor_t *wdecor, void *arg)
1071{
1072 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1073
1074 resp->close = true;
1075}
1076
1077static void test_wdecor_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos)
1078{
1079 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1080
1081 resp->move = true;
1082 resp->pos = *pos;
1083}
1084
1085static void test_wdecor_resize(ui_wdecor_t *wdecor, void *arg,
1086 ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
1087{
1088 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1089
1090 resp->resize = true;
1091 resp->rsztype = rsztype;
1092 resp->pos = *pos;
1093 resp->pos_id = pos_id;
1094}
1095
1096static void test_wdecor_set_cursor(ui_wdecor_t *wdecor, void *arg,
1097 ui_stock_cursor_t cursor)
1098{
1099 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1100
1101 resp->set_cursor = true;
1102 resp->cursor = cursor;
1103}
1104
1105PCUT_EXPORT(wdecor);
Note: See TracBrowser for help on using the repository browser.