source: mainline/uspace/lib/graph/graph.c@ e0a4686

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e0a4686 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 14.6 KB
RevLine 
[6d5e378]1/*
2 * Copyright (c) 2011 Petr Koupy
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 graph
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <assert.h>
37#include <errno.h>
38#include <inttypes.h>
39#include <stdio.h>
40#include <as.h>
[38d150e]41#include <stdlib.h>
[6d5e378]42#include "graph.h"
43
44#define NAMESPACE "graphemu"
45#define VISUALIZER_NAME "vsl"
46#define RENDERER_NAME "rnd"
47
48static sysarg_t namespace_idx = 0;
49static sysarg_t visualizer_idx = 0;
50static sysarg_t renderer_idx = 0;
51
52static LIST_INITIALIZE(visualizer_list);
53static LIST_INITIALIZE(renderer_list);
54
55static FIBRIL_MUTEX_INITIALIZE(visualizer_list_mtx);
56static FIBRIL_MUTEX_INITIALIZE(renderer_list_mtx);
57
58visualizer_t *graph_alloc_visualizer(void)
59{
[df2e621c]60 return ((visualizer_t *) malloc(sizeof(visualizer_t)));
[6d5e378]61}
62
63renderer_t *graph_alloc_renderer(void)
64{
65 // TODO
[df2e621c]66 return ((renderer_t *) malloc(sizeof(renderer_t)));
[6d5e378]67}
68
69void graph_init_visualizer(visualizer_t *vs)
70{
71 link_initialize(&vs->link);
72 atomic_set(&vs->ref_cnt, 0);
73 vs->notif_sess = NULL;
74 fibril_mutex_initialize(&vs->mode_mtx);
75 list_initialize(&vs->modes);
76 vs->mode_set = false;
77 vs->cells.data = NULL;
78 vs->dev_ctx = NULL;
79}
80
81void graph_init_renderer(renderer_t *rnd)
82{
83 // TODO
84 link_initialize(&rnd->link);
85 atomic_set(&rnd->ref_cnt, 0);
86}
87
[b7fd2a0]88errno_t graph_register_visualizer(visualizer_t *vs)
[6d5e378]89{
90 char node[LOC_NAME_MAXLEN + 1];
91 snprintf(node, LOC_NAME_MAXLEN, "%s%zu/%s%zu", NAMESPACE,
92 namespace_idx, VISUALIZER_NAME, visualizer_idx++);
[a35b458]93
[6d5e378]94 category_id_t cat;
[b7fd2a0]95 errno_t rc = loc_category_get_id("visualizer", &cat, 0);
[df2e621c]96 if (rc != EOK)
[6d5e378]97 return rc;
[a35b458]98
[6d5e378]99 rc = loc_service_register(node, &vs->reg_svc_handle);
[df2e621c]100 if (rc != EOK)
[6d5e378]101 return rc;
[a35b458]102
[6d5e378]103 rc = loc_service_add_to_cat(vs->reg_svc_handle, cat);
104 if (rc != EOK) {
105 loc_service_unregister(vs->reg_svc_handle);
106 return rc;
107 }
[a35b458]108
[6d5e378]109 fibril_mutex_lock(&visualizer_list_mtx);
110 list_append(&vs->link, &visualizer_list);
111 fibril_mutex_unlock(&visualizer_list_mtx);
[a35b458]112
[6d5e378]113 return rc;
114}
115
[b7fd2a0]116errno_t graph_register_renderer(renderer_t *rnd)
[6d5e378]117{
118 char node[LOC_NAME_MAXLEN + 1];
119 snprintf(node, LOC_NAME_MAXLEN, "%s%zu/%s%zu", NAMESPACE,
120 namespace_idx, RENDERER_NAME, renderer_idx++);
[a35b458]121
[6d5e378]122 category_id_t cat;
[b7fd2a0]123 errno_t rc = loc_category_get_id("renderer", &cat, 0);
[df2e621c]124 if (rc != EOK)
[6d5e378]125 return rc;
[a35b458]126
[6d5e378]127 rc = loc_service_register(node, &rnd->reg_svc_handle);
[df2e621c]128 if (rc != EOK)
[6d5e378]129 return rc;
[a35b458]130
[6d5e378]131 rc = loc_service_add_to_cat(rnd->reg_svc_handle, cat);
132 if (rc != EOK) {
133 loc_service_unregister(rnd->reg_svc_handle);
134 return rc;
135 }
[a35b458]136
[6d5e378]137 fibril_mutex_lock(&renderer_list_mtx);
138 list_append(&rnd->link, &renderer_list);
139 fibril_mutex_unlock(&renderer_list_mtx);
[a35b458]140
[6d5e378]141 return rc;
142}
143
144visualizer_t *graph_get_visualizer(sysarg_t handle)
145{
146 visualizer_t *vs = NULL;
[a35b458]147
[6d5e378]148 fibril_mutex_lock(&visualizer_list_mtx);
[a35b458]149
[feeac0d]150 list_foreach(visualizer_list, link, visualizer_t, vcur) {
151 if (vcur->reg_svc_handle == handle) {
152 vs = vcur;
[6d5e378]153 break;
154 }
155 }
[a35b458]156
[6d5e378]157 fibril_mutex_unlock(&visualizer_list_mtx);
[a35b458]158
[6d5e378]159 return vs;
160}
161
162renderer_t *graph_get_renderer(sysarg_t handle)
163{
164 renderer_t *rnd = NULL;
[a35b458]165
[6d5e378]166 fibril_mutex_lock(&renderer_list_mtx);
[a35b458]167
[feeac0d]168 list_foreach(renderer_list, link, renderer_t, rcur) {
169 if (rcur->reg_svc_handle == handle) {
170 rnd = rcur;
[6d5e378]171 break;
172 }
173 }
[a35b458]174
[6d5e378]175 fibril_mutex_unlock(&renderer_list_mtx);
[a35b458]176
[6d5e378]177 return rnd;
178}
179
[b7fd2a0]180errno_t graph_unregister_visualizer(visualizer_t *vs)
[6d5e378]181{
182 fibril_mutex_lock(&visualizer_list_mtx);
[b7fd2a0]183 errno_t rc = loc_service_unregister(vs->reg_svc_handle);
[6d5e378]184 list_remove(&vs->link);
185 fibril_mutex_unlock(&visualizer_list_mtx);
[a35b458]186
[6d5e378]187 return rc;
188}
189
[b7fd2a0]190errno_t graph_unregister_renderer(renderer_t *rnd)
[6d5e378]191{
192 fibril_mutex_lock(&renderer_list_mtx);
[b7fd2a0]193 errno_t rc = loc_service_unregister(rnd->reg_svc_handle);
[6d5e378]194 list_remove(&rnd->link);
195 fibril_mutex_unlock(&renderer_list_mtx);
[a35b458]196
[6d5e378]197 return rc;
198}
199
200void graph_destroy_visualizer(visualizer_t *vs)
201{
202 assert(atomic_get(&vs->ref_cnt) == 0);
203 assert(vs->notif_sess == NULL);
204 assert(!fibril_mutex_is_locked(&vs->mode_mtx));
205 assert(list_empty(&vs->modes));
206 assert(vs->mode_set == false);
207 assert(vs->cells.data == NULL);
208 assert(vs->dev_ctx == NULL);
[a35b458]209
[6d5e378]210 free(vs);
211}
212
213void graph_destroy_renderer(renderer_t *rnd)
214{
215 // TODO
216 assert(atomic_get(&rnd->ref_cnt) == 0);
[a35b458]217
[6d5e378]218 free(rnd);
219}
220
[b7fd2a0]221errno_t graph_notify_mode_change(async_sess_t *sess, sysarg_t handle, sysarg_t mode_idx)
[6d5e378]222{
223 async_exch_t *exch = async_exchange_begin(sess);
[b7fd2a0]224 errno_t ret = async_req_2_0(exch, VISUALIZER_MODE_CHANGE, handle, mode_idx);
[6d5e378]225 async_exchange_end(exch);
[a35b458]226
[6d5e378]227 return ret;
228}
229
[b7fd2a0]230errno_t graph_notify_disconnect(async_sess_t *sess, sysarg_t handle)
[6d5e378]231{
232 async_exch_t *exch = async_exchange_begin(sess);
[b7fd2a0]233 errno_t ret = async_req_1_0(exch, VISUALIZER_DISCONNECT, handle);
[6d5e378]234 async_exchange_end(exch);
[a35b458]235
[6d5e378]236 async_hangup(sess);
[a35b458]237
[6d5e378]238 return ret;
239}
240
241static void vs_claim(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
242{
243 vs->client_side_handle = IPC_GET_ARG1(*icall);
[b7fd2a0]244 errno_t rc = vs->ops.claim(vs);
[6d5e378]245 async_answer_0(iid, rc);
246}
247
248static void vs_yield(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
249{
250 /* Deallocate resources for the current mode. */
251 if (vs->mode_set) {
252 if (vs->cells.data != NULL) {
253 as_area_destroy((void *) vs->cells.data);
254 vs->cells.data = NULL;
255 }
256 }
[a35b458]257
[6d5e378]258 /* Driver might also deallocate resources for the current mode. */
[b7fd2a0]259 errno_t rc = vs->ops.yield(vs);
[a35b458]260
[6d5e378]261 /* Now that the driver was given a chance to deallocate resources,
262 * current mode can be unset. */
[df2e621c]263 if (vs->mode_set)
[6d5e378]264 vs->mode_set = false;
[a35b458]265
[6d5e378]266 async_answer_0(iid, rc);
267}
268
269static void vs_enumerate_modes(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
270{
[df2e621c]271 ipc_callid_t callid;
272 size_t len;
[a35b458]273
[df2e621c]274 if (!async_data_read_receive(&callid, &len)) {
275 async_answer_0(callid, EREFUSED);
276 async_answer_0(iid, EREFUSED);
277 return;
278 }
[a35b458]279
[6d5e378]280 fibril_mutex_lock(&vs->mode_mtx);
281 link_t *link = list_nth(&vs->modes, IPC_GET_ARG1(*icall));
[a35b458]282
[6d5e378]283 if (link != NULL) {
284 vslmode_list_element_t *mode_elem =
285 list_get_instance(link, vslmode_list_element_t, link);
[a35b458]286
[b7fd2a0]287 errno_t rc = async_data_read_finalize(callid, &mode_elem->mode, len);
[df2e621c]288 async_answer_0(iid, rc);
[6d5e378]289 } else {
[df2e621c]290 async_answer_0(callid, ENOENT);
[6d5e378]291 async_answer_0(iid, ENOENT);
292 }
[a35b458]293
[df2e621c]294 fibril_mutex_unlock(&vs->mode_mtx);
[6d5e378]295}
296
297static void vs_get_default_mode(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
298{
[df2e621c]299 ipc_callid_t callid;
300 size_t len;
[a35b458]301
[df2e621c]302 if (!async_data_read_receive(&callid, &len)) {
303 async_answer_0(callid, EREFUSED);
304 async_answer_0(iid, EREFUSED);
305 return;
306 }
[a35b458]307
[6d5e378]308 fibril_mutex_lock(&vs->mode_mtx);
309 vslmode_list_element_t *mode_elem = NULL;
[a35b458]310
[feeac0d]311 list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
[6d5e378]312 if (cur->mode.index == vs->def_mode_idx) {
313 mode_elem = cur;
314 break;
315 }
316 }
[a35b458]317
[6d5e378]318 if (mode_elem != NULL) {
[b7fd2a0]319 errno_t rc = async_data_read_finalize(callid, &mode_elem->mode, len);
[df2e621c]320 async_answer_0(iid, rc);
[6d5e378]321 } else {
322 fibril_mutex_unlock(&vs->mode_mtx);
[df2e621c]323 async_answer_0(callid, ENOENT);
[6d5e378]324 async_answer_0(iid, ENOENT);
325 }
[a35b458]326
[df2e621c]327 fibril_mutex_unlock(&vs->mode_mtx);
[6d5e378]328}
329
330static void vs_get_current_mode(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
331{
[df2e621c]332 ipc_callid_t callid;
333 size_t len;
[a35b458]334
[df2e621c]335 if (!async_data_read_receive(&callid, &len)) {
336 async_answer_0(callid, EREFUSED);
337 async_answer_0(iid, EREFUSED);
338 return;
339 }
[a35b458]340
[6d5e378]341 if (vs->mode_set) {
[b7fd2a0]342 errno_t rc = async_data_read_finalize(callid, &vs->cur_mode, len);
[df2e621c]343 async_answer_0(iid, rc);
[6d5e378]344 } else {
[df2e621c]345 async_answer_0(callid, ENOENT);
[6d5e378]346 async_answer_0(iid, ENOENT);
347 }
348}
349
350static void vs_get_mode(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
351{
[df2e621c]352 ipc_callid_t callid;
353 size_t len;
[a35b458]354
[df2e621c]355 if (!async_data_read_receive(&callid, &len)) {
356 async_answer_0(callid, EREFUSED);
357 async_answer_0(iid, EREFUSED);
358 return;
359 }
[a35b458]360
[6d5e378]361 sysarg_t mode_idx = IPC_GET_ARG1(*icall);
[a35b458]362
[6d5e378]363 fibril_mutex_lock(&vs->mode_mtx);
364 vslmode_list_element_t *mode_elem = NULL;
[a35b458]365
[feeac0d]366 list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
[6d5e378]367 if (cur->mode.index == mode_idx) {
368 mode_elem = cur;
369 break;
370 }
371 }
[a35b458]372
[6d5e378]373 if (mode_elem != NULL) {
[b7fd2a0]374 errno_t rc = async_data_read_finalize(callid, &mode_elem->mode, len);
[df2e621c]375 async_answer_0(iid, rc);
[6d5e378]376 } else {
[df2e621c]377 async_answer_0(callid, ENOENT);
[6d5e378]378 async_answer_0(iid, ENOENT);
379 }
[a35b458]380
[df2e621c]381 fibril_mutex_unlock(&vs->mode_mtx);
[6d5e378]382}
383
384static void vs_set_mode(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
385{
[df2e621c]386 ipc_callid_t callid;
387 size_t size;
388 unsigned int flags;
[a35b458]389
[df2e621c]390 /* Retrieve the shared cell storage for the new mode. */
391 if (!async_share_out_receive(&callid, &size, &flags)) {
392 async_answer_0(callid, EREFUSED);
393 async_answer_0(iid, EREFUSED);
394 return;
395 }
[a35b458]396
[6d5e378]397 /* Retrieve mode index and version. */
398 sysarg_t mode_idx = IPC_GET_ARG1(*icall);
399 sysarg_t mode_version = IPC_GET_ARG2(*icall);
[a35b458]400
[6d5e378]401 /* Find mode in the list. */
402 fibril_mutex_lock(&vs->mode_mtx);
403 vslmode_list_element_t *mode_elem = NULL;
[a35b458]404
[feeac0d]405 list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
[6d5e378]406 if (cur->mode.index == mode_idx) {
407 mode_elem = cur;
408 break;
409 }
410 }
[a35b458]411
[df2e621c]412 if (mode_elem == NULL) {
[6d5e378]413 fibril_mutex_unlock(&vs->mode_mtx);
[df2e621c]414 async_answer_0(callid, ENOENT);
[6d5e378]415 async_answer_0(iid, ENOENT);
416 return;
417 }
[a35b458]418
[df2e621c]419 /* Extract mode description from the list node. */
420 vslmode_t new_mode = mode_elem->mode;
421 fibril_mutex_unlock(&vs->mode_mtx);
[a35b458]422
[6d5e378]423 /* Check whether the mode is still up-to-date. */
424 if (new_mode.version != mode_version) {
[df2e621c]425 async_answer_0(callid, EINVAL);
[6d5e378]426 async_answer_0(iid, EINVAL);
427 return;
428 }
[a35b458]429
[6d5e378]430 void *new_cell_storage;
[b7fd2a0]431 errno_t rc = async_share_out_finalize(callid, &new_cell_storage);
[6d5e378]432 if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
433 async_answer_0(iid, ENOMEM);
434 return;
435 }
[a35b458]436
[6d5e378]437 /* Change device internal state. */
438 rc = vs->ops.change_mode(vs, new_mode);
[a35b458]439
[6d5e378]440 /* Device driver could not establish new mode. Rollback. */
441 if (rc != EOK) {
442 as_area_destroy(new_cell_storage);
443 async_answer_0(iid, ENOMEM);
444 return;
445 }
[a35b458]446
[df2e621c]447 /*
448 * Because resources for the new mode were successfully
449 * claimed, it is finally possible to free resources
450 * allocated for the old mode.
451 */
[6d5e378]452 if (vs->mode_set) {
453 if (vs->cells.data != NULL) {
454 as_area_destroy((void *) vs->cells.data);
455 vs->cells.data = NULL;
456 }
457 }
[a35b458]458
[6d5e378]459 /* Insert new mode into the visualizer. */
460 vs->cells.width = new_mode.screen_width;
461 vs->cells.height = new_mode.screen_height;
462 vs->cells.data = (pixel_t *) new_cell_storage;
463 vs->cur_mode = new_mode;
464 vs->mode_set = true;
[a35b458]465
[6d5e378]466 async_answer_0(iid, EOK);
467}
468
469static void vs_update_damaged_region(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
470{
471 sysarg_t x_offset = (IPC_GET_ARG5(*icall) >> 16);
472 sysarg_t y_offset = (IPC_GET_ARG5(*icall) & 0x0000ffff);
[a35b458]473
[b7fd2a0]474 errno_t rc = vs->ops.handle_damage(vs,
[6d5e378]475 IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
476 IPC_GET_ARG3(*icall), IPC_GET_ARG4(*icall),
[df2e621c]477 x_offset, y_offset);
[6d5e378]478 async_answer_0(iid, rc);
479}
480
481static void vs_suspend(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
482{
[b7fd2a0]483 errno_t rc = vs->ops.suspend(vs);
[6d5e378]484 async_answer_0(iid, rc);
485}
486
487static void vs_wakeup(visualizer_t *vs, ipc_callid_t iid, ipc_call_t *icall)
488{
[b7fd2a0]489 errno_t rc = vs->ops.wakeup(vs);
[6d5e378]490 async_answer_0(iid, rc);
491}
492
493void graph_visualizer_connection(visualizer_t *vs,
494 ipc_callid_t iid, ipc_call_t *icall, void *arg)
495{
496 ipc_call_t call;
497 ipc_callid_t callid;
[a35b458]498
[6d5e378]499 /* Claim the visualizer. */
500 if (!cas(&vs->ref_cnt, 0, 1)) {
501 async_answer_0(iid, ELIMIT);
502 return;
503 }
[a35b458]504
[6d5e378]505 /* Accept the connection. */
506 async_answer_0(iid, EOK);
[a35b458]507
[6d5e378]508 /* Establish callback session. */
509 callid = async_get_call(&call);
510 vs->notif_sess = async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
[df2e621c]511 if (vs->notif_sess != NULL)
[6d5e378]512 async_answer_0(callid, EOK);
[df2e621c]513 else
[6d5e378]514 async_answer_0(callid, ELIMIT);
[a35b458]515
[6d5e378]516 /* Enter command loop. */
517 while (true) {
518 callid = async_get_call(&call);
[a35b458]519
[6d5e378]520 if (!IPC_GET_IMETHOD(call)) {
521 async_answer_0(callid, EINVAL);
522 break;
523 }
[a35b458]524
[6d5e378]525 switch (IPC_GET_IMETHOD(call)) {
526 case VISUALIZER_CLAIM:
527 vs_claim(vs, callid, &call);
528 break;
529 case VISUALIZER_YIELD:
530 vs_yield(vs, callid, &call);
531 goto terminate;
532 case VISUALIZER_ENUMERATE_MODES:
533 vs_enumerate_modes(vs, callid, &call);
534 break;
535 case VISUALIZER_GET_DEFAULT_MODE:
536 vs_get_default_mode(vs, callid, &call);
537 break;
538 case VISUALIZER_GET_CURRENT_MODE:
539 vs_get_current_mode(vs, callid, &call);
540 break;
541 case VISUALIZER_GET_MODE:
542 vs_get_mode(vs, callid, &call);
543 break;
544 case VISUALIZER_SET_MODE:
545 vs_set_mode(vs, callid, &call);
546 break;
547 case VISUALIZER_UPDATE_DAMAGED_REGION:
548 vs_update_damaged_region(vs, callid, &call);
549 break;
550 case VISUALIZER_SUSPEND:
551 vs_suspend(vs, callid, &call);
552 break;
553 case VISUALIZER_WAKE_UP:
554 vs_wakeup(vs, callid, &call);
555 break;
556 default:
557 async_answer_0(callid, EINVAL);
558 goto terminate;
559 }
560 }
[a35b458]561
[6d5e378]562terminate:
563 async_hangup(vs->notif_sess);
564 vs->notif_sess = NULL;
565 atomic_set(&vs->ref_cnt, 0);
566}
567
568void graph_renderer_connection(renderer_t *rnd,
569 ipc_callid_t iid, ipc_call_t *icall, void *arg)
570{
571 // TODO
[a35b458]572
[6d5e378]573 ipc_call_t call;
574 ipc_callid_t callid;
[a35b458]575
[6d5e378]576 /* Accept the connection. */
577 atomic_inc(&rnd->ref_cnt);
578 async_answer_0(iid, EOK);
[a35b458]579
[6d5e378]580 /* Enter command loop. */
581 while (true) {
582 callid = async_get_call(&call);
[a35b458]583
[6d5e378]584 if (!IPC_GET_IMETHOD(call)) {
585 async_answer_0(callid, EINVAL);
586 break;
587 }
[a35b458]588
[6d5e378]589 switch (IPC_GET_IMETHOD(call)) {
590 default:
591 async_answer_0(callid, EINVAL);
592 goto terminate;
593 }
594 }
[a35b458]595
[6d5e378]596terminate:
597 atomic_dec(&rnd->ref_cnt);
598}
599
600void graph_client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
601{
602 /* Find the visualizer or renderer with the given service ID. */
[f9b2cb4c]603 visualizer_t *vs = graph_get_visualizer(IPC_GET_ARG2(*icall));
604 renderer_t *rnd = graph_get_renderer(IPC_GET_ARG2(*icall));
[a35b458]605
[df2e621c]606 if (vs != NULL)
[6d5e378]607 graph_visualizer_connection(vs, iid, icall, arg);
[df2e621c]608 else if (rnd != NULL)
[6d5e378]609 graph_renderer_connection(rnd, iid, icall, arg);
[df2e621c]610 else
[6d5e378]611 async_answer_0(iid, ENOENT);
612}
613
614/** @}
615 */
Note: See TracBrowser for help on using the repository browser.