From 31f6cb939bfd3e03d4b044ba1b6f445ee108953c Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Sun, 11 Apr 2010 16:45:06 +0300 Subject: [PATCH] daemon: room-studio port creation through jmcore virtualizer does not know about jmcore yet --- daemon/cmd_load_studio.c | 2 +- daemon/cmd_save_studio.c | 8 ++-- daemon/control.c | 2 +- daemon/graph.c | 32 +++++++++++--- daemon/graph.h | 5 ++- daemon/port.c | 16 ++++--- daemon/port.h | 4 +- daemon/room.c | 3 +- daemon/studio.c | 57 ++++++++++++++++++++++-- daemon/virtualizer.c | 5 ++- proxies/jmcore_proxy.c | 95 ++++++++++++++++++++++++++++++++++++++++ proxies/jmcore_proxy.h | 39 +++++++++++++++++ wscript | 1 + 13 files changed, 246 insertions(+), 23 deletions(-) create mode 100644 proxies/jmcore_proxy.c create mode 100644 proxies/jmcore_proxy.h diff --git a/daemon/cmd_load_studio.c b/daemon/cmd_load_studio.c index 8c8ec2ed..fbc6907f 100644 --- a/daemon/cmd_load_studio.c +++ b/daemon/cmd_load_studio.c @@ -328,7 +328,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr) log_info("jack port \"%s\" with uuid %s", attr[1], attr[3]); - if (!ladish_port_create(uuid, &context_ptr->port)) + if (!ladish_port_create(uuid, false, &context_ptr->port)) { log_error("ladish_port_create() failed."); return; diff --git a/daemon/cmd_save_studio.c b/daemon/cmd_save_studio.c index 7cb2126f..a2b4c4fe 100644 --- a/daemon/cmd_save_studio.c +++ b/daemon/cmd_save_studio.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009 Nedko Arnaudov + * Copyright (C) 2009,2010 Nedko Arnaudov * ************************************************************************** * This file contains implementation of the "save studio" command @@ -849,7 +849,7 @@ static bool run(void * command_context) save_context.fd = fd; - if (!ladish_graph_iterate_nodes(g_studio.jack_graph, &save_context, save_jack_client_begin, save_jack_port, save_jack_client_end)) + if (!ladish_graph_iterate_nodes(g_studio.jack_graph, true, &save_context, save_jack_client_begin, save_jack_port, save_jack_client_end)) { log_error("ladish_graph_iterate_nodes() failed"); goto close; @@ -870,7 +870,7 @@ static bool run(void * command_context) goto close; } - if (!ladish_graph_iterate_nodes(g_studio.studio_graph, &save_context, save_studio_client_begin, save_studio_port, save_studio_client_end)) + if (!ladish_graph_iterate_nodes(g_studio.studio_graph, true, &save_context, save_studio_client_begin, save_studio_port, save_studio_client_end)) { log_error("ladish_graph_iterate_nodes() failed"); goto close; @@ -886,7 +886,7 @@ static bool run(void * command_context) goto close; } - if (!ladish_graph_iterate_connections(g_studio.studio_graph, &save_context, save_studio_connection)) + if (!ladish_graph_iterate_connections(g_studio.studio_graph, true, &save_context, save_studio_connection)) { log_error("ladish_graph_iterate_connections() failed"); goto close; diff --git a/daemon/control.c b/daemon/control.c index 2de003c8..802ba94c 100644 --- a/daemon/control.c +++ b/daemon/control.c @@ -140,7 +140,7 @@ create_room_template_port( ASSERT(!(playback && (flags & JACKDBUS_PORT_FLAG_OUTPUT) != 0)); /* but not both */ client = playback ? room_descriptor_ptr->playback : room_descriptor_ptr->capture; - if (!ladish_port_create(uuid_ptr, &port)) + if (!ladish_port_create(uuid_ptr, true, &port)) { log_error("Creation of room template \"%s\" %s port \"%s\" failed.", room_descriptor_ptr->name, playback ? "playback" : "capture", name); return false; diff --git a/daemon/graph.c b/daemon/graph.c index 5e9d5fe5..949110a2 100644 --- a/daemon/graph.c +++ b/daemon/graph.c @@ -41,6 +41,8 @@ struct ladish_graph_port uint64_t id; ladish_port_handle port; bool hidden; + bool link; + uuid_t link_uuid_override; }; struct ladish_graph_client @@ -1258,6 +1260,12 @@ ladish_graph_add_port( ladish_port_add_ref(port_ptr->port); port_ptr->hidden = true; + port_ptr->link = ladish_port_is_link(port_handle); + if (port_ptr->link) + { + uuid_generate(port_ptr->link_uuid_override); + } + port_ptr->client_ptr = client_ptr; list_add_tail(&port_ptr->siblings_client, &client_ptr->ports); list_add_tail(&port_ptr->siblings_graph, &graph_ptr->ports); @@ -1866,9 +1874,21 @@ void ladish_graph_hide_non_virtual(ladish_graph_handle graph_handle) } } +void ladish_graph_get_port_uuid(ladish_graph_handle graph_handle, ladish_port_handle port, uuid_t uuid_ptr) +{ + struct ladish_graph_port * port_ptr; + + port_ptr = ladish_graph_find_port(graph_ptr, port); + ASSERT(port_ptr != NULL); + ASSERT(port_ptr->link); + + uuid_copy(uuid_ptr, port_ptr->link_uuid_override); +} + bool ladish_graph_iterate_nodes( ladish_graph_handle graph_handle, + bool skip_hidden, void * callback_context, bool (* client_begin_callback)( @@ -1903,7 +1923,7 @@ ladish_graph_iterate_nodes( { client_ptr = list_entry(client_node_ptr, struct ladish_graph_client, siblings); - if (client_ptr->hidden) + if (skip_hidden && client_ptr->hidden) { continue; } @@ -1929,7 +1949,7 @@ ladish_graph_iterate_nodes( { port_ptr = list_entry(port_node_ptr, struct ladish_graph_port, siblings_client); - if (port_ptr->hidden) + if (skip_hidden && port_ptr->hidden) { continue; } @@ -1963,6 +1983,7 @@ ladish_graph_iterate_nodes( bool ladish_graph_iterate_connections( ladish_graph_handle graph_handle, + bool skip_hidden, void * callback_context, bool (* callback)(void * context, ladish_port_handle port1_handle, ladish_port_handle port2_handle, ladish_dict_handle dict)) { @@ -1973,7 +1994,7 @@ ladish_graph_iterate_connections( { connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings); - if (connection_ptr->hidden) + if (skip_hidden && connection_ptr->hidden) { continue; } @@ -2105,7 +2126,7 @@ ladish_graph_copy_port_callback( return false; } - if (!ladish_graph_add_port(context, client_iteration_context_ptr, copy, port_name, port_type, port_flags, false)) + if (!ladish_graph_add_port(context, client_iteration_context_ptr, copy, port_name, port_type, port_flags, true)) { ladish_port_destroy(copy); return false; @@ -2116,10 +2137,11 @@ ladish_graph_copy_port_callback( #undef graph_ptr -bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest) +bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest, bool skip_hidden) { return ladish_graph_iterate_nodes( src, + skip_hidden, dest, ladish_graph_copy_client_begin_callback, ladish_graph_copy_port_callback, diff --git a/daemon/graph.h b/daemon/graph.h index 1b1b19ce..d0760211 100644 --- a/daemon/graph.h +++ b/daemon/graph.h @@ -48,7 +48,7 @@ bool uint64_t connection_id); bool ladish_graph_create(ladish_graph_handle * graph_handle_ptr, const char * opath); -bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest); +bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest, bool skip_hidden); void ladish_graph_destroy(ladish_graph_handle graph_handle); const char * ladish_graph_get_opath(ladish_graph_handle graph_handle); @@ -146,12 +146,14 @@ void ladish_graph_adjust_port(ladish_graph_handle graph_handle, ladish_port_hand void ladish_graph_show_connection(ladish_graph_handle graph_handle, uint64_t connection_id); void ladish_try_connect_hidden_connections(ladish_graph_handle graph_handle); void ladish_graph_hide_non_virtual(ladish_graph_handle graph_handle); +void ladish_graph_get_port_uuid(ladish_graph_handle graph, ladish_port_handle port, uuid_t uuid_ptr); void ladish_graph_dump(ladish_graph_handle graph_handle); bool ladish_graph_iterate_nodes( ladish_graph_handle graph_handle, + bool skip_hidden, void * callback_context, bool (* client_begin_callback)( @@ -179,6 +181,7 @@ ladish_graph_iterate_nodes( bool ladish_graph_iterate_connections( ladish_graph_handle graph_handle, + bool skip_hidden, void * callback_context, bool (* callback)(void * context, ladish_port_handle port1_handle, ladish_port_handle port2_handle, ladish_dict_handle dict)); diff --git a/daemon/port.c b/daemon/port.c index f9e8681a..a82c6f9a 100644 --- a/daemon/port.c +++ b/daemon/port.c @@ -26,13 +26,13 @@ #include "port.h" -/* JACK port or virtual port */ +/* JACK port */ struct ladish_port { int refcount; uuid_t uuid; /* The UUID of the port */ - bool virtual; /* Whether the port is virtual or JACK port */ - uint64_t jack_id; /* JACK port ID. zero for virtual ports. */ + bool link; /* Whether the port is studio-room link port */ + uint64_t jack_id; /* JACK port ID. */ ladish_dict_handle dict; }; @@ -40,6 +40,7 @@ struct ladish_port bool ladish_port_create( const uuid_t uuid_ptr, + bool link, ladish_port_handle * port_handle_ptr) { struct ladish_port * port_ptr; @@ -68,7 +69,7 @@ ladish_port_create( } port_ptr->jack_id = 0; - port_ptr->virtual = true; + port_ptr->link = link; port_ptr->refcount = 0; log_info("port %p created", port_ptr); @@ -80,7 +81,7 @@ ladish_port_create( bool ladish_port_create_copy(ladish_port_handle port_handle, ladish_port_handle * port_handle_ptr) { - return ladish_port_create(port_ptr->uuid, port_handle_ptr); + return ladish_port_create(port_ptr->uuid, port_ptr->link, port_handle_ptr); } void ladish_port_destroy(ladish_port_handle port_handle) @@ -128,4 +129,9 @@ void ladish_port_del_ref(ladish_port_handle port_handle) } } +bool ladish_port_is_link(ladish_port_handle port_handle) +{ + return port_ptr->link; +} + #undef port_ptr diff --git a/daemon/port.h b/daemon/port.h index 9b5c5b9c..f274a4ec 100644 --- a/daemon/port.h +++ b/daemon/port.h @@ -31,7 +31,7 @@ typedef struct ladish_port_tag { int unused; } * ladish_port_handle; -bool ladish_port_create(const uuid_t uuid_ptr, ladish_port_handle * port_handle_ptr); +bool ladish_port_create(const uuid_t uuid_ptr, bool link, ladish_port_handle * port_handle_ptr); bool ladish_port_create_copy(ladish_port_handle port_handle, ladish_port_handle * port_handle_ptr); void ladish_port_destroy(ladish_port_handle port_handle); ladish_dict_handle ladish_port_get_dict(ladish_port_handle port_handle); @@ -42,4 +42,6 @@ uint64_t ladish_port_get_jack_id(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); +bool ladish_port_is_link(ladish_port_handle port_handle); + #endif /* #ifndef PORT_H__62F81E7C_91FA_44AB_94A9_E0E2D226ED58__INCLUDED */ diff --git a/daemon/room.c b/daemon/room.c index a335b458..cb11912d 100644 --- a/daemon/room.c +++ b/daemon/room.c @@ -101,7 +101,7 @@ ladish_room_create( if (template != NULL) { - if (!ladish_graph_copy(ladish_room_get_graph(template), room_ptr->graph)) + if (!ladish_graph_copy(ladish_room_get_graph(template), room_ptr->graph, false)) { goto destroy_graph; } @@ -302,6 +302,7 @@ ladish_room_iterate_link_ports( return ladish_graph_iterate_nodes( room_ptr->graph, + false, &context, ladish_room_iterate_link_ports_client_callback, ladish_room_iterate_link_ports_port_callback, diff --git a/daemon/studio.c b/daemon/studio.c index 91b957b8..325164ce 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -40,6 +40,7 @@ #include "graph_dict.h" #include "escape.h" #include "studio.h" +#include "../proxies/jmcore_proxy.h" #define STUDIOS_DIR "/studios/" char * g_studios_dir; @@ -902,6 +903,14 @@ static void ladish_studio_is_started(struct dbus_method_call * call_ptr) method_return_new_single(call_ptr, DBUS_TYPE_BOOLEAN, &started); } +struct add_room_ports_context +{ + ladish_client_handle room_client; + ladish_graph_handle room_graph; +}; + +#define add_room_ports_context_ptr ((struct add_room_ports_context *)context) + static bool add_room_ports( @@ -911,17 +920,25 @@ add_room_ports( uint32_t port_type, uint32_t port_flags) { + uuid_t uuid_in_studio; + uuid_t uuid_in_room; + char input_str[37]; + char output_str[37]; + bool room_input; + //log_info("Studio room port \"%s\"", port_name); if (JACKDBUS_PORT_IS_INPUT(port_flags)) { JACKDBUS_PORT_CLEAR_INPUT(port_flags); JACKDBUS_PORT_SET_OUTPUT(port_flags); + room_input = true; } else if (JACKDBUS_PORT_IS_OUTPUT(port_flags)) { JACKDBUS_PORT_CLEAR_OUTPUT(port_flags); JACKDBUS_PORT_SET_INPUT(port_flags); + room_input = false; } else { @@ -929,9 +946,37 @@ add_room_ports( return false; } - return ladish_graph_add_port(g_studio.studio_graph, context, port_handle, port_name, port_type, port_flags, false); + if (!ladish_graph_add_port(g_studio.studio_graph, add_room_ports_context_ptr->room_client, port_handle, port_name, port_type, port_flags, true)) + { + log_error("ladish_graph_add_port() failed to add link port to studio graph"); + return false; + } + + 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); + + if (room_input) + { + uuid_unparse(uuid_in_room, input_str); + uuid_unparse(uuid_in_studio, output_str); + } + else + { + uuid_unparse(uuid_in_room, output_str); + uuid_unparse(uuid_in_studio, input_str); + } + + if (!jmcore_proxy_create_link(port_type == JACKDBUS_PORT_TYPE_MIDI, input_str, output_str)) + { + log_error("jmcore_proxy_create_link() failed."); + return false; + } + + return true; } +#undef add_room_ports_context_ptr + static void ladish_studio_create_room(struct dbus_method_call * call_ptr) { const char * room_name; @@ -940,6 +985,8 @@ static void ladish_studio_create_room(struct dbus_method_call * call_ptr) char room_dbus_name[1024]; ladish_client_handle room_client; uuid_t room_uuid; + ladish_graph_handle room_graph; + struct add_room_ports_context context; dbus_error_init(&g_dbus_error); @@ -969,9 +1016,10 @@ static void ladish_studio_create_room(struct dbus_method_call * call_ptr) goto fail_decrement_room_count; } + room_graph = ladish_room_get_graph(room); if (g_studio.virtualizer != NULL) { - ladish_virtualizer_set_graph_connection_handlers(g_studio.virtualizer, ladish_room_get_graph(room)); + ladish_virtualizer_set_graph_connection_handlers(g_studio.virtualizer, room_graph); } ladish_room_get_uuid(room, room_uuid); @@ -988,7 +1036,10 @@ static void ladish_studio_create_room(struct dbus_method_call * call_ptr) goto fail_destroy_room_client; } - if (!ladish_room_iterate_link_ports(room, room_client, add_room_ports)) + context.room_client = room_client; + context.room_graph = room_graph; + + if (!ladish_room_iterate_link_ports(room, &context, add_room_ports)) { lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Creation of studio room link ports failed."); goto fail_remove_room_client; diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index 5bff5b45..1899ec5c 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -51,6 +51,9 @@ 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; @@ -425,7 +428,7 @@ port_appeared( goto free_alsa_names; } - if (!ladish_port_create(NULL, &port)) + if (!ladish_port_create(NULL, false, &port)) { log_error("ladish_port_create() failed."); goto free_alsa_names; diff --git a/proxies/jmcore_proxy.c b/proxies/jmcore_proxy.c new file mode 100644 index 00000000..6156ceb1 --- /dev/null +++ b/proxies/jmcore_proxy.c @@ -0,0 +1,95 @@ +/* -*- Mode: C ; c-basic-offset: 2 -*- */ +/* + * LADI Session Handler (ladish) + * + * Copyright (C) 2010 Nedko Arnaudov + * + ************************************************************************** + * This file contains code that interfaces the jmcore through D-Bus + ************************************************************************** + * + * LADI Session Handler is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * LADI Session Handler is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LADI Session Handler. If not, see + * or write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "jmcore_proxy.h" +#include "../dbus_constants.h" + +int64_t g_jmcore_pid; + +static void on_jmcore_life_status_changed(bool appeared) +{ + g_jmcore_pid = 0; +} + +bool jmcore_proxy_init(void) +{ + if (!dbus_register_service_lifetime_hook(g_dbus_connection, JMCORE_SERVICE_NAME, on_jmcore_life_status_changed)) + { + log_error("dbus_register_service_lifetime_hook() failed for a2j service"); + return false; + } + + return jmcore_proxy_get_pid_noncached(&g_jmcore_pid); +} + +void jmcore_proxy_uninit(void) +{ +} + +const int64_t jmcore_proxy_get_pid_cached(void) +{ + if (g_jmcore_pid == 0) + { + jmcore_proxy_get_pid_noncached(&g_jmcore_pid); + } + + return g_jmcore_pid; +} + +bool jmcore_proxy_get_pid_noncached(int64_t * pid_ptr) +{ + if (!dbus_call(JMCORE_SERVICE_NAME, JMCORE_OBJECT_PATH, JMCORE_IFACE, "get_pid", "", "x", pid_ptr)) + { + log_error("jmcore::get_pid() failed."); + return false; + } + + return true; +} + +bool jmcore_proxy_create_link(bool midi, const char * input_port_name, const char * output_port_name) +{ + dbus_bool_t dbus_midi = midi; + + if (!dbus_call(JMCORE_SERVICE_NAME, JMCORE_OBJECT_PATH, JMCORE_IFACE, "create", "bss", &dbus_midi, &input_port_name, &output_port_name, "")) + { + log_error("jmcore::create() failed."); + return false; + } + + return true; +} + +bool jmcore_proxy_destroy_link(const char * port_name) +{ + if (!dbus_call(JMCORE_SERVICE_NAME, JMCORE_OBJECT_PATH, JMCORE_IFACE, "destroy", "s", &port_name, "")) + { + log_error("jmcore::destroy() failed."); + return false; + } + + return true; +} diff --git a/proxies/jmcore_proxy.h b/proxies/jmcore_proxy.h new file mode 100644 index 00000000..1340cbea --- /dev/null +++ b/proxies/jmcore_proxy.h @@ -0,0 +1,39 @@ +/* -*- Mode: C ; c-basic-offset: 2 -*- */ +/* + * LADI Session Handler (ladish) + * + * Copyright (C) 2010 Nedko Arnaudov + * + ************************************************************************** + * This file contains interface to code that interfaces the jmcore through D-Bus + ************************************************************************** + * + * LADI Session Handler is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * LADI Session Handler is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LADI Session Handler. If not, see + * or write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef JMCORE_PROXY_H__A39B2531_CD34_48B9_8561_323755ED551D__INCLUDED +#define JMCORE_PROXY_H__A39B2531_CD34_48B9_8561_323755ED551D__INCLUDED + +#include "common.h" + +bool jmcore_proxy_init(void); +void jmcore_proxy_uninit(void); +const int64_t jmcore_proxy_get_pid_cached(void); +bool jmcore_proxy_get_pid_noncached(int64_t * pid_ptr); +bool jmcore_proxy_create_link(bool midi, const char * input_port_name, const char * output_port_name); +bool jmcore_proxy_destroy_link(const char * port_name); + +#endif /* #ifndef JMCORE_PROXY_H__A39B2531_CD34_48B9_8561_323755ED551D__INCLUDED */ diff --git a/wscript b/wscript index d9c66290..2367fd47 100644 --- a/wscript +++ b/wscript @@ -239,6 +239,7 @@ def build(bld): 'jack_proxy.c', 'graph_proxy.c', 'a2j_proxy.c', + "jmcore_proxy.c", ]: daemon.source.append(os.path.join("proxies", source))