diff --git a/daemon/client.c b/daemon/client.c index 60be932a..0d55a198 100644 --- a/daemon/client.c +++ b/daemon/client.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains the implementation of the client objects @@ -158,6 +158,16 @@ void ladish_client_interlink(ladish_client_handle client_handle, ladish_client_h uuid_copy(client2_ptr->uuid_interlink, client_ptr->uuid); } +void ladish_client_interlink_copy(ladish_client_handle client_handle, ladish_client_handle client2_handle) +{ + uuid_copy(client_ptr->uuid_interlink, client2_ptr->uuid_interlink); +} + +void ladish_client_copy_app(ladish_client_handle client_handle, ladish_client_handle client2_handle) +{ + uuid_copy(client_ptr->uuid_app, client2_ptr->uuid_app); +} + #undef client2_ptr bool ladish_client_get_interlink(ladish_client_handle client_handle, uuid_t uuid) @@ -171,6 +181,17 @@ bool ladish_client_get_interlink(ladish_client_handle client_handle, uuid_t uuid return true; } +bool ladish_client_set_interlink(ladish_client_handle client_handle, uuid_t uuid) +{ + if (uuid_is_null(client_ptr->uuid_interlink)) + { + return false; + } + + uuid_copy(uuid, client_ptr->uuid_interlink); + return true; +} + void ladish_client_clear_interlink(ladish_client_handle client_handle) { uuid_clear(client_ptr->uuid_interlink); diff --git a/daemon/client.h b/daemon/client.h index e38f3e16..1cf7f77c 100644 --- a/daemon/client.h +++ b/daemon/client.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains the interface of the client objects @@ -59,11 +59,13 @@ void ladish_client_set_vgraph(ladish_client_handle client_handle, void * vgraph) void * ladish_client_get_vgraph(ladish_client_handle client_handle); void ladish_client_interlink(ladish_client_handle client1_handle, ladish_client_handle client2_handle); +void ladish_client_interlink_copy(ladish_client_handle dst_client_handle, ladish_client_handle src_client_handle); bool ladish_client_get_interlink(ladish_client_handle client_handle, uuid_t uuid); void ladish_client_clear_interlink(ladish_client_handle client_handle); void ladish_client_set_app(ladish_client_handle client_handle, const uuid_t uuid); bool ladish_client_get_app(ladish_client_handle client_handle, uuid_t uuid); bool ladish_client_has_app(ladish_client_handle client_handle); +void ladish_client_copy_app(ladish_client_handle dst_client_handle, ladish_client_handle src_client_handle); #endif /* #ifndef CLIENT_H__2160B4BA_D6D1_464D_9DC5_ECA50B0958AD__INCLUDED */ diff --git a/daemon/graph.c b/daemon/graph.c index 3019be8b..9598f033 100644 --- a/daemon/graph.c +++ b/daemon/graph.c @@ -2045,6 +2045,73 @@ ladish_graph_remove_port_by_jack_id( return client; } +void +ladish_graph_move_port( + ladish_graph_handle graph_handle, + ladish_port_handle port_handle, + ladish_client_handle client_handle) +{ + struct ladish_graph_port * port_ptr; + struct ladish_graph_client * client_ptr; + struct list_head * node_ptr; + struct ladish_graph_connection * connection_ptr; + + port_ptr = ladish_graph_find_port(graph_ptr, port_handle); + if (port_ptr == NULL) + { + ASSERT_NO_PASS; + return; + } + + client_ptr = ladish_graph_find_client(graph_ptr, client_handle); + if (client_ptr == NULL) + { + ASSERT_NO_PASS; + return; + } + + list_del(&port_ptr->siblings_client); + list_del(&port_ptr->siblings_graph); + graph_ptr->graph_version++; + + if (graph_ptr->opath != NULL && !port_ptr->hidden) + { + list_for_each(node_ptr, &graph_ptr->connections) + { + connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings); + if (!connection_ptr->hidden && (connection_ptr->port1_ptr == port_ptr || connection_ptr->port2_ptr == port_ptr)) + { + ladish_graph_emit_ports_disconnected(graph_ptr, connection_ptr); + graph_ptr->graph_version++; + } + } + + ladish_graph_emit_port_disappeared(graph_ptr, port_ptr); + } + + port_ptr->id = graph_ptr->next_port_id++; + 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); + graph_ptr->graph_version++; + + if (graph_ptr->opath != NULL && !port_ptr->hidden) + { + ladish_graph_emit_port_appeared(graph_ptr, port_ptr); + + list_for_each(node_ptr, &graph_ptr->connections) + { + connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings); + if (!connection_ptr->hidden && (connection_ptr->port1_ptr == port_ptr || connection_ptr->port2_ptr == port_ptr)) + { + graph_ptr->next_connection_id++; + graph_ptr->graph_version++; + ladish_graph_emit_ports_connected(graph_ptr, connection_ptr); + } + } + } +} + bool ladish_graph_rename_client( ladish_graph_handle graph_handle, diff --git a/daemon/graph.h b/daemon/graph.h index d4167955..7013cbce 100644 --- a/daemon/graph.h +++ b/daemon/graph.h @@ -102,6 +102,12 @@ ladish_graph_remove_port_by_jack_id( bool room, bool studio); +void +ladish_graph_move_port( + ladish_graph_handle graph_handle, + ladish_port_handle port_handle, + ladish_client_handle client_handle); + bool ladish_graph_rename_port( ladish_graph_handle graph_handle, diff --git a/daemon/graph_manager.c b/daemon/graph_manager.c new file mode 100644 index 00000000..7d09b692 --- /dev/null +++ b/daemon/graph_manager.c @@ -0,0 +1,225 @@ +/* -*- Mode: C ; c-basic-offset: 2 -*- */ +/* + * LADI Session Handler (ladish) + * + * Copyright (C) 2011 Nedko Arnaudov + * + ************************************************************************** + * The D-Bus patchbay manager + ************************************************************************** + * + * 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 "graph_manager.h" +#include "../dbus/error.h" +#include "../dbus_constants.h" +#include "graph.h" +#include "virtualizer.h" + +/**********************************************************************************/ +/* D-Bus methods */ +/**********************************************************************************/ + +#define graph ((ladish_graph_handle)call_ptr->iface_context) + +static void ladish_graph_manager_dbus_split(struct dbus_method_call * call_ptr) +{ + uint64_t client_id; + + if (!dbus_message_get_args( + call_ptr->message, + &g_dbus_error, + DBUS_TYPE_UINT64, &client_id, + DBUS_TYPE_INVALID)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message); + dbus_error_free(&g_dbus_error); + return; + } + + log_info("split request, graph '%s', client %"PRIu64, ladish_graph_get_description(graph), client_id); + + if (!ladish_virtualizer_split_client(graph, client_id)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "split failed"); + } + else + { + method_return_new_void(call_ptr); + } +} + +static void ladish_graph_manager_dbus_join(struct dbus_method_call * call_ptr) +{ + uint64_t client1_id; + uint64_t client2_id; + + if (!dbus_message_get_args( + call_ptr->message, + &g_dbus_error, + DBUS_TYPE_UINT64, &client1_id, + DBUS_TYPE_UINT64, &client2_id, + DBUS_TYPE_INVALID)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message); + dbus_error_free(&g_dbus_error); + return; + } + + log_info("join request, graph '%s', client1 %"PRIu64", client2 %"PRIu64, ladish_graph_get_description(graph), client1_id, client2_id); + + if (!ladish_virtualizer_join_clients(graph, client1_id, client2_id)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "join failed"); + } + else + { + method_return_new_void(call_ptr); + } +} + +static void ladish_graph_manager_dbus_rename_client(struct dbus_method_call * call_ptr) +{ + uint64_t client_id; + const char * newname; + + if (!dbus_message_get_args( + call_ptr->message, + &g_dbus_error, + DBUS_TYPE_UINT64, &client_id, + DBUS_TYPE_STRING, &newname, + DBUS_TYPE_INVALID)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message); + dbus_error_free(&g_dbus_error); + return; + } + + log_info("rename client request, graph '%s', client %"PRIu64", newname '%s'", ladish_graph_get_description(graph), client_id, newname); + + method_return_new_void(call_ptr); +} + +static void ladish_graph_manager_dbus_rename_port(struct dbus_method_call * call_ptr) +{ + uint64_t port_id; + const char * newname; + + if (!dbus_message_get_args( + call_ptr->message, + &g_dbus_error, + DBUS_TYPE_UINT64, &port_id, + DBUS_TYPE_STRING, &newname, + DBUS_TYPE_INVALID)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message); + dbus_error_free(&g_dbus_error); + return; + } + + log_info("rename port request, graph '%s', port %"PRIu64", newname '%s'", ladish_graph_get_description(graph), port_id, newname); + + method_return_new_void(call_ptr); +} + +static void ladish_graph_manager_dbus_move_port(struct dbus_method_call * call_ptr) +{ + uint64_t port_id; + uint64_t client_id; + + if (!dbus_message_get_args( + call_ptr->message, + &g_dbus_error, + DBUS_TYPE_UINT64, &port_id, + DBUS_TYPE_UINT64, &client_id, + DBUS_TYPE_INVALID)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message); + dbus_error_free(&g_dbus_error); + return; + } + + log_info("move port request, graph '%s', port %"PRIu64", client %"PRIu64, ladish_graph_get_description(graph), port_id, client_id); + + method_return_new_void(call_ptr); +} + +static void ladish_graph_manager_dbus_new_client(struct dbus_method_call * call_ptr) +{ + const char * name; + + if (!dbus_message_get_args( + call_ptr->message, + &g_dbus_error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message); + dbus_error_free(&g_dbus_error); + return; + } + + log_info("new client request, graph '%s', name '%s'", ladish_graph_get_description(graph), name); + + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "method \"%s\" not implemented yet", call_ptr->method_name); +} + +#undef graph_ptr + +METHOD_ARGS_BEGIN(Split, "Split client") + METHOD_ARG_DESCRIBE_IN("client_id", "t", "ID of the client") +METHOD_ARGS_END + +METHOD_ARGS_BEGIN(Join, "Join two clients") + METHOD_ARG_DESCRIBE_IN("client1_id", "t", "ID of the first client") + METHOD_ARG_DESCRIBE_IN("client2_id", "t", "ID of the second client") +METHOD_ARGS_END + +METHOD_ARGS_BEGIN(RenameClient, "Rename client") + METHOD_ARG_DESCRIBE_IN("client_id", "t", "ID of the client") + METHOD_ARG_DESCRIBE_IN("newname", "s", "New name for the client") +METHOD_ARGS_END + +METHOD_ARGS_BEGIN(RenamePort, "Rename port") + METHOD_ARG_DESCRIBE_IN("port_id", "t", "ID of the port") + METHOD_ARG_DESCRIBE_IN("newname", "s", "New name for the port") +METHOD_ARGS_END + +METHOD_ARGS_BEGIN(MovePort, "Move port") + METHOD_ARG_DESCRIBE_IN("port_id", "t", "ID of the port") + METHOD_ARG_DESCRIBE_IN("client_id", "t", "ID of the client where port will be moved to") +METHOD_ARGS_END + +METHOD_ARGS_BEGIN(NewClient, "New client") + METHOD_ARG_DESCRIBE_IN("name", "s", "Name for the new client") + METHOD_ARG_DESCRIBE_OUT("client_id", "t", "ID of the new client") +METHOD_ARGS_END + +METHODS_BEGIN + METHOD_DESCRIBE(Split, ladish_graph_manager_dbus_split) + METHOD_DESCRIBE(Join, ladish_graph_manager_dbus_join) + METHOD_DESCRIBE(RenameClient, ladish_graph_manager_dbus_rename_client) + METHOD_DESCRIBE(RenamePort, ladish_graph_manager_dbus_rename_port) + METHOD_DESCRIBE(MovePort, ladish_graph_manager_dbus_move_port) + METHOD_DESCRIBE(NewClient, ladish_graph_manager_dbus_new_client) +METHODS_END + +INTERFACE_BEGIN(g_iface_graph_manager, IFACE_GRAPH_MANAGER) + INTERFACE_DEFAULT_HANDLER + INTERFACE_EXPOSE_METHODS +INTERFACE_END + diff --git a/daemon/graph_manager.h b/daemon/graph_manager.h new file mode 100644 index 00000000..5124008c --- /dev/null +++ b/daemon/graph_manager.h @@ -0,0 +1,34 @@ +/* -*- Mode: C ; c-basic-offset: 2 -*- */ +/* + * LADI Session Handler (ladish) + * + * Copyright (C) 2011 Nedko Arnaudov + * + ************************************************************************** + * Interface of the D-Bus patchbay manager + ************************************************************************** + * + * 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 GRAPH_MANAGER_H__6A2FA5B3_74A0_4296_9D57_7FBE62D4BFC0__INCLUDED +#define GRAPH_MANAGER_H__6A2FA5B3_74A0_4296_9D57_7FBE62D4BFC0__INCLUDED + +#include "common.h" + +extern const struct dbus_interface_descriptor g_iface_graph_manager; + +#endif /* #ifndef GRAPH_MANAGER_H__6A2FA5B3_74A0_4296_9D57_7FBE62D4BFC0__INCLUDED */ diff --git a/daemon/room.c b/daemon/room.c index 71803773..0a3f7973 100644 --- a/daemon/room.c +++ b/daemon/room.c @@ -27,6 +27,7 @@ #include "room_internal.h" #include "../dbus_constants.h" #include "graph_dict.h" +#include "graph_manager.h" #include "../lib/wkports.h" #include "studio.h" #include "../proxies/jmcore_proxy.h" @@ -315,6 +316,7 @@ ladish_room_create( &g_interface_room, room_ptr, &g_interface_patchbay, ladish_graph_get_dbus_context(room_ptr->graph), &g_iface_graph_dict, room_ptr->graph, + &g_iface_graph_manager, room_ptr->graph, &g_iface_app_supervisor, room_ptr->app_supervisor, &g_iface_recent_items, NULL, NULL); diff --git a/daemon/studio.c b/daemon/studio.c index 3c256e8e..e3fac295 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains part of the studio singleton object implementation @@ -37,6 +37,7 @@ #include "../common/catdup.h" #include "../common/dirhelpers.h" #include "graph_dict.h" +#include "graph_manager.h" #include "escape.h" #include "studio.h" #include "../proxies/notify_proxy.h" @@ -85,6 +86,7 @@ bool ladish_studio_show(void) &g_interface_studio, &g_studio, &g_interface_patchbay, ladish_graph_get_dbus_context(g_studio.studio_graph), &g_iface_graph_dict, g_studio.studio_graph, + &g_iface_graph_manager, g_studio.studio_graph, &g_iface_app_supervisor, g_studio.app_supervisor, NULL); if (object == NULL) @@ -335,7 +337,7 @@ void ladish_studio_on_event_jack_started(void) log_info("jack conf successfully retrieved"); g_studio.jack_conf_valid = true; - if (!graph_proxy_create(JACKDBUS_SERVICE_NAME, JACKDBUS_OBJECT_PATH, false, &g_studio.jack_graph_proxy)) + if (!graph_proxy_create(JACKDBUS_SERVICE_NAME, JACKDBUS_OBJECT_PATH, false, false, &g_studio.jack_graph_proxy)) { log_error("graph_proxy_create() failed for jackdbus"); } diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index 12dae1a2..f0060b53 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -1504,3 +1504,86 @@ bool ladish_virtualizer_is_a2j_client(ladish_client_handle jclient) ladish_client_get_uuid(jclient, jclient_uuid); return uuid_compare(jclient_uuid, g_a2j_uuid) == 0; } + +static +bool +move_capture_port_callback( + void * context, + ladish_graph_handle graph_handle, + bool hidden, + ladish_client_handle client_handle, + const char * client_name, + ladish_port_handle port_handle, + const char * port_name, + uint32_t port_type, + uint32_t port_flags) +{ + ASSERT(client_handle != context); /* source and destination clients must be differ */ + + if (JACKDBUS_PORT_IS_INPUT(port_flags)) + { + ladish_graph_move_port(graph_handle, port_handle, context); + } + + return true; +} + +bool ladish_virtualizer_split_client(ladish_graph_handle vgraph, uint64_t client_id) +{ + ladish_client_handle vclient1; + ladish_client_handle vclient2; + const char * name; + + vclient1 = ladish_graph_find_client_by_id(vgraph, client_id); + if (vclient1 == NULL) + { + log_error("Cannot find client %"PRIu64" in %s", client_id, ladish_graph_get_description(vgraph)); + return false; + } + + name = ladish_graph_get_client_name(vgraph, vclient1); + + if (!ladish_client_create(NULL, &vclient2)) + { + log_error("ladish_client_create() failed."); + return false; + } + + ladish_client_interlink_copy(vclient2, vclient1); + ladish_client_copy_app(vclient2, vclient1); + + if (!ladish_graph_add_client(vgraph, vclient2, name, false)) + { + log_error("ladish_graph_add_client() failed to add client '%s' to virtual graph", name); + ladish_client_destroy(vclient2); + return false; + } + + return ladish_graph_interate_client_ports(vgraph, vclient1, vclient2, move_capture_port_callback); +} + +bool +ladish_virtualizer_join_clients( + ladish_graph_handle vgraph, + uint64_t client1_id, + uint64_t client2_id) +{ + ladish_client_handle vclient1; + ladish_client_handle vclient2; + + vclient1 = ladish_graph_find_client_by_id(vgraph, client1_id); + if (vclient1 == NULL) + { + log_error("Cannot find client %"PRIu64" in %s", client1_id, ladish_graph_get_description(vgraph)); + return false; + } + + vclient2 = ladish_graph_find_client_by_id(vgraph, client2_id); + if (vclient2 == NULL) + { + log_error("Cannot find client %"PRIu64" in %s", client2_id, ladish_graph_get_description(vgraph)); + return false; + } + + return true; +} diff --git a/daemon/virtualizer.h b/daemon/virtualizer.h index 58a0ce38..5536808b 100644 --- a/daemon/virtualizer.h +++ b/daemon/virtualizer.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains interface to graph dispatcher object @@ -79,4 +79,17 @@ void ladish_virtualizer_destroy( ladish_virtualizer_handle handle); +/* create new client and move capture ports of the supplied client the the new client */ +bool +ladish_virtualizer_split_client( + ladish_graph_handle vgraph, + uint64_t client_id); + +/* move ports of client2 to client1 and remove client2 */ +bool +ladish_virtualizer_join_clients( + ladish_graph_handle vgraph, + uint64_t client1_id, + uint64_t client2_id); + #endif /* #ifndef JACK_DISPATCH_H__C7566B66_081D_4D00_A702_7C18F7CC0735__INCLUDED */ diff --git a/dbus_constants.h b/dbus_constants.h index 41fe5d9f..e49985a0 100644 --- a/dbus_constants.h +++ b/dbus_constants.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains constants for D-Bus service and interface names and for D-Bus object paths @@ -43,6 +43,7 @@ #define APPLICATION_OBJECT_PATH DBUS_BASE_PATH "/Application" #define IFACE_APPLICATION DBUS_NAME_BASE ".App" #define IFACE_GRAPH_DICT DBUS_NAME_BASE ".GraphDict" +#define IFACE_GRAPH_MANAGER DBUS_NAME_BASE ".GraphManager" #define IFACE_RECENT_ITEMS DBUS_NAME_BASE ".RecentItems" #define JMCORE_SERVICE_NAME DBUS_NAME_BASE ".jmcore" diff --git a/gui/canvas.cpp b/gui/canvas.cpp index 2b5d75e5..7a89c083 100644 --- a/gui/canvas.cpp +++ b/gui/canvas.cpp @@ -117,6 +117,7 @@ public: { fill_module_menu(_menu->gobj(), m_context); } + _menu->show_all(); } void menu_disconnect_all() @@ -172,6 +173,7 @@ public: { fill_port_menu(_menu->gobj(), m_context); } + _menu->show_all(); } void on_menu_hide() diff --git a/gui/graph_canvas.c b/gui/graph_canvas.c index 3fbd6922..e4025f5b 100644 --- a/gui/graph_canvas.c +++ b/gui/graph_canvas.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains implementation of graph canvas object @@ -44,12 +44,15 @@ struct client canvas_module_handle canvas_module; struct list_head ports; struct graph_canvas * owner_ptr; + unsigned int inport_count; + unsigned int outport_count; }; struct port { struct list_head siblings; uint64_t id; + bool is_input; canvas_port_handle canvas_port; struct graph_canvas * graph_canvas; }; @@ -169,8 +172,38 @@ module_location_changed( y_str); } +static void on_popup_menu_action_split(GtkWidget * menuitem, gpointer module_context) +{ + //log_info("on_popup_menu_action_split"); + graph_proxy_split(client_ptr->owner_ptr->graph, client_ptr->id); +} + +static void fill_module_menu(GtkMenu * menu, void * module_context) +{ + GtkWidget * menuitem; + + log_info("fill_module_menu %"PRIu64, client_ptr->id); + + if (client_ptr->inport_count != 0 && + client_ptr->outport_count != 0) + { + menuitem = gtk_menu_item_new_with_label(_("Split")); + g_signal_connect(menuitem, "activate", (GCallback)on_popup_menu_action_split, client_ptr); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + } +} + #undef client_ptr +#define port_ptr ((struct client *)port_context) + +static void fill_port_menu(GtkMenu * menu, void * port_context) +{ + log_info("fill_port_menu %"PRIu64, port_ptr->id); +} + +#undef port_ptr + bool graph_canvas_create( int width, @@ -193,8 +226,8 @@ graph_canvas_create( disconnect_request, module_location_changed, fill_canvas_menu, - NULL, - NULL, + fill_module_menu, + fill_port_menu, &graph_canvas_ptr->canvas)) { free(graph_canvas_ptr); @@ -249,6 +282,8 @@ client_appeared( } client_ptr->id = id; + client_ptr->inport_count = 0; + client_ptr->outport_count = 0; INIT_LIST_HEAD(&client_ptr->ports); client_ptr->owner_ptr = graph_canvas_ptr; @@ -399,6 +434,7 @@ port_appeared( } port_ptr->id = port_id; + port_ptr->is_input = is_input; port_ptr->graph_canvas = graph_canvas_ptr; // Darkest tango palette colour, with S -= 6, V -= 6, w/ transparency @@ -449,6 +485,15 @@ port_appeared( list_add_tail(&port_ptr->siblings, &client_ptr->ports); free(name_override); + + if (is_input) + { + client_ptr->inport_count++; + } + else + { + client_ptr->outport_count++; + } } static @@ -479,6 +524,16 @@ port_disappeared( list_del(&port_ptr->siblings); canvas_destroy_port(graph_canvas_ptr->canvas, port_ptr->canvas_port); + + if (port_ptr->is_input) + { + client_ptr->inport_count--; + } + else + { + client_ptr->outport_count--; + } + free(port_ptr); } diff --git a/gui/graph_view.c b/gui/graph_view.c index 6d374529..27ef19c1 100644 --- a/gui/graph_view.c +++ b/gui/graph_view.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains implementation of the graph view object @@ -198,6 +198,7 @@ create_view( const char * service, const char * object, bool graph_dict_supported, + bool graph_manager_supported, bool app_supervisor_supported, bool force_activate, graph_view_handle * handle_ptr) @@ -223,7 +224,7 @@ create_view( view_ptr->full_name = view_ptr->view_name; view_ptr->project_name = NULL; - if (!graph_proxy_create(service, object, graph_dict_supported, &view_ptr->graph)) + if (!graph_proxy_create(service, object, graph_dict_supported, graph_manager_supported, &view_ptr->graph)) { goto free_name; } diff --git a/gui/graph_view.h b/gui/graph_view.h index ddb51a14..911d3037 100644 --- a/gui/graph_view.h +++ b/gui/graph_view.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains interface of the graph view object @@ -42,6 +42,7 @@ create_view( const char * object, bool graph_dict_supported, bool app_supervisor_supported, + bool graph_manager_supported, bool force_activate, graph_view_handle * handle_ptr); diff --git a/gui/jack.c b/gui/jack.c index 4174a48b..cbc8063c 100644 --- a/gui/jack.c +++ b/gui/jack.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2008, 2009, 2010 Nedko Arnaudov + * Copyright (C) 2008, 2009, 2010, 2011 Nedko Arnaudov * Copyright (C) 2007 Dave Robillard * ************************************************************************** @@ -56,7 +56,7 @@ static void update_raw_jack_visibility(void) /* if there is no jack view and its display is enabled and jack is avaialable, create the raw jack view */ if (g_jack_view == NULL && g_jack_view_enabled && g_jack_state != JACK_STATE_NA) { - if (!create_view(_("Raw JACK"), JACKDBUS_SERVICE_NAME, JACKDBUS_OBJECT_PATH, false, false, true, &g_jack_view)) + if (!create_view(_("Raw JACK"), JACKDBUS_SERVICE_NAME, JACKDBUS_OBJECT_PATH, false, false, false, true, &g_jack_view)) { log_error("create_view() failed for jack"); return; diff --git a/gui/room.c b/gui/room.c index a4ccfc22..c13f3ae5 100644 --- a/gui/room.c +++ b/gui/room.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2010 Nedko Arnaudov + * Copyright (C) 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains room related code @@ -119,7 +119,7 @@ static void room_appeared(const char * opath, const char * name, const char * te log_info("room \"%s\" appeared (%s). template is \"%s\"", name, opath, template); - if (!create_view(name, SERVICE_NAME, opath, true, true, false, &graph_view)) + if (!create_view(name, SERVICE_NAME, opath, true, true, true, false, &graph_view)) { log_error("create_view() failed for room \"%s\"", name); } diff --git a/gui/studio.c b/gui/studio.c index e560fe35..bd6217ec 100644 --- a/gui/studio.c +++ b/gui/studio.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2010 Nedko Arnaudov + * Copyright (C) 2010, 2011 Nedko Arnaudov * ************************************************************************** * This file contains the studio handling code @@ -63,7 +63,7 @@ void create_studio_view(const char * name) { ASSERT(!studio_loaded()); - if (!create_view(name, SERVICE_NAME, STUDIO_OBJECT_PATH, true, true, false, &g_studio_view)) + if (!create_view(name, SERVICE_NAME, STUDIO_OBJECT_PATH, true, true, true, false, &g_studio_view)) { log_error("create_view() failed for studio"); } diff --git a/proxies/graph_proxy.c b/proxies/graph_proxy.c index e4a419e1..087bbac1 100644 --- a/proxies/graph_proxy.c +++ b/proxies/graph_proxy.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009,2010 Nedko Arnaudov + * Copyright (C) 2009,2010,2011 Nedko Arnaudov * ************************************************************************** * This file contains implementation graph object that is backed through D-Bus @@ -49,6 +49,7 @@ struct graph uint64_t version; bool active; bool graph_dict_supported; + bool graph_manager_supported; }; static struct dbus_signal_hook g_signal_hooks[]; @@ -387,6 +388,7 @@ graph_proxy_create( const char * service, const char * object, bool graph_dict_supported, + bool graph_manager_supported, graph_proxy_handle * graph_proxy_handle_ptr) { struct graph * graph_ptr; @@ -418,6 +420,7 @@ graph_proxy_create( graph_ptr->active = false; graph_ptr->graph_dict_supported = graph_dict_supported; + graph_ptr->graph_manager_supported = graph_manager_supported; *graph_proxy_handle_ptr = (graph_proxy_handle)graph_ptr; @@ -972,6 +975,125 @@ bool graph_proxy_get_client_pid(graph_proxy_handle graph, uint64_t client_id, pi return true; } +bool +graph_proxy_split( + graph_proxy_handle graph, + uint64_t client_id) +{ + if (!graph_ptr->graph_manager_supported) + { + return false; + } + + if (!dbus_call(0, graph_ptr->service, graph_ptr->object, IFACE_GRAPH_MANAGER, "Split", "t", &client_id, "")) + { + log_error(IFACE_GRAPH_MANAGER ".Split() failed."); + return false; + } + + return true; +} + +bool +graph_proxy_join( + graph_proxy_handle graph, + uint64_t client1_id, + uint64_t client2_id) +{ + if (!graph_ptr->graph_manager_supported) + { + return false; + } + + if (!dbus_call(0, graph_ptr->service, graph_ptr->object, IFACE_GRAPH_MANAGER, "Join", "tt", &client1_id, &client2_id, "")) + { + log_error(IFACE_GRAPH_MANAGER ".Join() failed."); + return false; + } + + return true; +} + +bool +graph_proxy_rename_client( + graph_proxy_handle graph, + uint64_t client_id, + const char * newname) +{ + if (!graph_ptr->graph_manager_supported) + { + return false; + } + + if (!dbus_call(0, graph_ptr->service, graph_ptr->object, IFACE_GRAPH_MANAGER, "RenameClient", "ts", &client_id, &newname, "")) + { + log_error(IFACE_GRAPH_MANAGER ".RenameClient() failed."); + return false; + } + + return true; +} + +bool +graph_proxy_rename_port( + graph_proxy_handle graph, + uint64_t port_id, + const char * newname) +{ + if (!graph_ptr->graph_manager_supported) + { + return false; + } + + if (!dbus_call(0, graph_ptr->service, graph_ptr->object, IFACE_GRAPH_MANAGER, "RenamePort", "ts", &port_id, &newname, "")) + { + log_error(IFACE_GRAPH_MANAGER ".RenamePort() failed."); + return false; + } + + return true; +} + +bool +graph_proxy_move_port( + graph_proxy_handle graph, + uint64_t port_id, + uint64_t client_id) +{ + if (!graph_ptr->graph_manager_supported) + { + return false; + } + + if (!dbus_call(0, graph_ptr->service, graph_ptr->object, IFACE_GRAPH_MANAGER, "MovePort", "tt", &port_id, &client_id, "")) + { + log_error(IFACE_GRAPH_MANAGER ".MovePort() failed."); + return false; + } + + return true; +} + +bool +graph_proxy_new_client( + graph_proxy_handle graph, + const char * name, + uint64_t * client_id_ptr) +{ + if (!graph_ptr->graph_manager_supported) + { + return false; + } + + if (!dbus_call(0, graph_ptr->service, graph_ptr->object, IFACE_GRAPH_MANAGER, "NewClient", "s", &name, "t", client_id_ptr)) + { + log_error(IFACE_GRAPH_MANAGER ".NewClient() failed."); + return false; + } + + return true; +} + /* this must be static because it is referenced by the * dbus helper layer when hooks are active */ static struct dbus_signal_hook g_signal_hooks[] = diff --git a/proxies/graph_proxy.h b/proxies/graph_proxy.h index d761f74b..b41b8133 100644 --- a/proxies/graph_proxy.h +++ b/proxies/graph_proxy.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009,2010 Nedko Arnaudov + * Copyright (C) 2009,2010,2011 Nedko Arnaudov * ************************************************************************** * This file contains interface to graph object that is backed through D-Bus @@ -43,6 +43,7 @@ graph_proxy_create( const char * service, const char * object, bool graph_dict_supported, + bool graph_manager_supported, graph_proxy_handle * graph_proxy_ptr); void @@ -112,6 +113,41 @@ graph_proxy_dict_entry_drop( bool graph_proxy_get_client_pid(graph_proxy_handle graph, uint64_t client_id, pid_t * pid_ptr); +bool +graph_proxy_split( + graph_proxy_handle graph, + uint64_t client_id); + +bool +graph_proxy_join( + graph_proxy_handle graph, + uint64_t client1_id, + uint64_t client2_id); + +bool +graph_proxy_rename_client( + graph_proxy_handle graph, + uint64_t client_id, + const char * newname); + +bool +graph_proxy_rename_port( + graph_proxy_handle graph, + uint64_t port_id, + const char * newname); + +bool +graph_proxy_move_port( + graph_proxy_handle graph, + uint64_t port_id, + uint64_t client_id); + +bool +graph_proxy_new_client( + graph_proxy_handle graph, + const char * name, + uint64_t * client_id_ptr); + #if 0 { /* Adjust editor indent */ #endif diff --git a/wscript b/wscript index af9a2e10..92eee016 100644 --- a/wscript +++ b/wscript @@ -331,6 +331,7 @@ def build(bld): 'control.c', 'studio.c', 'graph.c', + 'graph_manager.c', 'client.c', 'port.c', 'virtualizer.c',