source: mainline/uspace/lib/display/src/disp_srv.c@ 6828a56

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

Add pos_id information to move request, too

This will become useful momentarily.

  • Property mode set to 100644
File size: 14.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 libdisplay
30 * @{
31 */
32/**
33 * @file
34 * @brief Display protocol server stub
35 */
36
37#include <disp_srv.h>
38#include <display/event.h>
39#include <display/info.h>
40#include <display/wndresize.h>
41#include <errno.h>
42#include <io/log.h>
43#include <ipc/display.h>
44#include <mem.h>
45#include <stdlib.h>
46#include <stddef.h>
47#include "../private/params.h"
48
49static void display_callback_create_srv(display_srv_t *srv, ipc_call_t *call)
50{
51 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
52 if (sess == NULL) {
53 async_answer_0(call, ENOMEM);
54 return;
55 }
56
57 srv->client_sess = sess;
58 async_answer_0(call, EOK);
59}
60
61static void display_window_create_srv(display_srv_t *srv, ipc_call_t *icall)
62{
63 sysarg_t wnd_id;
64 ipc_call_t call;
65 display_wnd_params_enc_t eparams;
66 display_wnd_params_t params;
67 char *caption;
68 size_t size;
69 errno_t rc;
70
71 if (!async_data_write_receive(&call, &size)) {
72 async_answer_0(&call, EREFUSED);
73 async_answer_0(icall, EREFUSED);
74 return;
75 }
76
77 if (size != sizeof(display_wnd_params_enc_t)) {
78 async_answer_0(&call, EINVAL);
79 async_answer_0(icall, EINVAL);
80 return;
81 }
82
83 rc = async_data_write_finalize(&call, &eparams, size);
84 if (rc != EOK) {
85 async_answer_0(&call, rc);
86 async_answer_0(icall, rc);
87 return;
88 }
89
90 caption = calloc(eparams.caption_size + 1, 1);
91 if (caption == NULL) {
92 async_answer_0(icall, ENOMEM);
93 return;
94 }
95
96 if (!async_data_write_receive(&call, &size)) {
97 free(caption);
98 async_answer_0(&call, EREFUSED);
99 async_answer_0(icall, EREFUSED);
100 return;
101 }
102
103 if (size != eparams.caption_size) {
104 free(caption);
105 async_answer_0(&call, EINVAL);
106 async_answer_0(icall, EINVAL);
107 return;
108 }
109
110 rc = async_data_write_finalize(&call, caption, eparams.caption_size);
111 if (rc != EOK) {
112 free(caption);
113 async_answer_0(&call, rc);
114 async_answer_0(icall, rc);
115 return;
116 }
117
118 if (srv->ops->window_create == NULL) {
119 free(caption);
120 async_answer_0(icall, ENOTSUP);
121 return;
122 }
123
124 /* Decode the parameters from transport */
125 params.rect = eparams.rect;
126 params.caption = caption;
127 params.min_size = eparams.min_size;
128 params.pos = eparams.pos;
129 params.flags = eparams.flags;
130
131 rc = srv->ops->window_create(srv->arg, &params, &wnd_id);
132 async_answer_1(icall, rc, wnd_id);
133}
134
135static void display_window_destroy_srv(display_srv_t *srv, ipc_call_t *icall)
136{
137 sysarg_t wnd_id;
138 errno_t rc;
139
140 wnd_id = ipc_get_arg1(icall);
141
142 if (srv->ops->window_destroy == NULL) {
143 async_answer_0(icall, ENOTSUP);
144 return;
145 }
146
147 rc = srv->ops->window_destroy(srv->arg, wnd_id);
148 async_answer_0(icall, rc);
149}
150
151static void display_window_move_req_srv(display_srv_t *srv, ipc_call_t *icall)
152{
153 sysarg_t wnd_id;
154 sysarg_t pos_id;
155 ipc_call_t call;
156 gfx_coord2_t pos;
157 size_t size;
158 errno_t rc;
159
160 wnd_id = ipc_get_arg1(icall);
161 pos_id = ipc_get_arg2(icall);
162
163 if (!async_data_write_receive(&call, &size)) {
164 async_answer_0(&call, EREFUSED);
165 async_answer_0(icall, EREFUSED);
166 return;
167 }
168
169 if (size != sizeof(gfx_coord2_t)) {
170 async_answer_0(&call, EINVAL);
171 async_answer_0(icall, EINVAL);
172 return;
173 }
174
175 rc = async_data_write_finalize(&call, &pos, size);
176 if (rc != EOK) {
177 async_answer_0(&call, rc);
178 async_answer_0(icall, rc);
179 return;
180 }
181
182 if (srv->ops->window_move_req == NULL) {
183 async_answer_0(icall, ENOTSUP);
184 return;
185 }
186
187 rc = srv->ops->window_move_req(srv->arg, wnd_id, &pos, pos_id);
188 async_answer_0(icall, rc);
189}
190
191static void display_window_move_srv(display_srv_t *srv, ipc_call_t *icall)
192{
193 sysarg_t wnd_id;
194 ipc_call_t call;
195 gfx_coord2_t dpos;
196 size_t size;
197 errno_t rc;
198
199 wnd_id = ipc_get_arg1(icall);
200
201 if (!async_data_write_receive(&call, &size)) {
202 async_answer_0(&call, EREFUSED);
203 async_answer_0(icall, EREFUSED);
204 return;
205 }
206
207 if (size != sizeof(gfx_coord2_t)) {
208 async_answer_0(&call, EINVAL);
209 async_answer_0(icall, EINVAL);
210 return;
211 }
212
213 rc = async_data_write_finalize(&call, &dpos, size);
214 if (rc != EOK) {
215 async_answer_0(&call, rc);
216 async_answer_0(icall, rc);
217 return;
218 }
219
220 if (srv->ops->window_move == NULL) {
221 async_answer_0(icall, ENOTSUP);
222 return;
223 }
224
225 rc = srv->ops->window_move(srv->arg, wnd_id, &dpos);
226 async_answer_0(icall, rc);
227}
228
229static void display_window_get_pos_srv(display_srv_t *srv, ipc_call_t *icall)
230{
231 sysarg_t wnd_id;
232 ipc_call_t call;
233 gfx_coord2_t dpos;
234 size_t size;
235 errno_t rc;
236
237 wnd_id = ipc_get_arg1(icall);
238
239 if (srv->ops->window_get_pos == NULL) {
240 async_answer_0(icall, ENOTSUP);
241 return;
242 }
243
244 if (!async_data_read_receive(&call, &size)) {
245 async_answer_0(&call, EREFUSED);
246 async_answer_0(icall, EREFUSED);
247 return;
248 }
249
250 rc = srv->ops->window_get_pos(srv->arg, wnd_id, &dpos);
251 if (rc != EOK) {
252 async_answer_0(&call, rc);
253 async_answer_0(icall, rc);
254 return;
255 }
256
257 if (size != sizeof(gfx_coord2_t)) {
258 async_answer_0(&call, EINVAL);
259 async_answer_0(icall, EINVAL);
260 return;
261 }
262
263 rc = async_data_read_finalize(&call, &dpos, size);
264 if (rc != EOK) {
265 async_answer_0(&call, rc);
266 async_answer_0(icall, rc);
267 return;
268 }
269
270 async_answer_0(icall, EOK);
271}
272
273static void display_window_get_max_rect_srv(display_srv_t *srv,
274 ipc_call_t *icall)
275{
276 sysarg_t wnd_id;
277 ipc_call_t call;
278 gfx_rect_t rect;
279 size_t size;
280 errno_t rc;
281
282 wnd_id = ipc_get_arg1(icall);
283
284 if (srv->ops->window_get_max_rect == NULL) {
285 async_answer_0(icall, ENOTSUP);
286 return;
287 }
288
289 if (!async_data_read_receive(&call, &size)) {
290 async_answer_0(&call, EREFUSED);
291 async_answer_0(icall, EREFUSED);
292 return;
293 }
294
295 rc = srv->ops->window_get_max_rect(srv->arg, wnd_id, &rect);
296 if (rc != EOK) {
297 async_answer_0(&call, rc);
298 async_answer_0(icall, rc);
299 return;
300 }
301
302 if (size != sizeof(gfx_rect_t)) {
303 async_answer_0(&call, EINVAL);
304 async_answer_0(icall, EINVAL);
305 return;
306 }
307
308 rc = async_data_read_finalize(&call, &rect, size);
309 if (rc != EOK) {
310 async_answer_0(&call, rc);
311 async_answer_0(icall, rc);
312 return;
313 }
314
315 async_answer_0(icall, EOK);
316}
317
318static void display_window_resize_req_srv(display_srv_t *srv, ipc_call_t *icall)
319{
320 sysarg_t wnd_id;
321 ipc_call_t call;
322 display_wnd_rsztype_t rsztype;
323 gfx_coord2_t pos;
324 sysarg_t pos_id;
325 size_t size;
326 errno_t rc;
327
328 wnd_id = ipc_get_arg1(icall);
329 rsztype = (display_wnd_rsztype_t) ipc_get_arg2(icall);
330 pos_id = ipc_get_arg3(icall);
331
332 if (!async_data_write_receive(&call, &size)) {
333 async_answer_0(&call, EREFUSED);
334 async_answer_0(icall, EREFUSED);
335 return;
336 }
337
338 if (size != sizeof(gfx_coord2_t)) {
339 async_answer_0(&call, EINVAL);
340 async_answer_0(icall, EINVAL);
341 return;
342 }
343
344 rc = async_data_write_finalize(&call, &pos, size);
345 if (rc != EOK) {
346 async_answer_0(&call, rc);
347 async_answer_0(icall, rc);
348 return;
349 }
350
351 if (srv->ops->window_resize_req == NULL) {
352 async_answer_0(icall, ENOTSUP);
353 return;
354 }
355
356 rc = srv->ops->window_resize_req(srv->arg, wnd_id, rsztype, &pos,
357 pos_id);
358 async_answer_0(icall, rc);
359}
360
361static void display_window_resize_srv(display_srv_t *srv, ipc_call_t *icall)
362{
363 sysarg_t wnd_id;
364 ipc_call_t call;
365 display_wnd_resize_t wresize;
366 size_t size;
367 errno_t rc;
368
369 wnd_id = ipc_get_arg1(icall);
370
371 if (!async_data_write_receive(&call, &size)) {
372 async_answer_0(&call, EREFUSED);
373 async_answer_0(icall, EREFUSED);
374 return;
375 }
376
377 if (size != sizeof(display_wnd_resize_t)) {
378 async_answer_0(&call, EINVAL);
379 async_answer_0(icall, EINVAL);
380 return;
381 }
382
383 rc = async_data_write_finalize(&call, &wresize, size);
384 if (rc != EOK) {
385 async_answer_0(&call, rc);
386 async_answer_0(icall, rc);
387 return;
388 }
389
390 if (srv->ops->window_resize == NULL) {
391 async_answer_0(icall, ENOTSUP);
392 return;
393 }
394
395 rc = srv->ops->window_resize(srv->arg, wnd_id, &wresize.offs,
396 &wresize.nrect);
397 async_answer_0(icall, rc);
398}
399
400static void display_window_minimize_srv(display_srv_t *srv, ipc_call_t *icall)
401{
402 sysarg_t wnd_id;
403 errno_t rc;
404
405 wnd_id = ipc_get_arg1(icall);
406
407 if (srv->ops->window_minimize == NULL) {
408 async_answer_0(icall, ENOTSUP);
409 return;
410 }
411
412 rc = srv->ops->window_minimize(srv->arg, wnd_id);
413 async_answer_0(icall, rc);
414}
415
416static void display_window_maximize_srv(display_srv_t *srv, ipc_call_t *icall)
417{
418 sysarg_t wnd_id;
419 errno_t rc;
420
421 wnd_id = ipc_get_arg1(icall);
422
423 if (srv->ops->window_maximize == NULL) {
424 async_answer_0(icall, ENOTSUP);
425 return;
426 }
427
428 rc = srv->ops->window_maximize(srv->arg, wnd_id);
429 async_answer_0(icall, rc);
430}
431
432static void display_window_unmaximize_srv(display_srv_t *srv, ipc_call_t *icall)
433{
434 sysarg_t wnd_id;
435 errno_t rc;
436
437 wnd_id = ipc_get_arg1(icall);
438
439 if (srv->ops->window_unmaximize == NULL) {
440 async_answer_0(icall, ENOTSUP);
441 return;
442 }
443
444 rc = srv->ops->window_unmaximize(srv->arg, wnd_id);
445 async_answer_0(icall, rc);
446}
447
448static void display_window_set_cursor_srv(display_srv_t *srv, ipc_call_t *icall)
449{
450 sysarg_t wnd_id;
451 display_stock_cursor_t cursor;
452 errno_t rc;
453
454 wnd_id = ipc_get_arg1(icall);
455 cursor = ipc_get_arg2(icall);
456
457 if (srv->ops->window_set_cursor == NULL) {
458 async_answer_0(icall, ENOTSUP);
459 return;
460 }
461
462 rc = srv->ops->window_set_cursor(srv->arg, wnd_id, cursor);
463 async_answer_0(icall, rc);
464}
465
466static void display_window_set_caption_srv(display_srv_t *srv,
467 ipc_call_t *icall)
468{
469 sysarg_t wnd_id;
470 ipc_call_t call;
471 char *caption;
472 size_t size;
473 errno_t rc;
474
475 wnd_id = ipc_get_arg1(icall);
476
477 if (!async_data_write_receive(&call, &size)) {
478 async_answer_0(&call, EREFUSED);
479 async_answer_0(icall, EREFUSED);
480 return;
481 }
482
483 caption = calloc(size + 1, 1);
484 if (caption == NULL) {
485 async_answer_0(&call, ENOMEM);
486 async_answer_0(icall, ENOMEM);
487 return;
488 }
489
490 rc = async_data_write_finalize(&call, caption, size);
491 if (rc != EOK) {
492 free(caption);
493 async_answer_0(&call, rc);
494 async_answer_0(icall, rc);
495 return;
496 }
497
498 if (srv->ops->window_set_caption == NULL) {
499 free(caption);
500 async_answer_0(icall, ENOTSUP);
501 return;
502 }
503
504 rc = srv->ops->window_set_caption(srv->arg, wnd_id, caption);
505 async_answer_0(icall, rc);
506 free(caption);
507}
508
509static void display_get_event_srv(display_srv_t *srv, ipc_call_t *icall)
510{
511 sysarg_t wnd_id;
512 display_wnd_ev_t event;
513 ipc_call_t call;
514 size_t size;
515 errno_t rc;
516
517 if (srv->ops->get_event == NULL) {
518 async_answer_0(icall, ENOTSUP);
519 return;
520 }
521
522 rc = srv->ops->get_event(srv->arg, &wnd_id, &event);
523 if (rc != EOK) {
524 async_answer_0(icall, rc);
525 return;
526 }
527
528 /* Transfer event data */
529 if (!async_data_read_receive(&call, &size)) {
530 async_answer_0(&call, EREFUSED);
531 async_answer_0(icall, EREFUSED);
532 return;
533 }
534
535 if (size != sizeof(event)) {
536 async_answer_0(icall, EREFUSED);
537 async_answer_0(&call, EREFUSED);
538 return;
539 }
540
541 rc = async_data_read_finalize(&call, &event, sizeof(event));
542 if (rc != EOK) {
543 async_answer_0(icall, rc);
544 async_answer_0(&call, rc);
545 return;
546 }
547
548 async_answer_1(icall, EOK, wnd_id);
549}
550
551static void display_get_info_srv(display_srv_t *srv, ipc_call_t *icall)
552{
553 display_info_t info;
554 ipc_call_t call;
555 size_t size;
556 errno_t rc;
557
558 if (srv->ops->get_info == NULL) {
559 async_answer_0(icall, ENOTSUP);
560 return;
561 }
562
563 /* Transfer information */
564 if (!async_data_read_receive(&call, &size)) {
565 async_answer_0(&call, EREFUSED);
566 async_answer_0(icall, EREFUSED);
567 return;
568 }
569
570 if (size != sizeof(info)) {
571 async_answer_0(icall, EREFUSED);
572 async_answer_0(&call, EREFUSED);
573 return;
574 }
575
576 rc = srv->ops->get_info(srv->arg, &info);
577 if (rc != EOK) {
578 async_answer_0(icall, rc);
579 async_answer_0(&call, rc);
580 return;
581 }
582
583 rc = async_data_read_finalize(&call, &info, sizeof(info));
584 if (rc != EOK) {
585 async_answer_0(icall, rc);
586 async_answer_0(&call, rc);
587 return;
588 }
589
590 async_answer_0(icall, EOK);
591}
592
593void display_conn(ipc_call_t *icall, display_srv_t *srv)
594{
595 /* Accept the connection */
596 async_accept_0(icall);
597
598 while (true) {
599 ipc_call_t call;
600
601 async_get_call(&call);
602 sysarg_t method = ipc_get_imethod(&call);
603
604 if (!method) {
605 /* The other side has hung up */
606 async_answer_0(&call, EOK);
607 break;
608 }
609
610 switch (method) {
611 case DISPLAY_CALLBACK_CREATE:
612 display_callback_create_srv(srv, &call);
613 break;
614 case DISPLAY_WINDOW_CREATE:
615 display_window_create_srv(srv, &call);
616 break;
617 case DISPLAY_WINDOW_DESTROY:
618 display_window_destroy_srv(srv, &call);
619 break;
620 case DISPLAY_WINDOW_MOVE_REQ:
621 display_window_move_req_srv(srv, &call);
622 break;
623 case DISPLAY_WINDOW_MOVE:
624 display_window_move_srv(srv, &call);
625 break;
626 case DISPLAY_WINDOW_GET_POS:
627 display_window_get_pos_srv(srv, &call);
628 break;
629 case DISPLAY_WINDOW_GET_MAX_RECT:
630 display_window_get_max_rect_srv(srv, &call);
631 break;
632 case DISPLAY_WINDOW_RESIZE_REQ:
633 display_window_resize_req_srv(srv, &call);
634 break;
635 case DISPLAY_WINDOW_RESIZE:
636 display_window_resize_srv(srv, &call);
637 break;
638 case DISPLAY_WINDOW_MINIMIZE:
639 display_window_minimize_srv(srv, &call);
640 break;
641 case DISPLAY_WINDOW_MAXIMIZE:
642 display_window_maximize_srv(srv, &call);
643 break;
644 case DISPLAY_WINDOW_UNMAXIMIZE:
645 display_window_unmaximize_srv(srv, &call);
646 break;
647 case DISPLAY_WINDOW_SET_CURSOR:
648 display_window_set_cursor_srv(srv, &call);
649 break;
650 case DISPLAY_WINDOW_SET_CAPTION:
651 display_window_set_caption_srv(srv, &call);
652 break;
653 case DISPLAY_GET_EVENT:
654 display_get_event_srv(srv, &call);
655 break;
656 case DISPLAY_GET_INFO:
657 display_get_info_srv(srv, &call);
658 break;
659 default:
660 async_answer_0(&call, ENOTSUP);
661 }
662 }
663
664 /* Hang up callback session */
665 if (srv->client_sess != NULL) {
666 async_hangup(srv->client_sess);
667 srv->client_sess = NULL;
668 }
669}
670
671/** Initialize display server structure
672 *
673 * @param srv Display server structure to initialize
674 */
675void display_srv_initialize(display_srv_t *srv)
676{
677 memset(srv, 0, sizeof(*srv));
678}
679
680/** Send 'pending' event to client.
681 *
682 * @param srv Display server structure
683 */
684void display_srv_ev_pending(display_srv_t *srv)
685{
686 async_exch_t *exch;
687
688 exch = async_exchange_begin(srv->client_sess);
689 async_msg_0(exch, DISPLAY_EV_PENDING);
690 async_exchange_end(exch);
691}
692
693/** @}
694 */
Note: See TracBrowser for help on using the repository browser.