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

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

Improve libdisplay tests, fix bugs

  • Property mode set to 100644
File size: 5.4 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 assert(list_empty(&client->windows));
78 ds_display_remove_client(client);
79 free(client);
80}
81
82/** Add window to client.
83 *
84 * @param client client
85 * @param wnd Window
86 * @return EOK on success, ENOMEM if there are no free window identifiers
87 */
88errno_t ds_client_add_window(ds_client_t *client, ds_window_t *wnd)
89{
90 assert(wnd->client == NULL);
91 assert(!link_used(&wnd->lwindows));
92
93 wnd->client = client;
94 wnd->id = client->display->next_wnd_id++;
95 list_append(&wnd->lwindows, &client->windows);
96
97 return EOK;
98}
99
100/** Remove window from client.
101 *
102 * @param wnd Window
103 */
104void ds_client_remove_window(ds_window_t *wnd)
105{
106 list_remove(&wnd->lwindows);
107 wnd->client = NULL;
108}
109
110/** Find window by ID.
111 *
112 * @param client Client
113 * @param id Window ID
114 */
115#include <stdio.h>
116ds_window_t *ds_client_find_window(ds_client_t *client, ds_wnd_id_t id)
117{
118 ds_window_t *wnd;
119
120 // TODO Make this faster
121 printf("ds_client_find_window: id=0x%lx\n", id);
122 wnd = ds_client_first_window(client);
123 while (wnd != NULL) {
124 printf("ds_client_find_window: wnd=%p wnd->id=0x%lx\n", wnd, wnd->id);
125 if (wnd->id == id)
126 return wnd;
127 wnd = ds_client_next_window(wnd);
128 }
129
130 return NULL;
131}
132
133/** Get first window in client.
134 *
135 * @param client Client
136 * @return First window or @c NULL if there is none
137 */
138ds_window_t *ds_client_first_window(ds_client_t *client)
139{
140 link_t *link = list_first(&client->windows);
141
142 if (link == NULL)
143 return NULL;
144
145 return list_get_instance(link, ds_window_t, lwindows);
146}
147
148/** Get next window in client.
149 *
150 * @param wnd Current window
151 * @return Next window or @c NULL if there is none
152 */
153ds_window_t *ds_client_next_window(ds_window_t *wnd)
154{
155 link_t *link = list_next(&wnd->lwindows, &wnd->client->windows);
156
157 if (link == NULL)
158 return NULL;
159
160 return list_get_instance(link, ds_window_t, lwindows);
161}
162
163/** Get next event from client event queue.
164 *
165 * @param client Client
166 * @param ewindow Place to store pointer to window receiving the event
167 * @param event Place to store event
168 * @return Graphic context
169 */
170errno_t ds_client_get_event(ds_client_t *client, ds_window_t **ewindow,
171 display_wnd_ev_t *event)
172{
173 link_t *link;
174 ds_window_ev_t *wevent;
175
176 link = list_first(&client->events);
177 if (link == NULL)
178 return ENOENT;
179
180 wevent = list_get_instance(link, ds_window_ev_t, levents);
181 list_remove(link);
182
183 *ewindow = wevent->window;
184 *event = wevent->event;
185 free(wevent);
186 return EOK;
187}
188
189/** Post keyboard event to the client's message queue.
190 *
191 * @param client Client
192 * @param ewindow Window that the message is targetted to
193 * @param event Event
194 *
195 * @return EOK on success or an error code
196 */
197errno_t ds_client_post_kbd_event(ds_client_t *client, ds_window_t *ewindow,
198 kbd_event_t *event)
199{
200 ds_window_ev_t *wevent;
201
202 wevent = calloc(1, sizeof(ds_window_ev_t));
203 if (wevent == NULL)
204 return ENOMEM;
205
206 wevent->window = ewindow;
207 wevent->event.kbd_event = *event;
208 list_append(&wevent->levents, &client->events);
209
210 /* Notify the client */
211 // TODO Do not send more than once until client drains the queue
212 client->cb->ev_pending(client->cb_arg);
213
214 return EOK;
215}
216
217/** @}
218 */
Note: See TracBrowser for help on using the repository browser.