daemon: jmcore support in virtualizer
[ladish.git] / daemon / graph.c
blob02c164080107cf6d1560795861d19c37801a848b
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008, 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
6 * Copyright (C) 2008 Juuso Alasuutari
8 **************************************************************************
9 * This file contains implementation of the D-Bus patchbay interface helpers
10 **************************************************************************
12 * LADI Session Handler is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * LADI Session Handler is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
24 * or write to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "common.h"
29 #include "graph.h"
30 #include "../dbus/error.h"
31 #include "../dbus_constants.h"
33 struct ladish_graph_port
35 struct list_head siblings_client;
36 struct list_head siblings_graph;
37 struct ladish_graph_client * client_ptr;
38 char * name;
39 uint32_t type;
40 uint32_t flags;
41 uint64_t id;
42 ladish_port_handle port;
43 bool hidden;
44 bool link;
45 uuid_t link_uuid_override;
48 struct ladish_graph_client
50 struct list_head siblings;
51 char * name;
52 uint64_t id;
53 ladish_client_handle client;
54 struct list_head ports;
55 bool hidden;
58 struct ladish_graph_connection
60 struct list_head siblings;
61 uint64_t id;
62 bool hidden;
63 struct ladish_graph_port * port1_ptr;
64 struct ladish_graph_port * port2_ptr;
65 ladish_dict_handle dict;
66 bool changing;
69 struct ladish_graph
71 char * opath;
72 ladish_dict_handle dict;
73 struct list_head clients;
74 struct list_head ports;
75 struct list_head connections;
76 uint64_t graph_version;
77 uint64_t next_client_id;
78 uint64_t next_port_id;
79 uint64_t next_connection_id;
81 void * context;
82 ladish_graph_connect_request_handler connect_handler;
83 ladish_graph_disconnect_request_handler disconnect_handler;
86 struct ladish_graph_port * ladish_graph_find_port_by_id_internal(struct ladish_graph * graph_ptr, uint64_t port_id)
88 struct list_head * node_ptr;
89 struct ladish_graph_port * port_ptr;
91 list_for_each(node_ptr, &graph_ptr->ports)
93 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph);
94 if (port_ptr->id == port_id)
96 return port_ptr;
100 return NULL;
103 struct ladish_graph_connection * ladish_graph_find_connection_by_id(struct ladish_graph * graph_ptr, uint64_t connection_id)
105 struct list_head * node_ptr;
106 struct ladish_graph_connection * connection_ptr;
108 list_for_each(node_ptr, &graph_ptr->connections)
110 connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
111 if (connection_ptr->id == connection_id)
113 return connection_ptr;
117 return NULL;
120 struct ladish_graph_connection *
121 ladish_graph_find_connection_by_ports(
122 struct ladish_graph * graph_ptr,
123 struct ladish_graph_port * port1_ptr,
124 struct ladish_graph_port * port2_ptr)
126 struct list_head * node_ptr;
127 struct ladish_graph_connection * connection_ptr;
129 list_for_each(node_ptr, &graph_ptr->connections)
131 connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
132 if ((connection_ptr->port1_ptr == port1_ptr && connection_ptr->port2_ptr == port2_ptr) ||
133 (connection_ptr->port1_ptr == port2_ptr && connection_ptr->port2_ptr == port1_ptr))
135 return connection_ptr;
139 return NULL;
142 #define graph_ptr ((struct ladish_graph *)call_ptr->iface_context)
144 static void get_all_ports(struct dbus_method_call * call_ptr)
146 DBusMessageIter iter, sub_iter;
148 call_ptr->reply = dbus_message_new_method_return(call_ptr->message);
149 if (call_ptr->reply == NULL)
151 goto fail;
154 dbus_message_iter_init_append(call_ptr->reply, &iter);
156 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub_iter))
158 goto fail_unref;
161 if (!dbus_message_iter_close_container(&iter, &sub_iter))
163 goto fail_unref;
166 return;
168 fail_unref:
169 dbus_message_unref(call_ptr->reply);
170 call_ptr->reply = NULL;
172 fail:
173 log_error("Ran out of memory trying to construct method return");
176 static void get_graph(struct dbus_method_call * call_ptr)
178 dbus_uint64_t known_version;
179 dbus_uint64_t current_version;
180 DBusMessageIter iter;
181 DBusMessageIter clients_array_iter;
182 DBusMessageIter connections_array_iter;
183 DBusMessageIter client_struct_iter;
184 struct list_head * client_node_ptr;
185 struct ladish_graph_client * client_ptr;
186 DBusMessageIter ports_array_iter;
187 struct list_head * port_node_ptr;
188 struct ladish_graph_port * port_ptr;
189 DBusMessageIter port_struct_iter;
190 struct list_head * connection_node_ptr;
191 struct ladish_graph_connection * connection_ptr;
192 DBusMessageIter connection_struct_iter;
194 //log_info("get_graph() called");
196 if (!dbus_message_get_args(call_ptr->message, &g_dbus_error, DBUS_TYPE_UINT64, &known_version, DBUS_TYPE_INVALID))
198 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message);
199 dbus_error_free(&g_dbus_error);
200 return;
203 //log_info("Getting graph, known version is %" PRIu64, known_version);
205 call_ptr->reply = dbus_message_new_method_return(call_ptr->message);
206 if (call_ptr->reply == NULL)
208 log_error("Ran out of memory trying to construct method return");
209 goto exit;
212 dbus_message_iter_init_append(call_ptr->reply, &iter);
214 current_version = graph_ptr->graph_version;
215 if (known_version > current_version)
217 lash_dbus_error(
218 call_ptr,
219 LASH_DBUS_ERROR_INVALID_ARGS,
220 "known graph version %" PRIu64 " is newer than actual version %" PRIu64,
221 known_version,
222 current_version);
223 goto exit;
226 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &current_version))
228 goto nomem;
231 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(tsa(tsuu))", &clients_array_iter))
233 goto nomem;
236 if (known_version < current_version)
238 list_for_each(client_node_ptr, &graph_ptr->clients)
240 client_ptr = list_entry(client_node_ptr, struct ladish_graph_client, siblings);
242 if (client_ptr->hidden)
244 continue;
247 if (!dbus_message_iter_open_container (&clients_array_iter, DBUS_TYPE_STRUCT, NULL, &client_struct_iter))
249 goto nomem_close_clients_array;
252 if (!dbus_message_iter_append_basic(&client_struct_iter, DBUS_TYPE_UINT64, &client_ptr->id))
254 goto nomem_close_client_struct;
257 log_info("client '%s' (%llu)", client_ptr->name, (unsigned long long)client_ptr->id);
258 if (!dbus_message_iter_append_basic(&client_struct_iter, DBUS_TYPE_STRING, &client_ptr->name))
260 goto nomem_close_client_struct;
263 if (!dbus_message_iter_open_container(&client_struct_iter, DBUS_TYPE_ARRAY, "(tsuu)", &ports_array_iter))
265 goto nomem_close_client_struct;
268 list_for_each(port_node_ptr, &client_ptr->ports)
270 port_ptr = list_entry(port_node_ptr, struct ladish_graph_port, siblings_client);
272 if (port_ptr->hidden)
274 continue;
277 if (!dbus_message_iter_open_container(&ports_array_iter, DBUS_TYPE_STRUCT, NULL, &port_struct_iter))
279 goto nomem_close_ports_array;
282 if (!dbus_message_iter_append_basic(&port_struct_iter, DBUS_TYPE_UINT64, &port_ptr->id))
284 goto nomem_close_port_struct;
287 if (!dbus_message_iter_append_basic(&port_struct_iter, DBUS_TYPE_STRING, &port_ptr->name))
289 goto nomem_close_port_struct;
292 if (!dbus_message_iter_append_basic(&port_struct_iter, DBUS_TYPE_UINT32, &port_ptr->flags))
294 goto nomem_close_port_struct;
297 if (!dbus_message_iter_append_basic(&port_struct_iter, DBUS_TYPE_UINT32, &port_ptr->type))
299 goto nomem_close_port_struct;
302 if (!dbus_message_iter_close_container(&ports_array_iter, &port_struct_iter))
304 goto nomem_close_ports_array;
308 if (!dbus_message_iter_close_container(&client_struct_iter, &ports_array_iter))
310 goto nomem_close_client_struct;
313 if (!dbus_message_iter_close_container(&clients_array_iter, &client_struct_iter))
315 goto nomem_close_clients_array;
320 if (!dbus_message_iter_close_container(&iter, &clients_array_iter))
322 goto nomem;
325 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(tstststst)", &connections_array_iter))
327 goto nomem;
330 if (known_version < current_version)
332 list_for_each(connection_node_ptr, &graph_ptr->connections)
334 connection_ptr = list_entry(connection_node_ptr, struct ladish_graph_connection, siblings);
336 if (connection_ptr->hidden)
338 continue;
341 if (!dbus_message_iter_open_container(&connections_array_iter, DBUS_TYPE_STRUCT, NULL, &connection_struct_iter))
343 goto nomem_close_connections_array;
346 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_UINT64, &connection_ptr->port1_ptr->client_ptr->id))
348 goto nomem_close_connection_struct;
351 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_STRING, &connection_ptr->port1_ptr->client_ptr->name))
353 goto nomem_close_connection_struct;
356 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_UINT64, &connection_ptr->port1_ptr->id))
358 goto nomem_close_connection_struct;
361 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_STRING, &connection_ptr->port1_ptr->name))
363 goto nomem_close_connection_struct;
366 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_UINT64, &connection_ptr->port2_ptr->client_ptr->id))
368 goto nomem_close_connection_struct;
371 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_STRING, &connection_ptr->port2_ptr->client_ptr->name))
373 goto nomem_close_connection_struct;
376 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_UINT64, &connection_ptr->port2_ptr->id))
378 goto nomem_close_connection_struct;
381 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_STRING, &connection_ptr->port2_ptr->name))
383 goto nomem_close_connection_struct;
386 if (!dbus_message_iter_append_basic(&connection_struct_iter, DBUS_TYPE_UINT64, &connection_ptr->id))
388 goto nomem_close_connection_struct;
391 if (!dbus_message_iter_close_container(&connections_array_iter, &connection_struct_iter))
393 goto nomem_close_connections_array;
398 if (!dbus_message_iter_close_container(&iter, &connections_array_iter))
400 goto nomem;
403 return;
405 nomem_close_connection_struct:
406 dbus_message_iter_close_container(&connections_array_iter, &connection_struct_iter);
408 nomem_close_connections_array:
409 dbus_message_iter_close_container(&iter, &connections_array_iter);
410 goto nomem;
412 nomem_close_port_struct:
413 dbus_message_iter_close_container(&ports_array_iter, &port_struct_iter);
415 nomem_close_ports_array:
416 dbus_message_iter_close_container(&client_struct_iter, &ports_array_iter);
418 nomem_close_client_struct:
419 dbus_message_iter_close_container(&clients_array_iter, &client_struct_iter);
421 nomem_close_clients_array:
422 dbus_message_iter_close_container(&iter, &clients_array_iter);
424 nomem:
425 dbus_message_unref(call_ptr->reply);
426 call_ptr->reply = NULL;
427 log_error("Ran out of memory trying to construct method return");
429 exit:
430 return;
433 static void connect_ports_by_name(struct dbus_method_call * call_ptr)
435 log_info("connect_ports_by_name() called.");
436 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "connect by name is not implemented yet");
439 static void connect_ports_by_id(struct dbus_method_call * call_ptr)
441 dbus_uint64_t port1_id;
442 dbus_uint64_t port2_id;
443 struct ladish_graph_port * port1_ptr;
444 struct ladish_graph_port * port2_ptr;
446 if (!dbus_message_get_args(call_ptr->message, &g_dbus_error, DBUS_TYPE_UINT64, &port1_id, DBUS_TYPE_UINT64, &port2_id, DBUS_TYPE_INVALID))
448 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message);
449 dbus_error_free(&g_dbus_error);
450 return;
453 log_info("connect_ports_by_id(%"PRIu64",%"PRIu64") called.", port1_id, port2_id);
455 if (graph_ptr->connect_handler == NULL)
457 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "connect requests on graph %s cannot be handlined", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
458 return;
461 port1_ptr = ladish_graph_find_port_by_id_internal(graph_ptr, port1_id);
462 if (port1_ptr == NULL)
464 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Cannot connect unknown port with id %"PRIu64, port1_id);
465 return;
468 port2_ptr = ladish_graph_find_port_by_id_internal(graph_ptr, port2_id);
469 if (port2_ptr == NULL)
471 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Cannot connect unknown port with id %"PRIu64, port2_id);
472 return;
475 log_info("connecting '%s':'%s' to '%s':'%s'", port1_ptr->client_ptr->name, port1_ptr->name, port2_ptr->client_ptr->name, port2_ptr->name);
477 if (graph_ptr->connect_handler(graph_ptr->context, (ladish_graph_handle)graph_ptr, port1_ptr->port, port2_ptr->port))
479 method_return_new_void(call_ptr);
481 else
483 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "connect failed");
487 static void disconnect_ports(struct dbus_method_call * call_ptr, struct ladish_graph_connection * connection_ptr)
489 log_info(
490 "disconnecting '%s':'%s' from '%s':'%s'",
491 connection_ptr->port1_ptr->client_ptr->name,
492 connection_ptr->port1_ptr->name,
493 connection_ptr->port2_ptr->client_ptr->name,
494 connection_ptr->port2_ptr->name);
496 connection_ptr->changing = true;
497 if (graph_ptr->disconnect_handler(graph_ptr->context, (ladish_graph_handle)graph_ptr, connection_ptr->id))
499 method_return_new_void(call_ptr);
501 else
503 connection_ptr->changing = false;
504 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "disconnect failed");
508 static void disconnect_ports_by_name(struct dbus_method_call * call_ptr)
510 log_info("disconnect_ports_by_name() called.");
511 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "disconnect by name is not implemented yet");
514 static void disconnect_ports_by_id(struct dbus_method_call * call_ptr)
516 dbus_uint64_t port1_id;
517 dbus_uint64_t port2_id;
518 struct ladish_graph_port * port1_ptr;
519 struct ladish_graph_port * port2_ptr;
520 struct ladish_graph_connection * connection_ptr;
522 if (!dbus_message_get_args(call_ptr->message, &g_dbus_error, DBUS_TYPE_UINT64, &port1_id, DBUS_TYPE_UINT64, &port2_id, DBUS_TYPE_INVALID))
524 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message);
525 dbus_error_free(&g_dbus_error);
526 return;
529 log_info("disconnect_ports_by_id(%"PRIu64",%"PRIu64") called.", port1_id, port2_id);
531 if (graph_ptr->disconnect_handler == NULL)
533 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "disconnect requests on graph %s cannot be handlined", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
534 return;
537 port1_ptr = ladish_graph_find_port_by_id_internal(graph_ptr, port1_id);
538 if (port1_ptr == NULL)
540 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Cannot disconnect unknown port with id %"PRIu64, port1_id);
541 return;
544 port2_ptr = ladish_graph_find_port_by_id_internal(graph_ptr, port2_id);
545 if (port2_ptr == NULL)
547 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Cannot disconnect unknown port with id %"PRIu64, port2_id);
548 return;
551 connection_ptr = ladish_graph_find_connection_by_ports(graph_ptr, port1_ptr, port2_ptr);
552 if (connection_ptr == NULL)
554 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Cannot disconnect not connected ports %"PRIu64" and %"PRIu64, port1_id, port2_id);
555 return;
558 disconnect_ports(call_ptr, connection_ptr);
561 static void disconnect_ports_by_connection_id(struct dbus_method_call * call_ptr)
563 dbus_uint64_t connection_id;
564 struct ladish_graph_connection * connection_ptr;
566 if (!dbus_message_get_args(call_ptr->message, &g_dbus_error, DBUS_TYPE_UINT64, &connection_id, DBUS_TYPE_INVALID))
568 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message);
569 dbus_error_free(&g_dbus_error);
570 return;
573 log_info("disconnect_ports_by_connection_id(%"PRIu64") called.", connection_id);
575 connection_ptr = ladish_graph_find_connection_by_id(graph_ptr, connection_id);
576 if (connection_ptr == NULL)
578 lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Cannot find connection with id %"PRIu64, connection_id);
579 return;
582 disconnect_ports(call_ptr, connection_ptr);
585 static void get_client_pid(struct dbus_method_call * call_ptr)
587 int64_t pid = 0;
588 method_return_new_single(call_ptr, DBUS_TYPE_INT64, &pid);
591 #undef graph_ptr
593 bool ladish_graph_create(ladish_graph_handle * graph_handle_ptr, const char * opath)
595 struct ladish_graph * graph_ptr;
597 graph_ptr = malloc(sizeof(struct ladish_graph));
598 if (graph_ptr == NULL)
600 log_error("malloc() failed to allocate struct graph_implementator");
601 return false;
604 if (opath != NULL)
606 graph_ptr->opath = strdup(opath);
607 if (graph_ptr->opath == NULL)
609 log_error("strdup() failed for graph opath");
610 free(graph_ptr);
611 return false;
614 else
616 graph_ptr->opath = NULL;
619 if (!ladish_dict_create(&graph_ptr->dict))
621 log_error("ladish_dict_create() failed for graph");
622 if (graph_ptr->opath != NULL)
624 free(graph_ptr->opath);
626 free(graph_ptr);
627 return false;
630 INIT_LIST_HEAD(&graph_ptr->clients);
631 INIT_LIST_HEAD(&graph_ptr->ports);
632 INIT_LIST_HEAD(&graph_ptr->connections);
634 graph_ptr->graph_version = 1;
635 graph_ptr->next_client_id = 1;
636 graph_ptr->next_port_id = 1;
637 graph_ptr->next_connection_id = 1;
639 graph_ptr->context = NULL;
640 graph_ptr->connect_handler = NULL;
641 graph_ptr->disconnect_handler = NULL;
643 *graph_handle_ptr = (ladish_graph_handle)graph_ptr;
644 return true;
647 static
648 struct ladish_graph_client *
649 ladish_graph_find_client(
650 struct ladish_graph * graph_ptr,
651 ladish_client_handle client)
653 struct list_head * node_ptr;
654 struct ladish_graph_client * client_ptr;
656 list_for_each(node_ptr, &graph_ptr->clients)
658 client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
659 if (client_ptr->client == client)
661 return client_ptr;
665 return NULL;
668 static
669 struct ladish_graph_port *
670 ladish_graph_find_port(
671 struct ladish_graph * graph_ptr,
672 ladish_port_handle port)
674 struct list_head * node_ptr;
675 struct ladish_graph_port * port_ptr;
677 //log_info("searching port %p", port);
679 list_for_each(node_ptr, &graph_ptr->ports)
681 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph);
682 //log_info("checking port %s:%s, %p", port_ptr->client_ptr->name, port_ptr->name, port_ptr->port);
683 if (port_ptr->port == port)
685 return port_ptr;
689 return NULL;
692 static
693 struct ladish_graph_port *
694 ladish_graph_find_port_by_jack_id_internal(
695 struct ladish_graph * graph_ptr,
696 uint64_t port_id,
697 bool room,
698 bool studio)
700 struct list_head * node_ptr;
701 struct ladish_graph_port * port_ptr;
703 ASSERT(room || studio);
705 list_for_each(node_ptr, &graph_ptr->ports)
707 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph);
708 //log_info("checking jack port id of port %s:%s, %p", port_ptr->client_ptr->name, port_ptr->name, port_ptr->port);
709 if ((studio && ladish_port_get_jack_id(port_ptr->port) == port_id) ||
710 (room && port_ptr->link && ladish_port_get_jack_id_room(port_ptr->port) == port_id))
712 //log_info("found");
713 return port_ptr;
717 return NULL;
720 #if 0
721 static
722 struct ladish_graph_port *
723 ladish_graph_find_client_port(
724 struct ladish_graph * graph_ptr,
725 struct ladish_graph_client * client_ptr,
726 ladish_port_handle port)
728 struct list_head * node_ptr;
729 struct ladish_graph_port * port_ptr;
731 list_for_each(node_ptr, &client_ptr->ports)
733 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_client);
734 if (port_ptr->port == port)
736 return port_ptr;
740 return NULL;
742 #endif
744 static void ladish_graph_hide_connection_internal(struct ladish_graph * graph_ptr, struct ladish_graph_connection * connection_ptr)
746 ASSERT(!connection_ptr->hidden);
747 connection_ptr->hidden = true;
748 graph_ptr->graph_version++;
750 if (graph_ptr->opath != NULL)
752 dbus_signal_emit(
753 g_dbus_connection,
754 graph_ptr->opath,
755 JACKDBUS_IFACE_PATCHBAY,
756 "PortsDisconnected",
757 "ttstststst",
758 &graph_ptr->graph_version,
759 &connection_ptr->port1_ptr->client_ptr->id,
760 &connection_ptr->port1_ptr->client_ptr->name,
761 &connection_ptr->port1_ptr->id,
762 &connection_ptr->port1_ptr->name,
763 &connection_ptr->port2_ptr->client_ptr->id,
764 &connection_ptr->port2_ptr->client_ptr->name,
765 &connection_ptr->port2_ptr->id,
766 &connection_ptr->port2_ptr->name,
767 &connection_ptr->id);
771 void ladish_graph_show_port_internal(struct ladish_graph * graph_ptr, struct ladish_graph_port * port_ptr)
773 if (port_ptr->client_ptr->hidden)
775 port_ptr->client_ptr->hidden = false;
776 graph_ptr->graph_version++;
777 if (graph_ptr->opath != NULL)
779 dbus_signal_emit(
780 g_dbus_connection,
781 graph_ptr->opath,
782 JACKDBUS_IFACE_PATCHBAY,
783 "ClientAppeared",
784 "tts",
785 &graph_ptr->graph_version,
786 &port_ptr->client_ptr->id,
787 &port_ptr->client_ptr->name);
791 ASSERT(port_ptr->hidden);
792 port_ptr->hidden = false;
793 graph_ptr->graph_version++;
794 if (graph_ptr->opath != NULL)
796 dbus_signal_emit(
797 g_dbus_connection,
798 graph_ptr->opath,
799 JACKDBUS_IFACE_PATCHBAY,
800 "PortAppeared",
801 "ttstsuu",
802 &graph_ptr->graph_version,
803 &port_ptr->client_ptr->id,
804 &port_ptr->client_ptr->name,
805 &port_ptr->id,
806 &port_ptr->name,
807 &port_ptr->flags,
808 &port_ptr->type);
810 ladish_try_connect_hidden_connections((ladish_graph_handle)graph_ptr);
814 void ladish_graph_hide_port_internal(struct ladish_graph * graph_ptr, struct ladish_graph_port * port_ptr)
816 ASSERT(!port_ptr->hidden);
817 port_ptr->hidden = true;
818 graph_ptr->graph_version++;
820 if (graph_ptr->opath != NULL)
822 dbus_signal_emit(
823 g_dbus_connection,
824 graph_ptr->opath,
825 JACKDBUS_IFACE_PATCHBAY,
826 "PortDisappeared",
827 "ttsts",
828 &graph_ptr->graph_version,
829 &port_ptr->client_ptr->id,
830 &port_ptr->client_ptr->name,
831 &port_ptr->id,
832 &port_ptr->name);
836 void ladish_graph_hide_client_internal(struct ladish_graph * graph_ptr, struct ladish_graph_client * client_ptr)
838 ASSERT(!client_ptr->hidden);
839 client_ptr->hidden = true;
840 graph_ptr->graph_version++;
842 if (graph_ptr->opath != NULL)
844 dbus_signal_emit(
845 g_dbus_connection,
846 graph_ptr->opath,
847 JACKDBUS_IFACE_PATCHBAY,
848 "ClientDisappeared",
849 "tts",
850 &graph_ptr->graph_version,
851 &client_ptr->id,
852 &client_ptr->name);
856 void ladish_hide_connections(struct ladish_graph * graph_ptr, struct ladish_graph_port * port_ptr)
858 struct list_head * node_ptr;
859 struct ladish_graph_connection * connection_ptr;
861 log_info("hidding connections of port %"PRIu64, port_ptr->id);
863 ASSERT(graph_ptr->opath != NULL);
865 list_for_each(node_ptr, &graph_ptr->connections)
867 connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
868 if (!connection_ptr->hidden && (connection_ptr->port1_ptr == port_ptr || connection_ptr->port2_ptr == port_ptr))
870 log_info("hidding connection between ports %"PRIu64" and %"PRIu64, connection_ptr->port1_ptr->id, connection_ptr->port2_ptr->id);
871 ladish_graph_hide_connection_internal(graph_ptr, connection_ptr);
876 static void ladish_graph_remove_connection_internal(struct ladish_graph * graph_ptr, struct ladish_graph_connection * connection_ptr)
878 list_del(&connection_ptr->siblings);
879 graph_ptr->graph_version++;
881 if (!connection_ptr->hidden && graph_ptr->opath != NULL)
883 dbus_signal_emit(
884 g_dbus_connection,
885 graph_ptr->opath,
886 JACKDBUS_IFACE_PATCHBAY,
887 "PortsDisconnected",
888 "ttstststst",
889 &graph_ptr->graph_version,
890 &connection_ptr->port1_ptr->client_ptr->id,
891 &connection_ptr->port1_ptr->client_ptr->name,
892 &connection_ptr->port1_ptr->id,
893 &connection_ptr->port1_ptr->name,
894 &connection_ptr->port2_ptr->client_ptr->id,
895 &connection_ptr->port2_ptr->client_ptr->name,
896 &connection_ptr->port2_ptr->id,
897 &connection_ptr->port2_ptr->name,
898 &connection_ptr->id);
901 ladish_dict_destroy(connection_ptr->dict);
902 free(connection_ptr);
905 void
906 ladish_graph_remove_port_internal(
907 struct ladish_graph * graph_ptr,
908 struct ladish_graph_client * client_ptr,
909 struct ladish_graph_port * port_ptr)
911 ladish_port_del_ref(port_ptr->port);
913 list_del(&port_ptr->siblings_client);
914 list_del(&port_ptr->siblings_graph);
916 log_info("removing port '%s':'%s' (%"PRIu64":%"PRIu64") from graph %s", client_ptr->name, port_ptr->name, client_ptr->id, port_ptr->id, graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
917 if (graph_ptr->opath != NULL && !port_ptr->hidden)
919 dbus_signal_emit(
920 g_dbus_connection,
921 graph_ptr->opath,
922 JACKDBUS_IFACE_PATCHBAY,
923 "PortDisappeared",
924 "ttsts",
925 &graph_ptr->graph_version,
926 &client_ptr->id,
927 &client_ptr->name,
928 &port_ptr->id,
929 &port_ptr->name);
932 free(port_ptr->name);
933 free(port_ptr);
936 static
937 void
938 ladish_graph_remove_client_internal(
939 struct ladish_graph * graph_ptr,
940 struct ladish_graph_client * client_ptr,
941 bool destroy_client)
943 struct ladish_graph_port * port_ptr;
945 while (!list_empty(&client_ptr->ports))
947 port_ptr = list_entry(client_ptr->ports.next, struct ladish_graph_port, siblings_client);
948 ladish_graph_remove_port_internal(graph_ptr, client_ptr, port_ptr);
951 graph_ptr->graph_version++;
952 list_del(&client_ptr->siblings);
953 log_info("removing client '%s' (%"PRIu64") from graph %s", client_ptr->name, client_ptr->id, graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
954 if (graph_ptr->opath != NULL && !client_ptr->hidden)
956 dbus_signal_emit(
957 g_dbus_connection,
958 graph_ptr->opath,
959 JACKDBUS_IFACE_PATCHBAY,
960 "ClientDisappeared",
961 "tts",
962 &graph_ptr->graph_version,
963 &client_ptr->id,
964 &client_ptr->name);
967 free(client_ptr->name);
969 if (destroy_client)
971 ladish_client_destroy(client_ptr->client);
974 free(client_ptr);
977 #define graph_ptr ((struct ladish_graph *)graph_handle)
979 void ladish_graph_destroy(ladish_graph_handle graph_handle)
981 ladish_graph_clear(graph_handle);
982 ladish_dict_destroy(graph_ptr->dict);
983 if (graph_ptr->opath != NULL)
985 free(graph_ptr->opath);
987 free(graph_ptr);
990 const char * ladish_graph_get_opath(ladish_graph_handle graph_handle)
992 return graph_ptr->opath;
995 const char * ladish_graph_get_description(ladish_graph_handle graph_handle)
997 return graph_ptr->opath != NULL ? graph_ptr->opath : "JACK";
1000 void
1001 ladish_graph_set_connection_handlers(
1002 ladish_graph_handle graph_handle,
1003 void * graph_context,
1004 ladish_graph_connect_request_handler connect_handler,
1005 ladish_graph_disconnect_request_handler disconnect_handler)
1007 log_info("setting connection handlers for graph '%s'", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
1008 graph_ptr->context = graph_context;
1009 graph_ptr->connect_handler = connect_handler;
1010 graph_ptr->disconnect_handler = disconnect_handler;
1013 void ladish_graph_clear(ladish_graph_handle graph_handle)
1015 struct ladish_graph_client * client_ptr;
1016 struct ladish_graph_connection * connection_ptr;
1018 log_info("ladish_graph_clear() called for graph '%s'", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
1020 while (!list_empty(&graph_ptr->connections))
1022 connection_ptr = list_entry(graph_ptr->connections.next, struct ladish_graph_connection, siblings);
1023 ladish_graph_remove_connection_internal(graph_ptr, connection_ptr);
1026 while (!list_empty(&graph_ptr->clients))
1028 client_ptr = list_entry(graph_ptr->clients.next, struct ladish_graph_client, siblings);
1029 ladish_graph_remove_client_internal(graph_ptr, client_ptr, true);
1033 void * ladish_graph_get_dbus_context(ladish_graph_handle graph_handle)
1035 return graph_handle;
1038 ladish_dict_handle ladish_graph_get_dict(ladish_graph_handle graph_handle)
1040 return graph_ptr->dict;
1043 void ladish_graph_show_connection(ladish_graph_handle graph_handle, uint64_t connection_id)
1045 struct ladish_graph_connection * connection_ptr;
1047 log_info("ladish_graph_show_connection() called.");
1049 connection_ptr = ladish_graph_find_connection_by_id(graph_ptr, connection_id);
1050 if (connection_ptr == NULL)
1052 ASSERT_NO_PASS;
1053 return;
1056 ASSERT(graph_ptr->opath != NULL);
1057 ASSERT(connection_ptr->hidden);
1058 connection_ptr->hidden = false;
1059 connection_ptr->changing = false;
1060 graph_ptr->graph_version++;
1062 dbus_signal_emit(
1063 g_dbus_connection,
1064 graph_ptr->opath,
1065 JACKDBUS_IFACE_PATCHBAY,
1066 "PortsConnected",
1067 "ttstststst",
1068 &graph_ptr->graph_version,
1069 &connection_ptr->port1_ptr->client_ptr->id,
1070 &connection_ptr->port1_ptr->client_ptr->name,
1071 &connection_ptr->port1_ptr->id,
1072 &connection_ptr->port1_ptr->name,
1073 &connection_ptr->port2_ptr->client_ptr->id,
1074 &connection_ptr->port2_ptr->client_ptr->name,
1075 &connection_ptr->port2_ptr->id,
1076 &connection_ptr->port2_ptr->name,
1077 &connection_ptr->id);
1080 void ladish_graph_show_port(ladish_graph_handle graph_handle, ladish_port_handle port_handle)
1082 struct ladish_graph_port * port_ptr;
1084 //log_info("ladish_graph_show_port() called.");
1086 port_ptr = ladish_graph_find_port(graph_ptr, port_handle);
1087 if (port_ptr == NULL)
1089 ASSERT_NO_PASS;
1090 return;
1093 //log_info("port '%s' is %s", port_ptr->name, port_ptr->hidden ? "invisible" : "visible");
1095 ladish_graph_show_port_internal(graph_ptr, port_ptr);
1098 void ladish_graph_hide_port(ladish_graph_handle graph_handle, ladish_port_handle port_handle)
1100 struct ladish_graph_port * port_ptr;
1102 log_info("ladish_graph_hide_port() called.");
1104 port_ptr = ladish_graph_find_port(graph_ptr, port_handle);
1105 if (port_ptr == NULL)
1107 ASSERT_NO_PASS;
1108 return;
1111 log_info("Hidding port %"PRIu64, port_ptr->id);
1113 ASSERT(!port_ptr->hidden);
1115 if (graph_ptr->opath != NULL)
1117 ladish_hide_connections(graph_ptr, port_ptr);
1120 ladish_graph_hide_port_internal(graph_ptr, port_ptr);
1123 void ladish_graph_hide_client(ladish_graph_handle graph_handle, ladish_client_handle client_handle)
1125 struct ladish_graph_client * client_ptr;
1127 log_info("ladish_graph_hide_client() called.");
1129 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1130 if (client_ptr == NULL)
1132 ASSERT_NO_PASS;
1133 return;
1136 ladish_graph_hide_client_internal(graph_ptr, client_ptr);
1139 void ladish_graph_show_client(ladish_graph_handle graph_handle, ladish_client_handle client_handle)
1141 struct ladish_graph_client * client_ptr;
1143 log_info("ladish_graph_show_client() called.");
1145 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1146 if (client_ptr == NULL)
1148 ASSERT_NO_PASS;
1149 return;
1152 ASSERT(client_ptr->hidden);
1153 client_ptr->hidden = false;
1154 graph_ptr->graph_version++;
1156 if (graph_ptr->opath != NULL)
1158 dbus_signal_emit(
1159 g_dbus_connection,
1160 graph_ptr->opath,
1161 JACKDBUS_IFACE_PATCHBAY,
1162 "ClientAppeared",
1163 "tts",
1164 &graph_ptr->graph_version,
1165 &client_ptr->id,
1166 &client_ptr->name);
1170 void ladish_graph_adjust_port(ladish_graph_handle graph_handle, ladish_port_handle port_handle, uint32_t type, uint32_t flags)
1172 struct ladish_graph_port * port_ptr;
1174 //log_info("ladish_graph_adjust_port() called.");
1176 port_ptr = ladish_graph_find_port(graph_ptr, port_handle);
1177 if (port_ptr == NULL)
1179 ASSERT_NO_PASS;
1180 return;
1183 port_ptr->type = type;
1184 port_ptr->flags = flags;
1187 bool ladish_graph_add_client(ladish_graph_handle graph_handle, ladish_client_handle client_handle, const char * name, bool hidden)
1189 struct ladish_graph_client * client_ptr;
1191 log_info("adding client '%s' (%p) to graph %s", name, client_handle, graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
1193 client_ptr = malloc(sizeof(struct ladish_graph_client));
1194 if (client_ptr == NULL)
1196 log_error("malloc() failed for struct ladish_graph_client");
1197 return false;
1200 client_ptr->name = strdup(name);
1201 if (client_ptr->name == NULL)
1203 log_error("strdup() failed for graph client name");
1204 free(client_ptr);
1205 return false;
1208 client_ptr->id = graph_ptr->next_client_id++;
1209 client_ptr->client = client_handle;
1210 client_ptr->hidden = hidden;
1211 graph_ptr->graph_version++;
1213 INIT_LIST_HEAD(&client_ptr->ports);
1215 list_add_tail(&client_ptr->siblings, &graph_ptr->clients);
1217 if (!hidden && graph_ptr->opath != NULL)
1219 dbus_signal_emit(
1220 g_dbus_connection,
1221 graph_ptr->opath,
1222 JACKDBUS_IFACE_PATCHBAY,
1223 "ClientAppeared",
1224 "tts",
1225 &graph_ptr->graph_version,
1226 &client_ptr->id,
1227 &client_ptr->name);
1230 return true;
1233 void
1234 ladish_graph_remove_client(
1235 ladish_graph_handle graph_handle,
1236 ladish_client_handle client_handle)
1238 struct ladish_graph_client * client_ptr;
1240 log_info("ladish_graph_remove_client() called.");
1242 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1243 if (client_ptr != NULL)
1245 ladish_graph_remove_client_internal(graph_ptr, client_ptr, false);
1247 else
1249 ASSERT_NO_PASS;
1253 bool
1254 ladish_graph_add_port(
1255 ladish_graph_handle graph_handle,
1256 ladish_client_handle client_handle,
1257 ladish_port_handle port_handle,
1258 const char * name,
1259 uint32_t type,
1260 uint32_t flags,
1261 bool hidden)
1263 struct ladish_graph_client * client_ptr;
1264 struct ladish_graph_port * port_ptr;
1266 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1267 if (client_ptr == NULL)
1269 log_error("cannot find client to add port to. graph is %s", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
1270 ASSERT_NO_PASS;
1271 return false;
1274 log_info("adding port '%s' (%p) to client '%s' in graph %s", name, port_handle, client_ptr->name, graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
1276 port_ptr = malloc(sizeof(struct ladish_graph_port));
1277 if (port_ptr == NULL)
1279 log_error("malloc() failed for struct ladish_graph_port");
1280 return false;
1283 port_ptr->name = strdup(name);
1284 if (port_ptr->name == NULL)
1286 log_error("strdup() failed for graph port name");
1287 free(port_ptr);
1288 return false;
1291 port_ptr->type = type;
1292 port_ptr->flags = flags;
1294 port_ptr->id = graph_ptr->next_port_id++;
1295 port_ptr->port = port_handle;
1296 ladish_port_add_ref(port_ptr->port);
1297 port_ptr->hidden = true;
1299 port_ptr->link = ladish_port_is_link(port_handle);
1300 if (port_ptr->link)
1302 uuid_generate(port_ptr->link_uuid_override);
1305 port_ptr->client_ptr = client_ptr;
1306 list_add_tail(&port_ptr->siblings_client, &client_ptr->ports);
1307 list_add_tail(&port_ptr->siblings_graph, &graph_ptr->ports);
1309 if (!hidden)
1311 ladish_graph_show_port_internal(graph_ptr, port_ptr);
1314 return true;
1317 uint64_t
1318 ladish_graph_add_connection(
1319 ladish_graph_handle graph_handle,
1320 ladish_port_handle port1_handle,
1321 ladish_port_handle port2_handle,
1322 bool hidden)
1324 struct ladish_graph_port * port1_ptr;
1325 struct ladish_graph_port * port2_ptr;
1326 struct ladish_graph_connection * connection_ptr;
1328 port1_ptr = ladish_graph_find_port(graph_ptr, port1_handle);
1329 ASSERT(port1_ptr != NULL);
1330 port2_ptr = ladish_graph_find_port(graph_ptr, port2_handle);
1331 ASSERT(port2_ptr != NULL);
1333 connection_ptr = malloc(sizeof(struct ladish_graph_connection));
1334 if (connection_ptr == NULL)
1336 log_error("malloc() failed for struct ladish_graph_connection");
1337 return 0;
1340 if (!ladish_dict_create(&connection_ptr->dict))
1342 log_error("ladish_dict_create() failed for connection");
1343 free(connection_ptr);
1344 return 0;
1347 connection_ptr->id = graph_ptr->next_connection_id++;
1348 connection_ptr->port1_ptr = port1_ptr;
1349 connection_ptr->port2_ptr = port2_ptr;
1350 connection_ptr->hidden = hidden;
1351 connection_ptr->changing = false;
1352 graph_ptr->graph_version++;
1354 list_add_tail(&connection_ptr->siblings, &graph_ptr->connections);
1356 /* log_info( */
1357 /* "new connection %"PRIu64" between '%s':'%s' and '%s':'%s'", */
1358 /* connection_ptr->id, */
1359 /* port1_ptr->client_ptr->name, */
1360 /* port1_ptr->name, */
1361 /* port2_ptr->client_ptr->name, */
1362 /* port2_ptr->name); */
1364 if (!hidden && graph_ptr->opath != NULL)
1366 dbus_signal_emit(
1367 g_dbus_connection,
1368 graph_ptr->opath,
1369 JACKDBUS_IFACE_PATCHBAY,
1370 "PortsConnected",
1371 "ttstststst",
1372 &graph_ptr->graph_version,
1373 &port1_ptr->client_ptr->id,
1374 &port1_ptr->client_ptr->name,
1375 &port1_ptr->id,
1376 &port1_ptr->name,
1377 &port2_ptr->client_ptr->id,
1378 &port2_ptr->client_ptr->name,
1379 &port2_ptr->id,
1380 &port2_ptr->name,
1381 &connection_ptr->id);
1384 return connection_ptr->id;
1387 void
1388 ladish_graph_remove_connection(
1389 ladish_graph_handle graph_handle,
1390 uint64_t connection_id,
1391 bool force)
1393 struct ladish_graph_connection * connection_ptr;
1395 connection_ptr = ladish_graph_find_connection_by_id(graph_ptr, connection_id);
1396 if (connection_ptr == NULL)
1398 ASSERT_NO_PASS;
1399 return;
1402 if (force || connection_ptr->changing)
1404 /* log_info( */
1405 /* "removing connection '%s':'%s' - '%s':'%s'", */
1406 /* connection_ptr->port1_ptr->client_ptr->name, */
1407 /* connection_ptr->port1_ptr->name, */
1408 /* connection_ptr->port2_ptr->client_ptr->name, */
1409 /* connection_ptr->port2_ptr->name); */
1411 ladish_graph_remove_connection_internal(graph_ptr, connection_ptr);
1413 else
1415 /* log_info( */
1416 /* "hiding connection '%s':'%s' - '%s':'%s'", */
1417 /* connection_ptr->port1_ptr->client_ptr->name, */
1418 /* connection_ptr->port1_ptr->name, */
1419 /* connection_ptr->port2_ptr->client_ptr->name, */
1420 /* connection_ptr->port2_ptr->name); */
1422 ladish_graph_hide_connection_internal(graph_ptr, connection_ptr);
1426 bool
1427 ladish_graph_get_connection_ports(
1428 ladish_graph_handle graph_handle,
1429 uint64_t connection_id,
1430 ladish_port_handle * port1_handle_ptr,
1431 ladish_port_handle * port2_handle_ptr)
1433 struct ladish_graph_connection * connection_ptr;
1435 connection_ptr = ladish_graph_find_connection_by_id(graph_ptr, connection_id);
1436 if (connection_ptr == NULL)
1438 return false;
1441 *port1_handle_ptr = connection_ptr->port1_ptr->port;
1442 *port2_handle_ptr = connection_ptr->port2_ptr->port;
1444 return true;
1447 ladish_dict_handle ladish_graph_get_connection_dict(ladish_graph_handle graph_handle, uint64_t connection_id)
1449 struct ladish_graph_connection * connection_ptr;
1451 connection_ptr = ladish_graph_find_connection_by_id(graph_ptr, connection_id);
1452 if (connection_ptr == NULL)
1454 return NULL;
1457 return connection_ptr->dict;
1460 bool
1461 ladish_graph_find_connection(
1462 ladish_graph_handle graph_handle,
1463 ladish_port_handle port1_handle,
1464 ladish_port_handle port2_handle,
1465 uint64_t * connection_id_ptr)
1467 struct ladish_graph_port * port1_ptr;
1468 struct ladish_graph_port * port2_ptr;
1469 struct ladish_graph_connection * connection_ptr;
1471 port1_ptr = ladish_graph_find_port(graph_ptr, port1_handle);
1472 if (port1_ptr == NULL)
1474 return false;
1477 port2_ptr = ladish_graph_find_port(graph_ptr, port2_handle);
1478 if (port1_ptr == NULL)
1480 return false;
1483 connection_ptr = ladish_graph_find_connection_by_ports(graph_ptr, port1_ptr, port2_ptr);
1484 if (connection_ptr == NULL)
1486 return false;
1489 *connection_id_ptr = connection_ptr->id;
1491 return true;
1494 ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_handle, const char * name)
1496 struct list_head * node_ptr;
1497 struct ladish_graph_client * client_ptr;
1499 list_for_each(node_ptr, &graph_ptr->clients)
1501 client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
1502 if (strcmp(client_ptr->name, name) == 0)
1504 return client_ptr->client;
1508 return NULL;
1511 ladish_port_handle ladish_graph_find_port_by_name(ladish_graph_handle graph_handle, ladish_client_handle client_handle, const char * name)
1513 struct ladish_graph_client * client_ptr;
1514 struct list_head * node_ptr;
1515 struct ladish_graph_port * port_ptr;
1517 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1518 if (client_ptr != NULL)
1520 list_for_each(node_ptr, &client_ptr->ports)
1522 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_client);
1523 if (strcmp(port_ptr->name, name) == 0)
1525 return port_ptr->port;
1529 else
1531 ASSERT_NO_PASS;
1534 return NULL;
1537 ladish_client_handle ladish_graph_find_client_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid)
1539 struct list_head * node_ptr;
1540 struct ladish_graph_client * client_ptr;
1541 uuid_t current_uuid;
1543 list_for_each(node_ptr, &graph_ptr->clients)
1545 client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
1546 ladish_client_get_uuid(client_ptr->client, current_uuid);
1547 if (uuid_compare(current_uuid, uuid) == 0)
1549 return client_ptr->client;
1553 return NULL;
1556 ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, bool use_link_override_uuids)
1558 struct list_head * node_ptr;
1559 struct ladish_graph_port * port_ptr;
1560 uuid_t current_uuid;
1561 /* char uuid1_str[37]; */
1562 /* char uuid2_str[37]; */
1564 /* log_info("searching by uuid for port in graph %s", ladish_graph_get_description(graph_handle)); */
1565 /* uuid_unparse(uuid, uuid1_str); */
1567 list_for_each(node_ptr, &graph_ptr->ports)
1569 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph);
1571 /* if (port_ptr->link) */
1572 /* { */
1573 /* uuid_unparse(port_ptr->link_uuid_override, uuid2_str); */
1574 /* log_info("comparing link uuid %s with %s", uuid2_str, uuid1_str); */
1575 /* } */
1577 if (port_ptr->link && uuid_compare(port_ptr->link_uuid_override, uuid) == 0)
1579 /* log_info("found port %p of client '%s'", port_ptr->port, port_ptr->client_ptr->name); */
1580 return port_ptr->port;
1583 ladish_port_get_uuid(port_ptr->port, current_uuid);
1584 /* uuid_unparse(current_uuid, uuid2_str); */
1585 /* log_info("comparing port uuid %s with %s", uuid2_str, uuid1_str); */
1586 if (uuid_compare(current_uuid, uuid) == 0)
1588 return port_ptr->port;
1592 return NULL;
1595 ladish_client_handle ladish_graph_get_port_client(ladish_graph_handle graph_handle, ladish_port_handle port_handle)
1597 struct ladish_graph_port * port_ptr;
1599 port_ptr = ladish_graph_find_port(graph_ptr, port_handle);
1600 if (port_ptr == NULL)
1602 return NULL;
1605 return port_ptr->client_ptr->client;
1608 bool ladish_graph_is_port_present(ladish_graph_handle graph_handle, ladish_port_handle port_handle)
1610 return ladish_graph_find_port(graph_ptr, port_handle) != NULL;
1613 ladish_client_handle ladish_graph_find_client_by_id(ladish_graph_handle graph_handle, uint64_t client_id)
1615 struct list_head * node_ptr;
1616 struct ladish_graph_client * client_ptr;
1618 list_for_each(node_ptr, &graph_ptr->clients)
1620 client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
1621 if (client_ptr->id == client_id)
1623 return client_ptr->client;
1627 return NULL;
1630 ladish_port_handle ladish_graph_find_port_by_id(ladish_graph_handle graph_handle, uint64_t port_id)
1632 struct ladish_graph_port * port_ptr;
1634 port_ptr = ladish_graph_find_port_by_id_internal(graph_ptr, port_id);
1635 if (port_ptr == NULL)
1637 return NULL;
1640 return port_ptr->port;
1643 ladish_client_handle ladish_graph_find_client_by_jack_id(ladish_graph_handle graph_handle, uint64_t client_id)
1645 struct list_head * node_ptr;
1646 struct ladish_graph_client * client_ptr;
1648 list_for_each(node_ptr, &graph_ptr->clients)
1650 client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
1651 if (ladish_client_get_jack_id(client_ptr->client) == client_id)
1653 return client_ptr->client;
1657 return NULL;
1660 ladish_port_handle ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_handle, uint64_t port_id, bool room, bool studio)
1662 struct ladish_graph_port * port_ptr;
1664 port_ptr = ladish_graph_find_port_by_jack_id_internal(graph_ptr, port_id, room, studio);
1665 if (port_ptr == NULL)
1667 return NULL;
1670 return port_ptr->port;
1673 ladish_client_handle
1674 ladish_graph_remove_port(
1675 ladish_graph_handle graph_handle,
1676 ladish_port_handle port)
1678 struct ladish_graph_port * port_ptr;
1680 port_ptr = ladish_graph_find_port(graph_ptr, port);
1681 if (port_ptr == NULL)
1683 return NULL;
1686 ladish_graph_remove_port_internal(graph_ptr, port_ptr->client_ptr, port_ptr);
1687 return port_ptr->client_ptr->client;
1690 ladish_client_handle
1691 ladish_graph_remove_port_by_jack_id(
1692 ladish_graph_handle graph_handle,
1693 uint64_t jack_port_id,
1694 bool room,
1695 bool studio)
1697 struct ladish_graph_port * port_ptr;
1699 port_ptr = ladish_graph_find_port_by_jack_id_internal(graph_ptr, jack_port_id, room, studio);
1700 if (port_ptr == NULL)
1702 return NULL;
1705 ladish_graph_remove_port_internal(graph_ptr, port_ptr->client_ptr, port_ptr);
1706 return port_ptr->client_ptr->client;
1709 bool
1710 ladish_graph_rename_client(
1711 ladish_graph_handle graph_handle,
1712 ladish_client_handle client_handle,
1713 const char * new_client_name)
1715 char * name;
1716 struct ladish_graph_client * client_ptr;
1717 char * old_name;
1719 name = strdup(new_client_name);
1720 if (name == NULL)
1722 log_error("strdup('%s') failed.", new_client_name);
1723 return false;
1726 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1727 if (client_ptr == NULL)
1729 free(name);
1730 ASSERT_NO_PASS;
1731 return false;
1734 old_name = client_ptr->name;
1735 client_ptr->name = name;
1737 graph_ptr->graph_version++;
1739 if (!client_ptr->hidden && graph_ptr->opath != NULL)
1741 dbus_signal_emit(
1742 g_dbus_connection,
1743 graph_ptr->opath,
1744 JACKDBUS_IFACE_PATCHBAY,
1745 "ClientRenamed",
1746 "ttss",
1747 &graph_ptr->graph_version,
1748 &client_ptr->id,
1749 &old_name,
1750 &client_ptr->name);
1753 free(old_name);
1755 return true;
1758 bool
1759 ladish_graph_rename_port(
1760 ladish_graph_handle graph_handle,
1761 ladish_port_handle port_handle,
1762 const char * new_port_name)
1764 char * name;
1765 struct ladish_graph_port * port_ptr;
1766 char * old_name;
1768 name = strdup(new_port_name);
1769 if (name == NULL)
1771 log_error("strdup('%s') failed.", new_port_name);
1772 return false;
1775 port_ptr = ladish_graph_find_port(graph_ptr, port_handle);
1776 if (port_ptr == NULL)
1778 ASSERT_NO_PASS;
1779 free(name);
1780 return false;
1783 old_name = port_ptr->name;
1784 port_ptr->name = name;
1786 graph_ptr->graph_version++;
1788 if (!port_ptr->hidden && graph_ptr->opath != NULL)
1790 dbus_signal_emit(
1791 g_dbus_connection,
1792 graph_ptr->opath,
1793 JACKDBUS_IFACE_PATCHBAY,
1794 "PortRenamed",
1795 "ttstss",
1796 &graph_ptr->graph_version,
1797 &port_ptr->client_ptr->id,
1798 &port_ptr->client_ptr->name,
1799 &port_ptr->id,
1800 &old_name,
1801 &port_ptr->name);
1804 free(old_name);
1806 return true;
1809 const char * ladish_graph_get_client_name(ladish_graph_handle graph_handle, ladish_client_handle client_handle)
1811 struct ladish_graph_client * client_ptr;
1813 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1814 if (client_ptr != NULL)
1816 return client_ptr->name;
1819 ASSERT_NO_PASS;
1820 return NULL;
1823 bool ladish_graph_is_client_empty(ladish_graph_handle graph_handle, ladish_client_handle client_handle)
1825 struct ladish_graph_client * client_ptr;
1827 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1828 if (client_ptr != NULL)
1830 return list_empty(&client_ptr->ports);
1833 ASSERT_NO_PASS;
1834 return true;
1837 bool ladish_graph_is_client_looks_empty(ladish_graph_handle graph_handle, ladish_client_handle client_handle)
1839 struct ladish_graph_client * client_ptr;
1840 struct list_head * node_ptr;
1841 struct ladish_graph_port * port_ptr;
1843 client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
1844 if (client_ptr != NULL)
1846 list_for_each(node_ptr, &client_ptr->ports)
1848 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_client);
1849 if (!port_ptr->hidden)
1851 //log_info("port '%s' is visible, client '%s' does not look empty", port_ptr->name, client_ptr->name);
1852 return false;
1854 else
1856 //log_info("port '%s' is invisible", port_ptr->name);
1860 log_info("client '%s' looks empty in graph %s", client_ptr->name, graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
1861 return true;
1864 ASSERT_NO_PASS;
1865 return true;
1868 void ladish_try_connect_hidden_connections(ladish_graph_handle graph_handle)
1870 struct list_head * node_ptr;
1871 struct ladish_graph_connection * connection_ptr;
1873 if (!list_empty(&graph_ptr->connections) && graph_ptr->connect_handler == NULL)
1875 ASSERT_NO_PASS;
1876 return;
1879 ASSERT(graph_ptr->opath != NULL);
1881 list_for_each(node_ptr, &graph_ptr->connections)
1883 connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
1884 if (connection_ptr->hidden &&
1885 !connection_ptr->changing &&
1886 !connection_ptr->port1_ptr->hidden &&
1887 !connection_ptr->port2_ptr->hidden)
1889 log_info(
1890 "auto connecting '%s':'%s' to '%s':'%s'",
1891 connection_ptr->port1_ptr->client_ptr->name,
1892 connection_ptr->port1_ptr->name,
1893 connection_ptr->port2_ptr->client_ptr->name,
1894 connection_ptr->port2_ptr->name);
1896 connection_ptr->changing = true;
1897 if (!graph_ptr->connect_handler(graph_ptr->context, graph_handle, connection_ptr->port1_ptr->port, connection_ptr->port2_ptr->port))
1899 connection_ptr->changing = false;
1900 log_error("auto connect failed.");
1906 void ladish_graph_hide_non_virtual(ladish_graph_handle graph_handle)
1908 struct list_head * node_ptr;
1909 struct ladish_graph_connection * connection_ptr;
1910 struct ladish_graph_port * port_ptr;
1911 struct ladish_graph_client * client_ptr;
1913 log_info("hiding everything in graph %s", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
1915 list_for_each(node_ptr, &graph_ptr->connections)
1917 connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
1918 if (!connection_ptr->hidden &&
1919 (ladish_client_get_jack_id(connection_ptr->port1_ptr->client_ptr->client) != 0 ||
1920 ladish_client_get_jack_id(connection_ptr->port2_ptr->client_ptr->client) != 0))
1922 log_debug("hidding connection between ports %"PRIu64" and %"PRIu64, connection_ptr->port1_ptr->id, connection_ptr->port2_ptr->id);
1923 ladish_graph_hide_connection_internal(graph_ptr, connection_ptr);
1927 list_for_each(node_ptr, &graph_ptr->ports)
1929 port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph);
1930 if (!port_ptr->hidden && ladish_client_get_jack_id(port_ptr->client_ptr->client) != 0)
1932 ladish_port_set_jack_id(port_ptr->port, 0);
1933 ladish_graph_hide_port_internal(graph_ptr, port_ptr);
1937 list_for_each(node_ptr, &graph_ptr->clients)
1939 client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
1940 if (!client_ptr->hidden && ladish_client_get_jack_id(client_ptr->client) != 0)
1942 ladish_client_set_jack_id(client_ptr->client, 0);
1943 ladish_graph_hide_client_internal(graph_ptr, client_ptr);
1948 void ladish_graph_get_port_uuid(ladish_graph_handle graph_handle, ladish_port_handle port, uuid_t uuid_ptr)
1950 struct ladish_graph_port * port_ptr;
1952 port_ptr = ladish_graph_find_port(graph_ptr, port);
1953 ASSERT(port_ptr != NULL);
1954 ASSERT(port_ptr->link);
1956 uuid_copy(uuid_ptr, port_ptr->link_uuid_override);
1959 const char * ladish_graph_get_port_name(ladish_graph_handle graph_handle, ladish_port_handle port)
1961 struct ladish_graph_port * port_ptr;
1963 port_ptr = ladish_graph_find_port(graph_ptr, port);
1964 ASSERT(port_ptr != NULL);
1966 return port_ptr->name;
1969 bool
1970 ladish_graph_iterate_nodes(
1971 ladish_graph_handle graph_handle,
1972 bool skip_hidden,
1973 void * callback_context,
1974 bool
1975 (* client_begin_callback)(
1976 void * context,
1977 ladish_client_handle client_handle,
1978 const char * client_name,
1979 void ** client_iteration_context_ptr_ptr),
1980 bool
1981 (* port_callback)(
1982 void * context,
1983 void * client_iteration_context_ptr,
1984 ladish_client_handle client_handle,
1985 const char * client_name,
1986 ladish_port_handle port_handle,
1987 const char * port_name,
1988 uint32_t port_type,
1989 uint32_t port_flags),
1990 bool
1991 (* client_end_callback)(
1992 void * context,
1993 ladish_client_handle client_handle,
1994 const char * client_name,
1995 void * client_iteration_context_ptr))
1997 struct list_head * client_node_ptr;
1998 struct ladish_graph_client * client_ptr;
1999 void * client_context;
2000 struct list_head * port_node_ptr;
2001 struct ladish_graph_port * port_ptr;
2003 list_for_each(client_node_ptr, &graph_ptr->clients)
2005 client_ptr = list_entry(client_node_ptr, struct ladish_graph_client, siblings);
2007 if (skip_hidden && client_ptr->hidden)
2009 continue;
2012 if (client_begin_callback != NULL)
2014 if (!client_begin_callback(callback_context, client_ptr->client, client_ptr->name, &client_context))
2016 return false;
2019 else
2021 client_context = NULL;
2024 if (port_callback == NULL)
2026 continue;
2029 list_for_each(port_node_ptr, &client_ptr->ports)
2031 port_ptr = list_entry(port_node_ptr, struct ladish_graph_port, siblings_client);
2033 if (skip_hidden && port_ptr->hidden)
2035 continue;
2038 if (!port_callback(
2039 callback_context,
2040 client_context,
2041 client_ptr->client,
2042 client_ptr->name,
2043 port_ptr->port,
2044 port_ptr->name,
2045 port_ptr->type,
2046 port_ptr->flags))
2048 return false;
2052 if (client_end_callback != NULL)
2054 if (!client_end_callback(callback_context, client_ptr->client, client_ptr->name, &client_context))
2056 return false;
2061 return true;
2064 bool
2065 ladish_graph_iterate_connections(
2066 ladish_graph_handle graph_handle,
2067 bool skip_hidden,
2068 void * callback_context,
2069 bool (* callback)(void * context, ladish_port_handle port1_handle, ladish_port_handle port2_handle, ladish_dict_handle dict))
2071 struct list_head * node_ptr;
2072 struct ladish_graph_connection * connection_ptr;
2074 list_for_each(node_ptr, &graph_ptr->connections)
2076 connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings);
2078 if (skip_hidden && connection_ptr->hidden)
2080 continue;
2083 if (!callback(callback_context, connection_ptr->port1_ptr->port, connection_ptr->port2_ptr->port, connection_ptr->dict))
2085 return false;
2089 return true;
2092 static
2093 bool
2094 dump_dict_entry(
2095 void * context,
2096 const char * key,
2097 const char * value)
2099 log_info("%s key '%s' with value '%s'", (const char *)context, key, value);
2100 return true;
2103 static
2104 void
2105 dump_dict(
2106 const char * indent,
2107 ladish_dict_handle dict)
2109 if (ladish_dict_is_empty(dict))
2111 return;
2114 log_info("%sdict:", indent);
2115 ladish_dict_iterate(dict, (void *)indent, dump_dict_entry);
2118 void ladish_graph_dump(ladish_graph_handle graph_handle)
2120 struct list_head * client_node_ptr;
2121 struct ladish_graph_client * client_ptr;
2122 struct list_head * port_node_ptr;
2123 struct ladish_graph_port * port_ptr;
2124 struct list_head * connection_node_ptr;
2125 struct ladish_graph_connection * connection_ptr;
2127 log_info("graph %s", graph_ptr->opath != NULL ? graph_ptr->opath : "JACK");
2128 log_info(" version %"PRIu64, graph_ptr->graph_version);
2129 dump_dict(" ", graph_ptr->dict);
2130 log_info(" clients:");
2131 list_for_each(client_node_ptr, &graph_ptr->clients)
2133 client_ptr = list_entry(client_node_ptr, struct ladish_graph_client, siblings);
2134 log_info(" %s client '%s', id=%"PRIu64", ptr=%p", client_ptr->hidden ? "invisible" : "visible", client_ptr->name, client_ptr->id, client_ptr->client);
2135 dump_dict(" ", ladish_client_get_dict(client_ptr->client));
2136 log_info(" ports:");
2137 list_for_each(port_node_ptr, &client_ptr->ports)
2139 port_ptr = list_entry(port_node_ptr, struct ladish_graph_port, siblings_client);
2141 log_info(" %s port '%s', id=%"PRIu64", type=0x%"PRIX32", flags=0x%"PRIX32", ptr=%p", port_ptr->hidden ? "invisible" : "visible", port_ptr->name, port_ptr->id, port_ptr->type, port_ptr->flags, port_ptr->port);
2142 dump_dict(" ", ladish_port_get_dict(port_ptr->port));
2145 log_info(" connections:");
2146 list_for_each(connection_node_ptr, &graph_ptr->connections)
2148 connection_ptr = list_entry(connection_node_ptr, struct ladish_graph_connection, siblings);
2150 log_info(
2151 " %s connection '%s':'%s' - '%s':'%s'%s",
2152 connection_ptr->hidden ? "invisible" : "visible",
2153 connection_ptr->port1_ptr->client_ptr->name,
2154 connection_ptr->port1_ptr->name,
2155 connection_ptr->port2_ptr->client_ptr->name,
2156 connection_ptr->port2_ptr->name,
2157 connection_ptr->changing ? " [changing]" : "");
2158 dump_dict(" ", connection_ptr->dict);
2162 #undef graph_ptr
2163 #define graph_ptr ((struct ladish_graph *)context)
2165 static
2166 bool
2167 ladish_graph_copy_client_begin_callback(
2168 void * context,
2169 ladish_client_handle client_handle,
2170 const char * client_name,
2171 void ** client_iteration_context_ptr_ptr)
2173 ladish_client_handle copy;
2175 if (!ladish_client_create_copy(client_handle, &copy))
2177 return false;
2180 if (!ladish_graph_add_client(context, copy, client_name, false))
2182 ladish_client_destroy(copy);
2183 return false;
2186 *client_iteration_context_ptr_ptr = copy;
2188 return true;
2191 static
2192 bool
2193 ladish_graph_copy_port_callback(
2194 void * context,
2195 void * client_iteration_context_ptr,
2196 ladish_client_handle client_handle,
2197 const char * client_name,
2198 ladish_port_handle port_handle,
2199 const char * port_name,
2200 uint32_t port_type,
2201 uint32_t port_flags)
2203 ladish_port_handle copy;
2205 if (!ladish_port_create_copy(port_handle, &copy))
2207 return false;
2210 if (!ladish_graph_add_port(context, client_iteration_context_ptr, copy, port_name, port_type, port_flags, true))
2212 ladish_port_destroy(copy);
2213 return false;
2216 return true;
2219 #undef graph_ptr
2221 bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest, bool skip_hidden)
2223 return ladish_graph_iterate_nodes(
2224 src,
2225 skip_hidden,
2226 dest,
2227 ladish_graph_copy_client_begin_callback,
2228 ladish_graph_copy_port_callback,
2229 NULL);
2232 METHOD_ARGS_BEGIN(GetAllPorts, "Get all ports")
2233 METHOD_ARG_DESCRIBE_IN("ports_list", "as", "List of all ports")
2234 METHOD_ARGS_END
2236 METHOD_ARGS_BEGIN(GetGraph, "Get whole graph")
2237 METHOD_ARG_DESCRIBE_IN("known_graph_version", DBUS_TYPE_UINT64_AS_STRING, "Known graph version")
2238 METHOD_ARG_DESCRIBE_OUT("current_graph_version", DBUS_TYPE_UINT64_AS_STRING, "Current graph version")
2239 METHOD_ARG_DESCRIBE_OUT("clients_and_ports", "a(tsa(tsuu))", "Clients and their ports")
2240 METHOD_ARG_DESCRIBE_OUT("connections", "a(tstststst)", "Connections array")
2241 METHOD_ARGS_END
2243 METHOD_ARGS_BEGIN(ConnectPortsByName, "Connect ports")
2244 METHOD_ARG_DESCRIBE_IN("client1_name", DBUS_TYPE_STRING_AS_STRING, "name first port client")
2245 METHOD_ARG_DESCRIBE_IN("port1_name", DBUS_TYPE_STRING_AS_STRING, "name of first port")
2246 METHOD_ARG_DESCRIBE_IN("client2_name", DBUS_TYPE_STRING_AS_STRING, "name second port client")
2247 METHOD_ARG_DESCRIBE_IN("port2_name", DBUS_TYPE_STRING_AS_STRING, "name of second port")
2248 METHOD_ARGS_END
2250 METHOD_ARGS_BEGIN(ConnectPortsByID, "Connect ports")
2251 METHOD_ARG_DESCRIBE_IN("port1_id", DBUS_TYPE_UINT64_AS_STRING, "id of first port")
2252 METHOD_ARG_DESCRIBE_IN("port2_id", DBUS_TYPE_UINT64_AS_STRING, "if of second port")
2253 METHOD_ARGS_END
2255 METHOD_ARGS_BEGIN(DisconnectPortsByName, "Disconnect ports")
2256 METHOD_ARG_DESCRIBE_IN("client1_name", DBUS_TYPE_STRING_AS_STRING, "name first port client")
2257 METHOD_ARG_DESCRIBE_IN("port1_name", DBUS_TYPE_STRING_AS_STRING, "name of first port")
2258 METHOD_ARG_DESCRIBE_IN("client2_name", DBUS_TYPE_STRING_AS_STRING, "name second port client")
2259 METHOD_ARG_DESCRIBE_IN("port2_name", DBUS_TYPE_STRING_AS_STRING, "name of second port")
2260 METHOD_ARGS_END
2262 METHOD_ARGS_BEGIN(DisconnectPortsByID, "Disconnect ports")
2263 METHOD_ARG_DESCRIBE_IN("port1_id", DBUS_TYPE_UINT64_AS_STRING, "id of first port")
2264 METHOD_ARG_DESCRIBE_IN("port2_id", DBUS_TYPE_UINT64_AS_STRING, "if of second port")
2265 METHOD_ARGS_END
2267 METHOD_ARGS_BEGIN(DisconnectPortsByConnectionID, "Disconnect ports")
2268 METHOD_ARG_DESCRIBE_IN("connection_id", DBUS_TYPE_UINT64_AS_STRING, "id of connection to disconnect")
2269 METHOD_ARGS_END
2271 METHOD_ARGS_BEGIN(GetClientPID, "get process id of client")
2272 METHOD_ARG_DESCRIBE_IN("client_id", DBUS_TYPE_UINT64_AS_STRING, "id of client")
2273 METHOD_ARG_DESCRIBE_OUT("process_id", DBUS_TYPE_INT64_AS_STRING, "pid of client")
2274 METHOD_ARGS_END
2276 METHODS_BEGIN
2277 METHOD_DESCRIBE(GetAllPorts, get_all_ports)
2278 METHOD_DESCRIBE(GetGraph, get_graph)
2279 METHOD_DESCRIBE(ConnectPortsByName, connect_ports_by_name)
2280 METHOD_DESCRIBE(ConnectPortsByID, connect_ports_by_id)
2281 METHOD_DESCRIBE(DisconnectPortsByName, disconnect_ports_by_name)
2282 METHOD_DESCRIBE(DisconnectPortsByID, disconnect_ports_by_id)
2283 METHOD_DESCRIBE(DisconnectPortsByConnectionID, disconnect_ports_by_connection_id)
2284 METHOD_DESCRIBE(GetClientPID, get_client_pid)
2285 METHODS_END
2287 SIGNAL_ARGS_BEGIN(GraphChanged, "")
2288 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING, "")
2289 SIGNAL_ARGS_END
2291 SIGNAL_ARGS_BEGIN(ClientAppeared, "")
2292 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING, "")
2293 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING, "")
2294 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING, "")
2295 SIGNAL_ARGS_END
2297 SIGNAL_ARGS_BEGIN(ClientDisappeared, "")
2298 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING, "")
2299 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING, "")
2300 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING, "")
2301 SIGNAL_ARGS_END
2303 SIGNAL_ARGS_BEGIN(PortAppeared, "")
2304 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING, "")
2305 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING, "")
2306 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING, "")
2307 SIGNAL_ARG_DESCRIBE("port_id", DBUS_TYPE_UINT64_AS_STRING, "")
2308 SIGNAL_ARG_DESCRIBE("port_name", DBUS_TYPE_STRING_AS_STRING, "")
2309 SIGNAL_ARG_DESCRIBE("port_flags", DBUS_TYPE_UINT32_AS_STRING, "")
2310 SIGNAL_ARG_DESCRIBE("port_type", DBUS_TYPE_UINT32_AS_STRING, "")
2311 SIGNAL_ARGS_END
2313 SIGNAL_ARGS_BEGIN(PortDisappeared, "")
2314 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING, "")
2315 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING, "")
2316 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING, "")
2317 SIGNAL_ARG_DESCRIBE("port_id", DBUS_TYPE_UINT64_AS_STRING, "")
2318 SIGNAL_ARG_DESCRIBE("port_name", DBUS_TYPE_STRING_AS_STRING, "")
2319 SIGNAL_ARGS_END
2321 SIGNAL_ARGS_BEGIN(PortsConnected, "")
2322 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING, "")
2323 SIGNAL_ARG_DESCRIBE("client1_id", DBUS_TYPE_UINT64_AS_STRING, "")
2324 SIGNAL_ARG_DESCRIBE("client1_name", DBUS_TYPE_STRING_AS_STRING, "")
2325 SIGNAL_ARG_DESCRIBE("port1_id", DBUS_TYPE_UINT64_AS_STRING, "")
2326 SIGNAL_ARG_DESCRIBE("port1_name", DBUS_TYPE_STRING_AS_STRING, "")
2327 SIGNAL_ARG_DESCRIBE("client2_id", DBUS_TYPE_UINT64_AS_STRING, "")
2328 SIGNAL_ARG_DESCRIBE("client2_name", DBUS_TYPE_STRING_AS_STRING, "")
2329 SIGNAL_ARG_DESCRIBE("port2_id", DBUS_TYPE_UINT64_AS_STRING, "")
2330 SIGNAL_ARG_DESCRIBE("port2_name", DBUS_TYPE_STRING_AS_STRING, "")
2331 SIGNAL_ARG_DESCRIBE("connection_id", DBUS_TYPE_UINT64_AS_STRING, "")
2332 SIGNAL_ARGS_END
2334 SIGNAL_ARGS_BEGIN(PortsDisconnected, "")
2335 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING, "")
2336 SIGNAL_ARG_DESCRIBE("client1_id", DBUS_TYPE_UINT64_AS_STRING, "")
2337 SIGNAL_ARG_DESCRIBE("client1_name", DBUS_TYPE_STRING_AS_STRING, "")
2338 SIGNAL_ARG_DESCRIBE("port1_id", DBUS_TYPE_UINT64_AS_STRING, "")
2339 SIGNAL_ARG_DESCRIBE("port1_name", DBUS_TYPE_STRING_AS_STRING, "")
2340 SIGNAL_ARG_DESCRIBE("client2_id", DBUS_TYPE_UINT64_AS_STRING, "")
2341 SIGNAL_ARG_DESCRIBE("client2_name", DBUS_TYPE_STRING_AS_STRING, "")
2342 SIGNAL_ARG_DESCRIBE("port2_id", DBUS_TYPE_UINT64_AS_STRING, "")
2343 SIGNAL_ARG_DESCRIBE("port2_name", DBUS_TYPE_STRING_AS_STRING, "")
2344 SIGNAL_ARG_DESCRIBE("connection_id", DBUS_TYPE_UINT64_AS_STRING, "")
2345 SIGNAL_ARGS_END
2347 SIGNALS_BEGIN
2348 SIGNAL_DESCRIBE(GraphChanged)
2349 SIGNAL_DESCRIBE(ClientAppeared)
2350 SIGNAL_DESCRIBE(ClientDisappeared)
2351 SIGNAL_DESCRIBE(PortAppeared)
2352 SIGNAL_DESCRIBE(PortDisappeared)
2353 SIGNAL_DESCRIBE(PortsConnected)
2354 SIGNAL_DESCRIBE(PortsDisconnected)
2355 SIGNALS_END
2357 INTERFACE_BEGIN(g_interface_patchbay, JACKDBUS_IFACE_PATCHBAY)
2358 INTERFACE_DEFAULT_HANDLER
2359 INTERFACE_EXPOSE_METHODS
2360 INTERFACE_EXPOSE_SIGNALS
2361 INTERFACE_END