source: mainline/uspace/srv/hid/display/display.c@ c2250702

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

Movement events from input server, display pointer, focus by click again

  • 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
175 wnd = ds_display_first_window(display);
176 while (wnd != NULL) {
177 // XXX Need to know window dimensions
178 if (pos->x >= wnd->dpos.x && pos->y >= wnd->dpos.y &&
179 pos->x <= wnd->dpos.x + 100 && pos->y <= wnd->dpos.y + 100) {
180 return wnd;
181 }
182
183 wnd = ds_display_next_window(wnd);
184 }
185
186 return NULL;
187}
188
189/** Add window to display.
190 *
191 * @param display Display
192 * @param wnd Window
193 */
194void ds_display_add_window(ds_display_t *display, ds_window_t *wnd)
195{
196 assert(wnd->display == NULL);
197 assert(!link_used(&wnd->ldwindows));
198
199 wnd->display = display;
200 list_prepend(&wnd->ldwindows, &display->windows);
201}
202
203/** Remove window from display.
204 *
205 * @param wnd Window
206 */
207void ds_display_remove_window(ds_window_t *wnd)
208{
209 list_remove(&wnd->ldwindows);
210 wnd->display = NULL;
211}
212
213/** Get first window in display.
214 *
215 * @param display Display
216 * @return First window or @c NULL if there is none
217 */
218ds_window_t *ds_display_first_window(ds_display_t *display)
219{
220 link_t *link = list_first(&display->windows);
221
222 if (link == NULL)
223 return NULL;
224
225 return list_get_instance(link, ds_window_t, ldwindows);
226}
227
228/** Get next window in client.
229 *
230 * @param wnd Current window
231 * @return Next window or @c NULL if there is none
232 */
233ds_window_t *ds_display_next_window(ds_window_t *wnd)
234{
235 link_t *link = list_next(&wnd->ldwindows, &wnd->display->windows);
236
237 if (link == NULL)
238 return NULL;
239
240 return list_get_instance(link, ds_window_t, ldwindows);
241}
242
243/** Post keyboard event to a display.
244 *
245 * The event is routed to the correct window by first determining the
246 * seat the keyboard device belongs to and then the event is sent to the
247 * window focused by that seat.
248 *
249 * @param display Display
250 * @param event Event
251 */
252errno_t ds_display_post_kbd_event(ds_display_t *display, kbd_event_t *event)
253{
254 ds_seat_t *seat;
255
256 // TODO Determine which seat the event belongs to
257 seat = ds_display_first_seat(display);
258 if (seat == NULL)
259 return EOK;
260
261 return ds_seat_post_kbd_event(seat, event);
262}
263
264/** Post position event to a display.
265 *
266 * @param display Display
267 * @param event Event
268 */
269errno_t ds_display_post_ptd_event(ds_display_t *display, ptd_event_t *event)
270{
271 ds_seat_t *seat;
272
273 // TODO Determine which seat the event belongs to
274 seat = ds_display_first_seat(display);
275 printf("ds_display_post_ptd_event: seat=%p\n", seat);
276 if (seat == NULL)
277 return EOK;
278
279 return ds_seat_post_ptd_event(seat, event);
280}
281
282/** Add seat to display.
283 *
284 * @param disp Display
285 * @param seat Seat
286 */
287void ds_display_add_seat(ds_display_t *disp, ds_seat_t *seat)
288{
289 assert(seat->display == NULL);
290 assert(!link_used(&seat->lseats));
291
292 seat->display = disp;
293 list_append(&seat->lseats, &disp->seats);
294}
295
296/** Remove seat from display.
297 *
298 * @param seat Seat
299 */
300void ds_display_remove_seat(ds_seat_t *seat)
301{
302 list_remove(&seat->lseats);
303 seat->display = NULL;
304}
305
306/** Get first seat in display.
307 *
308 * @param disp Display
309 * @return First seat or @c NULL if there is none
310 */
311ds_seat_t *ds_display_first_seat(ds_display_t *disp)
312{
313 link_t *link = list_first(&disp->seats);
314
315 if (link == NULL)
316 return NULL;
317
318 return list_get_instance(link, ds_seat_t, lseats);
319}
320
321/** Get next seat in display.
322 *
323 * @param seat Current seat
324 * @return Next seat or @c NULL if there is none
325 */
326ds_seat_t *ds_display_next_seat(ds_seat_t *seat)
327{
328 link_t *link = list_next(&seat->lseats, &seat->display->seats);
329
330 if (link == NULL)
331 return NULL;
332
333 return list_get_instance(link, ds_seat_t, lseats);
334}
335
336/** Add display device to display.
337 *
338 * @param disp Display
339 * @param ddev Display device
340 */
341void ds_display_add_ddev(ds_display_t *disp, ds_ddev_t *ddev)
342{
343 assert(ddev->display == NULL);
344 assert(!link_used(&ddev->lddevs));
345
346 ddev->display = disp;
347 list_append(&ddev->lddevs, &disp->ddevs);
348}
349
350/** Remove display device from display.
351 *
352 * @param ddev Display device
353 */
354void ds_display_remove_ddev(ds_ddev_t *ddev)
355{
356 list_remove(&ddev->lddevs);
357 ddev->display = NULL;
358}
359
360/** Get first display device in display.
361 *
362 * @param disp Display
363 * @return First display device or @c NULL if there is none
364 */
365ds_ddev_t *ds_display_first_ddev(ds_display_t *disp)
366{
367 link_t *link = list_first(&disp->ddevs);
368
369 if (link == NULL)
370 return NULL;
371
372 return list_get_instance(link, ds_ddev_t, lddevs);
373}
374
375/** Get next display device in display.
376 *
377 * @param ddev Current display device
378 * @return Next display device or @c NULL if there is none
379 */
380ds_ddev_t *ds_display_next_ddev(ds_ddev_t *ddev)
381{
382 link_t *link = list_next(&ddev->lddevs, &ddev->display->ddevs);
383
384 if (link == NULL)
385 return NULL;
386
387 return list_get_instance(link, ds_ddev_t, lddevs);
388}
389
390// XXX
391gfx_context_t *ds_display_get_gc(ds_display_t *display)
392{
393 ds_ddev_t *ddev;
394
395 ddev = ds_display_first_ddev(display);
396 if (ddev == NULL)
397 return NULL;
398
399 return ddev->gc;
400}
401
402/** @}
403 */
Note: See TracBrowser for help on using the repository browser.