source: mainline/uspace/lib/wndmgt/src/wndmgt_srv.c@ ca9aa89

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

Highlight active window in task bar

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * Copyright (c) 2023 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 libwndmgt
30 * @{
31 */
32/**
33 * @file
34 * @brief Window management protocol server stub
35 */
36
37#include <wndmgt_srv.h>
38#include <errno.h>
39#include <io/log.h>
40#include <ipc/wndmgt.h>
41#include <mem.h>
42#include <stdlib.h>
43#include <stddef.h>
44#include <str.h>
45#include <wndmgt.h>
46#include "../private/wndmgt.h"
47
48static void wndmgt_callback_create_srv(wndmgt_srv_t *srv, ipc_call_t *call)
49{
50 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
51 if (sess == NULL) {
52 async_answer_0(call, ENOMEM);
53 return;
54 }
55
56 srv->client_sess = sess;
57 async_answer_0(call, EOK);
58}
59
60static void wndmgt_get_window_list_srv(wndmgt_srv_t *srv, ipc_call_t *icall)
61{
62 ipc_call_t call;
63 wndmgt_window_list_t *list = NULL;
64 size_t size;
65 errno_t rc;
66
67 if (srv->ops->get_window_list == NULL) {
68 async_answer_0(icall, ENOTSUP);
69 return;
70 }
71
72 rc = srv->ops->get_window_list(srv->arg, &list);
73 if (rc != EOK) {
74 async_answer_0(icall, rc);
75 return;
76 }
77
78 /* Send list size */
79
80 if (!async_data_read_receive(&call, &size)) {
81 wndmgt_free_window_list(list);
82 async_answer_0(&call, EREFUSED);
83 async_answer_0(icall, EREFUSED);
84 return;
85 }
86
87 if (size != sizeof(list->nwindows)) {
88 wndmgt_free_window_list(list);
89 async_answer_0(&call, EINVAL);
90 async_answer_0(icall, EINVAL);
91 return;
92 }
93
94 rc = async_data_read_finalize(&call, &list->nwindows, size);
95 if (rc != EOK) {
96 wndmgt_free_window_list(list);
97 async_answer_0(&call, rc);
98 async_answer_0(icall, rc);
99 return;
100 }
101
102 /* Send window list */
103
104 if (!async_data_read_receive(&call, &size)) {
105 wndmgt_free_window_list(list);
106 async_answer_0(&call, EREFUSED);
107 async_answer_0(icall, EREFUSED);
108 return;
109 }
110
111 if (size != list->nwindows * sizeof(sysarg_t)) {
112 wndmgt_free_window_list(list);
113 async_answer_0(&call, EINVAL);
114 async_answer_0(icall, EINVAL);
115 return;
116 }
117
118 rc = async_data_read_finalize(&call, list->windows, size);
119 if (rc != EOK) {
120 wndmgt_free_window_list(list);
121 async_answer_0(&call, rc);
122 async_answer_0(icall, rc);
123 return;
124 }
125
126 async_answer_0(icall, EOK);
127 wndmgt_free_window_list(list);
128}
129
130static void wndmgt_get_window_info_srv(wndmgt_srv_t *srv, ipc_call_t *icall)
131{
132 sysarg_t wnd_id;
133 ipc_call_t call;
134 wndmgt_window_info_t *info = NULL;
135 size_t capsize;
136 size_t size;
137 errno_t rc;
138
139 wnd_id = ipc_get_arg1(icall);
140
141 if (srv->ops->get_window_info == NULL) {
142 async_answer_0(icall, ENOTSUP);
143 return;
144 }
145
146 rc = srv->ops->get_window_info(srv->arg, wnd_id, &info);
147 if (rc != EOK) {
148 async_answer_0(icall, rc);
149 return;
150 }
151
152 /* Send caption size */
153
154 if (!async_data_read_receive(&call, &size)) {
155 wndmgt_free_window_info(info);
156 async_answer_0(&call, EREFUSED);
157 async_answer_0(icall, EREFUSED);
158 return;
159 }
160
161 if (size != sizeof(size_t)) {
162 wndmgt_free_window_info(info);
163 async_answer_0(&call, EINVAL);
164 async_answer_0(icall, EINVAL);
165 return;
166 }
167
168 capsize = str_size(info->caption);
169
170 rc = async_data_read_finalize(&call, &capsize, size);
171 if (rc != EOK) {
172 wndmgt_free_window_info(info);
173 async_answer_0(&call, rc);
174 async_answer_0(icall, rc);
175 return;
176 }
177
178 /* Send caption */
179
180 if (!async_data_read_receive(&call, &size)) {
181 wndmgt_free_window_info(info);
182 async_answer_0(&call, EREFUSED);
183 async_answer_0(icall, EREFUSED);
184 return;
185 }
186
187 if (size != capsize) {
188 wndmgt_free_window_info(info);
189 async_answer_0(&call, EINVAL);
190 async_answer_0(icall, EINVAL);
191 return;
192 }
193
194 rc = async_data_read_finalize(&call, info->caption, size);
195 if (rc != EOK) {
196 wndmgt_free_window_info(info);
197 async_answer_0(&call, rc);
198 async_answer_0(icall, rc);
199 return;
200 }
201
202 async_answer_2(icall, EOK, info->flags, info->nfocus);
203 wndmgt_free_window_info(info);
204}
205
206static void wndmgt_activate_window_srv(wndmgt_srv_t *srv, ipc_call_t *icall)
207{
208 sysarg_t dev_id;
209 sysarg_t wnd_id;
210 errno_t rc;
211
212 dev_id = ipc_get_arg1(icall);
213 wnd_id = ipc_get_arg2(icall);
214
215 if (srv->ops->activate_window == NULL) {
216 async_answer_0(icall, ENOTSUP);
217 return;
218 }
219
220 rc = srv->ops->activate_window(srv->arg, dev_id, wnd_id);
221 async_answer_0(icall, rc);
222}
223
224static void wndmgt_close_window_srv(wndmgt_srv_t *srv, ipc_call_t *icall)
225{
226 sysarg_t wnd_id;
227 errno_t rc;
228
229 wnd_id = ipc_get_arg1(icall);
230
231 if (srv->ops->activate_window == NULL) {
232 async_answer_0(icall, ENOTSUP);
233 return;
234 }
235
236 rc = srv->ops->close_window(srv->arg, wnd_id);
237 async_answer_0(icall, rc);
238}
239
240static void wndmgt_get_event_srv(wndmgt_srv_t *srv, ipc_call_t *icall)
241{
242 wndmgt_ev_t event;
243 ipc_call_t call;
244 size_t size;
245 errno_t rc;
246
247 if (srv->ops->get_event == NULL) {
248 async_answer_0(icall, ENOTSUP);
249 return;
250 }
251
252 rc = srv->ops->get_event(srv->arg, &event);
253 if (rc != EOK) {
254 async_answer_0(icall, rc);
255 return;
256 }
257
258 /* Transfer event data */
259 if (!async_data_read_receive(&call, &size)) {
260 async_answer_0(&call, EREFUSED);
261 async_answer_0(icall, EREFUSED);
262 return;
263 }
264
265 if (size != sizeof(event)) {
266 async_answer_0(&call, EREFUSED);
267 async_answer_0(icall, EREFUSED);
268 return;
269 }
270
271 rc = async_data_read_finalize(&call, &event, sizeof(event));
272 if (rc != EOK) {
273 async_answer_0(&call, rc);
274 async_answer_0(icall, rc);
275 return;
276 }
277
278 async_answer_0(icall, EOK);
279}
280
281void wndmgt_conn(ipc_call_t *icall, wndmgt_srv_t *srv)
282{
283 /* Accept the connection */
284 async_accept_0(icall);
285
286 while (true) {
287 ipc_call_t call;
288
289 async_get_call(&call);
290 sysarg_t method = ipc_get_imethod(&call);
291
292 if (!method) {
293 /* The other side has hung up */
294 async_answer_0(&call, EOK);
295 break;
296 }
297
298 switch (method) {
299 case WNDMGT_CALLBACK_CREATE:
300 wndmgt_callback_create_srv(srv, &call);
301 break;
302 case WNDMGT_GET_WINDOW_LIST:
303 wndmgt_get_window_list_srv(srv, &call);
304 break;
305 case WNDMGT_GET_WINDOW_INFO:
306 wndmgt_get_window_info_srv(srv, &call);
307 break;
308 case WNDMGT_ACTIVATE_WINDOW:
309 wndmgt_activate_window_srv(srv, &call);
310 break;
311 case WNDMGT_CLOSE_WINDOW:
312 wndmgt_close_window_srv(srv, &call);
313 break;
314 case WNDMGT_GET_EVENT:
315 wndmgt_get_event_srv(srv, &call);
316 break;
317 default:
318 async_answer_0(&call, ENOTSUP);
319 }
320 }
321
322 /* Hang up callback session */
323 if (srv->client_sess != NULL) {
324 async_hangup(srv->client_sess);
325 srv->client_sess = NULL;
326 }
327}
328
329/** Initialize window management server structure
330 *
331 * @param srv Window management server structure to initialize
332 */
333void wndmgt_srv_initialize(wndmgt_srv_t *srv)
334{
335 memset(srv, 0, sizeof(*srv));
336}
337
338/** Send 'pending' event to client.
339 *
340 * @param srv Window management server structure
341 */
342void wndmgt_srv_ev_pending(wndmgt_srv_t *srv)
343{
344 async_exch_t *exch;
345
346 exch = async_exchange_begin(srv->client_sess);
347 async_msg_0(exch, WNDMGT_EV_PENDING);
348 async_exchange_end(exch);
349}
350
351/** @}
352 */
Note: See TracBrowser for help on using the repository browser.