source: mainline/uspace/srv/hid/display/test/cursor.c

Last change on this file was 4e7b0ad, checked in by Jiri Svoboda <jiri@…>, 3 years ago

Add missing actions in display destructor

We might to actually destroy the other components rather than assert
they have been destroyed. But we shall see when we actually implement
graceful shutdown for this (and any other) server.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 2022 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 <errno.h>
30#include <gfx/context.h>
31#include <stdbool.h>
32#include <pcut/pcut.h>
33
34#include "../cursor.h"
35#include "../cursimg.h"
36#include "../ddev.h"
37#include "../display.h"
38#include "../display.h"
39
40PCUT_INIT;
41
42PCUT_TEST_SUITE(cursor);
43
44static errno_t dummy_bitmap_create(void *, gfx_bitmap_params_t *,
45 gfx_bitmap_alloc_t *, void **);
46static errno_t dummy_bitmap_destroy(void *);
47static errno_t dummy_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
48static errno_t dummy_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
49
50static gfx_context_ops_t dummy_ops = {
51 .bitmap_create = dummy_bitmap_create,
52 .bitmap_destroy = dummy_bitmap_destroy,
53 .bitmap_render = dummy_bitmap_render,
54 .bitmap_get_alloc = dummy_bitmap_get_alloc
55};
56
57typedef struct {
58 bool render_called;
59} test_response_t;
60
61typedef struct {
62 test_response_t *resp;
63 gfx_bitmap_alloc_t alloc;
64} dummy_bitmap_t;
65
66/** Test ds_cursor_create(), ds_cursor_destroy(). */
67PCUT_TEST(cursor_create_destroy)
68{
69 ds_display_t *disp;
70 ds_cursor_t *cursor;
71 errno_t rc;
72
73 rc = ds_display_create(NULL, df_none, &disp);
74 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
75
76 rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
77 ds_cursimg[dcurs_arrow].image, &cursor);
78 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
79
80 ds_cursor_destroy(cursor);
81 ds_display_destroy(disp);
82}
83
84/** Test ds_cursor_paint() renders the cursor. */
85PCUT_TEST(cursor_paint_render)
86{
87 gfx_context_t *gc;
88 ds_display_t *disp;
89 ds_cursor_t *cursor;
90 ds_ddev_t *ddev;
91 ddev_info_t ddinfo;
92 gfx_coord2_t pos;
93 test_response_t resp;
94 errno_t rc;
95
96 rc = gfx_context_new(&dummy_ops, &resp, &gc);
97 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
98
99 rc = ds_display_create(gc, df_none, &disp);
100 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
101
102 ddev_info_init(&ddinfo);
103
104 rc = ds_ddev_create(disp, NULL, &ddinfo, NULL, 0, gc, &ddev);
105 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
106
107 rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
108 ds_cursimg[dcurs_arrow].image, &cursor);
109 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
110
111 resp.render_called = false;
112
113 pos.x = 0;
114 pos.y = 0;
115 ds_cursor_paint(cursor, &pos, NULL);
116
117 PCUT_ASSERT_TRUE(resp.render_called);
118
119 ds_ddev_close(ddev);
120 ds_cursor_destroy(cursor);
121 ds_display_destroy(disp);
122}
123
124/** Test ds_cursor_paint() optimizes out rendering using clipping rectangle. */
125PCUT_TEST(cursor_paint_norender)
126{
127 gfx_context_t *gc;
128 ds_display_t *disp;
129 ds_cursor_t *cursor;
130 ds_ddev_t *ddev;
131 ddev_info_t ddinfo;
132 gfx_coord2_t pos;
133 gfx_rect_t clip;
134 test_response_t resp;
135 errno_t rc;
136
137 rc = gfx_context_new(&dummy_ops, &resp, &gc);
138 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
139
140 rc = ds_display_create(gc, df_none, &disp);
141 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
142
143 ddev_info_init(&ddinfo);
144
145 rc = ds_ddev_create(disp, NULL, &ddinfo, NULL, 0, gc, &ddev);
146 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
147
148 rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
149 ds_cursimg[dcurs_arrow].image, &cursor);
150 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
151
152 resp.render_called = false;
153
154 /*
155 * Clipping rectangle not intersecting the area where cursor is to
156 * be rendered
157 */
158 clip.p0.x = 100;
159 clip.p0.y = 100;
160 clip.p1.x = 150;
161 clip.p1.y = 150;
162
163 pos.x = 0;
164 pos.y = 0;
165 ds_cursor_paint(cursor, &pos, &clip);
166
167 /* Rendering should have been optimized out */
168 PCUT_ASSERT_FALSE(resp.render_called);
169
170 ds_ddev_close(ddev);
171 ds_cursor_destroy(cursor);
172 ds_display_destroy(disp);
173}
174
175/** Test ds_cursor_get_rect() */
176PCUT_TEST(cursor_get_rect)
177{
178 ds_display_t *disp;
179 ds_cursor_t *cursor;
180 gfx_coord2_t pos1, pos2;
181 gfx_rect_t rect1, rect2;
182 errno_t rc;
183
184 rc = ds_display_create(NULL, df_none, &disp);
185 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
186
187 rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
188 ds_cursimg[dcurs_arrow].image, &cursor);
189 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
190
191 pos1.x = 10;
192 pos1.y = 11;
193
194 pos2.x = 22;
195 pos2.y = 23;
196
197 ds_cursor_get_rect(cursor, &pos1, &rect1);
198 ds_cursor_get_rect(cursor, &pos2, &rect2);
199
200 PCUT_ASSERT_FALSE(gfx_rect_is_empty(&rect1));
201 PCUT_ASSERT_FALSE(gfx_rect_is_empty(&rect2));
202
203 PCUT_ASSERT_INT_EQUALS(pos2.x - pos1.x, rect2.p0.x - rect1.p0.x);
204 PCUT_ASSERT_INT_EQUALS(pos2.y - pos1.y, rect2.p0.y - rect1.p0.y);
205 PCUT_ASSERT_INT_EQUALS(pos2.x - pos1.x, rect2.p1.x - rect1.p1.x);
206 PCUT_ASSERT_INT_EQUALS(pos2.y - pos1.y, rect2.p1.y - rect1.p1.y);
207
208 ds_cursor_destroy(cursor);
209 ds_display_destroy(disp);
210}
211
212static errno_t dummy_bitmap_create(void *arg, gfx_bitmap_params_t *params,
213 gfx_bitmap_alloc_t *alloc, void **rbm)
214{
215 test_response_t *resp = (test_response_t *) arg;
216 dummy_bitmap_t *bm;
217 gfx_coord2_t dims;
218
219 gfx_rect_dims(&params->rect, &dims);
220 bm = calloc(1, sizeof(dummy_bitmap_t));
221 if (bm == NULL)
222 return ENOMEM;
223
224 bm->resp = resp;
225 bm->alloc.pitch = dims.x * sizeof(uint32_t);
226 bm->alloc.off0 = 0;
227
228 bm->alloc.pixels = malloc(bm->alloc.pitch * dims.y * sizeof(uint32_t));
229 if (bm->alloc.pixels == NULL) {
230 free(bm);
231 return ENOMEM;
232 }
233
234 *rbm = (void *) bm;
235 return EOK;
236}
237
238static errno_t dummy_bitmap_destroy(void *arg)
239{
240 dummy_bitmap_t *bm = (dummy_bitmap_t *) arg;
241
242 free(bm);
243 return EOK;
244}
245
246static errno_t dummy_bitmap_render(void *arg, gfx_rect_t *rect,
247 gfx_coord2_t *dpos)
248{
249 dummy_bitmap_t *bm = (dummy_bitmap_t *) arg;
250
251 bm->resp->render_called = true;
252 return EOK;
253}
254
255static errno_t dummy_bitmap_get_alloc(void *arg, gfx_bitmap_alloc_t *alloc)
256{
257 dummy_bitmap_t *bm = (dummy_bitmap_t *) arg;
258
259 *alloc = bm->alloc;
260 return EOK;
261}
262
263PCUT_EXPORT(cursor);
Note: See TracBrowser for help on using the repository browser.