gui: remove unused and duplicate dbus helper code
[ladish.git] / proxies / graph_proxy.c
blob20b408b0c3b62c2f655f652f50e8f1abe9d069ec
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains implementation graph object that is backed through D-Bus
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "graph_proxy.h"
29 struct monitor
31 struct list_head siblings;
32 void * context;
33 void (* clear)(void * context);
34 void (* client_appeared)(void * context, uint64_t id, const char * name);
35 void (* client_disappeared)(void * context, uint64_t id);
36 void (* port_appeared)(void * context, uint64_t client_id, uint64_t port_id, const char * port_name, bool is_input, bool is_terminal, bool is_midi);
37 void (* port_disappeared)(void * context, uint64_t client_id, uint64_t port_id);
38 void (* ports_connected)(void * context, uint64_t client1_id, uint64_t port1_id, uint64_t client2_id, uint64_t port2_id);
39 void (* ports_disconnected)(void * context, uint64_t client1_id, uint64_t port1_id, uint64_t client2_id, uint64_t port2_id);
42 struct graph
44 struct list_head monitors;
45 char * service;
46 char * object;
47 uint64_t version;
48 bool active;
49 bool graph_dict_supported;
52 static struct dbus_signal_hook g_signal_hooks[];
54 static void clear(struct graph * graph_ptr)
56 struct list_head * node_ptr;
57 struct monitor * monitor_ptr;
59 list_for_each(node_ptr, &graph_ptr->monitors)
61 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
62 monitor_ptr->clear(monitor_ptr->context);
66 static void client_appeared(struct graph * graph_ptr, uint64_t id, const char * name)
68 struct list_head * node_ptr;
69 struct monitor * monitor_ptr;
71 list_for_each(node_ptr, &graph_ptr->monitors)
73 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
74 monitor_ptr->client_appeared(monitor_ptr->context, id, name);
78 static void client_disappeared(struct graph * graph_ptr, uint64_t id)
80 struct list_head * node_ptr;
81 struct monitor * monitor_ptr;
83 list_for_each(node_ptr, &graph_ptr->monitors)
85 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
86 monitor_ptr->client_disappeared(monitor_ptr->context, id);
90 static
91 void
92 port_appeared(
93 struct graph * graph_ptr,
94 uint64_t client_id,
95 uint64_t port_id,
96 const char * port_name,
97 uint32_t port_flags,
98 uint32_t port_type)
100 struct list_head * node_ptr;
101 struct monitor * monitor_ptr;
102 bool is_input;
103 bool is_terminal;
104 bool is_midi;
106 if (port_type != JACKDBUS_PORT_TYPE_AUDIO && port_type != JACKDBUS_PORT_TYPE_MIDI)
108 log_error("Unknown JACK D-Bus port type %d", (unsigned int)port_type);
109 return;
112 is_input = port_flags & JACKDBUS_PORT_FLAG_INPUT;
113 is_terminal = port_flags & JACKDBUS_PORT_FLAG_TERMINAL;
114 is_midi = port_type == JACKDBUS_PORT_TYPE_MIDI;
116 list_for_each(node_ptr, &graph_ptr->monitors)
118 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
119 monitor_ptr->port_appeared(monitor_ptr->context, client_id, port_id, port_name, is_input, is_terminal, is_midi);
123 static
124 void
125 port_disappeared(
126 struct graph * graph_ptr,
127 uint64_t client_id,
128 uint64_t port_id)
130 struct list_head * node_ptr;
131 struct monitor * monitor_ptr;
133 list_for_each(node_ptr, &graph_ptr->monitors)
135 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
136 monitor_ptr->port_disappeared(monitor_ptr->context, client_id, port_id);
140 static
141 void
142 ports_connected(
143 struct graph * graph_ptr,
144 uint64_t client1_id,
145 uint64_t port1_id,
146 uint64_t client2_id,
147 uint64_t port2_id)
149 struct list_head * node_ptr;
150 struct monitor * monitor_ptr;
152 list_for_each(node_ptr, &graph_ptr->monitors)
154 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
155 monitor_ptr->ports_connected(monitor_ptr->context, client1_id, port1_id, client2_id, port2_id);
159 static
160 void
161 ports_disconnected(
162 struct graph * graph_ptr,
163 uint64_t client1_id,
164 uint64_t port1_id,
165 uint64_t client2_id,
166 uint64_t port2_id)
168 struct list_head * node_ptr;
169 struct monitor * monitor_ptr;
171 list_for_each(node_ptr, &graph_ptr->monitors)
173 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
174 monitor_ptr->ports_disconnected(monitor_ptr->context, client1_id, port1_id, client2_id, port2_id);
178 static void refresh_internal(struct graph * graph_ptr, bool force)
180 DBusMessage* reply_ptr;
181 DBusMessageIter iter;
182 dbus_uint64_t version;
183 const char * reply_signature;
184 DBusMessageIter clients_array_iter;
185 DBusMessageIter client_struct_iter;
186 DBusMessageIter ports_array_iter;
187 DBusMessageIter port_struct_iter;
188 DBusMessageIter connections_array_iter;
189 DBusMessageIter connection_struct_iter;
190 dbus_uint64_t client_id;
191 const char *client_name;
192 dbus_uint64_t port_id;
193 const char *port_name;
194 dbus_uint32_t port_flags;
195 dbus_uint32_t port_type;
196 dbus_uint64_t client2_id;
197 const char *client2_name;
198 dbus_uint64_t port2_id;
199 const char *port2_name;
200 dbus_uint64_t connection_id;
202 log_info("refresh_internal() called");
204 if (force)
206 version = 0; // workaround module split/join stupidity
208 else
210 version = graph_ptr->version;
213 if (!dbus_call(graph_ptr->service, graph_ptr->object, JACKDBUS_IFACE_PATCHBAY, "GetGraph", "t", &version, NULL, &reply_ptr))
215 log_error("GetGraph() failed.");
216 return;
219 reply_signature = dbus_message_get_signature(reply_ptr);
221 if (strcmp(reply_signature, "ta(tsa(tsuu))a(tstststst)") != 0)
223 log_error("GetGraph() reply signature mismatch. '%s'", reply_signature);
224 goto unref;
227 dbus_message_iter_init(reply_ptr, &iter);
229 //log_info_msg("version " + (char)dbus_message_iter_get_arg_type(&iter));
230 dbus_message_iter_get_basic(&iter, &version);
231 dbus_message_iter_next(&iter);
233 if (!force && version <= graph_ptr->version)
235 goto unref;
238 clear(graph_ptr);
240 //log_info("got new graph version %llu", (unsigned long long)version);
241 graph_ptr->version = version;
243 //info_msg((std::string)"clients " + (char)dbus_message_iter_get_arg_type(&iter));
245 for (dbus_message_iter_recurse(&iter, &clients_array_iter);
246 dbus_message_iter_get_arg_type(&clients_array_iter) != DBUS_TYPE_INVALID;
247 dbus_message_iter_next(&clients_array_iter))
249 //info_msg((std::string)"a client " + (char)dbus_message_iter_get_arg_type(&clients_array_iter));
250 dbus_message_iter_recurse(&clients_array_iter, &client_struct_iter);
252 dbus_message_iter_get_basic(&client_struct_iter, &client_id);
253 dbus_message_iter_next(&client_struct_iter);
255 dbus_message_iter_get_basic(&client_struct_iter, &client_name);
256 dbus_message_iter_next(&client_struct_iter);
258 //info_msg((std::string)"client '" + client_name + "'");
260 client_appeared(graph_ptr, client_id, client_name);
262 for (dbus_message_iter_recurse(&client_struct_iter, &ports_array_iter);
263 dbus_message_iter_get_arg_type(&ports_array_iter) != DBUS_TYPE_INVALID;
264 dbus_message_iter_next(&ports_array_iter))
266 //info_msg((std::string)"a port " + (char)dbus_message_iter_get_arg_type(&ports_array_iter));
267 dbus_message_iter_recurse(&ports_array_iter, &port_struct_iter);
269 dbus_message_iter_get_basic(&port_struct_iter, &port_id);
270 dbus_message_iter_next(&port_struct_iter);
272 dbus_message_iter_get_basic(&port_struct_iter, &port_name);
273 dbus_message_iter_next(&port_struct_iter);
275 dbus_message_iter_get_basic(&port_struct_iter, &port_flags);
276 dbus_message_iter_next(&port_struct_iter);
278 dbus_message_iter_get_basic(&port_struct_iter, &port_type);
279 dbus_message_iter_next(&port_struct_iter);
281 //info_msg((std::string)"port: " + port_name);
283 port_appeared(graph_ptr, client_id, port_id, port_name, port_flags, port_type);
286 dbus_message_iter_next(&client_struct_iter);
289 dbus_message_iter_next(&iter);
291 for (dbus_message_iter_recurse(&iter, &connections_array_iter);
292 dbus_message_iter_get_arg_type(&connections_array_iter) != DBUS_TYPE_INVALID;
293 dbus_message_iter_next(&connections_array_iter))
295 //info_msg((std::string)"a connection " + (char)dbus_message_iter_get_arg_type(&connections_array_iter));
296 dbus_message_iter_recurse(&connections_array_iter, &connection_struct_iter);
298 dbus_message_iter_get_basic(&connection_struct_iter, &client_id);
299 dbus_message_iter_next(&connection_struct_iter);
301 dbus_message_iter_get_basic(&connection_struct_iter, &client_name);
302 dbus_message_iter_next(&connection_struct_iter);
304 dbus_message_iter_get_basic(&connection_struct_iter, &port_id);
305 dbus_message_iter_next(&connection_struct_iter);
307 dbus_message_iter_get_basic(&connection_struct_iter, &port_name);
308 dbus_message_iter_next(&connection_struct_iter);
310 dbus_message_iter_get_basic(&connection_struct_iter, &client2_id);
311 dbus_message_iter_next(&connection_struct_iter);
313 dbus_message_iter_get_basic(&connection_struct_iter, &client2_name);
314 dbus_message_iter_next(&connection_struct_iter);
316 dbus_message_iter_get_basic(&connection_struct_iter, &port2_id);
317 dbus_message_iter_next(&connection_struct_iter);
319 dbus_message_iter_get_basic(&connection_struct_iter, &port2_name);
320 dbus_message_iter_next(&connection_struct_iter);
322 dbus_message_iter_get_basic(&connection_struct_iter, &connection_id);
323 dbus_message_iter_next(&connection_struct_iter);
325 //info_msg(str(boost::format("connection(%llu) %s(%llu):%s(%llu) <-> %s(%llu):%s(%llu)") %
326 // connection_id %
327 // client_name %
328 // client_id %
329 // port_name %
330 // port_id %
331 // client2_name %
332 // client2_id %
333 // port2_name %
334 // port2_id));
336 ports_connected(graph_ptr, client_id, port_id, client2_id, port2_id);
339 unref:
340 dbus_message_unref(reply_ptr);
343 bool
344 graph_proxy_create(
345 const char * service,
346 const char * object,
347 bool graph_dict_supported,
348 graph_proxy_handle * graph_proxy_handle_ptr)
350 struct graph * graph_ptr;
352 graph_ptr = malloc(sizeof(struct graph));
353 if (graph_ptr == NULL)
355 log_error("malloc() failed to allocate struct graph");
356 goto fail;
359 graph_ptr->service = strdup(service);
360 if (graph_ptr->service == NULL)
362 log_error("strdup() failed too duplicate service name '%s'", service);
363 goto free_graph;
366 graph_ptr->object = strdup(object);
367 if (graph_ptr->object == NULL)
369 log_error("strdup() failed too duplicate object name '%s'", object);
370 goto free_service;
373 INIT_LIST_HEAD(&graph_ptr->monitors);
375 graph_ptr->version = 0;
376 graph_ptr->active = false;
378 graph_ptr->graph_dict_supported = graph_dict_supported;
380 *graph_proxy_handle_ptr = (graph_proxy_handle)graph_ptr;
382 return true;
384 free_service:
385 free(graph_ptr->service);
387 free_graph:
388 free(graph_ptr);
390 fail:
391 return false;
394 #define graph_ptr ((struct graph *)graph)
396 const char * graph_proxy_get_service(graph_proxy_handle graph)
398 return graph_ptr->service;
401 const char * graph_proxy_get_object(graph_proxy_handle graph)
403 return graph_ptr->object;
406 void
407 graph_proxy_destroy(
408 graph_proxy_handle graph)
410 ASSERT(list_empty(&graph_ptr->monitors));
412 if (graph_ptr->active)
414 dbus_unregister_object_signal_hooks(
415 g_dbus_connection,
416 graph_ptr->service,
417 graph_ptr->object,
418 JACKDBUS_IFACE_PATCHBAY);
421 free(graph_ptr->object);
422 free(graph_ptr->service);
423 free(graph_ptr);
426 bool
427 graph_proxy_activate(
428 graph_proxy_handle graph)
430 if (list_empty(&graph_ptr->monitors))
432 log_error("no monitors to activate");
433 return false;
436 if (graph_ptr->active)
438 log_error("graph already active");
439 return false;
442 if (!dbus_register_object_signal_hooks(
443 g_dbus_connection,
444 graph_ptr->service,
445 graph_ptr->object,
446 JACKDBUS_IFACE_PATCHBAY,
447 graph_ptr,
448 g_signal_hooks))
450 return false;
453 graph_ptr->active = true;
455 refresh_internal(graph_ptr, true);
457 return true;
460 bool
461 graph_proxy_attach(
462 graph_proxy_handle graph,
463 void * context,
464 void (* clear)(void * context),
465 void (* client_appeared)(void * context, uint64_t id, const char * name),
466 void (* client_disappeared)(void * context, uint64_t id),
467 void (* port_appeared)(void * context, uint64_t client_id, uint64_t port_id, const char * port_name, bool is_input, bool is_terminal, bool is_midi),
468 void (* port_disappeared)(void * context, uint64_t client_id, uint64_t port_id),
469 void (* ports_connected)(void * context, uint64_t client1_id, uint64_t port1_id, uint64_t client2_id, uint64_t port2_id),
470 void (* ports_disconnected)(void * context, uint64_t client1_id, uint64_t port1_id, uint64_t client2_id, uint64_t port2_id))
472 struct monitor * monitor_ptr;
474 if (graph_ptr->active)
476 return false;
479 monitor_ptr = malloc(sizeof(struct monitor));
480 if (monitor_ptr == NULL)
482 log_error("malloc() failed to allocate struct monitor");
483 return false;
486 monitor_ptr->context = context;
487 monitor_ptr->clear = clear;
488 monitor_ptr->client_appeared = client_appeared;
489 monitor_ptr->client_disappeared = client_disappeared;
490 monitor_ptr->port_appeared = port_appeared;
491 monitor_ptr->port_disappeared = port_disappeared;
492 monitor_ptr->ports_connected = ports_connected;
493 monitor_ptr->ports_disconnected = ports_disconnected;
495 list_add_tail(&monitor_ptr->siblings, &graph_ptr->monitors);
497 return true;
500 void
501 graph_proxy_detach(
502 graph_proxy_handle graph,
503 void * context)
505 struct list_head * node_ptr;
506 struct monitor * monitor_ptr;
508 list_for_each(node_ptr, &graph_ptr->monitors)
510 monitor_ptr = list_entry(node_ptr, struct monitor, siblings);
511 if (monitor_ptr->context == context)
513 list_del(&monitor_ptr->siblings);
514 free(monitor_ptr);
515 return;
519 ASSERT(false);
522 void
523 graph_proxy_connect_ports(
524 graph_proxy_handle graph,
525 uint64_t port1_id,
526 uint64_t port2_id)
528 if (!dbus_call(graph_ptr->service, graph_ptr->object, JACKDBUS_IFACE_PATCHBAY, "ConnectPortsByID", "tt", &port1_id, &port2_id, ""))
530 log_error("ConnectPortsByID() failed.");
534 void
535 graph_proxy_disconnect_ports(
536 graph_proxy_handle graph,
537 uint64_t port1_id,
538 uint64_t port2_id)
540 if (!dbus_call(graph_ptr->service, graph_ptr->object, JACKDBUS_IFACE_PATCHBAY, "DisconnectPortsByID", "tt", &port1_id, &port2_id, ""))
542 log_error("DisconnectPortsByID() failed.");
546 static void on_client_appeared(void * graph, DBusMessage * message_ptr)
548 dbus_uint64_t new_graph_version;
549 dbus_uint64_t client_id;
550 const char * client_name;
552 if (!dbus_message_get_args(
553 message_ptr,
554 &g_dbus_error,
555 DBUS_TYPE_UINT64, &new_graph_version,
556 DBUS_TYPE_UINT64, &client_id,
557 DBUS_TYPE_STRING, &client_name,
558 DBUS_TYPE_INVALID))
560 log_error("dbus_message_get_args() failed to extract ClientAppeared signal arguments (%s)", g_dbus_error.message);
561 dbus_error_free(&g_dbus_error);
562 return;
565 //log_info("ClientAppeared, %s(%llu), graph %llu", client_name, client_id, new_graph_version);
567 if (new_graph_version > graph_ptr->version)
569 //log_info("got new graph version %llu", (unsigned long long)new_graph_version);
570 graph_ptr->version = new_graph_version;
571 client_appeared(graph_ptr, client_id, client_name);
575 static void on_client_disappeared(void * graph, DBusMessage * message_ptr)
577 dbus_uint64_t new_graph_version;
578 dbus_uint64_t client_id;
579 const char * client_name;
581 if (!dbus_message_get_args(
582 message_ptr,
583 &g_dbus_error,
584 DBUS_TYPE_UINT64, &new_graph_version,
585 DBUS_TYPE_UINT64, &client_id,
586 DBUS_TYPE_STRING, &client_name,
587 DBUS_TYPE_INVALID))
589 log_error("dbus_message_get_args() failed to extract ClientDisappeared signal arguments (%s)", g_dbus_error.message);
590 dbus_error_free(&g_dbus_error);
591 return;
594 //log_info("ClientDisappeared, %s(%llu)", client_name, client_id);
596 if (new_graph_version > graph_ptr->version)
598 //log_info("got new graph version %llu", (unsigned long long)new_graph_version);
599 graph_ptr->version = new_graph_version;
600 client_disappeared(graph_ptr, client_id);
604 static void on_port_appeared(void * graph, DBusMessage * message_ptr)
606 dbus_uint64_t new_graph_version;
607 dbus_uint64_t client_id;
608 const char * client_name;
609 dbus_uint64_t port_id;
610 const char * port_name;
611 dbus_uint32_t port_flags;
612 dbus_uint32_t port_type;
614 if (!dbus_message_get_args(
615 message_ptr,
616 &g_dbus_error,
617 DBUS_TYPE_UINT64, &new_graph_version,
618 DBUS_TYPE_UINT64, &client_id,
619 DBUS_TYPE_STRING, &client_name,
620 DBUS_TYPE_UINT64, &port_id,
621 DBUS_TYPE_STRING, &port_name,
622 DBUS_TYPE_UINT32, &port_flags,
623 DBUS_TYPE_UINT32, &port_type,
624 DBUS_TYPE_INVALID))
626 log_error("dbus_message_get_args() failed to extract PortAppeared signal arguments (%s)", g_dbus_error.message);
627 dbus_error_free(&g_dbus_error);
628 return;
631 //me->info_msg(str(boost::format("PortAppeared, %s(%llu):%s(%llu), %lu, %lu") % client_name % client_id % port_name % port_id % port_flags % port_type));
633 if (new_graph_version > graph_ptr->version)
635 //log_info("got new graph version %llu", (unsigned long long)new_graph_version);
636 graph_ptr->version = new_graph_version;
637 port_appeared(graph_ptr, client_id, port_id, port_name, port_flags, port_type);
641 static void on_port_disappeared(void * graph, DBusMessage * message_ptr)
643 dbus_uint64_t new_graph_version;
644 dbus_uint64_t client_id;
645 const char * client_name;
646 dbus_uint64_t port_id;
647 const char * port_name;
649 if (!dbus_message_get_args(
650 message_ptr,
651 &g_dbus_error,
652 DBUS_TYPE_UINT64, &new_graph_version,
653 DBUS_TYPE_UINT64, &client_id,
654 DBUS_TYPE_STRING, &client_name,
655 DBUS_TYPE_UINT64, &port_id,
656 DBUS_TYPE_STRING, &port_name,
657 DBUS_TYPE_INVALID))
659 log_error("dbus_message_get_args() failed to extract PortDisappeared signal arguments (%s)", g_dbus_error.message);
660 dbus_error_free(&g_dbus_error);
661 return;
664 //me->info_msg(str(boost::format("PortDisappeared, %s(%llu):%s(%llu)") % client_name % client_id % port_name % port_id));
666 if (new_graph_version > graph_ptr->version)
668 //log_info("got new graph version %llu", (unsigned long long)new_graph_version);
669 graph_ptr->version = new_graph_version;
670 port_disappeared(graph_ptr, client_id, port_id);
674 static void on_ports_connected(void * graph, DBusMessage * message_ptr)
676 dbus_uint64_t new_graph_version;
677 dbus_uint64_t client_id;
678 const char * client_name;
679 dbus_uint64_t port_id;
680 const char * port_name;
681 dbus_uint64_t client2_id;
682 const char * client2_name;
683 dbus_uint64_t port2_id;
684 const char * port2_name;
685 dbus_uint64_t connection_id;
687 if (!dbus_message_get_args(
688 message_ptr,
689 &g_dbus_error,
690 DBUS_TYPE_UINT64, &new_graph_version,
691 DBUS_TYPE_UINT64, &client_id,
692 DBUS_TYPE_STRING, &client_name,
693 DBUS_TYPE_UINT64, &port_id,
694 DBUS_TYPE_STRING, &port_name,
695 DBUS_TYPE_UINT64, &client2_id,
696 DBUS_TYPE_STRING, &client2_name,
697 DBUS_TYPE_UINT64, &port2_id,
698 DBUS_TYPE_STRING, &port2_name,
699 DBUS_TYPE_UINT64, &connection_id,
700 DBUS_TYPE_INVALID))
702 log_error("dbus_message_get_args() failed to extract PortsConnected signal arguments (%s)", g_dbus_error.message);
703 dbus_error_free(&g_dbus_error);
704 return;
707 if (new_graph_version > graph_ptr->version)
709 //log_info("got new graph version %llu", (unsigned long long)new_graph_version);
710 graph_ptr->version = new_graph_version;
711 ports_connected(graph_ptr, client_id, port_id, client2_id, port2_id);
715 static void on_ports_disconnected(void * graph, DBusMessage * message_ptr)
717 dbus_uint64_t new_graph_version;
718 dbus_uint64_t client_id;
719 const char * client_name;
720 dbus_uint64_t port_id;
721 const char * port_name;
722 dbus_uint64_t client2_id;
723 const char * client2_name;
724 dbus_uint64_t port2_id;
725 const char * port2_name;
726 dbus_uint64_t connection_id;
728 if (!dbus_message_get_args(
729 message_ptr,
730 &g_dbus_error,
731 DBUS_TYPE_UINT64, &new_graph_version,
732 DBUS_TYPE_UINT64, &client_id,
733 DBUS_TYPE_STRING, &client_name,
734 DBUS_TYPE_UINT64, &port_id,
735 DBUS_TYPE_STRING, &port_name,
736 DBUS_TYPE_UINT64, &client2_id,
737 DBUS_TYPE_STRING, &client2_name,
738 DBUS_TYPE_UINT64, &port2_id,
739 DBUS_TYPE_STRING, &port2_name,
740 DBUS_TYPE_UINT64, &connection_id,
741 DBUS_TYPE_INVALID))
743 log_error("dbus_message_get_args() failed to extract PortsConnected signal arguments (%s)", g_dbus_error.message);
744 dbus_error_free(&g_dbus_error);
745 return;
748 if (new_graph_version > graph_ptr->version)
750 //log_info("got new graph version %llu", (unsigned long long)new_graph_version);
751 graph_ptr->version = new_graph_version;
752 ports_disconnected(graph_ptr, client_id, port_id, client2_id, port2_id);
756 bool
757 graph_proxy_dict_entry_set(
758 graph_proxy_handle graph,
759 uint32_t object_type,
760 uint64_t object_id,
761 const char * key,
762 const char * value)
764 if (!graph_ptr->graph_dict_supported)
766 return false;
769 if (!dbus_call(graph_ptr->service, graph_ptr->object, IFACE_GRAPH_DICT, "Set", "utss", &object_type, &object_id, &key, &value, ""))
771 log_error(IFACE_GRAPH_DICT ".Set() failed.");
772 return false;
775 return true;
778 bool
779 graph_proxy_dict_entry_get(
780 graph_proxy_handle graph,
781 uint32_t object_type,
782 uint64_t object_id,
783 const char * key,
784 char ** value_ptr_ptr)
786 DBusMessage * reply_ptr;
787 const char * reply_signature;
788 DBusMessageIter iter;
789 const char * cvalue_ptr;
790 char * value_ptr;
792 if (!graph_ptr->graph_dict_supported)
794 return false;
797 if (!dbus_call(graph_ptr->service, graph_ptr->object, IFACE_GRAPH_DICT, "Get", "uts", &object_type, &object_id, &key, NULL, &reply_ptr))
799 log_error(IFACE_GRAPH_DICT ".Get() failed.");
800 return false;
803 reply_signature = dbus_message_get_signature(reply_ptr);
805 if (strcmp(reply_signature, "s") != 0)
807 log_error("reply signature is '%s' but expected signature is 's'", reply_signature);
808 dbus_message_unref(reply_ptr);
809 return false;
812 dbus_message_iter_init(reply_ptr, &iter);
813 dbus_message_iter_get_basic(&iter, &cvalue_ptr);
814 value_ptr = strdup(cvalue_ptr);
815 dbus_message_unref(reply_ptr);
816 if (value_ptr == NULL)
818 log_error("strdup() failed for dict value");
819 return false;
821 *value_ptr_ptr = value_ptr;
822 return true;
825 bool
826 graph_proxy_dict_entry_drop(
827 graph_proxy_handle graph,
828 uint32_t object_type,
829 uint64_t object_id,
830 const char * key)
832 if (!graph_ptr->graph_dict_supported)
834 return false;
837 if (!dbus_call(graph_ptr->service, graph_ptr->object, IFACE_GRAPH_DICT, "Drop", "uts", &object_type, &object_id, &key, ""))
839 log_error(IFACE_GRAPH_DICT ".Drop() failed.");
840 return false;
843 return true;
846 bool graph_proxy_get_client_pid(graph_proxy_handle graph, uint64_t client_id, int64_t * pid_ptr)
848 if (!dbus_call(graph_ptr->service, graph_ptr->object, JACKDBUS_IFACE_PATCHBAY, "GetClientPID", "t", &client_id, "x", pid_ptr))
850 log_error("GetClientPID() failed.");
851 return false;
854 return true;
857 /* this must be static because it is referenced by the
858 * dbus helper layer when hooks are active */
859 static struct dbus_signal_hook g_signal_hooks[] =
861 {"ClientAppeared", on_client_appeared},
862 {"ClientDisappeared", on_client_disappeared},
863 {"PortAppeared", on_port_appeared},
864 {"PortDisappeared", on_port_disappeared},
865 {"PortsConnected", on_ports_connected},
866 {"PortsDisconnected", on_ports_disconnected},
867 {NULL, NULL}