1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008, 2009 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.
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
;
42 ladish_port_handle port
;
46 struct ladish_graph_client
48 struct list_head siblings
;
51 ladish_client_handle client
;
52 struct list_head ports
;
56 struct ladish_graph_connection
58 struct list_head siblings
;
61 struct ladish_graph_port
* port1_ptr
;
62 struct ladish_graph_port
* port2_ptr
;
63 ladish_dict_handle dict
;
70 ladish_dict_handle dict
;
71 struct list_head clients
;
72 struct list_head ports
;
73 struct list_head connections
;
74 uint64_t graph_version
;
75 uint64_t next_client_id
;
76 uint64_t next_port_id
;
77 uint64_t next_connection_id
;
80 ladish_graph_connect_request_handler connect_handler
;
81 ladish_graph_disconnect_request_handler disconnect_handler
;
84 struct ladish_graph_port
* ladish_graph_find_port_by_id_internal(struct ladish_graph
* graph_ptr
, uint64_t port_id
)
86 struct list_head
* node_ptr
;
87 struct ladish_graph_port
* port_ptr
;
89 list_for_each(node_ptr
, &graph_ptr
->ports
)
91 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_graph
);
92 if (port_ptr
->id
== port_id
)
101 struct ladish_graph_connection
* ladish_graph_find_connection_by_id(struct ladish_graph
* graph_ptr
, uint64_t connection_id
)
103 struct list_head
* node_ptr
;
104 struct ladish_graph_connection
* connection_ptr
;
106 list_for_each(node_ptr
, &graph_ptr
->connections
)
108 connection_ptr
= list_entry(node_ptr
, struct ladish_graph_connection
, siblings
);
109 if (connection_ptr
->id
== connection_id
)
111 return connection_ptr
;
118 struct ladish_graph_connection
*
119 ladish_graph_find_connection_by_ports(
120 struct ladish_graph
* graph_ptr
,
121 struct ladish_graph_port
* port1_ptr
,
122 struct ladish_graph_port
* port2_ptr
)
124 struct list_head
* node_ptr
;
125 struct ladish_graph_connection
* connection_ptr
;
127 list_for_each(node_ptr
, &graph_ptr
->connections
)
129 connection_ptr
= list_entry(node_ptr
, struct ladish_graph_connection
, siblings
);
130 if ((connection_ptr
->port1_ptr
== port1_ptr
&& connection_ptr
->port2_ptr
== port2_ptr
) ||
131 (connection_ptr
->port1_ptr
== port2_ptr
&& connection_ptr
->port2_ptr
== port1_ptr
))
133 return connection_ptr
;
140 #define graph_ptr ((struct ladish_graph *)call_ptr->iface_context)
142 static void get_all_ports(struct dbus_method_call
* call_ptr
)
144 DBusMessageIter iter
, sub_iter
;
146 call_ptr
->reply
= dbus_message_new_method_return(call_ptr
->message
);
147 if (call_ptr
->reply
== NULL
)
152 dbus_message_iter_init_append(call_ptr
->reply
, &iter
);
154 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
, "s", &sub_iter
))
159 if (!dbus_message_iter_close_container(&iter
, &sub_iter
))
167 dbus_message_unref(call_ptr
->reply
);
168 call_ptr
->reply
= NULL
;
171 log_error("Ran out of memory trying to construct method return");
174 static void get_graph(struct dbus_method_call
* call_ptr
)
176 dbus_uint64_t known_version
;
177 dbus_uint64_t current_version
;
178 DBusMessageIter iter
;
179 DBusMessageIter clients_array_iter
;
180 DBusMessageIter connections_array_iter
;
181 DBusMessageIter client_struct_iter
;
182 struct list_head
* client_node_ptr
;
183 struct ladish_graph_client
* client_ptr
;
184 DBusMessageIter ports_array_iter
;
185 struct list_head
* port_node_ptr
;
186 struct ladish_graph_port
* port_ptr
;
187 DBusMessageIter port_struct_iter
;
188 struct list_head
* connection_node_ptr
;
189 struct ladish_graph_connection
* connection_ptr
;
190 DBusMessageIter connection_struct_iter
;
192 //log_info("get_graph() called");
194 if (!dbus_message_get_args(call_ptr
->message
, &g_dbus_error
, DBUS_TYPE_UINT64
, &known_version
, DBUS_TYPE_INVALID
))
196 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, g_dbus_error
.message
);
197 dbus_error_free(&g_dbus_error
);
201 //log_info("Getting graph, known version is %" PRIu64, known_version);
203 call_ptr
->reply
= dbus_message_new_method_return(call_ptr
->message
);
204 if (call_ptr
->reply
== NULL
)
206 log_error("Ran out of memory trying to construct method return");
210 dbus_message_iter_init_append(call_ptr
->reply
, &iter
);
212 current_version
= graph_ptr
->graph_version
;
213 if (known_version
> current_version
)
217 LASH_DBUS_ERROR_INVALID_ARGS
,
218 "known graph version %" PRIu64
" is newer than actual version %" PRIu64
,
224 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_UINT64
, ¤t_version
))
229 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
, "(tsa(tsuu))", &clients_array_iter
))
234 if (known_version
< current_version
)
236 list_for_each(client_node_ptr
, &graph_ptr
->clients
)
238 client_ptr
= list_entry(client_node_ptr
, struct ladish_graph_client
, siblings
);
240 if (client_ptr
->hidden
)
245 if (!dbus_message_iter_open_container (&clients_array_iter
, DBUS_TYPE_STRUCT
, NULL
, &client_struct_iter
))
247 goto nomem_close_clients_array
;
250 if (!dbus_message_iter_append_basic(&client_struct_iter
, DBUS_TYPE_UINT64
, &client_ptr
->id
))
252 goto nomem_close_client_struct
;
255 log_info("client '%s' (%llu)", client_ptr
->name
, (unsigned long long)client_ptr
->id
);
256 if (!dbus_message_iter_append_basic(&client_struct_iter
, DBUS_TYPE_STRING
, &client_ptr
->name
))
258 goto nomem_close_client_struct
;
261 if (!dbus_message_iter_open_container(&client_struct_iter
, DBUS_TYPE_ARRAY
, "(tsuu)", &ports_array_iter
))
263 goto nomem_close_client_struct
;
266 list_for_each(port_node_ptr
, &client_ptr
->ports
)
268 port_ptr
= list_entry(port_node_ptr
, struct ladish_graph_port
, siblings_client
);
270 if (port_ptr
->hidden
)
275 if (!dbus_message_iter_open_container(&ports_array_iter
, DBUS_TYPE_STRUCT
, NULL
, &port_struct_iter
))
277 goto nomem_close_ports_array
;
280 if (!dbus_message_iter_append_basic(&port_struct_iter
, DBUS_TYPE_UINT64
, &port_ptr
->id
))
282 goto nomem_close_port_struct
;
285 if (!dbus_message_iter_append_basic(&port_struct_iter
, DBUS_TYPE_STRING
, &port_ptr
->name
))
287 goto nomem_close_port_struct
;
290 if (!dbus_message_iter_append_basic(&port_struct_iter
, DBUS_TYPE_UINT32
, &port_ptr
->flags
))
292 goto nomem_close_port_struct
;
295 if (!dbus_message_iter_append_basic(&port_struct_iter
, DBUS_TYPE_UINT32
, &port_ptr
->type
))
297 goto nomem_close_port_struct
;
300 if (!dbus_message_iter_close_container(&ports_array_iter
, &port_struct_iter
))
302 goto nomem_close_ports_array
;
306 if (!dbus_message_iter_close_container(&client_struct_iter
, &ports_array_iter
))
308 goto nomem_close_client_struct
;
311 if (!dbus_message_iter_close_container(&clients_array_iter
, &client_struct_iter
))
313 goto nomem_close_clients_array
;
318 if (!dbus_message_iter_close_container(&iter
, &clients_array_iter
))
323 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
, "(tstststst)", &connections_array_iter
))
328 if (known_version
< current_version
)
330 list_for_each(connection_node_ptr
, &graph_ptr
->connections
)
332 connection_ptr
= list_entry(connection_node_ptr
, struct ladish_graph_connection
, siblings
);
334 if (connection_ptr
->hidden
)
339 if (!dbus_message_iter_open_container(&connections_array_iter
, DBUS_TYPE_STRUCT
, NULL
, &connection_struct_iter
))
341 goto nomem_close_connections_array
;
344 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_UINT64
, &connection_ptr
->port1_ptr
->client_ptr
->id
))
346 goto nomem_close_connection_struct
;
349 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_STRING
, &connection_ptr
->port1_ptr
->client_ptr
->name
))
351 goto nomem_close_connection_struct
;
354 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_UINT64
, &connection_ptr
->port1_ptr
->id
))
356 goto nomem_close_connection_struct
;
359 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_STRING
, &connection_ptr
->port1_ptr
->name
))
361 goto nomem_close_connection_struct
;
364 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_UINT64
, &connection_ptr
->port2_ptr
->client_ptr
->id
))
366 goto nomem_close_connection_struct
;
369 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_STRING
, &connection_ptr
->port2_ptr
->client_ptr
->name
))
371 goto nomem_close_connection_struct
;
374 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_UINT64
, &connection_ptr
->port2_ptr
->id
))
376 goto nomem_close_connection_struct
;
379 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_STRING
, &connection_ptr
->port2_ptr
->name
))
381 goto nomem_close_connection_struct
;
384 if (!dbus_message_iter_append_basic(&connection_struct_iter
, DBUS_TYPE_UINT64
, &connection_ptr
->id
))
386 goto nomem_close_connection_struct
;
389 if (!dbus_message_iter_close_container(&connections_array_iter
, &connection_struct_iter
))
391 goto nomem_close_connections_array
;
396 if (!dbus_message_iter_close_container(&iter
, &connections_array_iter
))
403 nomem_close_connection_struct
:
404 dbus_message_iter_close_container(&connections_array_iter
, &connection_struct_iter
);
406 nomem_close_connections_array
:
407 dbus_message_iter_close_container(&iter
, &connections_array_iter
);
410 nomem_close_port_struct
:
411 dbus_message_iter_close_container(&ports_array_iter
, &port_struct_iter
);
413 nomem_close_ports_array
:
414 dbus_message_iter_close_container(&client_struct_iter
, &ports_array_iter
);
416 nomem_close_client_struct
:
417 dbus_message_iter_close_container(&clients_array_iter
, &client_struct_iter
);
419 nomem_close_clients_array
:
420 dbus_message_iter_close_container(&iter
, &clients_array_iter
);
423 dbus_message_unref(call_ptr
->reply
);
424 call_ptr
->reply
= NULL
;
425 log_error("Ran out of memory trying to construct method return");
431 static void connect_ports_by_name(struct dbus_method_call
* call_ptr
)
433 log_info("connect_ports_by_name() called.");
434 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "connect by name is not implemented yet");
437 static void connect_ports_by_id(struct dbus_method_call
* call_ptr
)
439 dbus_uint64_t port1_id
;
440 dbus_uint64_t port2_id
;
441 struct ladish_graph_port
* port1_ptr
;
442 struct ladish_graph_port
* port2_ptr
;
444 if (!dbus_message_get_args(call_ptr
->message
, &g_dbus_error
, DBUS_TYPE_UINT64
, &port1_id
, DBUS_TYPE_UINT64
, &port2_id
, DBUS_TYPE_INVALID
))
446 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, g_dbus_error
.message
);
447 dbus_error_free(&g_dbus_error
);
451 log_info("connect_ports_by_id(%"PRIu64
",%"PRIu64
") called.", port1_id
, port2_id
);
453 if (graph_ptr
->connect_handler
== NULL
)
455 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "connect requests on this graph cannot be handlined");
459 port1_ptr
= ladish_graph_find_port_by_id_internal(graph_ptr
, port1_id
);
460 if (port1_ptr
== NULL
)
462 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Cannot connect unknown port with id %"PRIu64
, port1_id
);
466 port2_ptr
= ladish_graph_find_port_by_id_internal(graph_ptr
, port2_id
);
467 if (port2_ptr
== NULL
)
469 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Cannot connect unknown port with id %"PRIu64
, port2_id
);
473 log_info("connecting '%s':'%s' to '%s':'%s'", port1_ptr
->client_ptr
->name
, port1_ptr
->name
, port2_ptr
->client_ptr
->name
, port2_ptr
->name
);
475 if (graph_ptr
->connect_handler(graph_ptr
->context
, (ladish_graph_handle
)graph_ptr
, port1_ptr
->port
, port2_ptr
->port
))
477 method_return_new_void(call_ptr
);
481 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "connect failed");
485 static void disconnect_ports(struct dbus_method_call
* call_ptr
, struct ladish_graph_connection
* connection_ptr
)
488 "disconnecting '%s':'%s' from '%s':'%s'",
489 connection_ptr
->port1_ptr
->client_ptr
->name
,
490 connection_ptr
->port1_ptr
->name
,
491 connection_ptr
->port2_ptr
->client_ptr
->name
,
492 connection_ptr
->port2_ptr
->name
);
494 connection_ptr
->changing
= true;
495 if (graph_ptr
->disconnect_handler(graph_ptr
->context
, (ladish_graph_handle
)graph_ptr
, connection_ptr
->id
))
497 method_return_new_void(call_ptr
);
501 connection_ptr
->changing
= false;
502 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "disconnect failed");
506 static void disconnect_ports_by_name(struct dbus_method_call
* call_ptr
)
508 log_info("disconnect_ports_by_name() called.");
509 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "disconnect by name is not implemented yet");
512 static void disconnect_ports_by_id(struct dbus_method_call
* call_ptr
)
514 dbus_uint64_t port1_id
;
515 dbus_uint64_t port2_id
;
516 struct ladish_graph_port
* port1_ptr
;
517 struct ladish_graph_port
* port2_ptr
;
518 struct ladish_graph_connection
* connection_ptr
;
520 if (!dbus_message_get_args(call_ptr
->message
, &g_dbus_error
, DBUS_TYPE_UINT64
, &port1_id
, DBUS_TYPE_UINT64
, &port2_id
, DBUS_TYPE_INVALID
))
522 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, g_dbus_error
.message
);
523 dbus_error_free(&g_dbus_error
);
527 log_info("disconnect_ports_by_id(%"PRIu64
",%"PRIu64
") called.", port1_id
, port2_id
);
529 if (graph_ptr
->disconnect_handler
== NULL
)
531 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "disconnect requests on this graph cannot be handlined");
535 port1_ptr
= ladish_graph_find_port_by_id_internal(graph_ptr
, port1_id
);
536 if (port1_ptr
== NULL
)
538 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Cannot disconnect unknown port with id %"PRIu64
, port1_id
);
542 port2_ptr
= ladish_graph_find_port_by_id_internal(graph_ptr
, port2_id
);
543 if (port2_ptr
== NULL
)
545 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Cannot disconnect unknown port with id %"PRIu64
, port2_id
);
549 connection_ptr
= ladish_graph_find_connection_by_ports(graph_ptr
, port1_ptr
, port2_ptr
);
550 if (connection_ptr
== NULL
)
552 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Cannot disconnect not connected ports %"PRIu64
" and %"PRIu64
, port1_id
, port2_id
);
556 disconnect_ports(call_ptr
, connection_ptr
);
559 static void disconnect_ports_by_connection_id(struct dbus_method_call
* call_ptr
)
561 dbus_uint64_t connection_id
;
562 struct ladish_graph_connection
* connection_ptr
;
564 if (!dbus_message_get_args(call_ptr
->message
, &g_dbus_error
, DBUS_TYPE_UINT64
, &connection_id
, DBUS_TYPE_INVALID
))
566 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, g_dbus_error
.message
);
567 dbus_error_free(&g_dbus_error
);
571 log_info("disconnect_ports_by_connection_id(%"PRIu64
") called.", connection_id
);
573 connection_ptr
= ladish_graph_find_connection_by_id(graph_ptr
, connection_id
);
574 if (connection_ptr
== NULL
)
576 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Cannot find connection with id %"PRIu64
, connection_id
);
580 disconnect_ports(call_ptr
, connection_ptr
);
583 static void get_client_pid(struct dbus_method_call
* call_ptr
)
586 method_return_new_single(call_ptr
, DBUS_TYPE_INT64
, &pid
);
591 bool ladish_graph_create(ladish_graph_handle
* graph_handle_ptr
, const char * opath
)
593 struct ladish_graph
* graph_ptr
;
595 graph_ptr
= malloc(sizeof(struct ladish_graph
));
596 if (graph_ptr
== NULL
)
598 log_error("malloc() failed to allocate struct graph_implementator");
604 graph_ptr
->opath
= strdup(opath
);
605 if (graph_ptr
->opath
== NULL
)
607 log_error("strdup() failed for graph opath");
614 graph_ptr
->opath
= NULL
;
617 if (!ladish_dict_create(&graph_ptr
->dict
))
619 log_error("ladish_dict_create() failed for graph");
620 if (graph_ptr
->opath
!= NULL
)
622 free(graph_ptr
->opath
);
628 INIT_LIST_HEAD(&graph_ptr
->clients
);
629 INIT_LIST_HEAD(&graph_ptr
->ports
);
630 INIT_LIST_HEAD(&graph_ptr
->connections
);
632 graph_ptr
->graph_version
= 1;
633 graph_ptr
->next_client_id
= 1;
634 graph_ptr
->next_port_id
= 1;
635 graph_ptr
->next_connection_id
= 1;
637 graph_ptr
->context
= NULL
;
638 graph_ptr
->connect_handler
= NULL
;
639 graph_ptr
->disconnect_handler
= NULL
;
641 *graph_handle_ptr
= (ladish_graph_handle
)graph_ptr
;
646 struct ladish_graph_client
*
647 ladish_graph_find_client(
648 struct ladish_graph
* graph_ptr
,
649 ladish_client_handle client
)
651 struct list_head
* node_ptr
;
652 struct ladish_graph_client
* client_ptr
;
654 list_for_each(node_ptr
, &graph_ptr
->clients
)
656 client_ptr
= list_entry(node_ptr
, struct ladish_graph_client
, siblings
);
657 if (client_ptr
->client
== client
)
667 struct ladish_graph_port
*
668 ladish_graph_find_port(
669 struct ladish_graph
* graph_ptr
,
670 ladish_port_handle port
)
672 struct list_head
* node_ptr
;
673 struct ladish_graph_port
* port_ptr
;
675 list_for_each(node_ptr
, &graph_ptr
->ports
)
677 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_graph
);
678 if (port_ptr
->port
== port
)
689 struct ladish_graph_port
*
690 ladish_graph_find_client_port(
691 struct ladish_graph
* graph_ptr
,
692 struct ladish_graph_client
* client_ptr
,
693 ladish_port_handle port
)
695 struct list_head
* node_ptr
;
696 struct ladish_graph_port
* port_ptr
;
698 list_for_each(node_ptr
, &client_ptr
->ports
)
700 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_client
);
701 if (port_ptr
->port
== port
)
711 static void ladish_graph_hide_connection_internal(struct ladish_graph
* graph_ptr
, struct ladish_graph_connection
* connection_ptr
)
713 ASSERT(!connection_ptr
->hidden
);
714 connection_ptr
->hidden
= true;
715 graph_ptr
->graph_version
++;
717 if (graph_ptr
->opath
!= NULL
)
722 JACKDBUS_IFACE_PATCHBAY
,
725 &graph_ptr
->graph_version
,
726 &connection_ptr
->port1_ptr
->client_ptr
->id
,
727 &connection_ptr
->port1_ptr
->client_ptr
->name
,
728 &connection_ptr
->port1_ptr
->id
,
729 &connection_ptr
->port1_ptr
->name
,
730 &connection_ptr
->port2_ptr
->client_ptr
->id
,
731 &connection_ptr
->port2_ptr
->client_ptr
->name
,
732 &connection_ptr
->port2_ptr
->id
,
733 &connection_ptr
->port2_ptr
->name
,
734 &connection_ptr
->id
);
738 void ladish_graph_show_port_internal(struct ladish_graph
* graph_ptr
, struct ladish_graph_port
* port_ptr
)
740 if (port_ptr
->client_ptr
->hidden
)
742 port_ptr
->client_ptr
->hidden
= false;
743 graph_ptr
->graph_version
++;
744 if (graph_ptr
->opath
!= NULL
)
749 JACKDBUS_IFACE_PATCHBAY
,
752 &graph_ptr
->graph_version
,
753 &port_ptr
->client_ptr
->id
,
754 &port_ptr
->client_ptr
->name
);
758 ASSERT(port_ptr
->hidden
);
759 port_ptr
->hidden
= false;
760 graph_ptr
->graph_version
++;
761 if (graph_ptr
->opath
!= NULL
)
766 JACKDBUS_IFACE_PATCHBAY
,
769 &graph_ptr
->graph_version
,
770 &port_ptr
->client_ptr
->id
,
771 &port_ptr
->client_ptr
->name
,
777 ladish_try_connect_hidden_connections((ladish_graph_handle
)graph_ptr
);
781 void ladish_graph_hide_port_internal(struct ladish_graph
* graph_ptr
, struct ladish_graph_port
* port_ptr
)
783 ASSERT(!port_ptr
->hidden
);
784 port_ptr
->hidden
= true;
785 graph_ptr
->graph_version
++;
787 if (graph_ptr
->opath
!= NULL
)
792 JACKDBUS_IFACE_PATCHBAY
,
795 &graph_ptr
->graph_version
,
796 &port_ptr
->client_ptr
->id
,
797 &port_ptr
->client_ptr
->name
,
803 void ladish_graph_hide_client_internal(struct ladish_graph
* graph_ptr
, struct ladish_graph_client
* client_ptr
)
805 ASSERT(!client_ptr
->hidden
);
806 client_ptr
->hidden
= true;
807 graph_ptr
->graph_version
++;
809 if (graph_ptr
->opath
!= NULL
)
814 JACKDBUS_IFACE_PATCHBAY
,
817 &graph_ptr
->graph_version
,
823 void ladish_hide_connections(struct ladish_graph
* graph_ptr
, struct ladish_graph_port
* port_ptr
)
825 struct list_head
* node_ptr
;
826 struct ladish_graph_connection
* connection_ptr
;
828 log_info("hidding connections of port %"PRIu64
, port_ptr
->id
);
830 ASSERT(graph_ptr
->opath
!= NULL
);
832 list_for_each(node_ptr
, &graph_ptr
->connections
)
834 connection_ptr
= list_entry(node_ptr
, struct ladish_graph_connection
, siblings
);
835 if (!connection_ptr
->hidden
&& (connection_ptr
->port1_ptr
== port_ptr
|| connection_ptr
->port2_ptr
== port_ptr
))
837 log_info("hidding connection between ports %"PRIu64
" and %"PRIu64
, connection_ptr
->port1_ptr
->id
, connection_ptr
->port2_ptr
->id
);
838 ladish_graph_hide_connection_internal(graph_ptr
, connection_ptr
);
843 static void ladish_graph_remove_connection_internal(struct ladish_graph
* graph_ptr
, struct ladish_graph_connection
* connection_ptr
)
845 list_del(&connection_ptr
->siblings
);
846 graph_ptr
->graph_version
++;
848 if (!connection_ptr
->hidden
&& graph_ptr
->opath
!= NULL
)
853 JACKDBUS_IFACE_PATCHBAY
,
856 &graph_ptr
->graph_version
,
857 &connection_ptr
->port1_ptr
->client_ptr
->id
,
858 &connection_ptr
->port1_ptr
->client_ptr
->name
,
859 &connection_ptr
->port1_ptr
->id
,
860 &connection_ptr
->port1_ptr
->name
,
861 &connection_ptr
->port2_ptr
->client_ptr
->id
,
862 &connection_ptr
->port2_ptr
->client_ptr
->name
,
863 &connection_ptr
->port2_ptr
->id
,
864 &connection_ptr
->port2_ptr
->name
,
865 &connection_ptr
->id
);
868 ladish_dict_destroy(connection_ptr
->dict
);
869 free(connection_ptr
);
873 ladish_graph_remove_port_internal(
874 struct ladish_graph
* graph_ptr
,
875 struct ladish_graph_client
* client_ptr
,
876 struct ladish_graph_port
* port_ptr
,
881 ladish_port_destroy(port_ptr
->port
);
884 list_del(&port_ptr
->siblings_client
);
885 list_del(&port_ptr
->siblings_graph
);
887 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");
888 if (graph_ptr
->opath
!= NULL
&& !port_ptr
->hidden
)
893 JACKDBUS_IFACE_PATCHBAY
,
896 &graph_ptr
->graph_version
,
903 free(port_ptr
->name
);
909 ladish_graph_remove_client_internal(
910 struct ladish_graph
* graph_ptr
,
911 struct ladish_graph_client
* client_ptr
,
915 struct ladish_graph_port
* port_ptr
;
917 while (!list_empty(&client_ptr
->ports
))
919 port_ptr
= list_entry(client_ptr
->ports
.next
, struct ladish_graph_port
, siblings_client
);
920 ladish_graph_remove_port_internal(graph_ptr
, client_ptr
, port_ptr
, destroy_ports
);
923 graph_ptr
->graph_version
++;
924 list_del(&client_ptr
->siblings
);
925 log_info("removing client '%s' (%"PRIu64
") from graph %s", client_ptr
->name
, client_ptr
->id
, graph_ptr
->opath
!= NULL
? graph_ptr
->opath
: "JACK");
926 if (graph_ptr
->opath
!= NULL
&& !client_ptr
->hidden
)
931 JACKDBUS_IFACE_PATCHBAY
,
934 &graph_ptr
->graph_version
,
939 free(client_ptr
->name
);
943 ladish_client_destroy(client_ptr
->client
);
949 #define graph_ptr ((struct ladish_graph *)graph_handle)
951 void ladish_graph_destroy(ladish_graph_handle graph_handle
, bool destroy_ports
)
953 ladish_graph_clear(graph_handle
, destroy_ports
);
954 ladish_dict_destroy(graph_ptr
->dict
);
955 if (graph_ptr
->opath
!= NULL
)
957 free(graph_ptr
->opath
);
963 ladish_graph_set_connection_handlers(
964 ladish_graph_handle graph_handle
,
965 void * graph_context
,
966 ladish_graph_connect_request_handler connect_handler
,
967 ladish_graph_disconnect_request_handler disconnect_handler
)
969 graph_ptr
->context
= graph_context
;
970 graph_ptr
->connect_handler
= connect_handler
;
971 graph_ptr
->disconnect_handler
= disconnect_handler
;
974 void ladish_graph_clear(ladish_graph_handle graph_handle
, bool destroy_ports
)
976 struct ladish_graph_client
* client_ptr
;
977 struct ladish_graph_connection
* connection_ptr
;
979 log_info("ladish_graph_clear() called for graph '%s'", graph_ptr
->opath
!= NULL
? graph_ptr
->opath
: "JACK");
981 while (!list_empty(&graph_ptr
->connections
))
983 connection_ptr
= list_entry(graph_ptr
->connections
.next
, struct ladish_graph_connection
, siblings
);
984 ladish_graph_remove_connection_internal(graph_ptr
, connection_ptr
);
987 while (!list_empty(&graph_ptr
->clients
))
989 client_ptr
= list_entry(graph_ptr
->clients
.next
, struct ladish_graph_client
, siblings
);
990 ladish_graph_remove_client_internal(graph_ptr
, client_ptr
, true, destroy_ports
);
994 void * ladish_graph_get_dbus_context(ladish_graph_handle graph_handle
)
999 ladish_dict_handle
ladish_graph_get_dict(ladish_graph_handle graph_handle
)
1001 return graph_ptr
->dict
;
1004 void ladish_graph_show_connection(ladish_graph_handle graph_handle
, uint64_t connection_id
)
1006 struct ladish_graph_connection
* connection_ptr
;
1008 log_info("ladish_graph_show_connection() called.");
1010 connection_ptr
= ladish_graph_find_connection_by_id(graph_ptr
, connection_id
);
1011 if (connection_ptr
== NULL
)
1017 ASSERT(graph_ptr
->opath
!= NULL
);
1018 ASSERT(connection_ptr
->hidden
);
1019 connection_ptr
->hidden
= false;
1020 connection_ptr
->changing
= false;
1021 graph_ptr
->graph_version
++;
1026 JACKDBUS_IFACE_PATCHBAY
,
1029 &graph_ptr
->graph_version
,
1030 &connection_ptr
->port1_ptr
->client_ptr
->id
,
1031 &connection_ptr
->port1_ptr
->client_ptr
->name
,
1032 &connection_ptr
->port1_ptr
->id
,
1033 &connection_ptr
->port1_ptr
->name
,
1034 &connection_ptr
->port2_ptr
->client_ptr
->id
,
1035 &connection_ptr
->port2_ptr
->client_ptr
->name
,
1036 &connection_ptr
->port2_ptr
->id
,
1037 &connection_ptr
->port2_ptr
->name
,
1038 &connection_ptr
->id
);
1041 void ladish_graph_show_port(ladish_graph_handle graph_handle
, ladish_port_handle port_handle
)
1043 struct ladish_graph_port
* port_ptr
;
1045 //log_info("ladish_graph_show_port() called.");
1047 port_ptr
= ladish_graph_find_port(graph_ptr
, port_handle
);
1048 if (port_ptr
== NULL
)
1054 //log_info("port '%s' is %s", port_ptr->name, port_ptr->hidden ? "invisible" : "visible");
1056 ladish_graph_show_port_internal(graph_ptr
, port_ptr
);
1059 void ladish_graph_hide_port(ladish_graph_handle graph_handle
, ladish_port_handle port_handle
)
1061 struct ladish_graph_port
* port_ptr
;
1063 log_info("ladish_graph_hide_port() called.");
1065 port_ptr
= ladish_graph_find_port(graph_ptr
, port_handle
);
1066 if (port_ptr
== NULL
)
1072 log_info("Hidding port %"PRIu64
, port_ptr
->id
);
1074 ASSERT(!port_ptr
->hidden
);
1076 if (graph_ptr
->opath
!= NULL
)
1078 ladish_hide_connections(graph_ptr
, port_ptr
);
1081 ladish_graph_hide_port_internal(graph_ptr
, port_ptr
);
1084 void ladish_graph_hide_client(ladish_graph_handle graph_handle
, ladish_client_handle client_handle
)
1086 struct ladish_graph_client
* client_ptr
;
1088 log_info("ladish_graph_hide_client() called.");
1090 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1091 if (client_ptr
== NULL
)
1097 ladish_graph_hide_client_internal(graph_ptr
, client_ptr
);
1100 void ladish_graph_show_client(ladish_graph_handle graph_handle
, ladish_client_handle client_handle
)
1102 struct ladish_graph_client
* client_ptr
;
1104 log_info("ladish_graph_show_client() called.");
1106 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1107 if (client_ptr
== NULL
)
1113 ASSERT(client_ptr
->hidden
);
1114 client_ptr
->hidden
= false;
1115 graph_ptr
->graph_version
++;
1117 if (graph_ptr
->opath
!= NULL
)
1122 JACKDBUS_IFACE_PATCHBAY
,
1125 &graph_ptr
->graph_version
,
1131 void ladish_graph_adjust_port(ladish_graph_handle graph_handle
, ladish_port_handle port_handle
, uint32_t type
, uint32_t flags
)
1133 struct ladish_graph_port
* port_ptr
;
1135 //log_info("ladish_graph_adjust_port() called.");
1137 port_ptr
= ladish_graph_find_port(graph_ptr
, port_handle
);
1138 if (port_ptr
== NULL
)
1144 port_ptr
->type
= type
;
1145 port_ptr
->flags
= flags
;
1148 bool ladish_graph_add_client(ladish_graph_handle graph_handle
, ladish_client_handle client_handle
, const char * name
, bool hidden
)
1150 struct ladish_graph_client
* client_ptr
;
1152 log_info("adding client '%s' (%p) to graph %s", name
, client_handle
, graph_ptr
->opath
!= NULL
? graph_ptr
->opath
: "JACK");
1154 client_ptr
= malloc(sizeof(struct ladish_graph_client
));
1155 if (client_ptr
== NULL
)
1157 log_error("malloc() failed for struct ladish_graph_client");
1161 client_ptr
->name
= strdup(name
);
1162 if (client_ptr
->name
== NULL
)
1164 log_error("strdup() failed for graph client name");
1169 client_ptr
->id
= graph_ptr
->next_client_id
++;
1170 client_ptr
->client
= client_handle
;
1171 client_ptr
->hidden
= hidden
;
1172 graph_ptr
->graph_version
++;
1174 INIT_LIST_HEAD(&client_ptr
->ports
);
1176 list_add_tail(&client_ptr
->siblings
, &graph_ptr
->clients
);
1178 if (!hidden
&& graph_ptr
->opath
!= NULL
)
1183 JACKDBUS_IFACE_PATCHBAY
,
1186 &graph_ptr
->graph_version
,
1195 ladish_graph_remove_client(
1196 ladish_graph_handle graph_handle
,
1197 ladish_client_handle client_handle
,
1200 struct ladish_graph_client
* client_ptr
;
1202 log_info("ladish_graph_remove_client() called.");
1204 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1205 if (client_ptr
!= NULL
)
1207 ladish_graph_remove_client_internal(graph_ptr
, client_ptr
, false, destroy_ports
);
1216 ladish_graph_add_port(
1217 ladish_graph_handle graph_handle
,
1218 ladish_client_handle client_handle
,
1219 ladish_port_handle port_handle
,
1225 struct ladish_graph_client
* client_ptr
;
1226 struct ladish_graph_port
* port_ptr
;
1228 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1229 if (client_ptr
== NULL
)
1231 log_error("cannot find client to add port to. graph is %s", graph_ptr
->opath
!= NULL
? graph_ptr
->opath
: "JACK");
1236 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");
1238 port_ptr
= malloc(sizeof(struct ladish_graph_port
));
1239 if (port_ptr
== NULL
)
1241 log_error("malloc() failed for struct ladish_graph_port");
1245 port_ptr
->name
= strdup(name
);
1246 if (port_ptr
->name
== NULL
)
1248 log_error("strdup() failed for graph port name");
1253 port_ptr
->type
= type
;
1254 port_ptr
->flags
= flags
;
1256 port_ptr
->id
= graph_ptr
->next_port_id
++;
1257 port_ptr
->port
= port_handle
;
1258 port_ptr
->hidden
= true;
1260 port_ptr
->client_ptr
= client_ptr
;
1261 list_add_tail(&port_ptr
->siblings_client
, &client_ptr
->ports
);
1262 list_add_tail(&port_ptr
->siblings_graph
, &graph_ptr
->ports
);
1266 ladish_graph_show_port_internal(graph_ptr
, port_ptr
);
1273 ladish_graph_add_connection(
1274 ladish_graph_handle graph_handle
,
1275 ladish_port_handle port1_handle
,
1276 ladish_port_handle port2_handle
,
1279 struct ladish_graph_port
* port1_ptr
;
1280 struct ladish_graph_port
* port2_ptr
;
1281 struct ladish_graph_connection
* connection_ptr
;
1283 port1_ptr
= ladish_graph_find_port(graph_ptr
, port1_handle
);
1284 ASSERT(port1_ptr
!= NULL
);
1285 port2_ptr
= ladish_graph_find_port(graph_ptr
, port2_handle
);
1286 ASSERT(port2_ptr
!= NULL
);
1288 connection_ptr
= malloc(sizeof(struct ladish_graph_connection
));
1289 if (connection_ptr
== NULL
)
1291 log_error("malloc() failed for struct ladish_graph_connection");
1295 if (!ladish_dict_create(&connection_ptr
->dict
))
1297 log_error("ladish_dict_create() failed for connection");
1298 free(connection_ptr
);
1302 connection_ptr
->id
= graph_ptr
->next_connection_id
++;
1303 connection_ptr
->port1_ptr
= port1_ptr
;
1304 connection_ptr
->port2_ptr
= port2_ptr
;
1305 connection_ptr
->hidden
= hidden
;
1306 connection_ptr
->changing
= false;
1307 graph_ptr
->graph_version
++;
1309 list_add_tail(&connection_ptr
->siblings
, &graph_ptr
->connections
);
1312 /* "new connection %"PRIu64" between '%s':'%s' and '%s':'%s'", */
1313 /* connection_ptr->id, */
1314 /* port1_ptr->client_ptr->name, */
1315 /* port1_ptr->name, */
1316 /* port2_ptr->client_ptr->name, */
1317 /* port2_ptr->name); */
1319 if (!hidden
&& graph_ptr
->opath
!= NULL
)
1324 JACKDBUS_IFACE_PATCHBAY
,
1327 &graph_ptr
->graph_version
,
1328 &port1_ptr
->client_ptr
->id
,
1329 &port1_ptr
->client_ptr
->name
,
1332 &port2_ptr
->client_ptr
->id
,
1333 &port2_ptr
->client_ptr
->name
,
1336 &connection_ptr
->id
);
1339 return connection_ptr
->id
;
1343 ladish_graph_remove_connection(
1344 ladish_graph_handle graph_handle
,
1345 uint64_t connection_id
)
1347 struct ladish_graph_connection
* connection_ptr
;
1349 connection_ptr
= ladish_graph_find_connection_by_id(graph_ptr
, connection_id
);
1350 if (connection_ptr
== NULL
)
1356 if (connection_ptr
->changing
)
1359 /* "removing connection '%s':'%s' - '%s':'%s'", */
1360 /* connection_ptr->port1_ptr->client_ptr->name, */
1361 /* connection_ptr->port1_ptr->name, */
1362 /* connection_ptr->port2_ptr->client_ptr->name, */
1363 /* connection_ptr->port2_ptr->name); */
1365 ladish_graph_remove_connection_internal(graph_ptr
, connection_ptr
);
1370 /* "hiding connection '%s':'%s' - '%s':'%s'", */
1371 /* connection_ptr->port1_ptr->client_ptr->name, */
1372 /* connection_ptr->port1_ptr->name, */
1373 /* connection_ptr->port2_ptr->client_ptr->name, */
1374 /* connection_ptr->port2_ptr->name); */
1376 ladish_graph_hide_connection_internal(graph_ptr
, connection_ptr
);
1381 ladish_graph_get_connection_ports(
1382 ladish_graph_handle graph_handle
,
1383 uint64_t connection_id
,
1384 ladish_port_handle
* port1_handle_ptr
,
1385 ladish_port_handle
* port2_handle_ptr
)
1387 struct ladish_graph_connection
* connection_ptr
;
1389 connection_ptr
= ladish_graph_find_connection_by_id(graph_ptr
, connection_id
);
1390 if (connection_ptr
== NULL
)
1395 *port1_handle_ptr
= connection_ptr
->port1_ptr
->port
;
1396 *port2_handle_ptr
= connection_ptr
->port2_ptr
->port
;
1401 ladish_dict_handle
ladish_graph_get_connection_dict(ladish_graph_handle graph_handle
, uint64_t connection_id
)
1403 struct ladish_graph_connection
* connection_ptr
;
1405 connection_ptr
= ladish_graph_find_connection_by_id(graph_ptr
, connection_id
);
1406 if (connection_ptr
== NULL
)
1411 return connection_ptr
->dict
;
1415 ladish_graph_find_connection(
1416 ladish_graph_handle graph_handle
,
1417 ladish_port_handle port1_handle
,
1418 ladish_port_handle port2_handle
,
1419 uint64_t * connection_id_ptr
)
1421 struct ladish_graph_port
* port1_ptr
;
1422 struct ladish_graph_port
* port2_ptr
;
1423 struct ladish_graph_connection
* connection_ptr
;
1425 port1_ptr
= ladish_graph_find_port(graph_ptr
, port1_handle
);
1426 if (port1_ptr
== NULL
)
1431 port2_ptr
= ladish_graph_find_port(graph_ptr
, port2_handle
);
1432 if (port1_ptr
== NULL
)
1437 connection_ptr
= ladish_graph_find_connection_by_ports(graph_ptr
, port1_ptr
, port2_ptr
);
1438 if (connection_ptr
== NULL
)
1443 *connection_id_ptr
= connection_ptr
->id
;
1448 ladish_client_handle
ladish_graph_find_client_by_name(ladish_graph_handle graph_handle
, const char * name
)
1450 struct list_head
* node_ptr
;
1451 struct ladish_graph_client
* client_ptr
;
1453 list_for_each(node_ptr
, &graph_ptr
->clients
)
1455 client_ptr
= list_entry(node_ptr
, struct ladish_graph_client
, siblings
);
1456 if (strcmp(client_ptr
->name
, name
) == 0)
1458 return client_ptr
->client
;
1465 ladish_port_handle
ladish_graph_find_port_by_name(ladish_graph_handle graph_handle
, ladish_client_handle client_handle
, const char * name
)
1467 struct ladish_graph_client
* client_ptr
;
1468 struct list_head
* node_ptr
;
1469 struct ladish_graph_port
* port_ptr
;
1471 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1472 if (client_ptr
!= NULL
)
1474 list_for_each(node_ptr
, &client_ptr
->ports
)
1476 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_client
);
1477 if (strcmp(port_ptr
->name
, name
) == 0)
1479 return port_ptr
->port
;
1491 ladish_client_handle
ladish_graph_find_client_by_uuid(ladish_graph_handle graph_handle
, const uuid_t uuid
)
1493 struct list_head
* node_ptr
;
1494 struct ladish_graph_client
* client_ptr
;
1495 uuid_t current_uuid
;
1497 list_for_each(node_ptr
, &graph_ptr
->clients
)
1499 client_ptr
= list_entry(node_ptr
, struct ladish_graph_client
, siblings
);
1500 ladish_client_get_uuid(client_ptr
->client
, current_uuid
);
1501 if (uuid_compare(current_uuid
, uuid
) == 0)
1503 return client_ptr
->client
;
1510 ladish_port_handle
ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle
, const uuid_t uuid
)
1512 struct list_head
* node_ptr
;
1513 struct ladish_graph_port
* port_ptr
;
1514 uuid_t current_uuid
;
1516 list_for_each(node_ptr
, &graph_ptr
->ports
)
1518 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_graph
);
1519 ladish_port_get_uuid(port_ptr
->port
, current_uuid
);
1520 if (uuid_compare(current_uuid
, uuid
) == 0)
1522 return port_ptr
->port
;
1529 ladish_client_handle
ladish_graph_get_port_client(ladish_graph_handle graph_handle
, ladish_port_handle port_handle
)
1531 struct ladish_graph_port
* port_ptr
;
1533 port_ptr
= ladish_graph_find_port(graph_ptr
, port_handle
);
1534 if (port_ptr
== NULL
)
1539 return port_ptr
->client_ptr
->client
;
1542 bool ladish_graph_is_port_present(ladish_graph_handle graph_handle
, ladish_port_handle port_handle
)
1544 return ladish_graph_find_port(graph_ptr
, port_handle
) != NULL
;
1547 ladish_client_handle
ladish_graph_find_client_by_id(ladish_graph_handle graph_handle
, uint64_t client_id
)
1549 struct list_head
* node_ptr
;
1550 struct ladish_graph_client
* client_ptr
;
1552 list_for_each(node_ptr
, &graph_ptr
->clients
)
1554 client_ptr
= list_entry(node_ptr
, struct ladish_graph_client
, siblings
);
1555 if (client_ptr
->id
== client_id
)
1557 return client_ptr
->client
;
1564 ladish_port_handle
ladish_graph_find_port_by_id(ladish_graph_handle graph_handle
, uint64_t port_id
)
1566 struct ladish_graph_port
* port_ptr
;
1568 port_ptr
= ladish_graph_find_port_by_id_internal(graph_ptr
, port_id
);
1569 if (port_ptr
== NULL
)
1574 return port_ptr
->port
;
1577 ladish_client_handle
ladish_graph_find_client_by_jack_id(ladish_graph_handle graph_handle
, uint64_t client_id
)
1579 struct list_head
* node_ptr
;
1580 struct ladish_graph_client
* client_ptr
;
1582 list_for_each(node_ptr
, &graph_ptr
->clients
)
1584 client_ptr
= list_entry(node_ptr
, struct ladish_graph_client
, siblings
);
1585 if (ladish_client_get_jack_id(client_ptr
->client
) == client_id
)
1587 return client_ptr
->client
;
1594 ladish_port_handle
ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_handle
, uint64_t port_id
)
1596 struct list_head
* node_ptr
;
1597 struct ladish_graph_port
* port_ptr
;
1599 list_for_each(node_ptr
, &graph_ptr
->ports
)
1601 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_graph
);
1602 if (ladish_port_get_jack_id(port_ptr
->port
) == port_id
)
1604 return port_ptr
->port
;
1611 ladish_client_handle
1612 ladish_graph_remove_port(
1613 ladish_graph_handle graph_handle
,
1614 ladish_port_handle port
)
1616 struct ladish_graph_port
* port_ptr
;
1618 port_ptr
= ladish_graph_find_port(graph_ptr
, port
);
1619 if (port_ptr
== NULL
)
1624 ladish_graph_remove_port_internal(graph_ptr
, port_ptr
->client_ptr
, port_ptr
, false);
1625 return port_ptr
->client_ptr
->client
;
1628 const char * ladish_graph_get_client_name(ladish_graph_handle graph_handle
, ladish_client_handle client_handle
)
1630 struct ladish_graph_client
* client_ptr
;
1632 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1633 if (client_ptr
!= NULL
)
1635 return client_ptr
->name
;
1642 bool ladish_graph_is_client_empty(ladish_graph_handle graph_handle
, ladish_client_handle client_handle
)
1644 struct ladish_graph_client
* client_ptr
;
1646 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1647 if (client_ptr
!= NULL
)
1649 return list_empty(&client_ptr
->ports
);
1656 bool ladish_graph_is_client_looks_empty(ladish_graph_handle graph_handle
, ladish_client_handle client_handle
)
1658 struct ladish_graph_client
* client_ptr
;
1659 struct list_head
* node_ptr
;
1660 struct ladish_graph_port
* port_ptr
;
1662 client_ptr
= ladish_graph_find_client(graph_ptr
, client_handle
);
1663 if (client_ptr
!= NULL
)
1665 list_for_each(node_ptr
, &client_ptr
->ports
)
1667 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_client
);
1668 if (!port_ptr
->hidden
)
1670 //log_info("port '%s' is visible, client '%s' does not look empty", port_ptr->name, client_ptr->name);
1675 //log_info("port '%s' is invisible", port_ptr->name);
1679 log_info("client '%s' looks empty in graph %s", client_ptr
->name
, graph_ptr
->opath
!= NULL
? graph_ptr
->opath
: "JACK");
1687 void ladish_try_connect_hidden_connections(ladish_graph_handle graph_handle
)
1689 struct list_head
* node_ptr
;
1690 struct ladish_graph_connection
* connection_ptr
;
1692 if (graph_ptr
->connect_handler
== NULL
)
1698 ASSERT(graph_ptr
->opath
!= NULL
);
1700 list_for_each(node_ptr
, &graph_ptr
->connections
)
1702 connection_ptr
= list_entry(node_ptr
, struct ladish_graph_connection
, siblings
);
1703 if (connection_ptr
->hidden
&&
1704 !connection_ptr
->changing
&&
1705 !connection_ptr
->port1_ptr
->hidden
&&
1706 !connection_ptr
->port2_ptr
->hidden
)
1709 "auto connecting '%s':'%s' to '%s':'%s'",
1710 connection_ptr
->port1_ptr
->client_ptr
->name
,
1711 connection_ptr
->port1_ptr
->name
,
1712 connection_ptr
->port2_ptr
->client_ptr
->name
,
1713 connection_ptr
->port2_ptr
->name
);
1715 connection_ptr
->changing
= true;
1716 if (!graph_ptr
->connect_handler(graph_ptr
->context
, graph_handle
, connection_ptr
->port1_ptr
->port
, connection_ptr
->port2_ptr
->port
))
1718 connection_ptr
->changing
= false;
1719 log_error("auto connect failed.");
1725 void ladish_graph_hide_all(ladish_graph_handle graph_handle
)
1727 struct list_head
* node_ptr
;
1728 struct ladish_graph_connection
* connection_ptr
;
1729 struct ladish_graph_port
* port_ptr
;
1730 struct ladish_graph_client
* client_ptr
;
1732 log_info("hiding everything in graph %s", graph_ptr
->opath
!= NULL
? graph_ptr
->opath
: "JACK");
1734 list_for_each(node_ptr
, &graph_ptr
->connections
)
1736 connection_ptr
= list_entry(node_ptr
, struct ladish_graph_connection
, siblings
);
1737 if (!connection_ptr
->hidden
)
1739 log_debug("hidding connection between ports %"PRIu64
" and %"PRIu64
, connection_ptr
->port1_ptr
->id
, connection_ptr
->port2_ptr
->id
);
1740 ladish_graph_hide_connection_internal(graph_ptr
, connection_ptr
);
1744 list_for_each(node_ptr
, &graph_ptr
->ports
)
1746 port_ptr
= list_entry(node_ptr
, struct ladish_graph_port
, siblings_graph
);
1747 if (!port_ptr
->hidden
)
1749 ladish_port_set_jack_id(port_ptr
->port
, 0);
1750 ladish_graph_hide_port_internal(graph_ptr
, port_ptr
);
1754 list_for_each(node_ptr
, &graph_ptr
->clients
)
1756 client_ptr
= list_entry(node_ptr
, struct ladish_graph_client
, siblings
);
1757 if (!client_ptr
->hidden
)
1759 ladish_client_set_jack_id(client_ptr
->client
, 0);
1760 ladish_graph_hide_client_internal(graph_ptr
, client_ptr
);
1766 ladish_graph_iterate_nodes(
1767 ladish_graph_handle graph_handle
,
1768 void * callback_context
,
1770 (* client_begin_callback
)(
1772 ladish_client_handle client_handle
,
1773 const char * client_name
,
1774 void ** client_iteration_context_ptr_ptr
),
1778 void * client_iteration_context_ptr
,
1779 ladish_client_handle client_handle
,
1780 const char * client_name
,
1781 ladish_port_handle port_handle
,
1782 const char * port_name
,
1784 uint32_t port_flags
),
1786 (* client_end_callback
)(
1788 ladish_client_handle client_handle
,
1789 const char * client_name
,
1790 void * client_iteration_context_ptr
))
1792 struct list_head
* client_node_ptr
;
1793 struct ladish_graph_client
* client_ptr
;
1794 void * client_context
;
1795 struct list_head
* port_node_ptr
;
1796 struct ladish_graph_port
* port_ptr
;
1798 list_for_each(client_node_ptr
, &graph_ptr
->clients
)
1800 client_ptr
= list_entry(client_node_ptr
, struct ladish_graph_client
, siblings
);
1802 if (client_ptr
->hidden
)
1807 if (!client_begin_callback(callback_context
, client_ptr
->client
, client_ptr
->name
, &client_context
))
1812 list_for_each(port_node_ptr
, &client_ptr
->ports
)
1814 port_ptr
= list_entry(port_node_ptr
, struct ladish_graph_port
, siblings_client
);
1816 if (port_ptr
->hidden
)
1835 if (!client_end_callback(callback_context
, client_ptr
->client
, client_ptr
->name
, &client_context
))
1845 ladish_graph_iterate_connections(
1846 ladish_graph_handle graph_handle
,
1847 void * callback_context
,
1848 bool (* callback
)(void * context
, ladish_port_handle port1_handle
, ladish_port_handle port2_handle
, ladish_dict_handle dict
))
1850 struct list_head
* node_ptr
;
1851 struct ladish_graph_connection
* connection_ptr
;
1853 list_for_each(node_ptr
, &graph_ptr
->connections
)
1855 connection_ptr
= list_entry(node_ptr
, struct ladish_graph_connection
, siblings
);
1857 if (connection_ptr
->hidden
)
1862 if (!callback(callback_context
, connection_ptr
->port1_ptr
->port
, connection_ptr
->port2_ptr
->port
, connection_ptr
->dict
))
1878 log_info("%s key '%s' with value '%s'", (const char *)context
, key
, value
);
1885 const char * indent
,
1886 ladish_dict_handle dict
)
1888 if (ladish_dict_is_empty(dict
))
1893 log_info("%sdict:", indent
);
1894 ladish_dict_iterate(dict
, (void *)indent
, dump_dict_entry
);
1897 void ladish_graph_dump(ladish_graph_handle graph_handle
)
1899 struct list_head
* client_node_ptr
;
1900 struct ladish_graph_client
* client_ptr
;
1901 struct list_head
* port_node_ptr
;
1902 struct ladish_graph_port
* port_ptr
;
1903 struct list_head
* connection_node_ptr
;
1904 struct ladish_graph_connection
* connection_ptr
;
1906 log_info("graph %s", graph_ptr
->opath
!= NULL
? graph_ptr
->opath
: "JACK");
1907 log_info(" version %"PRIu64
, graph_ptr
->graph_version
);
1908 dump_dict(" ", graph_ptr
->dict
);
1909 log_info(" clients:");
1910 list_for_each(client_node_ptr
, &graph_ptr
->clients
)
1912 client_ptr
= list_entry(client_node_ptr
, struct ladish_graph_client
, siblings
);
1913 log_info(" %s client '%s', id=%"PRIu64
", ptr=%p", client_ptr
->hidden
? "invisible" : "visible", client_ptr
->name
, client_ptr
->id
, client_ptr
->client
);
1914 dump_dict(" ", ladish_client_get_dict(client_ptr
->client
));
1915 log_info(" ports:");
1916 list_for_each(port_node_ptr
, &client_ptr
->ports
)
1918 port_ptr
= list_entry(port_node_ptr
, struct ladish_graph_port
, siblings_client
);
1920 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
);
1921 dump_dict(" ", ladish_port_get_dict(port_ptr
->port
));
1924 log_info(" connections:");
1925 list_for_each(connection_node_ptr
, &graph_ptr
->connections
)
1927 connection_ptr
= list_entry(connection_node_ptr
, struct ladish_graph_connection
, siblings
);
1930 " %s connection '%s':'%s' - '%s':'%s'%s",
1931 connection_ptr
->hidden
? "invisible" : "visible",
1932 connection_ptr
->port1_ptr
->client_ptr
->name
,
1933 connection_ptr
->port1_ptr
->name
,
1934 connection_ptr
->port2_ptr
->client_ptr
->name
,
1935 connection_ptr
->port2_ptr
->name
,
1936 connection_ptr
->changing
? " [changing]" : "");
1937 dump_dict(" ", ladish_port_get_dict(port_ptr
->port
));
1943 METHOD_ARGS_BEGIN(GetAllPorts
, "Get all ports")
1944 METHOD_ARG_DESCRIBE_IN("ports_list", "as", "List of all ports")
1947 METHOD_ARGS_BEGIN(GetGraph
, "Get whole graph")
1948 METHOD_ARG_DESCRIBE_IN("known_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "Known graph version")
1949 METHOD_ARG_DESCRIBE_OUT("current_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "Current graph version")
1950 METHOD_ARG_DESCRIBE_OUT("clients_and_ports", "a(tsa(tsuu))", "Clients and their ports")
1951 METHOD_ARG_DESCRIBE_OUT("connections", "a(tstststst)", "Connections array")
1954 METHOD_ARGS_BEGIN(ConnectPortsByName
, "Connect ports")
1955 METHOD_ARG_DESCRIBE_IN("client1_name", DBUS_TYPE_STRING_AS_STRING
, "name first port client")
1956 METHOD_ARG_DESCRIBE_IN("port1_name", DBUS_TYPE_STRING_AS_STRING
, "name of first port")
1957 METHOD_ARG_DESCRIBE_IN("client2_name", DBUS_TYPE_STRING_AS_STRING
, "name second port client")
1958 METHOD_ARG_DESCRIBE_IN("port2_name", DBUS_TYPE_STRING_AS_STRING
, "name of second port")
1961 METHOD_ARGS_BEGIN(ConnectPortsByID
, "Connect ports")
1962 METHOD_ARG_DESCRIBE_IN("port1_id", DBUS_TYPE_UINT64_AS_STRING
, "id of first port")
1963 METHOD_ARG_DESCRIBE_IN("port2_id", DBUS_TYPE_UINT64_AS_STRING
, "if of second port")
1966 METHOD_ARGS_BEGIN(DisconnectPortsByName
, "Disconnect ports")
1967 METHOD_ARG_DESCRIBE_IN("client1_name", DBUS_TYPE_STRING_AS_STRING
, "name first port client")
1968 METHOD_ARG_DESCRIBE_IN("port1_name", DBUS_TYPE_STRING_AS_STRING
, "name of first port")
1969 METHOD_ARG_DESCRIBE_IN("client2_name", DBUS_TYPE_STRING_AS_STRING
, "name second port client")
1970 METHOD_ARG_DESCRIBE_IN("port2_name", DBUS_TYPE_STRING_AS_STRING
, "name of second port")
1973 METHOD_ARGS_BEGIN(DisconnectPortsByID
, "Disconnect ports")
1974 METHOD_ARG_DESCRIBE_IN("port1_id", DBUS_TYPE_UINT64_AS_STRING
, "id of first port")
1975 METHOD_ARG_DESCRIBE_IN("port2_id", DBUS_TYPE_UINT64_AS_STRING
, "if of second port")
1978 METHOD_ARGS_BEGIN(DisconnectPortsByConnectionID
, "Disconnect ports")
1979 METHOD_ARG_DESCRIBE_IN("connection_id", DBUS_TYPE_UINT64_AS_STRING
, "id of connection to disconnect")
1982 METHOD_ARGS_BEGIN(GetClientPID
, "get process id of client")
1983 METHOD_ARG_DESCRIBE_IN("client_id", DBUS_TYPE_UINT64_AS_STRING
, "id of client")
1984 METHOD_ARG_DESCRIBE_OUT("process_id", DBUS_TYPE_INT64_AS_STRING
, "pid of client")
1988 METHOD_DESCRIBE(GetAllPorts
, get_all_ports
)
1989 METHOD_DESCRIBE(GetGraph
, get_graph
)
1990 METHOD_DESCRIBE(ConnectPortsByName
, connect_ports_by_name
)
1991 METHOD_DESCRIBE(ConnectPortsByID
, connect_ports_by_id
)
1992 METHOD_DESCRIBE(DisconnectPortsByName
, disconnect_ports_by_name
)
1993 METHOD_DESCRIBE(DisconnectPortsByID
, disconnect_ports_by_id
)
1994 METHOD_DESCRIBE(DisconnectPortsByConnectionID
, disconnect_ports_by_connection_id
)
1995 METHOD_DESCRIBE(GetClientPID
, get_client_pid
)
1998 SIGNAL_ARGS_BEGIN(GraphChanged
, "")
1999 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "")
2002 SIGNAL_ARGS_BEGIN(ClientAppeared
, "")
2003 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "")
2004 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2005 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING
, "")
2008 SIGNAL_ARGS_BEGIN(ClientDisappeared
, "")
2009 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "")
2010 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2011 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING
, "")
2014 SIGNAL_ARGS_BEGIN(PortAppeared
, "")
2015 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "")
2016 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2017 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING
, "")
2018 SIGNAL_ARG_DESCRIBE("port_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2019 SIGNAL_ARG_DESCRIBE("port_name", DBUS_TYPE_STRING_AS_STRING
, "")
2020 SIGNAL_ARG_DESCRIBE("port_flags", DBUS_TYPE_UINT32_AS_STRING
, "")
2021 SIGNAL_ARG_DESCRIBE("port_type", DBUS_TYPE_UINT32_AS_STRING
, "")
2024 SIGNAL_ARGS_BEGIN(PortDisappeared
, "")
2025 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "")
2026 SIGNAL_ARG_DESCRIBE("client_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2027 SIGNAL_ARG_DESCRIBE("client_name", DBUS_TYPE_STRING_AS_STRING
, "")
2028 SIGNAL_ARG_DESCRIBE("port_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2029 SIGNAL_ARG_DESCRIBE("port_name", DBUS_TYPE_STRING_AS_STRING
, "")
2032 SIGNAL_ARGS_BEGIN(PortsConnected
, "")
2033 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "")
2034 SIGNAL_ARG_DESCRIBE("client1_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2035 SIGNAL_ARG_DESCRIBE("client1_name", DBUS_TYPE_STRING_AS_STRING
, "")
2036 SIGNAL_ARG_DESCRIBE("port1_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2037 SIGNAL_ARG_DESCRIBE("port1_name", DBUS_TYPE_STRING_AS_STRING
, "")
2038 SIGNAL_ARG_DESCRIBE("client2_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2039 SIGNAL_ARG_DESCRIBE("client2_name", DBUS_TYPE_STRING_AS_STRING
, "")
2040 SIGNAL_ARG_DESCRIBE("port2_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2041 SIGNAL_ARG_DESCRIBE("port2_name", DBUS_TYPE_STRING_AS_STRING
, "")
2042 SIGNAL_ARG_DESCRIBE("connection_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2045 SIGNAL_ARGS_BEGIN(PortsDisconnected
, "")
2046 SIGNAL_ARG_DESCRIBE("new_graph_version", DBUS_TYPE_UINT64_AS_STRING
, "")
2047 SIGNAL_ARG_DESCRIBE("client1_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2048 SIGNAL_ARG_DESCRIBE("client1_name", DBUS_TYPE_STRING_AS_STRING
, "")
2049 SIGNAL_ARG_DESCRIBE("port1_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2050 SIGNAL_ARG_DESCRIBE("port1_name", DBUS_TYPE_STRING_AS_STRING
, "")
2051 SIGNAL_ARG_DESCRIBE("client2_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2052 SIGNAL_ARG_DESCRIBE("client2_name", DBUS_TYPE_STRING_AS_STRING
, "")
2053 SIGNAL_ARG_DESCRIBE("port2_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2054 SIGNAL_ARG_DESCRIBE("port2_name", DBUS_TYPE_STRING_AS_STRING
, "")
2055 SIGNAL_ARG_DESCRIBE("connection_id", DBUS_TYPE_UINT64_AS_STRING
, "")
2059 SIGNAL_DESCRIBE(GraphChanged
)
2060 SIGNAL_DESCRIBE(ClientAppeared
)
2061 SIGNAL_DESCRIBE(ClientDisappeared
)
2062 SIGNAL_DESCRIBE(PortAppeared
)
2063 SIGNAL_DESCRIBE(PortDisappeared
)
2064 SIGNAL_DESCRIBE(PortsConnected
)
2065 SIGNAL_DESCRIBE(PortsDisconnected
)
2068 INTERFACE_BEGIN(g_interface_patchbay
, JACKDBUS_IFACE_PATCHBAY
)
2069 INTERFACE_DEFAULT_HANDLER
2070 INTERFACE_EXPOSE_METHODS
2071 INTERFACE_EXPOSE_SIGNALS