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

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

Allow getting display dimensions

Can be used to position special windows such as panels, or to help
emulate libgui's window placement policy. To support multi-monitor
setups we would rather need to be able to query individual monitors.
But let's keep things simple for now.

  • Property mode set to 100644
File size: 8.6 KB
Line 
1/*
2 * Copyright (c) 2019 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_t params;
66 size_t size;
67 errno_t rc;
68
69 if (!async_data_write_receive(&call, &size)) {
70 async_answer_0(&call, EREFUSED);
71 async_answer_0(icall, EREFUSED);
72 return;
73 }
74
75 if (size != sizeof(display_wnd_params_t)) {
76 async_answer_0(&call, EINVAL);
77 async_answer_0(icall, EINVAL);
78 return;
79 }
80
81 rc = async_data_write_finalize(&call, &params, size);
82 if (rc != EOK) {
83 async_answer_0(&call, rc);
84 async_answer_0(icall, rc);
85 return;
86 }
87
88 if (srv->ops->window_create == NULL) {
89 async_answer_0(icall, ENOTSUP);
90 return;
91 }
92
93 rc = srv->ops->window_create(srv->arg, &params, &wnd_id);
94 async_answer_1(icall, rc, wnd_id);
95}
96
97static void display_window_destroy_srv(display_srv_t *srv, ipc_call_t *icall)
98{
99 sysarg_t wnd_id;
100 errno_t rc;
101
102 wnd_id = ipc_get_arg1(icall);
103
104 if (srv->ops->window_destroy == NULL) {
105 async_answer_0(icall, ENOTSUP);
106 return;
107 }
108
109 rc = srv->ops->window_destroy(srv->arg, wnd_id);
110 async_answer_0(icall, rc);
111}
112
113static void display_window_move_req_srv(display_srv_t *srv, ipc_call_t *icall)
114{
115 sysarg_t wnd_id;
116 ipc_call_t call;
117 gfx_coord2_t pos;
118 size_t size;
119 errno_t rc;
120
121 wnd_id = ipc_get_arg1(icall);
122
123 if (!async_data_write_receive(&call, &size)) {
124 async_answer_0(&call, EREFUSED);
125 async_answer_0(icall, EREFUSED);
126 return;
127 }
128
129 if (size != sizeof(gfx_coord2_t)) {
130 async_answer_0(&call, EINVAL);
131 async_answer_0(icall, EINVAL);
132 return;
133 }
134
135 rc = async_data_write_finalize(&call, &pos, size);
136 if (rc != EOK) {
137 async_answer_0(&call, rc);
138 async_answer_0(icall, rc);
139 return;
140 }
141
142 if (srv->ops->window_move_req == NULL) {
143 async_answer_0(icall, ENOTSUP);
144 return;
145 }
146
147 rc = srv->ops->window_move_req(srv->arg, wnd_id, &pos);
148 async_answer_0(icall, rc);
149}
150
151static void display_window_resize_req_srv(display_srv_t *srv, ipc_call_t *icall)
152{
153 sysarg_t wnd_id;
154 ipc_call_t call;
155 display_wnd_rsztype_t rsztype;
156 gfx_coord2_t pos;
157 size_t size;
158 errno_t rc;
159
160 wnd_id = ipc_get_arg1(icall);
161 rsztype = (display_wnd_rsztype_t) 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_resize_req == NULL) {
183 async_answer_0(icall, ENOTSUP);
184 return;
185 }
186
187 rc = srv->ops->window_resize_req(srv->arg, wnd_id, rsztype, &pos);
188 async_answer_0(icall, rc);
189}
190
191static void display_window_resize_srv(display_srv_t *srv, ipc_call_t *icall)
192{
193 sysarg_t wnd_id;
194 ipc_call_t call;
195 display_wnd_resize_t wresize;
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(display_wnd_resize_t)) {
208 async_answer_0(&call, EINVAL);
209 async_answer_0(icall, EINVAL);
210 return;
211 }
212
213 rc = async_data_write_finalize(&call, &wresize, 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_resize == NULL) {
221 async_answer_0(icall, ENOTSUP);
222 return;
223 }
224
225 rc = srv->ops->window_resize(srv->arg, wnd_id, &wresize.offs,
226 &wresize.nrect);
227 async_answer_0(icall, rc);
228}
229
230static void display_get_event_srv(display_srv_t *srv, ipc_call_t *icall)
231{
232 sysarg_t wnd_id;
233 display_wnd_ev_t event;
234 ipc_call_t call;
235 size_t size;
236 errno_t rc;
237
238 if (srv->ops->get_event == NULL) {
239 async_answer_0(icall, ENOTSUP);
240 return;
241 }
242
243 rc = srv->ops->get_event(srv->arg, &wnd_id, &event);
244 if (rc != EOK) {
245 async_answer_0(icall, rc);
246 return;
247 }
248
249 /* Transfer event data */
250 if (!async_data_read_receive(&call, &size)) {
251 async_answer_0(icall, EREFUSED);
252 return;
253 }
254
255 if (size != sizeof(event)) {
256 async_answer_0(icall, EREFUSED);
257 async_answer_0(&call, EREFUSED);
258 return;
259 }
260
261 rc = async_data_read_finalize(&call, &event, sizeof(event));
262 if (rc != EOK) {
263 async_answer_0(icall, rc);
264 async_answer_0(&call, rc);
265 return;
266 }
267
268 async_answer_1(icall, EOK, wnd_id);
269}
270
271static void display_get_info_srv(display_srv_t *srv, ipc_call_t *icall)
272{
273 display_info_t info;
274 ipc_call_t call;
275 size_t size;
276 errno_t rc;
277
278 if (srv->ops->get_info == NULL) {
279 async_answer_0(icall, ENOTSUP);
280 return;
281 }
282
283 /* Transfer information */
284 if (!async_data_read_receive(&call, &size)) {
285 async_answer_0(icall, EREFUSED);
286 return;
287 }
288
289 if (size != sizeof(info)) {
290 async_answer_0(icall, EREFUSED);
291 async_answer_0(&call, EREFUSED);
292 return;
293 }
294
295 rc = srv->ops->get_info(srv->arg, &info);
296 if (rc != EOK) {
297 async_answer_0(icall, rc);
298 async_answer_0(&call, rc);
299 return;
300 }
301
302 rc = async_data_read_finalize(&call, &info, sizeof(info));
303 if (rc != EOK) {
304 async_answer_0(icall, rc);
305 async_answer_0(&call, rc);
306 return;
307 }
308
309 async_answer_0(icall, EOK);
310}
311
312void display_conn(ipc_call_t *icall, display_srv_t *srv)
313{
314 /* Accept the connection */
315 async_accept_0(icall);
316
317 while (true) {
318 ipc_call_t call;
319
320 async_get_call(&call);
321 sysarg_t method = ipc_get_imethod(&call);
322
323 if (!method) {
324 /* The other side has hung up */
325 async_answer_0(&call, EOK);
326 break;
327 }
328
329 switch (method) {
330 case DISPLAY_CALLBACK_CREATE:
331 display_callback_create_srv(srv, &call);
332 break;
333 case DISPLAY_WINDOW_CREATE:
334 display_window_create_srv(srv, &call);
335 break;
336 case DISPLAY_WINDOW_DESTROY:
337 display_window_destroy_srv(srv, &call);
338 break;
339 case DISPLAY_WINDOW_MOVE_REQ:
340 display_window_move_req_srv(srv, &call);
341 break;
342 case DISPLAY_WINDOW_RESIZE_REQ:
343 display_window_resize_req_srv(srv, &call);
344 break;
345 case DISPLAY_WINDOW_RESIZE:
346 display_window_resize_srv(srv, &call);
347 break;
348 case DISPLAY_GET_EVENT:
349 display_get_event_srv(srv, &call);
350 break;
351 case DISPLAY_GET_INFO:
352 display_get_info_srv(srv, &call);
353 break;
354 default:
355 async_answer_0(&call, ENOTSUP);
356 }
357 }
358
359 /* Hang up callback session */
360 if (srv->client_sess != NULL) {
361 async_hangup(srv->client_sess);
362 srv->client_sess = NULL;
363 }
364}
365
366/** Initialize display server structure
367 *
368 * @param srv Display server structure to initialize
369 */
370void display_srv_initialize(display_srv_t *srv)
371{
372 memset(srv, 0, sizeof(*srv));
373}
374
375/** Send 'pending' event to client.
376 *
377 * @param srv Display server structure
378 */
379void display_srv_ev_pending(display_srv_t *srv)
380{
381 async_exch_t *exch;
382
383 exch = async_exchange_begin(srv->client_sess);
384 async_msg_0(exch, DISPLAY_EV_PENDING);
385 async_exchange_end(exch);
386}
387
388/** @}
389 */
Note: See TracBrowser for help on using the repository browser.