source: mainline/uspace/srv/hid/display/client.c@ bf22cb78

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

Fix 32-bit build

  • Property mode set to 100644
File size: 5.6 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 client
34 */
35
36#include <adt/list.h>
37#include <errno.h>
38#include <stdlib.h>
39#include "client.h"
40#include "display.h"
41#include "window.h"
42
43/** Create client.
44 *
45 * @param display Parent display
46 * @param cb Client callbacks
47 * @param cb_arg Callback argument
48 * @param rclient Place to store pointer to new client.
49 * @return EOK on success, ENOMEM if out of memory
50 */
51errno_t ds_client_create(ds_display_t *display, ds_client_cb_t *cb,
52 void *cb_arg, ds_client_t **rclient)
53{
54 ds_client_t *client;
55
56 client = calloc(1, sizeof(ds_client_t));
57 if (client == NULL)
58 return ENOMEM;
59
60 list_initialize(&client->windows);
61 list_initialize(&client->events);
62 client->cb = cb;
63 client->cb_arg = cb_arg;
64
65 ds_display_add_client(display, client);
66
67 *rclient = client;
68 return EOK;
69}
70
71/** Destroy client.
72 *
73 * @param client Client
74 */
75void ds_client_destroy(ds_client_t *client)
76{
77 ds_window_t *window;
78
79 window = ds_client_first_window(client);
80 while (window != NULL) {
81 ds_window_destroy(window);
82 window = ds_client_first_window(client);
83 }
84
85 assert(list_empty(&client->windows));
86 ds_display_remove_client(client);
87 free(client);
88}
89
90/** Add window to client.
91 *
92 * @param client client
93 * @param wnd Window
94 * @return EOK on success, ENOMEM if there are no free window identifiers
95 */
96errno_t ds_client_add_window(ds_client_t *client, ds_window_t *wnd)
97{
98 assert(wnd->client == NULL);
99 assert(!link_used(&wnd->lwindows));
100
101 wnd->client = client;
102 wnd->id = client->display->next_wnd_id++;
103 list_append(&wnd->lwindows, &client->windows);
104
105 return EOK;
106}
107
108/** Remove window from client.
109 *
110 * @param wnd Window
111 */
112void ds_client_remove_window(ds_window_t *wnd)
113{
114 list_remove(&wnd->lwindows);
115 wnd->client = NULL;
116}
117
118/** Find window by ID.
119 *
120 * @param client Client
121 * @param id Window ID
122 */
123#include <stdio.h>
124ds_window_t *ds_client_find_window(ds_client_t *client, ds_wnd_id_t id)
125{
126 ds_window_t *wnd;
127
128 // TODO Make this faster
129 printf("ds_client_find_window: id=0x%x\n", (unsigned) id);
130 wnd = ds_client_first_window(client);
131 while (wnd != NULL) {
132 printf("ds_client_find_window: wnd=%p wnd->id=0x%x\n", wnd,
133 (unsigned) wnd->id);
134 if (wnd->id == id)
135 return wnd;
136 wnd = ds_client_next_window(wnd);
137 }
138
139 return NULL;
140}
141
142/** Get first window in client.
143 *
144 * @param client Client
145 * @return First window or @c NULL if there is none
146 */
147ds_window_t *ds_client_first_window(ds_client_t *client)
148{
149 link_t *link = list_first(&client->windows);
150
151 if (link == NULL)
152 return NULL;
153
154 return list_get_instance(link, ds_window_t, lwindows);
155}
156
157/** Get next window in client.
158 *
159 * @param wnd Current window
160 * @return Next window or @c NULL if there is none
161 */
162ds_window_t *ds_client_next_window(ds_window_t *wnd)
163{
164 link_t *link = list_next(&wnd->lwindows, &wnd->client->windows);
165
166 if (link == NULL)
167 return NULL;
168
169 return list_get_instance(link, ds_window_t, lwindows);
170}
171
172/** Get next event from client event queue.
173 *
174 * @param client Client
175 * @param ewindow Place to store pointer to window receiving the event
176 * @param event Place to store event
177 * @return Graphic context
178 */
179errno_t ds_client_get_event(ds_client_t *client, ds_window_t **ewindow,
180 display_wnd_ev_t *event)
181{
182 link_t *link;
183 ds_window_ev_t *wevent;
184
185 link = list_first(&client->events);
186 if (link == NULL)
187 return ENOENT;
188
189 wevent = list_get_instance(link, ds_window_ev_t, levents);
190 list_remove(link);
191
192 *ewindow = wevent->window;
193 *event = wevent->event;
194 free(wevent);
195 return EOK;
196}
197
198/** Post keyboard event to the client's message queue.
199 *
200 * @param client Client
201 * @param ewindow Window that the message is targetted to
202 * @param event Event
203 *
204 * @return EOK on success or an error code
205 */
206errno_t ds_client_post_kbd_event(ds_client_t *client, ds_window_t *ewindow,
207 kbd_event_t *event)
208{
209 ds_window_ev_t *wevent;
210
211 wevent = calloc(1, sizeof(ds_window_ev_t));
212 if (wevent == NULL)
213 return ENOMEM;
214
215 wevent->window = ewindow;
216 wevent->event.kbd_event = *event;
217 list_append(&wevent->levents, &client->events);
218
219 /* Notify the client */
220 // TODO Do not send more than once until client drains the queue
221 client->cb->ev_pending(client->cb_arg);
222
223 return EOK;
224}
225
226/** @}
227 */
Note: See TracBrowser for help on using the repository browser.