Fix tight loop on studio unload caused by recent development
[ladish.git] / daemon / jack_dispatch.c
blob7179c08087c735d4520d9f55058bbeec313a7170
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 of the graph dispatcher object
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 "jack_dispatch.h"
29 struct jack_dispatcher
31 graph_proxy_handle jack_graph;
32 ladish_graph_handle studio_graph;
33 uint64_t system_client_id;
34 ladish_client_handle system_capture_client;
35 ladish_client_handle system_playback_client;
38 #define dispatcher_ptr ((struct jack_dispatcher *)context)
40 static void clear(void * context)
42 lash_info("clear");
45 static void client_appeared(void * context, uint64_t id, const char * name)
47 ladish_client_handle client;
49 lash_info("client_appeared(%llu, %s)", (unsigned long long)id, name);
51 if (strcmp(name, "system") == 0)
53 dispatcher_ptr->system_client_id = id;
55 else
57 ladish_client_create(NULL, true, false, true, &client);
58 ladish_client_set_graph_name(client, ladish_graph_get_opath(dispatcher_ptr->studio_graph), name);
59 ladish_graph_add_client(dispatcher_ptr->studio_graph, client);
63 static void client_disappeared(void * context, uint64_t id)
65 lash_info("client_disappeared(%llu)", (unsigned long long)id);
67 if (id == dispatcher_ptr->system_client_id)
69 dispatcher_ptr->system_client_id = 0;
73 static 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)
75 lash_info("port_appeared(%llu, %llu, %s (%s, %s))", (unsigned long long)client_id, (unsigned long long)port_id, port_name, is_input ? "in" : "out", is_midi ? "midi" : "audio");
77 if (client_id == dispatcher_ptr->system_client_id)
79 if (!is_input && dispatcher_ptr->system_capture_client == NULL)
81 ladish_client_create(NULL, true, false, true, &dispatcher_ptr->system_capture_client);
82 ladish_client_set_graph_name(dispatcher_ptr->system_capture_client, ladish_graph_get_opath(dispatcher_ptr->studio_graph), "Hardware Capture");
83 ladish_graph_add_client(dispatcher_ptr->studio_graph, dispatcher_ptr->system_capture_client);
85 else if (is_input && dispatcher_ptr->system_playback_client == NULL)
87 ladish_client_create(NULL, true, false, true, &dispatcher_ptr->system_playback_client);
88 ladish_client_set_graph_name(dispatcher_ptr->system_playback_client, ladish_graph_get_opath(dispatcher_ptr->studio_graph), "Hardware Playback");
89 ladish_graph_add_client(dispatcher_ptr->studio_graph, dispatcher_ptr->system_playback_client);
94 static void port_disappeared(void * context, uint64_t client_id, uint64_t port_id)
96 lash_info("port_disappeared(%llu)", (unsigned long long)port_id);
99 static void ports_connected(void * context, uint64_t client1_id, uint64_t port1_id, uint64_t client2_id, uint64_t port2_id)
101 lash_info("ports_connected");
104 static void ports_disconnected(void * context, uint64_t client1_id, uint64_t port1_id, uint64_t client2_id, uint64_t port2_id)
106 lash_info("ports_disconnected");
109 #undef dispatcher_ptr
111 bool
112 ladish_jack_dispatcher_create(
113 graph_proxy_handle jack_graph,
114 ladish_graph_handle studio_graph,
115 ladish_jack_dispatcher_handle * handle_ptr)
117 struct jack_dispatcher * dispatcher_ptr;
119 dispatcher_ptr = malloc(sizeof(struct jack_dispatcher));
120 if (dispatcher_ptr == NULL)
122 lash_error("malloc() failed for struct jack_dispatcher");
123 return false;
126 dispatcher_ptr->jack_graph = jack_graph;
127 dispatcher_ptr->studio_graph = studio_graph;
128 dispatcher_ptr->system_client_id = 0;
129 dispatcher_ptr->system_capture_client = NULL;
130 dispatcher_ptr->system_playback_client = NULL;
132 if (!graph_proxy_attach(
133 jack_graph,
134 dispatcher_ptr,
135 clear,
136 client_appeared,
137 client_disappeared,
138 port_appeared,
139 port_disappeared,
140 ports_connected,
141 ports_disconnected))
143 free(dispatcher_ptr);
144 return false;
147 *handle_ptr = (ladish_jack_dispatcher_handle)dispatcher_ptr;
148 return true;
151 #define dispatcher_ptr ((struct jack_dispatcher *)handle)
153 void
154 ladish_jack_dispatcher_destroy(
155 ladish_jack_dispatcher_handle handle)
157 graph_proxy_detach((graph_proxy_handle)handle, dispatcher_ptr);
160 #undef dispatcher_ptr