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

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

Introduce window focus, housed in a seat object

  • Property mode set to 100644
File size: 5.9 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 *rdisp = disp;
64 return EOK;
65}
66
67/** Destroy display.
68 *
69 * @param disp Display
70 */
71void ds_display_destroy(ds_display_t *disp)
72{
73 assert(list_empty(&disp->clients));
74 assert(list_empty(&disp->seats));
75 free(disp);
76}
77
78/** Add client to display.
79 *
80 * @param disp Display
81 * @param client Client
82 */
83void ds_display_add_client(ds_display_t *disp, ds_client_t *client)
84{
85 assert(client->display == NULL);
86 assert(!link_used(&client->lclients));
87
88 client->display = disp;
89 list_append(&client->lclients, &disp->clients);
90}
91
92/** Remove client from display.
93 *
94 * @param client Client
95 */
96void ds_display_remove_client(ds_client_t *client)
97{
98 list_remove(&client->lclients);
99 client->display = NULL;
100}
101
102/** Get first client in display.
103 *
104 * @param disp Display
105 * @return First client or @c NULL if there is none
106 */
107ds_client_t *ds_display_first_client(ds_display_t *disp)
108{
109 link_t *link = list_first(&disp->clients);
110
111 if (link == NULL)
112 return NULL;
113
114 return list_get_instance(link, ds_client_t, lclients);
115}
116
117/** Get next client in display.
118 *
119 * @param client Current client
120 * @return Next client or @c NULL if there is none
121 */
122ds_client_t *ds_display_next_client(ds_client_t *client)
123{
124 link_t *link = list_next(&client->lclients, &client->display->clients);
125
126 if (link == NULL)
127 return NULL;
128
129 return list_get_instance(link, ds_client_t, lclients);
130}
131
132/** Find window in all clients by ID.
133 *
134 * XXX This is just a hack needed to match GC connection to a window,
135 * as we don't have a good safe way to pass the GC endpoint to our client
136 * on demand.
137 *
138 * @param display Display
139 * @param id Window ID
140 */
141#include <stdio.h>
142ds_window_t *ds_display_find_window(ds_display_t *display, ds_wnd_id_t id)
143{
144 ds_client_t *client;
145 ds_window_t *wnd;
146
147 printf("ds_display_find_window: id=0x%x\n", (unsigned) id);
148
149 client = ds_display_first_client(display);
150 while (client != NULL) {
151 printf("ds_display_find_window: client=%p\n", client);
152 wnd = ds_client_find_window(client, id);
153 if (wnd != NULL) {
154 printf("ds_display_find_window: found wnd=%p id=0x%x\n",
155 wnd, (unsigned) wnd->id);
156 return wnd;
157 }
158 client = ds_display_next_client(client);
159 }
160
161 printf("ds_display_find_window: not found\n");
162 return NULL;
163}
164
165/** Post keyboard event to a display.
166 *
167 * The event is routed to the correct window by first determining the
168 * seat the keyboard device belongs to and then the event is sent to the
169 * window focused by that seat.
170 *
171 * @param display Display
172 * @param event Event
173 */
174errno_t ds_display_post_kbd_event(ds_display_t *display, kbd_event_t *event)
175{
176 ds_seat_t *seat;
177
178 // TODO Determine which seat the event belongs to
179 seat = ds_display_first_seat(display);
180 if (seat == NULL)
181 return EOK;
182
183 return ds_seat_post_kbd_event(seat, event);
184}
185
186/** Add seat to display.
187 *
188 * @param disp Display
189 * @param seat Seat
190 */
191void ds_display_add_seat(ds_display_t *disp, ds_seat_t *seat)
192{
193 assert(seat->display == NULL);
194 assert(!link_used(&seat->lseats));
195
196 seat->display = disp;
197 list_append(&seat->lseats, &disp->seats);
198}
199
200/** Remove seat from display.
201 *
202 * @param seat Seat
203 */
204void ds_display_remove_seat(ds_seat_t *seat)
205{
206 list_remove(&seat->lseats);
207 seat->display = NULL;
208}
209
210/** Get first seat in display.
211 *
212 * @param disp Display
213 * @return First seat or @c NULL if there is none
214 */
215ds_seat_t *ds_display_first_seat(ds_display_t *disp)
216{
217 link_t *link = list_first(&disp->seats);
218
219 if (link == NULL)
220 return NULL;
221
222 return list_get_instance(link, ds_seat_t, lseats);
223}
224
225/** Get next seat in display.
226 *
227 * @param seat Current seat
228 * @return Next seat or @c NULL if there is none
229 */
230ds_seat_t *ds_display_next_seat(ds_seat_t *seat)
231{
232 link_t *link = list_next(&seat->lseats, &seat->display->seats);
233
234 if (link == NULL)
235 return NULL;
236
237 return list_get_instance(link, ds_seat_t, lseats);
238}
239
240/** @}
241 */
Note: See TracBrowser for help on using the repository browser.