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

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

Add GC operation to set clipping rectangle

The number of changed files is due to the proliferation of GC
implementations, mostly these are just dummies in unit tests.
Definitely need to tame those in the future.

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