From 245897bc6d71b9402ed5b31dcab04f8bbe37b879 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Sun, 11 Apr 2010 22:24:41 +0300 Subject: [PATCH] daemon: jmcore support in virtualizer --- daemon/cmd_load_studio.c | 6 +- daemon/graph.c | 101 +++++++++-- daemon/graph.h | 13 +- daemon/port.c | 23 ++- daemon/port.h | 3 + daemon/studio.c | 21 ++- daemon/virtualizer.c | 354 +++++++++++++++++++++++++++++---------- proxies/graph_proxy.c | 10 +- proxies/graph_proxy.h | 4 +- 9 files changed, 416 insertions(+), 119 deletions(-) diff --git a/daemon/cmd_load_studio.c b/daemon/cmd_load_studio.c index fbc6907f..5a5e0e51 100644 --- a/daemon/cmd_load_studio.c +++ b/daemon/cmd_load_studio.c @@ -370,7 +370,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr) log_info("studio port \"%s\" with uuid %s", attr[1], attr[3]); - context_ptr->port = ladish_graph_find_port_by_uuid(g_studio.jack_graph, uuid); + context_ptr->port = ladish_graph_find_port_by_uuid(g_studio.jack_graph, uuid, false); if (context_ptr->port == NULL) { log_error("studio client with non-jack port %s", attr[3]); @@ -431,7 +431,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr) log_info("studio connection between port %s and port %s", attr[1], attr[3]); - port1 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid); + port1 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid, false); if (port1 == NULL) { log_error("studio client with unknown port %s", attr[1]); @@ -439,7 +439,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr) return; } - port2 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2); + port2 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2, false); if (port2 == NULL) { log_error("studio client with unknown port %s", attr[3]); diff --git a/daemon/graph.c b/daemon/graph.c index 949110a2..02c16408 100644 --- a/daemon/graph.c +++ b/daemon/graph.c @@ -674,9 +674,12 @@ ladish_graph_find_port( struct list_head * node_ptr; struct ladish_graph_port * port_ptr; + //log_info("searching port %p", port); + list_for_each(node_ptr, &graph_ptr->ports) { port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph); + //log_info("checking port %s:%s, %p", port_ptr->client_ptr->name, port_ptr->name, port_ptr->port); if (port_ptr->port == port) { return port_ptr; @@ -686,6 +689,34 @@ ladish_graph_find_port( return NULL; } +static +struct ladish_graph_port * +ladish_graph_find_port_by_jack_id_internal( + struct ladish_graph * graph_ptr, + uint64_t port_id, + bool room, + bool studio) +{ + struct list_head * node_ptr; + struct ladish_graph_port * port_ptr; + + ASSERT(room || studio); + + list_for_each(node_ptr, &graph_ptr->ports) + { + port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph); + //log_info("checking jack port id of port %s:%s, %p", port_ptr->client_ptr->name, port_ptr->name, port_ptr->port); + if ((studio && ladish_port_get_jack_id(port_ptr->port) == port_id) || + (room && port_ptr->link && ladish_port_get_jack_id_room(port_ptr->port) == port_id)) + { + //log_info("found"); + return port_ptr; + } + } + + return NULL; +} + #if 0 static struct ladish_graph_port * @@ -961,6 +992,11 @@ const char * ladish_graph_get_opath(ladish_graph_handle graph_handle) return graph_ptr->opath; } +const char * ladish_graph_get_description(ladish_graph_handle graph_handle) +{ + return graph_ptr->opath != NULL ? graph_ptr->opath : "JACK"; +} + void ladish_graph_set_connection_handlers( ladish_graph_handle graph_handle, @@ -1517,16 +1553,36 @@ ladish_client_handle ladish_graph_find_client_by_uuid(ladish_graph_handle graph_ return NULL; } -ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid) +ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, bool use_link_override_uuids) { struct list_head * node_ptr; struct ladish_graph_port * port_ptr; uuid_t current_uuid; + /* char uuid1_str[37]; */ + /* char uuid2_str[37]; */ + + /* log_info("searching by uuid for port in graph %s", ladish_graph_get_description(graph_handle)); */ + /* uuid_unparse(uuid, uuid1_str); */ list_for_each(node_ptr, &graph_ptr->ports) { port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph); + + /* if (port_ptr->link) */ + /* { */ + /* uuid_unparse(port_ptr->link_uuid_override, uuid2_str); */ + /* log_info("comparing link uuid %s with %s", uuid2_str, uuid1_str); */ + /* } */ + + if (port_ptr->link && uuid_compare(port_ptr->link_uuid_override, uuid) == 0) + { + /* log_info("found port %p of client '%s'", port_ptr->port, port_ptr->client_ptr->name); */ + return port_ptr->port; + } + ladish_port_get_uuid(port_ptr->port, current_uuid); + /* uuid_unparse(current_uuid, uuid2_str); */ + /* log_info("comparing port uuid %s with %s", uuid2_str, uuid1_str); */ if (uuid_compare(current_uuid, uuid) == 0) { return port_ptr->port; @@ -1601,21 +1657,17 @@ ladish_client_handle ladish_graph_find_client_by_jack_id(ladish_graph_handle gra return NULL; } -ladish_port_handle ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_handle, uint64_t port_id) +ladish_port_handle ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_handle, uint64_t port_id, bool room, bool studio) { - struct list_head * node_ptr; struct ladish_graph_port * port_ptr; - list_for_each(node_ptr, &graph_ptr->ports) + port_ptr = ladish_graph_find_port_by_jack_id_internal(graph_ptr, port_id, room, studio); + if (port_ptr == NULL) { - port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_graph); - if (ladish_port_get_jack_id(port_ptr->port) == port_id) - { - return port_ptr->port; - } + return NULL; } - return NULL; + return port_ptr->port; } ladish_client_handle @@ -1635,6 +1687,25 @@ ladish_graph_remove_port( return port_ptr->client_ptr->client; } +ladish_client_handle +ladish_graph_remove_port_by_jack_id( + ladish_graph_handle graph_handle, + uint64_t jack_port_id, + bool room, + bool studio) +{ + struct ladish_graph_port * port_ptr; + + port_ptr = ladish_graph_find_port_by_jack_id_internal(graph_ptr, jack_port_id, room, studio); + if (port_ptr == NULL) + { + return NULL; + } + + ladish_graph_remove_port_internal(graph_ptr, port_ptr->client_ptr, port_ptr); + return port_ptr->client_ptr->client; +} + bool ladish_graph_rename_client( ladish_graph_handle graph_handle, @@ -1885,6 +1956,16 @@ void ladish_graph_get_port_uuid(ladish_graph_handle graph_handle, ladish_port_ha uuid_copy(uuid_ptr, port_ptr->link_uuid_override); } +const char * ladish_graph_get_port_name(ladish_graph_handle graph_handle, ladish_port_handle port) +{ + struct ladish_graph_port * port_ptr; + + port_ptr = ladish_graph_find_port(graph_ptr, port); + ASSERT(port_ptr != NULL); + + return port_ptr->name; +} + bool ladish_graph_iterate_nodes( ladish_graph_handle graph_handle, diff --git a/daemon/graph.h b/daemon/graph.h index d0760211..369d2510 100644 --- a/daemon/graph.h +++ b/daemon/graph.h @@ -52,6 +52,7 @@ bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest, bool s void ladish_graph_destroy(ladish_graph_handle graph_handle); const char * ladish_graph_get_opath(ladish_graph_handle graph_handle); +const char * ladish_graph_get_description(ladish_graph_handle graph_handle); void ladish_graph_set_connection_handlers( @@ -92,6 +93,13 @@ ladish_graph_remove_port( ladish_graph_handle graph_handle, ladish_port_handle port_handle); +ladish_client_handle +ladish_graph_remove_port_by_jack_id( + ladish_graph_handle graph_handle, + uint64_t jack_port_id, + bool room, + bool studio); + bool ladish_graph_rename_port( ladish_graph_handle graph_handle, @@ -128,13 +136,14 @@ ladish_graph_find_connection( ladish_client_handle ladish_graph_find_client_by_id(ladish_graph_handle graph_handle, uint64_t client_id); ladish_port_handle ladish_graph_find_port_by_id(ladish_graph_handle graph_handle, uint64_t port_id); ladish_client_handle ladish_graph_find_client_by_jack_id(ladish_graph_handle graph_handle, uint64_t client_id); -ladish_port_handle ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_handle, uint64_t port_id); +ladish_port_handle ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_handle, uint64_t port_id, bool room, bool studio); ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_handle, const char * name); ladish_port_handle ladish_graph_find_port_by_name(ladish_graph_handle graph_handle, ladish_client_handle client_handle, const char * name); ladish_client_handle ladish_graph_find_client_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid); -ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid); +ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, bool use_link_override_uuids); ladish_client_handle ladish_graph_get_port_client(ladish_graph_handle graph_handle, ladish_port_handle port_handle); const char * ladish_graph_get_client_name(ladish_graph_handle graph_handle, ladish_client_handle client_handle); +const char * ladish_graph_get_port_name(ladish_graph_handle graph, ladish_port_handle port); bool ladish_graph_is_client_empty(ladish_graph_handle graph_handle, ladish_client_handle client_handle); bool ladish_graph_is_client_looks_empty(ladish_graph_handle graph_handle, ladish_client_handle client_handle); bool ladish_graph_is_port_present(ladish_graph_handle graph_handle, ladish_port_handle port_handle); diff --git a/daemon/port.c b/daemon/port.c index a82c6f9a..bb3f9f67 100644 --- a/daemon/port.c +++ b/daemon/port.c @@ -33,6 +33,7 @@ struct ladish_port uuid_t uuid; /* The UUID of the port */ bool link; /* Whether the port is studio-room link port */ uint64_t jack_id; /* JACK port ID. */ + uint64_t jack_id_room; /* JACK port ID in room. valid only for link ports */ ladish_dict_handle dict; }; @@ -69,6 +70,7 @@ ladish_port_create( } port_ptr->jack_id = 0; + port_ptr->jack_id_room = 0; port_ptr->link = link; port_ptr->refcount = 0; @@ -104,7 +106,7 @@ void ladish_port_get_uuid(ladish_port_handle port_handle, uuid_t uuid) void ladish_port_set_jack_id(ladish_port_handle port_handle, uint64_t jack_id) { - log_info("port jack id set to %"PRIu64, jack_id); + log_info("port %p jack id set to %"PRIu64, port_handle, jack_id); port_ptr->jack_id = jack_id; } @@ -113,6 +115,25 @@ uint64_t ladish_port_get_jack_id(ladish_port_handle port_handle) return port_ptr->jack_id; } +void ladish_port_set_jack_id_room(ladish_port_handle port_handle, uint64_t jack_id) +{ + log_info("port %p jack id (room) set to %"PRIu64, port_handle, jack_id); + ASSERT(port_ptr->link); + port_ptr->jack_id_room = jack_id; +} + +uint64_t ladish_port_get_jack_id_room(ladish_port_handle port_handle) +{ + if (port_ptr->link) + { + return port_ptr->jack_id_room; + } + else + { + return port_ptr->jack_id; + } +} + void ladish_port_add_ref(ladish_port_handle port_handle) { port_ptr->refcount++; diff --git a/daemon/port.h b/daemon/port.h index f274a4ec..9f84993b 100644 --- a/daemon/port.h +++ b/daemon/port.h @@ -36,8 +36,11 @@ bool ladish_port_create_copy(ladish_port_handle port_handle, ladish_port_handle void ladish_port_destroy(ladish_port_handle port_handle); ladish_dict_handle ladish_port_get_dict(ladish_port_handle port_handle); void ladish_port_get_uuid(ladish_port_handle port_handle, uuid_t uuid); + void ladish_port_set_jack_id(ladish_port_handle port_handle, uint64_t jack_id); uint64_t ladish_port_get_jack_id(ladish_port_handle port_handle); +void ladish_port_set_jack_id_room(ladish_port_handle port_handle, uint64_t jack_id); +uint64_t ladish_port_get_jack_id_room(ladish_port_handle port_handle); void ladish_port_add_ref(ladish_port_handle port_handle); void ladish_port_del_ref(ladish_port_handle port_handle); diff --git a/daemon/studio.c b/daemon/studio.c index 325164ce..72de2a8a 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -922,9 +922,11 @@ add_room_ports( { uuid_t uuid_in_studio; uuid_t uuid_in_room; - char input_str[37]; - char output_str[37]; + char uuid_in_studio_str[37]; + char uuid_in_room_str[37]; bool room_input; + const char * input_port; + const char * output_port; //log_info("Studio room port \"%s\"", port_name); @@ -955,18 +957,23 @@ add_room_ports( ladish_graph_get_port_uuid(add_room_ports_context_ptr->room_graph, port_handle, uuid_in_room); ladish_graph_get_port_uuid(g_studio.studio_graph, port_handle, uuid_in_studio); + uuid_unparse(uuid_in_room, uuid_in_room_str); + uuid_unparse(uuid_in_studio, uuid_in_studio_str); + if (room_input) { - uuid_unparse(uuid_in_room, input_str); - uuid_unparse(uuid_in_studio, output_str); + input_port = uuid_in_room_str; + output_port = uuid_in_studio_str; + log_info("room input port %s is linked to studio output port %s", input_port, output_port); } else { - uuid_unparse(uuid_in_room, output_str); - uuid_unparse(uuid_in_studio, input_str); + input_port = uuid_in_studio_str; + output_port = uuid_in_room_str; + log_info("studio input port %s is linked to room output port %s", input_port, output_port); } - if (!jmcore_proxy_create_link(port_type == JACKDBUS_PORT_TYPE_MIDI, input_str, output_str)) + if (!jmcore_proxy_create_link(port_type == JACKDBUS_PORT_TYPE_MIDI, input_port, output_port)) { log_error("jmcore_proxy_create_link() failed."); return false; diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index 1899ec5c..f0da0170 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -27,6 +27,7 @@ #include "virtualizer.h" #include "../dbus_constants.h" #include "../proxies/a2j_proxy.h" +#include "../proxies/jmcore_proxy.h" #include "procfs.h" #include "app_supervisor.h" #include "studio_internal.h" @@ -51,9 +52,6 @@ UUID_DEFINE(g_system_playback_uuid,0xB2,0xA0,0xBB,0x06,0x28,0xD8,0x4B,0xFE,0x95, /* be23a242-e2b2-11de-b795-002618af5e42 */ UUID_DEFINE(g_a2j_uuid,0xBE,0x23,0xA2,0x42,0xE2,0xB2,0x11,0xDE,0xB7,0x95,0x00,0x26,0x18,0xAF,0x5E,0x42); -/* 25836767-2611-4268-9f33-a8a76ce8353f */ -UUID_DEFINE(g_jmcore_uuid,0x25,0x83,0x67,0x67,0x26,0x11,0x42,0x68,0x9F,0x33,0xA8,0xA7,0x6C,0xE8,0x35,0x3F); - struct app_find_context { pid_t pid; @@ -102,44 +100,108 @@ bool get_app_name_from_supervisor(void * context, ladish_graph_handle graph, lad #undef app_find_context_ptr -char * get_app_name(struct virtualizer * virtualizer_ptr, uint64_t client_id, pid_t * app_pid_ptr, ladish_graph_handle * graph_ptr) +char * get_app_name(struct virtualizer * virtualizer_ptr, uint64_t client_id, pid_t pid, ladish_graph_handle * graph_ptr) { - int64_t pid; struct app_find_context context; - if (!graph_proxy_get_client_pid(virtualizer_ptr->jack_graph_proxy, client_id, &pid)) - { - log_info("client %"PRIu64" pid is unknown", client_id); - *app_pid_ptr = 0; - return NULL; - } - - log_info("client pid is %"PRId64, pid); - context.pid = (pid_t)pid; context.app_name = NULL; context.graph = NULL; - if (pid != 0) /* skip internal clients that will match the pending clients in the graph, both have zero pid */ - { - studio_iterate_virtual_graphs(&context, get_app_name_from_supervisor); - } + studio_iterate_virtual_graphs(&context, get_app_name_from_supervisor); if (context.app_name != NULL) { ASSERT(context.graph != NULL); - ASSERT(context.pid != 0); *graph_ptr = context.graph; - *app_pid_ptr = context.pid; - } - else - { - *app_pid_ptr = 0; } return context.app_name; } +struct find_link_port_context +{ + uuid_t uuid; + uint64_t jack_id; + ladish_port_handle port; + ladish_graph_handle graph; +}; + +#define find_link_port_context_ptr ((struct find_link_port_context *)context) + +static bool find_link_port_vgraph_callback_by_uuid(void * context, ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) +{ + ladish_port_handle port; + + port = ladish_graph_find_port_by_uuid(graph, find_link_port_context_ptr->uuid, true); + if (port != NULL) + { + find_link_port_context_ptr->port = port; + find_link_port_context_ptr->graph = graph; + return false; + } + + return true; /* continue vgraph iteration */ +} + +static bool find_link_port_vgraph_callback_by_jack_id(void * context, ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) +{ + ladish_port_handle port; + bool room; + + log_info("searching link port with jack id %"PRIu64" in graph %s", find_link_port_context_ptr->jack_id, ladish_graph_get_description(graph)); + + room = graph != g_studio.studio_graph; + + port = ladish_graph_find_port_by_jack_id(graph, find_link_port_context_ptr->jack_id, room, !room); + if (port != NULL) + { + find_link_port_context_ptr->port = port; + find_link_port_context_ptr->graph = graph; + return false; + } + + return true; /* continue vgraph iteration */ +} + +#undef find_link_port_context_ptr + +static ladish_graph_handle find_link_port_vgraph_by_uuid(struct virtualizer * virtualizer_ptr, const char * port_name, ladish_port_handle * port_ptr) +{ + struct find_link_port_context context; + + uuid_parse(port_name, context.uuid); + context.graph = NULL; + context.port = NULL; + + studio_iterate_virtual_graphs(&context, find_link_port_vgraph_callback_by_uuid); + + if (port_ptr != NULL && context.graph != NULL) + { + *port_ptr = context.port; + } + + return context.graph; +} + +static ladish_graph_handle find_link_port_vgraph_by_jack_id(struct virtualizer * virtualizer_ptr, uint64_t jack_id, ladish_port_handle * port_ptr) +{ + struct find_link_port_context context; + + context.jack_id = jack_id; + context.graph = NULL; + context.port = NULL; + + studio_iterate_virtual_graphs(&context, find_link_port_vgraph_callback_by_jack_id); + + if (port_ptr != NULL && context.graph != NULL) + { + *port_ptr = context.port; + } + + return context.graph; +} + static bool lookup_port( @@ -152,7 +214,7 @@ lookup_port( ladish_client_handle jclient; ladish_graph_handle vgraph; - port = ladish_graph_find_port_by_jack_id(virtualizer_ptr->jack_graph, port_id); + port = ladish_graph_find_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true); if (port == NULL) { log_error("Unknown JACK port with id %"PRIu64" (dis)connected", port_id); @@ -169,8 +231,14 @@ lookup_port( vgraph = ladish_client_get_vgraph(jclient); if (vgraph == NULL) { - log_error("port %"PRIu64" of jack client without vgraph was (dis)connected"); - return false; + vgraph = find_link_port_vgraph_by_jack_id(virtualizer_ptr, port_id, NULL); + if (vgraph == NULL) + { + log_error("Cannot find vgraph for (dis)connected jmcore port"); + return false; + } + + log_info("link port found in graph %s", ladish_graph_get_description(vgraph)); } *port_ptr = port; @@ -194,44 +262,68 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name) const char * name; pid_t pid; ladish_graph_handle graph; + bool jmcore; log_info("client_appeared(%"PRIu64", %s)", id, jack_name); a2j_name = a2j_proxy_get_jack_client_name_cached(); is_a2j = a2j_name != NULL && strcmp(a2j_name, jack_name) == 0; - app_name = get_app_name(virtualizer_ptr, id, &pid, &graph); - if (app_name != NULL) + name = jack_name; + app_name = NULL; + jmcore = false; + + if (!graph_proxy_get_client_pid(virtualizer_ptr->jack_graph_proxy, id, &pid)) { - log_info("app name is '%s'", app_name); - name = app_name; + log_info("client %"PRIu64" pid is unknown", id); } else { - name = jack_name; - } + log_info("client pid is %"PRId64, pid); - if (is_a2j) - { - client = ladish_graph_find_client_by_uuid(virtualizer_ptr->jack_graph, g_a2j_uuid); - } - else - { - client = ladish_graph_find_client_by_name(virtualizer_ptr->jack_graph, name); - } - - if (client != NULL) - { - log_info("found existing client"); - if (ladish_client_get_jack_id(client) != 0) + if (pid != 0) /* skip internal clients that will match the pending clients in the graph, both have zero pid */ { - log_error("Ignoring client with duplicate name '%s' ('%s')", name, jack_name); - goto free_app_name; + jmcore = pid == jmcore_proxy_get_pid_cached(); + if (jmcore) + { + log_info("jmcore client appeared"); + } + else + { + app_name = get_app_name(virtualizer_ptr, id, pid, &graph); + if (app_name != NULL) + { + log_info("app name is '%s'", app_name); + name = app_name; + } + } + } + } + + if (!jmcore) + { + if (is_a2j) + { + client = ladish_graph_find_client_by_uuid(virtualizer_ptr->jack_graph, g_a2j_uuid); + } + else + { + client = ladish_graph_find_client_by_name(virtualizer_ptr->jack_graph, name); } - ladish_client_set_jack_id(client, id); - ladish_graph_show_client(virtualizer_ptr->jack_graph, client); - goto done; + if (client != NULL) + { + log_info("found existing client"); + if (ladish_client_get_jack_id(client) != 0) + { + log_error("Ignoring client with duplicate name '%s' ('%s')", name, jack_name); + goto free_app_name; + } + + ladish_client_set_jack_id(client, id); + ladish_graph_show_client(virtualizer_ptr->jack_graph, client); + goto done; + } } if (!ladish_client_create(is_a2j ? g_a2j_uuid : NULL, &client)) @@ -261,6 +353,11 @@ done: ladish_client_set_vgraph(client, graph); virtualizer_ptr->our_clients_count++; } + else if (jmcore) + { + ladish_client_set_pid(client, pid); + ASSERT(ladish_client_get_vgraph(client) == NULL); + } else { /* unknown and internal clients appear in the studio graph */ @@ -290,6 +387,13 @@ static void client_disappeared(void * context, uint64_t id) log_info("client disappeared: '%s'", ladish_graph_get_client_name(virtualizer_ptr->jack_graph, client)); + if (ladish_client_get_vgraph(client) == NULL) + { /* remove jmcore clients, the are not persisted in the jack graph */ + ladish_graph_remove_client(virtualizer_ptr->jack_graph, client); + ladish_client_destroy(client); + return; + } + pid = ladish_client_get_pid(client); if (pid != 0) { @@ -342,6 +446,13 @@ port_appeared( log_info("port_appeared(%"PRIu64", %"PRIu64", %s (%s, %s))", client_id, port_id, real_jack_port_name, is_input ? "in" : "out", is_midi ? "midi" : "audio"); + type = is_midi ? JACKDBUS_PORT_TYPE_MIDI : JACKDBUS_PORT_TYPE_AUDIO; + flags = is_input ? JACKDBUS_PORT_FLAG_INPUT : JACKDBUS_PORT_FLAG_OUTPUT; + if (is_terminal) + { + flags |= JACKDBUS_PORT_FLAG_TERMINAL; + } + /********************/ /* gather info about the appeared port */ @@ -349,11 +460,50 @@ port_appeared( if (jack_client == NULL) { log_error("Port of unknown JACK client with id %"PRIu64" appeared", client_id); - goto fail; + goto exit; } /* find the virtual graph that owns the app that owns the client that owns the appeared port */ vgraph = ladish_client_get_vgraph(jack_client); + if (vgraph == NULL) + { + vgraph = find_link_port_vgraph_by_uuid(virtualizer_ptr, real_jack_port_name, &port); + if (vgraph == NULL) + { + log_error("Cannot find vgraph for appeared jmcore port '%s'", real_jack_port_name); + goto exit; + } + + /* jmcore port appeared */ + + log_info("jmcore port appeared in vgraph %s", ladish_graph_get_description(vgraph)); + + if (!ladish_graph_add_port(virtualizer_ptr->jack_graph, jack_client, port, real_jack_port_name, type, flags, false)) + { + log_error("ladish_graph_add_port() failed."); + goto free_alsa_names; + } + + if (vgraph == g_studio.studio_graph) + { + ladish_port_set_jack_id(port, port_id); + } + else + { + ladish_port_set_jack_id_room(port, port_id); + } + + vclient = ladish_graph_get_port_client(vgraph, port); + if (vclient == NULL) + { + log_error("link port client not found in vgraph %s", ladish_graph_get_description(vgraph)); + ASSERT_NO_PASS; + goto exit; + } + + ladish_graph_show_port(vgraph, port); + goto exit; + } ladish_client_get_uuid(jack_client, client_uuid); is_a2j = uuid_compare(client_uuid, g_a2j_uuid) == 0; @@ -385,13 +535,6 @@ port_appeared( jack_client_name = ladish_graph_get_client_name(virtualizer_ptr->jack_graph, jack_client); - type = is_midi ? JACKDBUS_PORT_TYPE_MIDI : JACKDBUS_PORT_TYPE_AUDIO; - flags = is_input ? JACKDBUS_PORT_FLAG_INPUT : JACKDBUS_PORT_FLAG_OUTPUT; - if (is_terminal) - { - flags |= JACKDBUS_PORT_FLAG_TERMINAL; - } - /********************/ /* search (by name) the appeared port in jack graph @@ -564,7 +707,7 @@ free_alsa_names: free(alsa_port_name); } -fail: +exit: return; } @@ -573,8 +716,9 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i ladish_client_handle client; ladish_port_handle port; ladish_graph_handle vgraph; + bool jmcore; - log_info("port_disappeared(%"PRIu64")", port_id); + log_info("port_disappeared(%"PRIu64", %"PRIu64")", client_id, port_id); client = ladish_graph_find_client_by_jack_id(virtualizer_ptr->jack_graph, client_id); if (client == NULL) @@ -583,37 +727,63 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i return; } - /* find the virtual graph that owns the app that owns the client that owns the disappeared port */ - vgraph = ladish_client_get_vgraph(client); - - port = ladish_graph_find_port_by_jack_id(virtualizer_ptr->jack_graph, port_id); + port = ladish_graph_find_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true); if (port == NULL) { log_error("Unknown JACK port with id %"PRIu64" disappeared", port_id); return; } + /* find the virtual graph that owns the app that owns the client that owns the disappeared port */ + jmcore = false; + vgraph = ladish_client_get_vgraph(client); + if (vgraph == NULL) + { + vgraph = find_link_port_vgraph_by_uuid(virtualizer_ptr, ladish_graph_get_port_name(virtualizer_ptr->jack_graph, port), NULL); + if (vgraph == NULL) + { + log_error("Cannot find vgraph for disappeared jmcore port"); + } + else + { + jmcore = true; + ladish_graph_remove_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true); + } + } + if (true) /* if client is supposed to be persisted */ { - ladish_port_set_jack_id(port, 0); - ladish_graph_hide_port(virtualizer_ptr->jack_graph, port); - ladish_graph_hide_port(vgraph, port); - client = ladish_graph_get_port_client(vgraph, port); - if (ladish_graph_is_client_looks_empty(vgraph, client)) + if (!jmcore) { + ladish_port_set_jack_id(port, 0); + ladish_graph_hide_port(virtualizer_ptr->jack_graph, port); + } + if (vgraph != NULL) + { + ladish_graph_hide_port(vgraph, port); + client = ladish_graph_get_port_client(vgraph, port); + if (ladish_graph_is_client_looks_empty(vgraph, client)) + { ladish_graph_hide_client(vgraph, client); + } } } else { - ladish_graph_remove_port(virtualizer_ptr->jack_graph, port); - - client = ladish_graph_remove_port(vgraph, port); - if (client != NULL) + if (!jmcore) { - if (ladish_graph_is_client_empty(vgraph, client)) + ladish_graph_remove_port(virtualizer_ptr->jack_graph, port); + } + + if (vgraph != NULL) + { + client = ladish_graph_remove_port(vgraph, port); + if (client != NULL) { - ladish_graph_remove_client(vgraph, client); + if (ladish_graph_is_client_empty(vgraph, client)) + { + ladish_graph_remove_client(vgraph, client); + } } } } @@ -637,7 +807,7 @@ static void port_renamed(void * context, uint64_t client_id, uint64_t port_id, c /* find the virtual graph that owns the app that owns the client that owns the renamed port */ vgraph = ladish_client_get_vgraph(client); - port = ladish_graph_find_port_by_jack_id(virtualizer_ptr->jack_graph, port_id); + port = ladish_graph_find_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true); if (port == NULL) { log_error("Unknown JACK port with id %"PRIu64" was renamed", port_id); @@ -663,14 +833,15 @@ static bool ports_connect_request(void * context, ladish_graph_handle graph_hand ASSERT(ladish_graph_get_opath(graph_handle)); /* studio or room virtual graph */ log_info("virtualizer: ports connect request"); - port1_id = ladish_port_get_jack_id(port1); - port2_id = ladish_port_get_jack_id(port2); - - if (port1_id == 0 || port2_id == 0) + if (graph_handle == g_studio.studio_graph) { - /* TODO */ - log_error("connecting room-studio link ports is not implemented yet"); - return false; + port1_id = ladish_port_get_jack_id(port1); + port2_id = ladish_port_get_jack_id(port2); + } + else + { + port1_id = ladish_port_get_jack_id_room(port1); + port2_id = ladish_port_get_jack_id_room(port2); } graph_proxy_connect_ports(virtualizer_ptr->jack_graph_proxy, port1_id, port2_id); @@ -695,14 +866,15 @@ static bool ports_disconnect_request(void * context, ladish_graph_handle graph_h return false; } - port1_id = ladish_port_get_jack_id(port1); - port2_id = ladish_port_get_jack_id(port2); - - if (port1_id == 0 || port2_id == 0) + if (graph_handle == g_studio.studio_graph) { - /* TODO */ - log_error("disconnecting room-studio link ports is not implemented yet"); - return false; + port1_id = ladish_port_get_jack_id(port1); + port2_id = ladish_port_get_jack_id(port2); + } + else + { + port1_id = ladish_port_get_jack_id_room(port1); + port2_id = ladish_port_get_jack_id_room(port2); } graph_proxy_disconnect_ports(virtualizer_ptr->jack_graph_proxy, port1_id, port2_id); diff --git a/proxies/graph_proxy.c b/proxies/graph_proxy.c index 77a17210..6ff45097 100644 --- a/proxies/graph_proxy.c +++ b/proxies/graph_proxy.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009 Nedko Arnaudov + * Copyright (C) 2009,2010 Nedko Arnaudov * ************************************************************************** * This file contains implementation graph object that is backed through D-Bus @@ -951,14 +951,18 @@ graph_proxy_dict_entry_drop( return true; } -bool graph_proxy_get_client_pid(graph_proxy_handle graph, uint64_t client_id, int64_t * pid_ptr) +bool graph_proxy_get_client_pid(graph_proxy_handle graph, uint64_t client_id, pid_t * pid_ptr) { - if (!dbus_call(graph_ptr->service, graph_ptr->object, JACKDBUS_IFACE_PATCHBAY, "GetClientPID", "t", &client_id, "x", pid_ptr)) + int64_t pid; + + if (!dbus_call(graph_ptr->service, graph_ptr->object, JACKDBUS_IFACE_PATCHBAY, "GetClientPID", "t", &client_id, "x", &pid)) { log_error("GetClientPID() failed."); return false; } + *pid_ptr = pid; + return true; } diff --git a/proxies/graph_proxy.h b/proxies/graph_proxy.h index f19a5f58..45add1a9 100644 --- a/proxies/graph_proxy.h +++ b/proxies/graph_proxy.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009 Nedko Arnaudov + * Copyright (C) 2009,2010 Nedko Arnaudov * ************************************************************************** * This file contains interface to graph object that is backed through D-Bus @@ -110,7 +110,7 @@ graph_proxy_dict_entry_drop( uint64_t object_id, const char * key); -bool graph_proxy_get_client_pid(graph_proxy_handle graph, uint64_t client_id, int64_t * pid_ptr); +bool graph_proxy_get_client_pid(graph_proxy_handle graph, uint64_t client_id, pid_t * pid_ptr); #if 0 { /* Adjust editor indent */