From 13bc814f0bc739e5e6902ca37fc420608c4506ad Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Wed, 24 Mar 2010 01:11:53 +0200 Subject: [PATCH] daemon: fill the Basic room template with ports and copy them when creating studio rooms --- daemon/client.c | 10 ++- daemon/client.h | 7 +- daemon/control.c | 178 ++++++++++++++++++++++++++++++++++++++++++----- daemon/graph.c | 80 ++++++++++++++++++++- daemon/graph.h | 1 + daemon/port.c | 9 ++- daemon/port.h | 5 +- daemon/room.c | 28 +++++--- daemon/room.h | 2 + lib/wkports.h | 6 ++ 10 files changed, 292 insertions(+), 34 deletions(-) diff --git a/daemon/client.c b/daemon/client.c index 16d2f4cb..bf5bc433 100644 --- a/daemon/client.c +++ b/daemon/client.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009 Nedko Arnaudov + * Copyright (C) 2009, 2010 Nedko Arnaudov * ************************************************************************** * This file contains the implementation of the client objects @@ -102,6 +102,14 @@ ladish_client_create( #define client_ptr ((struct ladish_client *)client_handle) +bool +ladish_client_create_copy( + ladish_client_handle client_handle, + ladish_client_handle * client_handle_ptr) +{ + return ladish_client_create(client_ptr->uuid, client_ptr->virtual, client_ptr->link, client_ptr->system, client_handle_ptr); +} + void ladish_client_destroy( ladish_client_handle client_handle) diff --git a/daemon/client.h b/daemon/client.h index 6446757f..1a6f7a39 100644 --- a/daemon/client.h +++ b/daemon/client.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009 Nedko Arnaudov + * Copyright (C) 2009, 2010 Nedko Arnaudov * ************************************************************************** * This file contains the interface of the client objects @@ -39,6 +39,11 @@ ladish_client_create( bool system, ladish_client_handle * client_handle_ptr); +bool +ladish_client_create_copy( + ladish_client_handle client_handle, + ladish_client_handle * client_handle_ptr); + void ladish_client_destroy( ladish_client_handle client_handle); diff --git a/daemon/control.c b/daemon/control.c index bcf3d7e8..32b69087 100644 --- a/daemon/control.c +++ b/daemon/control.c @@ -44,39 +44,183 @@ UUID_DEFINE(basic_room,0xC6,0x03,0xF2,0xA0,0xD9,0x6A,0x49,0x3E,0xA8,0xCF,0x55,0x static struct list_head g_room_templates; -bool create_builtin_room_templates(void) +static bool create_empty_room_template(const uuid_t uuid_ptr, const char * name, ladish_room_handle * room_ptr) { - ladish_room_handle room; - - if (!ladish_room_create(empty_room, "Empty", NULL, NULL, &room)) + if (!ladish_room_create(uuid_ptr, name, NULL, NULL, room_ptr)) { - log_error("ladish_room_create() failed."); + log_error("ladish_room_create() failed for room template \"%s\".", name); return false; } - list_add_tail(ladish_room_get_list_node(room), &g_room_templates); - - if (!ladish_room_create(basic_room, "Basic", NULL, NULL, &room)) - { - log_error("ladish_room_create() failed."); - return false; - } - - list_add_tail(ladish_room_get_list_node(room), &g_room_templates); - return true; } -bool create_room_templates(void) +struct room_descriptor { - if (!create_builtin_room_templates()) + const char * name; + ladish_room_handle room; + ladish_graph_handle graph; + ladish_client_handle capture; + ladish_client_handle playback; +}; + +static +bool +create_room_template( + const uuid_t uuid_ptr, + const char * name, + struct room_descriptor * room_descriptor_ptr) +{ + ladish_room_handle room; + ladish_graph_handle graph; + ladish_client_handle capture; + ladish_client_handle playback; + + if (!create_empty_room_template(uuid_ptr, name, &room)) { + log_error("ladish_room_create() failed for room template \"%s\".", name); + goto fail; + } + + graph = ladish_room_get_graph(room); + + if (!ladish_client_create(ladish_wkclient_capture, true, true, false, &capture)) + { + log_error("ladish_client_create() failed to create capture client to room template \"%s\".", name); + goto fail_destroy; + } + + if (!ladish_graph_add_client(graph, capture, "Capture", false)) + { + log_error("ladish_graph_add_client() failed to add capture client to room template \"%s\".", name); + goto fail_destroy; + } + + if (!ladish_client_create(ladish_wkclient_playback, true, true, false, &playback)) + { + log_error("ladish_client_create() failed to create playback client to room template \"%s\".", name); + goto fail_destroy; + } + + if (!ladish_graph_add_client(graph, playback, "Playback", false)) + { + log_error("ladish_graph_add_client() failed to add playback client to room template \"%s\".", name); + goto fail_destroy; + } + + room_descriptor_ptr->name = ladish_room_get_name(room); + room_descriptor_ptr->room = room; + room_descriptor_ptr->graph = graph; + room_descriptor_ptr->capture = capture; + room_descriptor_ptr->playback = playback; + + return true; + +fail_destroy: + ladish_room_destroy(room); /* this will destroy the graph clients as well */ +fail: + return false; +} + +static +bool +create_room_template_port( + struct room_descriptor * room_descriptor_ptr, + const uuid_t uuid_ptr, + const char * name, + uint32_t type, + uint32_t flags) +{ + ladish_port_handle port; + bool playback; + ladish_client_handle client; + + playback = (flags & JACKDBUS_PORT_FLAG_INPUT) != 0; + ASSERT(playback || (flags & JACKDBUS_PORT_FLAG_OUTPUT) != 0); /* playback or capture */ + 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)) + { + log_error("Creation of room template \"%s\" %s port \"%s\" failed.", room_descriptor_ptr->name, playback ? "playback" : "capture", name); + return false; + } + + if (!ladish_graph_add_port(room_descriptor_ptr->graph, client, port, name, type, flags, false)) + { + log_error("Adding of room template \"%s\" %s port \"%s\" to graph failed.", room_descriptor_ptr->name, playback ? "playback" : "capture", name); + ladish_port_destroy(port); return false; } return true; } +void create_builtin_room_templates(void) +{ + struct room_descriptor room_descriptor; + + if (create_empty_room_template(empty_room, "Empty", &room_descriptor.room)) + { + list_add_tail(ladish_room_get_list_node(room_descriptor.room), &g_room_templates); + } + + if (create_room_template(basic_room, "Basic", &room_descriptor)) + { + if (!create_room_template_port(&room_descriptor, ladish_wkport_capture_left, "Left", JACKDBUS_PORT_TYPE_AUDIO, JACKDBUS_PORT_FLAG_OUTPUT)) + { + goto fail; + } + + if (!create_room_template_port(&room_descriptor, ladish_wkport_capture_right, "Right", JACKDBUS_PORT_TYPE_AUDIO, JACKDBUS_PORT_FLAG_OUTPUT)) + { + goto fail; + } + + if (!create_room_template_port(&room_descriptor, ladish_wkport_midi_capture, "MIDI", JACKDBUS_PORT_TYPE_MIDI, JACKDBUS_PORT_FLAG_OUTPUT)) + { + goto fail; + } + + if (!create_room_template_port(&room_descriptor, ladish_wkport_playback_left, "Left", JACKDBUS_PORT_TYPE_AUDIO, JACKDBUS_PORT_FLAG_INPUT)) + { + goto fail; + } + + if (!create_room_template_port(&room_descriptor, ladish_wkport_playback_right, "Right", JACKDBUS_PORT_TYPE_AUDIO, JACKDBUS_PORT_FLAG_INPUT)) + { + goto fail; + } + + if (!create_room_template_port(&room_descriptor, ladish_wkport_monitor_left, "Monitor Left", JACKDBUS_PORT_TYPE_AUDIO, JACKDBUS_PORT_FLAG_INPUT)) + { + goto fail; + } + + if (!create_room_template_port(&room_descriptor, ladish_wkport_monitor_right, "Monitor Right", JACKDBUS_PORT_TYPE_AUDIO, JACKDBUS_PORT_FLAG_INPUT)) + { + goto fail; + } + + if (!create_room_template_port(&room_descriptor, ladish_wkport_midi_playback, "MIDI", JACKDBUS_PORT_TYPE_MIDI, JACKDBUS_PORT_FLAG_INPUT)) + { + goto fail; + } + + list_add_tail(ladish_room_get_list_node(room_descriptor.room), &g_room_templates); + } + + return; + +fail: + ladish_room_destroy(room_descriptor.room); /* this will destroy the graph clients and ports as well */ +} + +void create_room_templates(void) +{ + create_builtin_room_templates(); +} + void maybe_create_room_templates(void) { if (list_empty(&g_room_templates)) diff --git a/daemon/graph.c b/daemon/graph.c index 16397204..4ac0ce73 100644 --- a/daemon/graph.c +++ b/daemon/graph.c @@ -1795,7 +1795,7 @@ void ladish_try_connect_hidden_connections(ladish_graph_handle graph_handle) struct list_head * node_ptr; struct ladish_graph_connection * connection_ptr; - if (graph_ptr->connect_handler == NULL) + if (!list_empty(&graph_ptr->connections) && graph_ptr->connect_handler == NULL) { ASSERT_NO_PASS; return; @@ -2045,6 +2045,84 @@ void ladish_graph_dump(ladish_graph_handle graph_handle) } #undef graph_ptr +#define graph_ptr ((struct ladish_graph *)context) + +static +bool +ladish_graph_copy_client_begin_callback( + void * context, + ladish_client_handle client_handle, + const char * client_name, + void ** client_iteration_context_ptr_ptr) +{ + ladish_client_handle copy; + + if (!ladish_client_create_copy(client_handle, ©)) + { + return false; + } + + if (!ladish_graph_add_client(context, copy, client_name, false)) + { + ladish_client_destroy(copy); + return false; + } + + *client_iteration_context_ptr_ptr = copy; + + return true; +} + +static +bool +ladish_graph_copy_port_callback( + void * context, + void * client_iteration_context_ptr, + 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) +{ + ladish_port_handle copy; + + if (!ladish_port_create_copy(port_handle, ©)) + { + return false; + } + + if (!ladish_graph_add_port(context, client_iteration_context_ptr, copy, port_name, port_type, port_flags, false)) + { + ladish_port_destroy(copy); + return false; + } + + return true; +} + +static +bool +ladish_graph_copy_client_end_callback( + void * context, + ladish_client_handle client_handle, + const char * client_name, + void * client_iteration_context_ptr) +{ + return true; +} + +#undef graph_ptr + +bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest) +{ + return ladish_graph_iterate_nodes( + src, + dest, + ladish_graph_copy_client_begin_callback, + ladish_graph_copy_port_callback, + ladish_graph_copy_client_end_callback); +} METHOD_ARGS_BEGIN(GetAllPorts, "Get all ports") METHOD_ARG_DESCRIBE_IN("ports_list", "as", "List of all ports") diff --git a/daemon/graph.h b/daemon/graph.h index e82c3d57..204794a0 100644 --- a/daemon/graph.h +++ b/daemon/graph.h @@ -48,6 +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); void ladish_graph_destroy(ladish_graph_handle graph_handle, bool destroy_ports); const char * ladish_graph_get_opath(ladish_graph_handle graph_handle); diff --git a/daemon/port.c b/daemon/port.c index 70d8a743..dbe2efce 100644 --- a/daemon/port.c +++ b/daemon/port.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009 Nedko Arnaudov + * Copyright (C) 2009, 2010 Nedko Arnaudov * ************************************************************************** * This file contains the implementation of the port objects @@ -53,7 +53,7 @@ struct ladish_port bool ladish_port_create( - uuid_t uuid_ptr, + const uuid_t uuid_ptr, ladish_port_handle * port_handle_ptr) { struct ladish_port * port_ptr; @@ -95,6 +95,11 @@ ladish_port_create( #define port_ptr ((struct ladish_port * )port_handle) +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); +} + void ladish_port_destroy(ladish_port_handle port_handle) { log_info("port %p destroy", port_ptr); diff --git a/daemon/port.h b/daemon/port.h index a013a1aa..b6f7a344 100644 --- a/daemon/port.h +++ b/daemon/port.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009 Nedko Arnaudov + * Copyright (C) 2009, 2010 Nedko Arnaudov * ************************************************************************** * This file contains the interface of the port objects @@ -31,7 +31,8 @@ typedef struct ladish_port_tag { int unused; } * ladish_port_handle; -bool ladish_port_create(uuid_t uuid_ptr, ladish_port_handle * port_handle_ptr); +bool ladish_port_create(const uuid_t uuid_ptr, 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); void ladish_port_get_uuid(ladish_port_handle port_handle, uuid_t uuid); diff --git a/daemon/room.c b/daemon/room.c index a92befde..d3d2e85b 100644 --- a/daemon/room.c +++ b/daemon/room.c @@ -26,7 +26,6 @@ #include "room.h" #include "../dbus_constants.h" -#include "graph.h" #include "graph_dict.h" struct ladish_room @@ -91,14 +90,24 @@ ladish_room_create( return false; } - if (object_path) + if (!ladish_graph_create(&room_ptr->graph, object_path)) { - if (!ladish_graph_create(&room_ptr->graph, object_path)) + free(room_ptr); + return false; + } + + if (template != NULL) + { + if (!ladish_graph_copy(ladish_room_get_graph(template), room_ptr->graph)) { + ladish_graph_destroy(room_ptr->graph, true); free(room_ptr); return false; } + } + if (object_path) + { room_ptr->dbus_object = dbus_object_path_new( object_path, &g_interface_room, room_ptr, @@ -128,7 +137,6 @@ ladish_room_create( else { room_ptr->dbus_object = NULL; - room_ptr->graph = NULL; } *room_handle_ptr = (ladish_room_handle)room_ptr; @@ -144,9 +152,9 @@ ladish_room_destroy( if (room_ptr->dbus_object != NULL) { dbus_object_path_destroy(g_dbus_connection, room_ptr->dbus_object); - ladish_graph_destroy(room_ptr->graph, true); } + ladish_graph_destroy(room_ptr->graph, true); free(room_ptr->name); free(room_ptr); } @@ -163,11 +171,6 @@ const char * ladish_room_get_name(ladish_room_handle room_handle) const char * ladish_room_get_opath(ladish_room_handle room_handle) { - if (room_ptr->graph == NULL) - { - return NULL; - } - return ladish_graph_get_opath(room_ptr->graph); } @@ -187,6 +190,11 @@ void ladish_room_get_uuid(ladish_room_handle room_handle, uuid_t uuid_ptr) uuid_copy(uuid_ptr, room_ptr->uuid); } +ladish_graph_handle ladish_room_get_graph(ladish_room_handle room_handle) +{ + return room_ptr->graph; +} + #undef room_ptr ladish_room_handle ladish_room_from_list_node(struct list_head * node_ptr) diff --git a/daemon/room.h b/daemon/room.h index af579d43..0e98f5bd 100644 --- a/daemon/room.h +++ b/daemon/room.h @@ -28,6 +28,7 @@ #define ROOM_H__9A1CF253_0A17_402A_BDF8_9BD72B467118__INCLUDED #include "common.h" +#include "graph.h" typedef struct ladish_room_tag { int unused; } * ladish_room_handle; @@ -50,5 +51,6 @@ const char * ladish_room_get_name(ladish_room_handle room_handle); const char * ladish_room_get_opath(ladish_room_handle room_handle); bool ladish_room_get_template_uuid(ladish_room_handle room_handle, uuid_t uuid_ptr); void ladish_room_get_uuid(ladish_room_handle room_handle, uuid_t uuid_ptr); +ladish_graph_handle ladish_room_get_graph(ladish_room_handle room_handle); #endif /* #ifndef ROOM_H__9A1CF253_0A17_402A_BDF8_9BD72B467118__INCLUDED */ diff --git a/lib/wkports.h b/lib/wkports.h index ff8a4ee8..1b8d25c9 100644 --- a/lib/wkports.h +++ b/lib/wkports.h @@ -27,6 +27,12 @@ #ifndef WKPORTS_H__0C316912_FC11_4B34_A8DB_5F9C359ACA03__INCLUDED #define WKPORTS_H__0C316912_FC11_4B34_A8DB_5F9C359ACA03__INCLUDED +/* 9c8ab1b7-211c-4056-bd91-94d63b3df9f2 */ +UUID_DEFINE(ladish_wkclient_capture,0x9C,0x8A,0xB1,0xB7,0x21,0x1C,0x40,0x56,0xBD,0x91,0x94,0xD6,0x3B,0x3D,0xF9,0xF2); + +/* e53018fe-4ae5-4d4c-b4a1-3b8f12e1ae91 */ +UUID_DEFINE(ladish_wkclient_playback,0xE5,0x30,0x18,0xFE,0x4A,0xE5,0x4D,0x4C,0xB4,0xA1,0x3B,0x8F,0x12,0xE1,0xAE,0x91); + /* 2776ef6f-39e1-4c5e-8920-3deeb409c3f5 */ UUID_DEFINE(ladish_wkport_playback_left,0x27,0x76,0xEF,0x6F,0x39,0xE1,0x4C,0x5E,0x89,0x20,0x3D,0xEE,0xB4,0x09,0xC3,0xF5);