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

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

Add list of all windows on a display, in stacking order

  • Property mode set to 100644
File size: 7.0 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->gc = gc;
61 disp->next_wnd_id = 1;
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/** Add window to display.
167 *
168 * @param display Display
169 * @param wnd Window
170 */
171void ds_display_add_window(ds_display_t *display, ds_window_t *wnd)
172{
173 assert(wnd->display == NULL);
174 assert(!link_used(&wnd->ldwindows));
175
176 wnd->display = display;
177 list_prepend(&wnd->ldwindows, &display->windows);
178}
179
180/** Remove window from display.
181 *
182 * @param wnd Window
183 */
184void ds_display_remove_window(ds_window_t *wnd)
185{
186 list_remove(&wnd->ldwindows);
187 wnd->display = NULL;
188}
189
190/** Get first window in display.
191 *
192 * @param display Display
193 * @return First window or @c NULL if there is none
194 */
195ds_window_t *ds_display_first_window(ds_display_t *display)
196{
197 link_t *link = list_first(&display->windows);
198
199 if (link == NULL)
200 return NULL;
201
202 return list_get_instance(link, ds_window_t, ldwindows);
203}
204
205/** Get next window in client.
206 *
207 * @param wnd Current window
208 * @return Next window or @c NULL if there is none
209 */
210ds_window_t *ds_display_next_window(ds_window_t *wnd)
211{
212 link_t *link = list_next(&wnd->ldwindows, &wnd->display->windows);
213
214 if (link == NULL)
215 return NULL;
216
217 return list_get_instance(link, ds_window_t, ldwindows);
218}
219
220/** Post keyboard event to a display.
221 *
222 * The event is routed to the correct window by first determining the
223 * seat the keyboard device belongs to and then the event is sent to the
224 * window focused by that seat.
225 *
226 * @param display Display
227 * @param event Event
228 */
229errno_t ds_display_post_kbd_event(ds_display_t *display, kbd_event_t *event)
230{
231 ds_seat_t *seat;
232
233 // TODO Determine which seat the event belongs to
234 seat = ds_display_first_seat(display);
235 if (seat == NULL)
236 return EOK;
237
238 return ds_seat_post_kbd_event(seat, event);
239}
240
241/** Add seat to display.
242 *
243 * @param disp Display
244 * @param seat Seat
245 */
246void ds_display_add_seat(ds_display_t *disp, ds_seat_t *seat)
247{
248 assert(seat->display == NULL);
249 assert(!link_used(&seat->lseats));
250
251 seat->display = disp;
252 list_append(&seat->lseats, &disp->seats);
253}
254
255/** Remove seat from display.
256 *
257 * @param seat Seat
258 */
259void ds_display_remove_seat(ds_seat_t *seat)
260{
261 list_remove(&seat->lseats);
262 seat->display = NULL;
263}
264
265/** Get first seat in display.
266 *
267 * @param disp Display
268 * @return First seat or @c NULL if there is none
269 */
270ds_seat_t *ds_display_first_seat(ds_display_t *disp)
271{
272 link_t *link = list_first(&disp->seats);
273
274 if (link == NULL)
275 return NULL;
276
277 return list_get_instance(link, ds_seat_t, lseats);
278}
279
280/** Get next seat in display.
281 *
282 * @param seat Current seat
283 * @return Next seat or @c NULL if there is none
284 */
285ds_seat_t *ds_display_next_seat(ds_seat_t *seat)
286{
287 link_t *link = list_next(&seat->lseats, &seat->display->seats);
288
289 if (link == NULL)
290 return NULL;
291
292 return list_get_instance(link, ds_seat_t, lseats);
293}
294
295/** @}
296 */
Note: See TracBrowser for help on using the repository browser.