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
RevLine 
[5d94b16c]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>
[902f0906]37#include <io/cons_event.h>
[5d94b16c]38#include <ipc/console.h>
39#include <stdlib.h>
[8d2dd7f2]40#include <stddef.h>
[5d94b16c]41
42#include <io/con_srv.h>
43
[b7fd2a0]44static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *call)
[902f0906]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
[a46e56b]68static void con_read_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]69 ipc_call_t *call)
70{
71 void *buf;
72 size_t size;
[b7fd2a0]73 errno_t rc;
[a46e56b]74 cap_call_handle_t rcall_handle;
[5d94b16c]75
[a46e56b]76 if (!async_data_read_receive(&rcall_handle, &size)) {
77 async_answer_0(chandle, EINVAL);
[5d94b16c]78 return;
79 }
80
81 buf = malloc(size);
82 if (buf == NULL) {
[a46e56b]83 async_answer_0(rcall_handle, ENOMEM);
84 async_answer_0(chandle, ENOMEM);
[5d94b16c]85 return;
86 }
87
88 if (srv->srvs->ops->read == NULL) {
[a46e56b]89 async_answer_0(rcall_handle, ENOTSUP);
90 async_answer_0(chandle, ENOTSUP);
[ccfe9c3]91 free(buf);
[5d94b16c]92 return;
93 }
94
[c8211849]95 size_t nread;
96 rc = srv->srvs->ops->read(srv, buf, size, &nread);
97 if (rc != EOK) {
[a46e56b]98 async_answer_0(rcall_handle, rc);
99 async_answer_0(chandle, rc);
[ccfe9c3]100 free(buf);
[5d94b16c]101 return;
102 }
103
[a46e56b]104 async_data_read_finalize(rcall_handle, buf, nread);
[5d94b16c]105 free(buf);
106
[a46e56b]107 async_answer_1(chandle, EOK, nread);
[5d94b16c]108}
109
[a46e56b]110static void con_write_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]111 ipc_call_t *call)
112{
113 void *data;
114 size_t size;
[b7fd2a0]115 errno_t rc;
[5d94b16c]116
117 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
118 if (rc != EOK) {
[a46e56b]119 async_answer_0(chandle, rc);
[5d94b16c]120 return;
121 }
122
123 if (srv->srvs->ops->write == NULL) {
[a46e56b]124 async_answer_0(chandle, ENOTSUP);
[5d94b16c]125 return;
126 }
127
[c8211849]128 size_t nwritten = 0;
129 rc = srv->srvs->ops->write(srv, data, size, &nwritten);
[5d94b16c]130 free(data);
131
[a46e56b]132 async_answer_1(chandle, rc, nwritten);
[5d94b16c]133}
134
[a46e56b]135static void con_sync_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]136 ipc_call_t *call)
137{
138 if (srv->srvs->ops->sync == NULL) {
[a46e56b]139 async_answer_0(chandle, ENOTSUP);
[5d94b16c]140 return;
141 }
142
143 srv->srvs->ops->sync(srv);
[a46e56b]144 async_answer_0(chandle, EOK);
[5d94b16c]145}
146
[a46e56b]147static void con_clear_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]148 ipc_call_t *call)
149{
150 if (srv->srvs->ops->clear == NULL) {
[a46e56b]151 async_answer_0(chandle, ENOTSUP);
[5d94b16c]152 return;
153 }
154
155 srv->srvs->ops->clear(srv);
[a46e56b]156 async_answer_0(chandle, EOK);
[5d94b16c]157}
158
[a46e56b]159static void con_set_pos_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]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) {
[a46e56b]169 async_answer_0(chandle, ENOTSUP);
[5d94b16c]170 return;
171 }
172
173 srv->srvs->ops->set_pos(srv, col, row);
[a46e56b]174 async_answer_0(chandle, EOK);
[5d94b16c]175}
176
[a46e56b]177static void con_get_pos_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]178 ipc_call_t *call)
179{
[b7fd2a0]180 errno_t rc;
[5d94b16c]181 sysarg_t col;
182 sysarg_t row;
183
184 if (srv->srvs->ops->get_pos == NULL) {
[a46e56b]185 async_answer_0(chandle, ENOTSUP);
[5d94b16c]186 return;
187 }
188
189 rc = srv->srvs->ops->get_pos(srv, &col, &row);
[a46e56b]190 async_answer_2(chandle, rc, col, row);
[5d94b16c]191}
192
[a46e56b]193static void con_get_size_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]194 ipc_call_t *call)
195{
[b7fd2a0]196 errno_t rc;
[5d94b16c]197 sysarg_t cols;
198 sysarg_t rows;
199
200 if (srv->srvs->ops->get_size == NULL) {
[a46e56b]201 async_answer_0(chandle, ENOTSUP);
[5d94b16c]202 return;
203 }
204
205 rc = srv->srvs->ops->get_size(srv, &cols, &rows);
[a46e56b]206 async_answer_2(chandle, rc, cols, rows);
[5d94b16c]207}
208
[a46e56b]209static void con_get_color_cap_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]210 ipc_call_t *call)
211{
[b7fd2a0]212 errno_t rc;
[5d94b16c]213 console_caps_t ccap;
214
215 if (srv->srvs->ops->get_color_cap == NULL) {
[a46e56b]216 async_answer_0(chandle, ENOTSUP);
[5d94b16c]217 return;
218 }
219
220 rc = srv->srvs->ops->get_color_cap(srv, &ccap);
[a46e56b]221 async_answer_1(chandle, rc, (sysarg_t)ccap);
[5d94b16c]222}
223
[a46e56b]224static void con_set_style_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]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) {
[a46e56b]232 async_answer_0(chandle, ENOTSUP);
[5d94b16c]233 return;
234 }
235
236 srv->srvs->ops->set_style(srv, style);
[a46e56b]237 async_answer_0(chandle, EOK);
[5d94b16c]238}
239
[a46e56b]240static void con_set_color_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]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) {
[a46e56b]252 async_answer_0(chandle, ENOTSUP);
[5d94b16c]253 return;
254 }
255
256 srv->srvs->ops->set_color(srv, bgcolor, fgcolor, flags);
[a46e56b]257 async_answer_0(chandle, EOK);
[5d94b16c]258}
259
[a46e56b]260static void con_set_rgb_color_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]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) {
[a46e56b]270 async_answer_0(chandle, ENOTSUP);
[5d94b16c]271 return;
272 }
273
274 srv->srvs->ops->set_rgb_color(srv, bgcolor, fgcolor);
[a46e56b]275 async_answer_0(chandle, EOK);
[5d94b16c]276}
277
[a46e56b]278static void con_set_cursor_visibility_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]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) {
[a46e56b]286 async_answer_0(chandle, ENOTSUP);
[5d94b16c]287 return;
288 }
289
290 srv->srvs->ops->set_cursor_visibility(srv, show);
[a46e56b]291 async_answer_0(chandle, EOK);
[5d94b16c]292}
293
[a46e56b]294static void con_get_event_srv(con_srv_t *srv, cap_call_handle_t chandle,
[5d94b16c]295 ipc_call_t *call)
296{
[b7fd2a0]297 errno_t rc;
[902f0906]298 cons_event_t event;
299 ipc_call_t result;
[5d94b16c]300
301 if (srv->srvs->ops->get_event == NULL) {
[a46e56b]302 async_answer_0(chandle, ENOTSUP);
[5d94b16c]303 return;
304 }
305
306 rc = srv->srvs->ops->get_event(srv, &event);
[902f0906]307 if (rc != EOK) {
[a46e56b]308 async_answer_0(chandle, rc);
[902f0906]309 return;
310 }
311
312 rc = console_ev_encode(&event, &result);
313 if (rc != EOK) {
[a46e56b]314 async_answer_0(chandle, rc);
[902f0906]315 return;
316 }
317
[a46e56b]318 async_answer_5(chandle, rc, IPC_GET_ARG1(result), IPC_GET_ARG2(result),
[902f0906]319 IPC_GET_ARG3(result), IPC_GET_ARG4(result), IPC_GET_ARG5(result));
[5d94b16c]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
[a46e56b]342errno_t con_conn(cap_call_handle_t icall_handle, ipc_call_t *icall, con_srvs_t *srvs)
[5d94b16c]343{
344 con_srv_t *srv;
[b7fd2a0]345 errno_t rc;
[5d94b16c]346
347 /* Accept the connection */
[a46e56b]348 async_answer_0(icall_handle, EOK);
[5d94b16c]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;
[a46e56b]362 cap_call_handle_t chandle = 0;
[5d94b16c]363
[a46e56b]364 while (chandle == 0) {
[5d94b16c]365 /* XXX Need to be able to abort immediately */
[a46e56b]366 chandle = async_get_call_timeout(&call,
[5d94b16c]367 srvs->abort_timeout);
368
369 if (srv->srvs->aborted) {
[a46e56b]370 if (chandle != 0)
371 async_answer_0(chandle, EINTR);
[5d94b16c]372 break;
373 }
374 }
375
[a46e56b]376 if (chandle == 0)
[5d94b16c]377 break;
378
379 sysarg_t method = IPC_GET_IMETHOD(call);
380
381 if (!method) {
382 /* The other side has hung up */
[a46e56b]383 async_answer_0(chandle, EOK);
[5d94b16c]384 break;
385 }
386
387 switch (method) {
388 case VFS_OUT_READ:
[a46e56b]389 con_read_srv(srv, chandle, &call);
[5d94b16c]390 break;
391 case VFS_OUT_WRITE:
[a46e56b]392 con_write_srv(srv, chandle, &call);
[5d94b16c]393 break;
394 case VFS_OUT_SYNC:
[a46e56b]395 con_sync_srv(srv, chandle, &call);
[5d94b16c]396 break;
397 case CONSOLE_CLEAR:
[a46e56b]398 con_clear_srv(srv, chandle, &call);
[5d94b16c]399 break;
400 case CONSOLE_SET_POS:
[a46e56b]401 con_set_pos_srv(srv, chandle, &call);
[5d94b16c]402 break;
403 case CONSOLE_GET_POS:
[a46e56b]404 con_get_pos_srv(srv, chandle, &call);
[5d94b16c]405 break;
406 case CONSOLE_GET_SIZE:
[a46e56b]407 con_get_size_srv(srv, chandle, &call);
[5d94b16c]408 break;
409 case CONSOLE_GET_COLOR_CAP:
[a46e56b]410 con_get_color_cap_srv(srv, chandle, &call);
[5d94b16c]411 break;
412 case CONSOLE_SET_STYLE:
[a46e56b]413 con_set_style_srv(srv, chandle, &call);
[5d94b16c]414 break;
415 case CONSOLE_SET_COLOR:
[a46e56b]416 con_set_color_srv(srv, chandle, &call);
[5d94b16c]417 break;
418 case CONSOLE_SET_RGB_COLOR:
[a46e56b]419 con_set_rgb_color_srv(srv, chandle, &call);
[5d94b16c]420 break;
421 case CONSOLE_SET_CURSOR_VISIBILITY:
[a46e56b]422 con_set_cursor_visibility_srv(srv, chandle, &call);
[5d94b16c]423 break;
424 case CONSOLE_GET_EVENT:
[a46e56b]425 con_get_event_srv(srv, chandle, &call);
[5d94b16c]426 break;
427 default:
[a46e56b]428 async_answer_0(chandle, ENOTSUP);
[5d94b16c]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.