source: mainline/uspace/lib/display/src/disp_srv.c@ 7cc30e9

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

Display server needs to store window caption

Even though it does not use it itself, it needs to provide it to
window managers (e.g. Task bar). We need to be able to set caption
for a new window and to change it for an existing window.

  • Property mode set to 100644
File size: 14.2 KB
Line 
1/*
2 * Copyright (c) 2022 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 ipc_call_t call;
155 gfx_coord2_t pos;
156 size_t size;
157 errno_t rc;
158
159 wnd_id = ipc_get_arg1(icall);
160
161 if (!async_data_write_receive(&call, &size)) {
162 async_answer_0(&call, EREFUSED);
163 async_answer_0(icall, EREFUSED);
164 return;
165 }
166
167 if (size != sizeof(gfx_coord2_t)) {
168 async_answer_0(&call, EINVAL);
169 async_answer_0(icall, EINVAL);
170 return;
171 }
172
173 rc = async_data_write_finalize(&call, &pos, size);
174 if (rc != EOK) {
175 async_answer_0(&call, rc);
176 async_answer_0(icall, rc);
177 return;
178 }
179
180 if (srv->ops->window_move_req == NULL) {
181 async_answer_0(icall, ENOTSUP);
182 return;
183 }
184
185 rc = srv->ops->window_move_req(srv->arg, wnd_id, &pos);
186 async_answer_0(icall, rc);
187}
188
189static void display_window_move_srv(display_srv_t *srv, ipc_call_t *icall)
190{
191 sysarg_t wnd_id;
192 ipc_call_t call;
193 gfx_coord2_t dpos;
194 size_t size;
195 errno_t rc;
196
197 wnd_id = ipc_get_arg1(icall);
198
199 if (!async_data_write_receive(&call, &size)) {
200 async_answer_0(&call, EREFUSED);
201 async_answer_0(icall, EREFUSED);
202 return;
203 }
204
205 if (size != sizeof(gfx_coord2_t)) {
206 async_answer_0(&call, EINVAL);
207 async_answer_0(icall, EINVAL);
208 return;
209 }
210
211 rc = async_data_write_finalize(&call, &dpos, size);
212 if (rc != EOK) {
213 async_answer_0(&call, rc);
214 async_answer_0(icall, rc);
215 return;
216 }
217
218 if (srv->ops->window_move == NULL) {
219 async_answer_0(icall, ENOTSUP);
220 return;
221 }
222
223 rc = srv->ops->window_move(srv->arg, wnd_id, &dpos);
224 async_answer_0(icall, rc);
225}
226
227static void display_window_get_pos_srv(display_srv_t *srv, ipc_call_t *icall)
228{
229 sysarg_t wnd_id;
230 ipc_call_t call;
231 gfx_coord2_t dpos;
232 size_t size;
233 errno_t rc;
234
235 wnd_id = ipc_get_arg1(icall);
236
237 if (srv->ops->window_get_pos == NULL) {
238 async_answer_0(icall, ENOTSUP);
239 return;
240 }
241
242 if (!async_data_read_receive(&call, &size)) {
243 async_answer_0(icall, EREFUSED);
244 return;
245 }
246
247 rc = srv->ops->window_get_pos(srv->arg, wnd_id, &dpos);
248 if (rc != EOK) {
249 async_answer_0(&call, rc);
250 async_answer_0(icall, rc);
251 return;
252 }
253
254 if (size != sizeof(gfx_coord2_t)) {
255 async_answer_0(&call, EINVAL);
256 async_answer_0(icall, EINVAL);
257 return;
258 }
259
260 rc = async_data_read_finalize(&call, &dpos, size);
261 if (rc != EOK) {
262 async_answer_0(&call, rc);
263 async_answer_0(icall, rc);
264 return;
265 }
266
267 async_answer_0(icall, EOK);
268}
269
270static void display_window_get_max_rect_srv(display_srv_t *srv,
271 ipc_call_t *icall)
272{
273 sysarg_t wnd_id;
274 ipc_call_t call;
275 gfx_rect_t rect;
276 size_t size;
277 errno_t rc;
278
279 wnd_id = ipc_get_arg1(icall);
280
281 if (srv->ops->window_get_max_rect == NULL) {
282 async_answer_0(icall, ENOTSUP);
283 return;
284 }
285
286 if (!async_data_read_receive(&call, &size)) {
287 async_answer_0(icall, EREFUSED);
288 return;
289 }
290
291 rc = srv->ops->window_get_max_rect(srv->arg, wnd_id, &rect);
292 if (rc != EOK) {
293 async_answer_0(&call, rc);
294 async_answer_0(icall, rc);
295 return;
296 }
297
298 if (size != sizeof(gfx_rect_t)) {
299 async_answer_0(&call, EINVAL);
300 async_answer_0(icall, EINVAL);
301 return;
302 }
303
304 rc = async_data_read_finalize(&call, &rect, size);
305 if (rc != EOK) {
306 async_answer_0(&call, rc);
307 async_answer_0(icall, rc);
308 return;
309 }
310
311 async_answer_0(icall, EOK);
312}
313
314static void display_window_resize_req_srv(display_srv_t *srv, ipc_call_t *icall)
315{
316 sysarg_t wnd_id;
317 ipc_call_t call;
318 display_wnd_rsztype_t rsztype;
319 gfx_coord2_t pos;
320 size_t size;
321 errno_t rc;
322
323 wnd_id = ipc_get_arg1(icall);
324 rsztype = (display_wnd_rsztype_t) ipc_get_arg2(icall);
325
326 if (!async_data_write_receive(&call, &size)) {
327 async_answer_0(&call, EREFUSED);
328 async_answer_0(icall, EREFUSED);
329 return;
330 }
331
332 if (size != sizeof(gfx_coord2_t)) {
333 async_answer_0(&call, EINVAL);
334 async_answer_0(icall, EINVAL);
335 return;
336 }
337
338 rc = async_data_write_finalize(&call, &pos, size);
339 if (rc != EOK) {
340 async_answer_0(&call, rc);
341 async_answer_0(icall, rc);
342 return;
343 }
344
345 if (srv->ops->window_resize_req == NULL) {
346 async_answer_0(icall, ENOTSUP);
347 return;
348 }
349
350 rc = srv->ops->window_resize_req(srv->arg, wnd_id, rsztype, &pos);
351 async_answer_0(icall, rc);
352}
353
354static void display_window_resize_srv(display_srv_t *srv, ipc_call_t *icall)
355{
356 sysarg_t wnd_id;
357 ipc_call_t call;
358 display_wnd_resize_t wresize;
359 size_t size;
360 errno_t rc;
361
362 wnd_id = ipc_get_arg1(icall);
363
364 if (!async_data_write_receive(&call, &size)) {
365 async_answer_0(&call, EREFUSED);
366 async_answer_0(icall, EREFUSED);
367 return;
368 }
369
370 if (size != sizeof(display_wnd_resize_t)) {
371 async_answer_0(&call, EINVAL);
372 async_answer_0(icall, EINVAL);
373 return;
374 }
375
376 rc = async_data_write_finalize(&call, &wresize, size);
377 if (rc != EOK) {
378 async_answer_0(&call, rc);
379 async_answer_0(icall, rc);
380 return;
381 }
382
383 if (srv->ops->window_resize == NULL) {
384 async_answer_0(icall, ENOTSUP);
385 return;
386 }
387
388 rc = srv->ops->window_resize(srv->arg, wnd_id, &wresize.offs,
389 &wresize.nrect);
390 async_answer_0(icall, rc);
391}
392
393static void display_window_maximize_srv(display_srv_t *srv, ipc_call_t *icall)
394{
395 sysarg_t wnd_id;
396 errno_t rc;
397
398 wnd_id = ipc_get_arg1(icall);
399
400 if (srv->ops->window_maximize == NULL) {
401 async_answer_0(icall, ENOTSUP);
402 return;
403 }
404
405 rc = srv->ops->window_maximize(srv->arg, wnd_id);
406 async_answer_0(icall, rc);
407}
408
409static void display_window_unmaximize_srv(display_srv_t *srv, ipc_call_t *icall)
410{
411 sysarg_t wnd_id;
412 errno_t rc;
413
414 wnd_id = ipc_get_arg1(icall);
415
416 if (srv->ops->window_unmaximize == NULL) {
417 async_answer_0(icall, ENOTSUP);
418 return;
419 }
420
421 rc = srv->ops->window_unmaximize(srv->arg, wnd_id);
422 async_answer_0(icall, rc);
423}
424
425static void display_window_set_cursor_srv(display_srv_t *srv, ipc_call_t *icall)
426{
427 sysarg_t wnd_id;
428 display_stock_cursor_t cursor;
429 errno_t rc;
430
431 wnd_id = ipc_get_arg1(icall);
432 cursor = ipc_get_arg2(icall);
433
434 if (srv->ops->window_set_cursor == NULL) {
435 async_answer_0(icall, ENOTSUP);
436 return;
437 }
438
439 rc = srv->ops->window_set_cursor(srv->arg, wnd_id, cursor);
440 async_answer_0(icall, rc);
441}
442
443static void display_window_set_caption_srv(display_srv_t *srv,
444 ipc_call_t *icall)
445{
446 sysarg_t wnd_id;
447 ipc_call_t call;
448 char *caption;
449 size_t size;
450 errno_t rc;
451
452 wnd_id = ipc_get_arg1(icall);
453
454 if (!async_data_write_receive(&call, &size)) {
455 async_answer_0(&call, EREFUSED);
456 async_answer_0(icall, EREFUSED);
457 return;
458 }
459
460 caption = calloc(size + 1, 1);
461 if (caption == NULL) {
462 async_answer_0(&call, ENOMEM);
463 async_answer_0(icall, ENOMEM);
464 return;
465 }
466
467 rc = async_data_write_finalize(&call, caption, size);
468 if (rc != EOK) {
469 free(caption);
470 async_answer_0(&call, rc);
471 async_answer_0(icall, rc);
472 return;
473 }
474
475 if (srv->ops->window_set_caption == NULL) {
476 free(caption);
477 async_answer_0(icall, ENOTSUP);
478 return;
479 }
480
481 rc = srv->ops->window_set_caption(srv->arg, wnd_id, caption);
482 async_answer_0(icall, rc);
483 free(caption);
484}
485
486static void display_get_event_srv(display_srv_t *srv, ipc_call_t *icall)
487{
488 sysarg_t wnd_id;
489 display_wnd_ev_t event;
490 ipc_call_t call;
491 size_t size;
492 errno_t rc;
493
494 if (srv->ops->get_event == NULL) {
495 async_answer_0(icall, ENOTSUP);
496 return;
497 }
498
499 rc = srv->ops->get_event(srv->arg, &wnd_id, &event);
500 if (rc != EOK) {
501 async_answer_0(icall, rc);
502 return;
503 }
504
505 /* Transfer event data */
506 if (!async_data_read_receive(&call, &size)) {
507 async_answer_0(icall, EREFUSED);
508 return;
509 }
510
511 if (size != sizeof(event)) {
512 async_answer_0(icall, EREFUSED);
513 async_answer_0(&call, EREFUSED);
514 return;
515 }
516
517 rc = async_data_read_finalize(&call, &event, sizeof(event));
518 if (rc != EOK) {
519 async_answer_0(icall, rc);
520 async_answer_0(&call, rc);
521 return;
522 }
523
524 async_answer_1(icall, EOK, wnd_id);
525}
526
527static void display_get_info_srv(display_srv_t *srv, ipc_call_t *icall)
528{
529 display_info_t info;
530 ipc_call_t call;
531 size_t size;
532 errno_t rc;
533
534 if (srv->ops->get_info == NULL) {
535 async_answer_0(icall, ENOTSUP);
536 return;
537 }
538
539 /* Transfer information */
540 if (!async_data_read_receive(&call, &size)) {
541 async_answer_0(icall, EREFUSED);
542 return;
543 }
544
545 if (size != sizeof(info)) {
546 async_answer_0(icall, EREFUSED);
547 async_answer_0(&call, EREFUSED);
548 return;
549 }
550
551 rc = srv->ops->get_info(srv->arg, &info);
552 if (rc != EOK) {
553 async_answer_0(icall, rc);
554 async_answer_0(&call, rc);
555 return;
556 }
557
558 rc = async_data_read_finalize(&call, &info, sizeof(info));
559 if (rc != EOK) {
560 async_answer_0(icall, rc);
561 async_answer_0(&call, rc);
562 return;
563 }
564
565 async_answer_0(icall, EOK);
566}
567
568void display_conn(ipc_call_t *icall, display_srv_t *srv)
569{
570 /* Accept the connection */
571 async_accept_0(icall);
572
573 while (true) {
574 ipc_call_t call;
575
576 async_get_call(&call);
577 sysarg_t method = ipc_get_imethod(&call);
578
579 if (!method) {
580 /* The other side has hung up */
581 async_answer_0(&call, EOK);
582 break;
583 }
584
585 switch (method) {
586 case DISPLAY_CALLBACK_CREATE:
587 display_callback_create_srv(srv, &call);
588 break;
589 case DISPLAY_WINDOW_CREATE:
590 display_window_create_srv(srv, &call);
591 break;
592 case DISPLAY_WINDOW_DESTROY:
593 display_window_destroy_srv(srv, &call);
594 break;
595 case DISPLAY_WINDOW_MOVE_REQ:
596 display_window_move_req_srv(srv, &call);
597 break;
598 case DISPLAY_WINDOW_MOVE:
599 display_window_move_srv(srv, &call);
600 break;
601 case DISPLAY_WINDOW_GET_POS:
602 display_window_get_pos_srv(srv, &call);
603 break;
604 case DISPLAY_WINDOW_GET_MAX_RECT:
605 display_window_get_max_rect_srv(srv, &call);
606 break;
607 case DISPLAY_WINDOW_RESIZE_REQ:
608 display_window_resize_req_srv(srv, &call);
609 break;
610 case DISPLAY_WINDOW_RESIZE:
611 display_window_resize_srv(srv, &call);
612 break;
613 case DISPLAY_WINDOW_MAXIMIZE:
614 display_window_maximize_srv(srv, &call);
615 break;
616 case DISPLAY_WINDOW_UNMAXIMIZE:
617 display_window_unmaximize_srv(srv, &call);
618 break;
619 case DISPLAY_WINDOW_SET_CURSOR:
620 display_window_set_cursor_srv(srv, &call);
621 break;
622 case DISPLAY_WINDOW_SET_CAPTION:
623 display_window_set_caption_srv(srv, &call);
624 break;
625 case DISPLAY_GET_EVENT:
626 display_get_event_srv(srv, &call);
627 break;
628 case DISPLAY_GET_INFO:
629 display_get_info_srv(srv, &call);
630 break;
631 default:
632 async_answer_0(&call, ENOTSUP);
633 }
634 }
635
636 /* Hang up callback session */
637 if (srv->client_sess != NULL) {
638 async_hangup(srv->client_sess);
639 srv->client_sess = NULL;
640 }
641}
642
643/** Initialize display server structure
644 *
645 * @param srv Display server structure to initialize
646 */
647void display_srv_initialize(display_srv_t *srv)
648{
649 memset(srv, 0, sizeof(*srv));
650}
651
652/** Send 'pending' event to client.
653 *
654 * @param srv Display server structure
655 */
656void display_srv_ev_pending(display_srv_t *srv)
657{
658 async_exch_t *exch;
659
660 exch = async_exchange_begin(srv->client_sess);
661 async_msg_0(exch, DISPLAY_EV_PENDING);
662 async_exchange_end(exch);
663}
664
665/** @}
666 */
Note: See TracBrowser for help on using the repository browser.