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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 38d150e was 8d2dd7f2, checked in by Jakub Jermar <jakub@…>, 8 years ago

Reduce the number of files that include <sys/types.h>

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