source: mainline/uspace/lib/c/generic/io/con_srv.c@ c8afd5a

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

Fix some block comments (found by ccheck).

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/*
2 * Copyright (c) 2012 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 libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Console protocol server stub
35 */
36#include <errno.h>
37#include <io/cons_event.h>
38#include <ipc/console.h>
39#include <stdlib.h>
40#include <stddef.h>
41
42#include <io/con_srv.h>
43
44static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *call)
45{
46 IPC_SET_ARG1(*call, event->type);
47
48 switch (event->type) {
49 case CEV_KEY:
50 IPC_SET_ARG2(*call, event->ev.key.type);
51 IPC_SET_ARG3(*call, event->ev.key.key);
52 IPC_SET_ARG4(*call, event->ev.key.mods);
53 IPC_SET_ARG5(*call, event->ev.key.c);
54 break;
55 case CEV_POS:
56 IPC_SET_ARG2(*call, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
57 IPC_SET_ARG3(*call, event->ev.pos.btn_num);
58 IPC_SET_ARG4(*call, event->ev.pos.hpos);
59 IPC_SET_ARG5(*call, event->ev.pos.vpos);
60 break;
61 default:
62 return EIO;
63 }
64
65 return EOK;
66}
67
68static void con_read_srv(con_srv_t *srv, cap_call_handle_t chandle,
69 ipc_call_t *call)
70{
71 void *buf;
72 size_t size;
73 errno_t rc;
74 cap_call_handle_t rcall_handle;
75
76 if (!async_data_read_receive(&rcall_handle, &size)) {
77 async_answer_0(chandle, EINVAL);
78 return;
79 }
80
81 buf = malloc(size);
82 if (buf == NULL) {
83 async_answer_0(rcall_handle, ENOMEM);
84 async_answer_0(chandle, ENOMEM);
85 return;
86 }
87
88 if (srv->srvs->ops->read == NULL) {
89 async_answer_0(rcall_handle, ENOTSUP);
90 async_answer_0(chandle, ENOTSUP);
91 free(buf);
92 return;
93 }
94
95 size_t nread;
96 rc = srv->srvs->ops->read(srv, buf, size, &nread);
97 if (rc != EOK) {
98 async_answer_0(rcall_handle, rc);
99 async_answer_0(chandle, rc);
100 free(buf);
101 return;
102 }
103
104 async_data_read_finalize(rcall_handle, buf, nread);
105 free(buf);
106
107 async_answer_1(chandle, EOK, nread);
108}
109
110static void con_write_srv(con_srv_t *srv, cap_call_handle_t chandle,
111 ipc_call_t *call)
112{
113 void *data;
114 size_t size;
115 errno_t rc;
116
117 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
118 if (rc != EOK) {
119 async_answer_0(chandle, rc);
120 return;
121 }
122
123 if (srv->srvs->ops->write == NULL) {
124 async_answer_0(chandle, ENOTSUP);
125 return;
126 }
127
128 size_t nwritten = 0;
129 rc = srv->srvs->ops->write(srv, data, size, &nwritten);
130 free(data);
131
132 async_answer_1(chandle, rc, nwritten);
133}
134
135static void con_sync_srv(con_srv_t *srv, cap_call_handle_t chandle,
136 ipc_call_t *call)
137{
138 if (srv->srvs->ops->sync == NULL) {
139 async_answer_0(chandle, ENOTSUP);
140 return;
141 }
142
143 srv->srvs->ops->sync(srv);
144 async_answer_0(chandle, EOK);
145}
146
147static void con_clear_srv(con_srv_t *srv, cap_call_handle_t chandle,
148 ipc_call_t *call)
149{
150 if (srv->srvs->ops->clear == NULL) {
151 async_answer_0(chandle, ENOTSUP);
152 return;
153 }
154
155 srv->srvs->ops->clear(srv);
156 async_answer_0(chandle, EOK);
157}
158
159static void con_set_pos_srv(con_srv_t *srv, cap_call_handle_t chandle,
160 ipc_call_t *call)
161{
162 sysarg_t col;
163 sysarg_t row;
164
165 col = IPC_GET_ARG1(*call);
166 row = IPC_GET_ARG2(*call);
167
168 if (srv->srvs->ops->set_pos == NULL) {
169 async_answer_0(chandle, ENOTSUP);
170 return;
171 }
172
173 srv->srvs->ops->set_pos(srv, col, row);
174 async_answer_0(chandle, EOK);
175}
176
177static void con_get_pos_srv(con_srv_t *srv, cap_call_handle_t chandle,
178 ipc_call_t *call)
179{
180 errno_t rc;
181 sysarg_t col;
182 sysarg_t row;
183
184 if (srv->srvs->ops->get_pos == NULL) {
185 async_answer_0(chandle, ENOTSUP);
186 return;
187 }
188
189 rc = srv->srvs->ops->get_pos(srv, &col, &row);
190 async_answer_2(chandle, rc, col, row);
191}
192
193static void con_get_size_srv(con_srv_t *srv, cap_call_handle_t chandle,
194 ipc_call_t *call)
195{
196 errno_t rc;
197 sysarg_t cols;
198 sysarg_t rows;
199
200 if (srv->srvs->ops->get_size == NULL) {
201 async_answer_0(chandle, ENOTSUP);
202 return;
203 }
204
205 rc = srv->srvs->ops->get_size(srv, &cols, &rows);
206 async_answer_2(chandle, rc, cols, rows);
207}
208
209static void con_get_color_cap_srv(con_srv_t *srv, cap_call_handle_t chandle,
210 ipc_call_t *call)
211{
212 errno_t rc;
213 console_caps_t ccap;
214
215 if (srv->srvs->ops->get_color_cap == NULL) {
216 async_answer_0(chandle, ENOTSUP);
217 return;
218 }
219
220 rc = srv->srvs->ops->get_color_cap(srv, &ccap);
221 async_answer_1(chandle, rc, (sysarg_t)ccap);
222}
223
224static void con_set_style_srv(con_srv_t *srv, cap_call_handle_t chandle,
225 ipc_call_t *call)
226{
227 console_style_t style;
228
229 style = IPC_GET_ARG1(*call);
230
231 if (srv->srvs->ops->set_style == NULL) {
232 async_answer_0(chandle, ENOTSUP);
233 return;
234 }
235
236 srv->srvs->ops->set_style(srv, style);
237 async_answer_0(chandle, EOK);
238}
239
240static void con_set_color_srv(con_srv_t *srv, cap_call_handle_t chandle,
241 ipc_call_t *call)
242{
243 console_color_t bgcolor;
244 console_color_t fgcolor;
245 console_color_attr_t flags;
246
247 bgcolor = IPC_GET_ARG1(*call);
248 fgcolor = IPC_GET_ARG2(*call);
249 flags = IPC_GET_ARG3(*call);
250
251 if (srv->srvs->ops->set_color == NULL) {
252 async_answer_0(chandle, ENOTSUP);
253 return;
254 }
255
256 srv->srvs->ops->set_color(srv, bgcolor, fgcolor, flags);
257 async_answer_0(chandle, EOK);
258}
259
260static void con_set_rgb_color_srv(con_srv_t *srv, cap_call_handle_t chandle,
261 ipc_call_t *call)
262{
263 pixel_t bgcolor;
264 pixel_t fgcolor;
265
266 bgcolor = IPC_GET_ARG1(*call);
267 fgcolor = IPC_GET_ARG2(*call);
268
269 if (srv->srvs->ops->set_rgb_color == NULL) {
270 async_answer_0(chandle, ENOTSUP);
271 return;
272 }
273
274 srv->srvs->ops->set_rgb_color(srv, bgcolor, fgcolor);
275 async_answer_0(chandle, EOK);
276}
277
278static void con_set_cursor_visibility_srv(con_srv_t *srv, cap_call_handle_t chandle,
279 ipc_call_t *call)
280{
281 bool show;
282
283 show = IPC_GET_ARG1(*call);
284
285 if (srv->srvs->ops->set_cursor_visibility == NULL) {
286 async_answer_0(chandle, ENOTSUP);
287 return;
288 }
289
290 srv->srvs->ops->set_cursor_visibility(srv, show);
291 async_answer_0(chandle, EOK);
292}
293
294static void con_get_event_srv(con_srv_t *srv, cap_call_handle_t chandle,
295 ipc_call_t *call)
296{
297 errno_t rc;
298 cons_event_t event;
299 ipc_call_t result;
300
301 if (srv->srvs->ops->get_event == NULL) {
302 async_answer_0(chandle, ENOTSUP);
303 return;
304 }
305
306 rc = srv->srvs->ops->get_event(srv, &event);
307 if (rc != EOK) {
308 async_answer_0(chandle, rc);
309 return;
310 }
311
312 rc = console_ev_encode(&event, &result);
313 if (rc != EOK) {
314 async_answer_0(chandle, rc);
315 return;
316 }
317
318 async_answer_5(chandle, rc, IPC_GET_ARG1(result), IPC_GET_ARG2(result),
319 IPC_GET_ARG3(result), IPC_GET_ARG4(result), IPC_GET_ARG5(result));
320}
321
322static con_srv_t *con_srv_create(con_srvs_t *srvs)
323{
324 con_srv_t *srv;
325
326 srv = calloc(1, sizeof(*srv));
327 if (srv == NULL)
328 return NULL;
329
330 srv->srvs = srvs;
331 return srv;
332}
333
334void con_srvs_init(con_srvs_t *srvs)
335{
336 srvs->ops = NULL;
337 srvs->sarg = NULL;
338 srvs->abort_timeout = 0;
339 srvs->aborted = false;
340}
341
342errno_t con_conn(cap_call_handle_t icall_handle, ipc_call_t *icall, con_srvs_t *srvs)
343{
344 con_srv_t *srv;
345 errno_t rc;
346
347 /* Accept the connection */
348 async_answer_0(icall_handle, EOK);
349
350 srv = con_srv_create(srvs);
351 if (srv == NULL)
352 return ENOMEM;
353
354 srv->client_sess = NULL;
355
356 rc = srvs->ops->open(srvs, srv);
357 if (rc != EOK)
358 return rc;
359
360 while (true) {
361 ipc_call_t call;
362 cap_call_handle_t chandle = 0;
363
364 while (chandle == 0) {
365 /* XXX Need to be able to abort immediately */
366 chandle = async_get_call_timeout(&call,
367 srvs->abort_timeout);
368
369 if (srv->srvs->aborted) {
370 if (chandle != 0)
371 async_answer_0(chandle, EINTR);
372 break;
373 }
374 }
375
376 if (chandle == 0)
377 break;
378
379 sysarg_t method = IPC_GET_IMETHOD(call);
380
381 if (!method) {
382 /* The other side has hung up */
383 async_answer_0(chandle, EOK);
384 break;
385 }
386
387 switch (method) {
388 case VFS_OUT_READ:
389 con_read_srv(srv, chandle, &call);
390 break;
391 case VFS_OUT_WRITE:
392 con_write_srv(srv, chandle, &call);
393 break;
394 case VFS_OUT_SYNC:
395 con_sync_srv(srv, chandle, &call);
396 break;
397 case CONSOLE_CLEAR:
398 con_clear_srv(srv, chandle, &call);
399 break;
400 case CONSOLE_SET_POS:
401 con_set_pos_srv(srv, chandle, &call);
402 break;
403 case CONSOLE_GET_POS:
404 con_get_pos_srv(srv, chandle, &call);
405 break;
406 case CONSOLE_GET_SIZE:
407 con_get_size_srv(srv, chandle, &call);
408 break;
409 case CONSOLE_GET_COLOR_CAP:
410 con_get_color_cap_srv(srv, chandle, &call);
411 break;
412 case CONSOLE_SET_STYLE:
413 con_set_style_srv(srv, chandle, &call);
414 break;
415 case CONSOLE_SET_COLOR:
416 con_set_color_srv(srv, chandle, &call);
417 break;
418 case CONSOLE_SET_RGB_COLOR:
419 con_set_rgb_color_srv(srv, chandle, &call);
420 break;
421 case CONSOLE_SET_CURSOR_VISIBILITY:
422 con_set_cursor_visibility_srv(srv, chandle, &call);
423 break;
424 case CONSOLE_GET_EVENT:
425 con_get_event_srv(srv, chandle, &call);
426 break;
427 default:
428 async_answer_0(chandle, ENOTSUP);
429 }
430 }
431
432 rc = srvs->ops->close(srv);
433 free(srv);
434
435 return rc;
436}
437
438/** @}
439 */
Note: See TracBrowser for help on using the repository browser.