source: mainline/uspace/srv/hid/display/display.c@ 8e9781f

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

Use window dimensions for picking window to focus

  • Property mode set to 100644
File size: 9.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/** @addtogroup display
30 * @{
31 */
32/**
33 * @file Display server display
34 */
35
36#include <errno.h>
37#include <gfx/context.h>
38#include <io/log.h>
39#include <stdlib.h>
40#include "client.h"
41#include "seat.h"
42#include "window.h"
43#include "display.h"
44
45/** Create display.
46 *
47 * @param gc Graphics context for displaying output
48 * @param rdisp Place to store pointer to new display.
49 * @return EOK on success, ENOMEM if out of memory
50 */
51errno_t ds_display_create(gfx_context_t *gc, ds_display_t **rdisp)
52{
53 ds_display_t *disp;
54
55 disp = calloc(1, sizeof(ds_display_t));
56 if (disp == NULL)
57 return ENOMEM;
58
59 list_initialize(&disp->clients);
60 disp->next_wnd_id = 1;
61 list_initialize(&disp->ddevs);
62 list_initialize(&disp->seats);
63 list_initialize(&disp->windows);
64 *rdisp = disp;
65 return EOK;
66}
67
68/** Destroy display.
69 *
70 * @param disp Display
71 */
72void ds_display_destroy(ds_display_t *disp)
73{
74 assert(list_empty(&disp->clients));
75 assert(list_empty(&disp->seats));
76 free(disp);
77}
78
79/** Add client to display.
80 *
81 * @param disp Display
82 * @param client Client
83 */
84void ds_display_add_client(ds_display_t *disp, ds_client_t *client)
85{
86 assert(client->display == NULL);
87 assert(!link_used(&client->lclients));
88
89 client->display = disp;
90 list_append(&client->lclients, &disp->clients);
91}
92
93/** Remove client from display.
94 *
95 * @param client Client
96 */
97void ds_display_remove_client(ds_client_t *client)
98{
99 list_remove(&client->lclients);
100 client->display = NULL;
101}
102
103/** Get first client in display.
104 *
105 * @param disp Display
106 * @return First client or @c NULL if there is none
107 */
108ds_client_t *ds_display_first_client(ds_display_t *disp)
109{
110 link_t *link = list_first(&disp->clients);
111
112 if (link == NULL)
113 return NULL;
114
115 return list_get_instance(link, ds_client_t, lclients);
116}
117
118/** Get next client in display.
119 *
120 * @param client Current client
121 * @return Next client or @c NULL if there is none
122 */
123ds_client_t *ds_display_next_client(ds_client_t *client)
124{
125 link_t *link = list_next(&client->lclients, &client->display->clients);
126
127 if (link == NULL)
128 return NULL;
129
130 return list_get_instance(link, ds_client_t, lclients);
131}
132
133/** Find window in all clients by ID.
134 *
135 * XXX This is just a hack needed to match GC connection to a window,
136 * as we don't have a good safe way to pass the GC endpoint to our client
137 * on demand.
138 *
139 * @param display Display
140 * @param id Window ID
141 */
142#include <stdio.h>
143ds_window_t *ds_display_find_window(ds_display_t *display, ds_wnd_id_t id)
144{
145 ds_client_t *client;
146 ds_window_t *wnd;
147
148 printf("ds_display_find_window: id=0x%x\n", (unsigned) id);
149
150 client = ds_display_first_client(display);
151 while (client != NULL) {
152 printf("ds_display_find_window: client=%p\n", client);
153 wnd = ds_client_find_window(client, id);
154 if (wnd != NULL) {
155 printf("ds_display_find_window: found wnd=%p id=0x%x\n",
156 wnd, (unsigned) wnd->id);
157 return wnd;
158 }
159 client = ds_display_next_client(client);
160 }
161
162 printf("ds_display_find_window: not found\n");
163 return NULL;
164}
165
166/** Find window by display position.
167 *
168 * @param display Display
169 * @param pos Display position
170 */
171ds_window_t *ds_display_window_by_pos(ds_display_t *display, gfx_coord2_t *pos)
172{
173 ds_window_t *wnd;
174 gfx_rect_t drect;
175
176 wnd = ds_display_first_window(display);
177 while (wnd != NULL) {
178 /* Window bounding rectangle on display */
179 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
180
181 if (gfx_pix_inside_rect(pos, &drect))
182 return wnd;
183
184 wnd = ds_display_next_window(wnd);
185 }
186
187 return NULL;
188}
189
190/** Add window to display.
191 *
192 * @param display Display
193 * @param wnd Window
194 */
195void ds_display_add_window(ds_display_t *display, ds_window_t *wnd)
196{
197 assert(wnd->display == NULL);
198 assert(!link_used(&wnd->ldwindows));
199
200 wnd->display = display;
201 list_prepend(&wnd->ldwindows, &display->windows);
202}
203
204/** Remove window from display.
205 *
206 * @param wnd Window
207 */
208void ds_display_remove_window(ds_window_t *wnd)
209{
210 list_remove(&wnd->ldwindows);
211 wnd->display = NULL;
212}
213
214/** Get first window in display.
215 *
216 * @param display Display
217 * @return First window or @c NULL if there is none
218 */
219ds_window_t *ds_display_first_window(ds_display_t *display)
220{
221 link_t *link = list_first(&display->windows);
222
223 if (link == NULL)
224 return NULL;
225
226 return list_get_instance(link, ds_window_t, ldwindows);
227}
228
229/** Get next window in client.
230 *
231 * @param wnd Current window
232 * @return Next window or @c NULL if there is none
233 */
234ds_window_t *ds_display_next_window(ds_window_t *wnd)
235{
236 link_t *link = list_next(&wnd->ldwindows, &wnd->display->windows);
237
238 if (link == NULL)
239 return NULL;
240
241 return list_get_instance(link, ds_window_t, ldwindows);
242}
243
244/** Post keyboard event to a display.
245 *
246 * The event is routed to the correct window by first determining the
247 * seat the keyboard device belongs to and then the event is sent to the
248 * window focused by that seat.
249 *
250 * @param display Display
251 * @param event Event
252 */
253errno_t ds_display_post_kbd_event(ds_display_t *display, kbd_event_t *event)
254{
255 ds_seat_t *seat;
256
257 // TODO Determine which seat the event belongs to
258 seat = ds_display_first_seat(display);
259 if (seat == NULL)
260 return EOK;
261
262 return ds_seat_post_kbd_event(seat, event);
263}
264
265/** Post position event to a display.
266 *
267 * @param display Display
268 * @param event Event
269 */
270errno_t ds_display_post_ptd_event(ds_display_t *display, ptd_event_t *event)
271{
272 ds_seat_t *seat;
273
274 // TODO Determine which seat the event belongs to
275 seat = ds_display_first_seat(display);
276 printf("ds_display_post_ptd_event: seat=%p\n", seat);
277 if (seat == NULL)
278 return EOK;
279
280 return ds_seat_post_ptd_event(seat, event);
281}
282
283/** Add seat to display.
284 *
285 * @param disp Display
286 * @param seat Seat
287 */
288void ds_display_add_seat(ds_display_t *disp, ds_seat_t *seat)
289{
290 assert(seat->display == NULL);
291 assert(!link_used(&seat->lseats));
292
293 seat->display = disp;
294 list_append(&seat->lseats, &disp->seats);
295}
296
297/** Remove seat from display.
298 *
299 * @param seat Seat
300 */
301void ds_display_remove_seat(ds_seat_t *seat)
302{
303 list_remove(&seat->lseats);
304 seat->display = NULL;
305}
306
307/** Get first seat in display.
308 *
309 * @param disp Display
310 * @return First seat or @c NULL if there is none
311 */
312ds_seat_t *ds_display_first_seat(ds_display_t *disp)
313{
314 link_t *link = list_first(&disp->seats);
315
316 if (link == NULL)
317 return NULL;
318
319 return list_get_instance(link, ds_seat_t, lseats);
320}
321
322/** Get next seat in display.
323 *
324 * @param seat Current seat
325 * @return Next seat or @c NULL if there is none
326 */
327ds_seat_t *ds_display_next_seat(ds_seat_t *seat)
328{
329 link_t *link = list_next(&seat->lseats, &seat->display->seats);
330
331 if (link == NULL)
332 return NULL;
333
334 return list_get_instance(link, ds_seat_t, lseats);
335}
336
337/** Add display device to display.
338 *
339 * @param disp Display
340 * @param ddev Display device
341 */
342void ds_display_add_ddev(ds_display_t *disp, ds_ddev_t *ddev)
343{
344 assert(ddev->display == NULL);
345 assert(!link_used(&ddev->lddevs));
346
347 ddev->display = disp;
348 list_append(&ddev->lddevs, &disp->ddevs);
349}
350
351/** Remove display device from display.
352 *
353 * @param ddev Display device
354 */
355void ds_display_remove_ddev(ds_ddev_t *ddev)
356{
357 list_remove(&ddev->lddevs);
358 ddev->display = NULL;
359}
360
361/** Get first display device in display.
362 *
363 * @param disp Display
364 * @return First display device or @c NULL if there is none
365 */
366ds_ddev_t *ds_display_first_ddev(ds_display_t *disp)
367{
368 link_t *link = list_first(&disp->ddevs);
369
370 if (link == NULL)
371 return NULL;
372
373 return list_get_instance(link, ds_ddev_t, lddevs);
374}
375
376/** Get next display device in display.
377 *
378 * @param ddev Current display device
379 * @return Next display device or @c NULL if there is none
380 */
381ds_ddev_t *ds_display_next_ddev(ds_ddev_t *ddev)
382{
383 link_t *link = list_next(&ddev->lddevs, &ddev->display->ddevs);
384
385 if (link == NULL)
386 return NULL;
387
388 return list_get_instance(link, ds_ddev_t, lddevs);
389}
390
391// XXX
392gfx_context_t *ds_display_get_gc(ds_display_t *display)
393{
394 ds_ddev_t *ddev;
395
396 ddev = ds_display_first_ddev(display);
397 if (ddev == NULL)
398 return NULL;
399
400 return ddev->gc;
401}
402
403/** @}
404 */
Note: See TracBrowser for help on using the repository browser.