daemon: load studios with rooms
This commit is contained in:
parent
5bb96d51e7
commit
00cc1087dc
|
@ -52,6 +52,8 @@
|
|||
#define PARSE_CONTEXT_CONNECTION 12
|
||||
#define PARSE_CONTEXT_APPLICATIONS 13
|
||||
#define PARSE_CONTEXT_APPLICATION 14
|
||||
#define PARSE_CONTEXT_ROOMS 15
|
||||
#define PARSE_CONTEXT_ROOM 16
|
||||
|
||||
#define MAX_STACK_DEPTH 10
|
||||
#define MAX_DATA_SIZE 10240
|
||||
|
@ -67,13 +69,14 @@ struct parse_context
|
|||
ladish_client_handle client;
|
||||
ladish_port_handle port;
|
||||
ladish_dict_handle dict;
|
||||
ladish_room_handle room;
|
||||
uint64_t connection_id;
|
||||
bool terminal;
|
||||
bool autorun;
|
||||
uint8_t level;
|
||||
};
|
||||
|
||||
static const char * get_string_attribute(const char * const * attr, const char * key)
|
||||
static const char * get_string_attribute_internal(const char * const * attr, const char * key, bool optional)
|
||||
{
|
||||
while (attr[0] != NULL)
|
||||
{
|
||||
|
@ -85,15 +88,24 @@ static const char * get_string_attribute(const char * const * attr, const char *
|
|||
attr += 2;
|
||||
}
|
||||
|
||||
log_error("attribute \"%s\" is missing");
|
||||
if (!optional)
|
||||
{
|
||||
log_error("attribute \"%s\" is missing", key);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char * get_uuid_attribute(const char * const * attr, const char * key, uuid_t uuid)
|
||||
static const char * get_string_attribute(const char * const * attr, const char * key)
|
||||
{
|
||||
return get_string_attribute_internal(attr, key, false);
|
||||
}
|
||||
|
||||
static const char * get_uuid_attribute(const char * const * attr, const char * key, uuid_t uuid, bool optional)
|
||||
{
|
||||
const char * value;
|
||||
|
||||
value = get_string_attribute(attr, key);
|
||||
value = get_string_attribute_internal(attr, key, optional);
|
||||
if (value == NULL)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -183,7 +195,7 @@ get_name_and_uuid_attributes(
|
|||
return false;
|
||||
}
|
||||
|
||||
uuid_str = get_uuid_attribute(attr, "uuid", uuid);
|
||||
uuid_str = get_uuid_attribute(attr, "uuid", uuid, false);
|
||||
if (uuid_str == NULL)
|
||||
{
|
||||
log_error("%s \"uuid\" attribute is not available. name=\"%s\"", element_description, name_str);
|
||||
|
@ -195,6 +207,134 @@ get_name_and_uuid_attributes(
|
|||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
parse_port_type_and_direction_attributes(
|
||||
const char * element_description,
|
||||
const char * const * attr,
|
||||
uint32_t * type_ptr,
|
||||
uint32_t * flags_ptr)
|
||||
{
|
||||
const char * type_str;
|
||||
const char * direction_str;
|
||||
|
||||
type_str = get_string_attribute(attr, "type");
|
||||
if (type_str == NULL)
|
||||
{
|
||||
log_error("%s \"type\" attribute is not available", element_description);
|
||||
return false;
|
||||
}
|
||||
|
||||
direction_str = get_string_attribute(attr, "direction");
|
||||
if (direction_str == NULL)
|
||||
{
|
||||
log_error("%s \"direction\" attribute is not available", element_description);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(type_str, "midi") == 0)
|
||||
{
|
||||
*type_ptr = JACKDBUS_PORT_TYPE_MIDI;
|
||||
}
|
||||
else if (strcmp(type_str, "audio") == 0)
|
||||
{
|
||||
*type_ptr = JACKDBUS_PORT_TYPE_AUDIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("%s \"type\" attribute contains unknown value \"%s\"", element_description, type_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(direction_str, "playback") == 0)
|
||||
{
|
||||
*flags_ptr = 0;
|
||||
JACKDBUS_PORT_SET_INPUT(*flags_ptr);
|
||||
}
|
||||
else if (strcmp(direction_str, "capture") == 0)
|
||||
{
|
||||
*flags_ptr = 0;
|
||||
JACKDBUS_PORT_SET_OUTPUT(*flags_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("%s \"direction\" attribute contains unknown value \"%s\"", element_description, direction_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dump_element_stack(struct parse_context * context_ptr)
|
||||
{
|
||||
signed int depth;
|
||||
const char * descr;
|
||||
|
||||
log_info("depth=%d", context_ptr->depth);
|
||||
|
||||
for (depth = context_ptr->depth; depth >= 0; depth--)
|
||||
{
|
||||
switch (context_ptr->element[depth])
|
||||
{
|
||||
case PARSE_CONTEXT_ROOT:
|
||||
descr = "root";
|
||||
break;
|
||||
case PARSE_CONTEXT_STUDIO:
|
||||
descr = "studio";
|
||||
break;
|
||||
case PARSE_CONTEXT_JACK:
|
||||
descr = "jack";
|
||||
break;
|
||||
case PARSE_CONTEXT_CONF:
|
||||
descr = "conf";
|
||||
break;
|
||||
case PARSE_CONTEXT_PARAMETER:
|
||||
descr = "parameter";
|
||||
break;
|
||||
case PARSE_CONTEXT_CLIENTS:
|
||||
descr = "clients";
|
||||
break;
|
||||
case PARSE_CONTEXT_CLIENT:
|
||||
descr = "client";
|
||||
break;
|
||||
case PARSE_CONTEXT_PORTS:
|
||||
descr = "ports";
|
||||
break;
|
||||
case PARSE_CONTEXT_PORT:
|
||||
descr = "port";
|
||||
break;
|
||||
case PARSE_CONTEXT_DICT:
|
||||
descr = "dict";
|
||||
break;
|
||||
case PARSE_CONTEXT_KEY:
|
||||
descr = "key";
|
||||
break;
|
||||
case PARSE_CONTEXT_CONNECTIONS:
|
||||
descr = "connections";
|
||||
break;
|
||||
case PARSE_CONTEXT_CONNECTION:
|
||||
descr = "connection";
|
||||
break;
|
||||
case PARSE_CONTEXT_APPLICATIONS:
|
||||
descr = "applications";
|
||||
break;
|
||||
case PARSE_CONTEXT_APPLICATION:
|
||||
descr = "application";
|
||||
break;
|
||||
case PARSE_CONTEXT_ROOMS:
|
||||
descr = "rooms";
|
||||
break;
|
||||
case PARSE_CONTEXT_ROOM:
|
||||
descr = "room";
|
||||
break;
|
||||
default:
|
||||
descr = "?";
|
||||
}
|
||||
|
||||
log_info("%d - %u (%s)", depth, context_ptr->element[depth], descr);
|
||||
}
|
||||
}
|
||||
|
||||
#define context_ptr ((struct parse_context *)data)
|
||||
|
||||
static void callback_chrdata(void * data, const XML_Char * s, int len)
|
||||
|
@ -230,6 +370,8 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
|
|||
uuid_t uuid2;
|
||||
ladish_port_handle port1;
|
||||
ladish_port_handle port2;
|
||||
uint32_t port_type;
|
||||
uint32_t port_flags;
|
||||
|
||||
if (context_ptr->error)
|
||||
{
|
||||
|
@ -295,6 +437,50 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
|
|||
return;
|
||||
}
|
||||
|
||||
if (strcmp(el, "rooms") == 0)
|
||||
{
|
||||
//log_info("<rooms>");
|
||||
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ROOMS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(el, "room") == 0)
|
||||
{
|
||||
//log_info("<room>");
|
||||
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ROOM;
|
||||
|
||||
if (context_ptr->room != NULL)
|
||||
{
|
||||
log_error("nested rooms");
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (context_ptr->depth == 2 &&
|
||||
context_ptr->element[0] == PARSE_CONTEXT_STUDIO &&
|
||||
context_ptr->element[1] == PARSE_CONTEXT_ROOMS)
|
||||
{
|
||||
if (!get_name_and_uuid_attributes("/studio/rooms/room", attr, &name, &uuid_str, uuid))
|
||||
{
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ladish_room_create(uuid, name, NULL, g_studio.studio_graph, &context_ptr->room))
|
||||
{
|
||||
log_error("ladish_room_create() failed.");
|
||||
context_ptr->error = XML_TRUE;
|
||||
ASSERT(context_ptr->room == NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
log_error("ignoring <room> element in wrong context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(el, "client") == 0)
|
||||
{
|
||||
//log_info("<client>");
|
||||
|
@ -349,6 +535,13 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
|
|||
|
||||
log_info("studio client \"%s\" with uuid %s", name, uuid_str);
|
||||
|
||||
context_ptr->client = ladish_graph_find_client_by_uuid(g_studio.studio_graph, uuid);
|
||||
if (context_ptr->client != NULL)
|
||||
{
|
||||
log_info("Found existing client");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ladish_client_create(uuid, &context_ptr->client))
|
||||
{
|
||||
log_error("ladish_client_create() failed.");
|
||||
|
@ -389,73 +582,125 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
|
|||
return;
|
||||
}
|
||||
|
||||
if (context_ptr->client == NULL)
|
||||
if (context_ptr->depth >= 3 &&
|
||||
context_ptr->element[context_ptr->depth - 3] == PARSE_CONTEXT_CLIENTS &&
|
||||
context_ptr->element[context_ptr->depth - 2] == PARSE_CONTEXT_CLIENT &&
|
||||
context_ptr->element[context_ptr->depth - 1] == PARSE_CONTEXT_PORTS)
|
||||
{
|
||||
//log_info("client port");
|
||||
if (context_ptr->client == NULL)
|
||||
{
|
||||
log_error("client-less port");
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (context_ptr->depth == 5 &&
|
||||
context_ptr->element[0] == PARSE_CONTEXT_STUDIO &&
|
||||
context_ptr->element[1] == PARSE_CONTEXT_JACK &&
|
||||
context_ptr->element[2] == PARSE_CONTEXT_CLIENTS &&
|
||||
context_ptr->element[3] == PARSE_CONTEXT_CLIENT &&
|
||||
context_ptr->element[4] == PARSE_CONTEXT_PORTS)
|
||||
{
|
||||
if (!get_name_and_uuid_attributes("/studio/jack/clients/client/ports/port", attr, &name, &uuid_str, uuid))
|
||||
{
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("jack port \"%s\" with uuid %s", name, uuid_str);
|
||||
|
||||
if (!ladish_port_create(uuid, false, &context_ptr->port))
|
||||
if (context_ptr->depth == 5 && context_ptr->element[0] == PARSE_CONTEXT_STUDIO && context_ptr->element[1] == PARSE_CONTEXT_JACK)
|
||||
{
|
||||
log_error("ladish_port_create() failed.");
|
||||
if (!get_name_and_uuid_attributes("/studio/jack/clients/client/ports/port", attr, &name, &uuid_str, uuid))
|
||||
{
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("jack port \"%s\" with uuid %s", name, uuid_str);
|
||||
|
||||
if (!ladish_port_create(uuid, false, &context_ptr->port))
|
||||
{
|
||||
log_error("ladish_port_create() failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ladish_graph_add_port(g_studio.jack_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
|
||||
{
|
||||
log_error("ladish_graph_add_port() failed.");
|
||||
ladish_port_destroy(context_ptr->port);
|
||||
context_ptr->port = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ladish_graph_add_port(g_studio.jack_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
|
||||
else if (context_ptr->depth == 4 && context_ptr->element[0] == PARSE_CONTEXT_STUDIO)
|
||||
{
|
||||
log_error("ladish_graph_add_port() failed.");
|
||||
ladish_port_destroy(context_ptr->port);
|
||||
context_ptr->port = NULL;
|
||||
if (!get_name_and_uuid_attributes("/studio/clients/client/ports/port", attr, &name, &uuid_str, uuid))
|
||||
{
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
uuid2_str = get_uuid_attribute(attr, "link_uuid", uuid2, true);
|
||||
|
||||
log_info("studio port \"%s\" with uuid %s (%s)", name, uuid_str, uuid_str == NULL ? "normal" : "room link");
|
||||
|
||||
if (uuid2_str == NULL)
|
||||
{ /* normal studio port */
|
||||
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", uuid_str);
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ladish_graph_add_port(g_studio.studio_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
|
||||
{
|
||||
log_error("ladish_graph_add_port() failed.");
|
||||
ladish_port_destroy(context_ptr->port);
|
||||
context_ptr->port = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* room link port */
|
||||
context_ptr->port = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2, false);
|
||||
if (context_ptr->port == NULL)
|
||||
{
|
||||
log_error("room link port not found");
|
||||
context_ptr->port = NULL;
|
||||
}
|
||||
|
||||
ladish_graph_set_link_port_override_uuid(g_studio.studio_graph, uuid2, uuid);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (context_ptr->depth == 4 &&
|
||||
else if (context_ptr->depth == 3 &&
|
||||
context_ptr->element[0] == PARSE_CONTEXT_STUDIO &&
|
||||
context_ptr->element[1] == PARSE_CONTEXT_CLIENTS &&
|
||||
context_ptr->element[2] == PARSE_CONTEXT_CLIENT &&
|
||||
context_ptr->element[3] == PARSE_CONTEXT_PORTS)
|
||||
context_ptr->element[1] == PARSE_CONTEXT_ROOMS &&
|
||||
context_ptr->element[2] == PARSE_CONTEXT_ROOM)
|
||||
{
|
||||
if (!get_name_and_uuid_attributes("/studio/clients/client/ports/port", attr, &name, &uuid_str, uuid))
|
||||
ASSERT(context_ptr->room != NULL);
|
||||
//log_info("room port");
|
||||
|
||||
if (!get_name_and_uuid_attributes("/studio/rooms/room/port", attr, &name, &uuid_str, uuid))
|
||||
{
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("studio port \"%s\" with uuid %s", name, uuid_str);
|
||||
log_info("room port \"%s\" with uuid %s", name, uuid_str);
|
||||
|
||||
context_ptr->port = ladish_graph_find_port_by_uuid(g_studio.jack_graph, uuid, false);
|
||||
if (!parse_port_type_and_direction_attributes("/studio/rooms/room/port", attr, &port_type, &port_flags))
|
||||
{
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
context_ptr->port = ladish_room_add_port(context_ptr->room, uuid, name, port_type, port_flags);
|
||||
if (context_ptr->port == NULL)
|
||||
{
|
||||
log_error("studio client with non-jack port %s", uuid_str);
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
log_error("ladish_room_add_port() failed.");
|
||||
context_ptr->port = NULL;
|
||||
}
|
||||
|
||||
if (!ladish_graph_add_port(g_studio.studio_graph, context_ptr->client, context_ptr->port, name, 0, 0, true))
|
||||
{
|
||||
log_error("ladish_graph_add_port() failed.");
|
||||
ladish_port_destroy(context_ptr->port);
|
||||
context_ptr->port = NULL;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
log_error("port element in wrong place");
|
||||
dump_element_stack(context_ptr);
|
||||
context_ptr->error = XML_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -471,7 +716,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
|
|||
//log_info("<connection>");
|
||||
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_CONNECTION;
|
||||
|
||||
uuid_str = get_uuid_attribute(attr, "port1", uuid);
|
||||
uuid_str = get_uuid_attribute(attr, "port1", uuid, false);
|
||||
if (uuid_str == NULL)
|
||||
{
|
||||
log_error("/studio/connections/connection \"port1\" attribute is not available.");
|
||||
|
@ -479,7 +724,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
|
|||
return;
|
||||
}
|
||||
|
||||
uuid2_str = get_uuid_attribute(attr, "port2", uuid2);
|
||||
uuid2_str = get_uuid_attribute(attr, "port2", uuid2, false);
|
||||
if (uuid2_str == NULL)
|
||||
{
|
||||
log_error("/studio/connections/connection \"port2\" attribute is not available.");
|
||||
|
@ -489,7 +734,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
|
|||
|
||||
log_info("studio connection between port %s and port %s", uuid_str, uuid2_str);
|
||||
|
||||
port1 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid, false);
|
||||
port1 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid, true);
|
||||
if (port1 == NULL)
|
||||
{
|
||||
log_error("studio client with unknown port %s", uuid_str);
|
||||
|
@ -497,7 +742,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, false);
|
||||
port2 = ladish_graph_find_port_by_uuid(g_studio.studio_graph, uuid2, true);
|
||||
if (port2 == NULL)
|
||||
{
|
||||
log_error("studio client with unknown port %s", uuid2_str);
|
||||
|
@ -800,6 +1045,12 @@ static void callback_elend(void * data, const char * el)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_ROOM)
|
||||
{
|
||||
//log_info("</room>");
|
||||
ASSERT(context_ptr->room != NULL);
|
||||
context_ptr->room = NULL;
|
||||
}
|
||||
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_DICT)
|
||||
{
|
||||
//log_info("</dict>");
|
||||
|
@ -979,6 +1230,7 @@ static bool run(void * command_context)
|
|||
parse_context.client = NULL;
|
||||
parse_context.port = NULL;
|
||||
parse_context.dict = NULL;
|
||||
parse_context.room = NULL;
|
||||
|
||||
XML_SetElementHandler(parser, callback_elstart, callback_elend);
|
||||
XML_SetCharacterDataHandler(parser, callback_chrdata);
|
||||
|
|
|
@ -135,9 +135,9 @@ create_room_template_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 */
|
||||
playback = JACKDBUS_PORT_IS_INPUT(flags);
|
||||
ASSERT(playback || JACKDBUS_PORT_IS_OUTPUT(flags)); /* playback or capture */
|
||||
ASSERT(!(playback && JACKDBUS_PORT_IS_OUTPUT(flags))); /* but not both */
|
||||
client = playback ? room_descriptor_ptr->playback : room_descriptor_ptr->capture;
|
||||
|
||||
if (!ladish_port_create(uuid_ptr, true, &port))
|
||||
|
|
|
@ -101,6 +101,49 @@ static struct ladish_graph_port * ladish_graph_find_port_by_id_internal(struct l
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct ladish_graph_port *
|
||||
ladish_graph_find_port_by_uuid_internal(
|
||||
struct ladish_graph * graph_ptr,
|
||||
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 (use_link_override_uuids && 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ladish_graph_connection * ladish_graph_find_connection_by_id(struct ladish_graph * graph_ptr, uint64_t connection_id)
|
||||
{
|
||||
struct list_head * node_ptr;
|
||||
|
@ -1607,38 +1650,12 @@ ladish_client_handle ladish_graph_find_client_by_uuid(ladish_graph_handle graph_
|
|||
|
||||
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 = ladish_graph_find_port_by_uuid_internal(graph_ptr, uuid, use_link_override_uuids);
|
||||
if (port_ptr != NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return port_ptr->port;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -2025,6 +2042,15 @@ const char * ladish_graph_get_port_name(ladish_graph_handle graph_handle, ladish
|
|||
return port_ptr->name;
|
||||
}
|
||||
|
||||
void ladish_graph_set_link_port_override_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, const uuid_t override_uuid)
|
||||
{
|
||||
struct ladish_graph_port * port_ptr;
|
||||
|
||||
port_ptr = ladish_graph_find_port_by_uuid_internal(graph_ptr, uuid, false);
|
||||
ASSERT(ladish_port_is_link(port_ptr->port));
|
||||
uuid_copy(port_ptr->link_uuid_override, override_uuid);
|
||||
}
|
||||
|
||||
bool
|
||||
ladish_graph_iterate_nodes(
|
||||
ladish_graph_handle graph_handle,
|
||||
|
|
|
@ -159,6 +159,7 @@ void ladish_graph_show_connection(ladish_graph_handle graph_handle, uint64_t con
|
|||
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_set_link_port_override_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, const uuid_t override_uuid);
|
||||
|
||||
void ladish_graph_dump(ladish_graph_handle graph_handle);
|
||||
|
||||
|
|
131
daemon/room.c
131
daemon/room.c
|
@ -54,22 +54,15 @@ extern const struct dbus_interface_descriptor g_interface_room;
|
|||
/* implemented in studio.c */
|
||||
void ladish_on_app_renamed(void * context, const char * old_name, const char * new_app_name);
|
||||
|
||||
static bool get_port_direction(uint32_t port_flags, bool * room_input_ptr)
|
||||
static bool port_is_input(uint32_t flags)
|
||||
{
|
||||
if (JACKDBUS_PORT_IS_INPUT(port_flags))
|
||||
{
|
||||
*room_input_ptr = true;
|
||||
return true;
|
||||
}
|
||||
bool playback;
|
||||
|
||||
if (JACKDBUS_PORT_IS_OUTPUT(port_flags))
|
||||
{
|
||||
*room_input_ptr = false;
|
||||
return true;
|
||||
}
|
||||
playback = JACKDBUS_PORT_IS_INPUT(flags);
|
||||
ASSERT(playback || JACKDBUS_PORT_IS_OUTPUT(flags)); /* playback or capture */
|
||||
ASSERT(!(playback && JACKDBUS_PORT_IS_OUTPUT(flags))); /* but not both */
|
||||
|
||||
log_error("room link port with bad flags %"PRIu32, port_flags);
|
||||
return false;
|
||||
return playback;
|
||||
}
|
||||
|
||||
struct ladish_room * ladish_room_create_internal(const uuid_t uuid_ptr, const char * name, const char * object_path)
|
||||
|
@ -145,16 +138,9 @@ create_shadow_port(
|
|||
uint32_t port_type,
|
||||
uint32_t port_flags)
|
||||
{
|
||||
bool room_input;
|
||||
|
||||
//log_info("Studio room port \"%s\"", port_name);
|
||||
|
||||
if (!get_port_direction(port_flags, &room_input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (room_input)
|
||||
if (port_is_input(port_flags))
|
||||
{
|
||||
JACKDBUS_PORT_CLEAR_INPUT(port_flags);
|
||||
JACKDBUS_PORT_SET_OUTPUT(port_flags);
|
||||
|
@ -187,24 +173,18 @@ create_port_link(
|
|||
uuid_t uuid_in_room;
|
||||
char uuid_in_owner_str[37];
|
||||
char uuid_in_room_str[37];
|
||||
bool room_input;
|
||||
const char * input_port;
|
||||
const char * output_port;
|
||||
|
||||
//log_info("Room port \"%s\"", port_name);
|
||||
|
||||
if (!get_port_direction(port_flags, &room_input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ladish_graph_get_port_uuid(room_ptr->graph, port_handle, uuid_in_room);
|
||||
ladish_graph_get_port_uuid(room_ptr->owner, port_handle, uuid_in_owner);
|
||||
|
||||
uuid_unparse(uuid_in_room, uuid_in_room_str);
|
||||
uuid_unparse(uuid_in_owner, uuid_in_owner_str);
|
||||
|
||||
if (room_input)
|
||||
if (port_is_input(port_flags))
|
||||
{
|
||||
input_port = uuid_in_room_str;
|
||||
output_port = uuid_in_owner_str;
|
||||
|
@ -301,13 +281,20 @@ ladish_room_create(
|
|||
}
|
||||
|
||||
room_ptr->index = index;
|
||||
ladish_room_get_uuid(template, room_ptr->template_uuid);
|
||||
room_ptr->owner = owner;
|
||||
room_ptr->started = false;
|
||||
|
||||
if (!ladish_graph_copy(ladish_room_get_graph(template), room_ptr->graph, false))
|
||||
if (template != NULL)
|
||||
{
|
||||
goto destroy;
|
||||
ladish_room_get_uuid(template, room_ptr->template_uuid);
|
||||
if (!ladish_graph_copy(ladish_room_get_graph(template), room_ptr->graph, false))
|
||||
{
|
||||
goto destroy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uuid_clear(room_ptr->template_uuid);
|
||||
}
|
||||
|
||||
if (!ladish_app_supervisor_create(&room_ptr->app_supervisor, object_path, room_ptr->name, room_ptr->graph, ladish_on_app_renamed))
|
||||
|
@ -399,11 +386,11 @@ void ladish_room_destroy(ladish_room_handle room_handle)
|
|||
|
||||
ladish_graph_remove_client(room_ptr->owner, room_ptr->client);
|
||||
ladish_client_destroy(room_ptr->client);
|
||||
|
||||
ladish_studio_room_disappeared((ladish_room_handle)room_ptr);
|
||||
ladish_studio_release_room_index(room_ptr->index);
|
||||
}
|
||||
|
||||
ladish_studio_room_disappeared((ladish_room_handle)room_ptr);
|
||||
ladish_studio_release_room_index(room_ptr->index);
|
||||
|
||||
ladish_graph_destroy(room_ptr->graph);
|
||||
free(room_ptr->name);
|
||||
free(room_ptr);
|
||||
|
@ -603,6 +590,82 @@ bool ladish_room_stopped(ladish_room_handle room_handle)
|
|||
return true;
|
||||
}
|
||||
|
||||
ladish_port_handle
|
||||
ladish_room_add_port(
|
||||
ladish_room_handle room_handle,
|
||||
const uuid_t uuid_ptr,
|
||||
const char * name,
|
||||
uint32_t type,
|
||||
uint32_t flags)
|
||||
{
|
||||
ladish_port_handle port;
|
||||
bool playback;
|
||||
ladish_client_handle client;
|
||||
const char * client_name;
|
||||
uuid_t client_uuid;
|
||||
bool new_client;
|
||||
|
||||
playback = port_is_input(flags);
|
||||
|
||||
ASSERT(!uuid_is_null(uuid_ptr));
|
||||
if (!ladish_port_create(uuid_ptr, true, &port))
|
||||
{
|
||||
log_error("Creation of room port \"%s\" failed.", name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
client_name = playback ? "Playback" : "Capture";
|
||||
uuid_copy(client_uuid, playback ? ladish_wkclient_playback : ladish_wkclient_capture);
|
||||
|
||||
/* if client is not found, create it and add it to graph */
|
||||
client = ladish_graph_find_client_by_uuid(room_ptr->graph, client_uuid);
|
||||
new_client = client == NULL;
|
||||
if (new_client)
|
||||
{
|
||||
if (!ladish_client_create(client_uuid, &client))
|
||||
{
|
||||
log_error("ladish_client_create() failed to create %s room client.", playback ? "playback" : "capture");
|
||||
goto fail_destroy_port;
|
||||
}
|
||||
|
||||
if (!ladish_graph_add_client(room_ptr->graph, client, client_name, true))
|
||||
{
|
||||
log_error("ladish_graph_add_client() failed to add %s room client to room graph.", playback ? "playback" : "capture");
|
||||
goto fail_destroy_client;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ladish_graph_add_port(room_ptr->graph, client, port, name, type, flags, true))
|
||||
{
|
||||
log_error("ladish_graph_add_port() failed to add %s room port \"%s\" to room graph.", playback ? "playback" : "capture", name);
|
||||
goto fail_destroy_client;
|
||||
}
|
||||
|
||||
if (!create_shadow_port(room_ptr, port, name, type, flags))
|
||||
{
|
||||
log_error("ladish_graph_add_port() failed to add port \"%s\" to room owner graph.", name);
|
||||
goto fail_remove_port;
|
||||
}
|
||||
|
||||
return port;
|
||||
|
||||
fail_remove_port:
|
||||
ASSERT(client != NULL);
|
||||
if (ladish_graph_remove_port(room_ptr->graph, port) != client)
|
||||
{
|
||||
ASSERT_NO_PASS;
|
||||
}
|
||||
fail_destroy_client:
|
||||
if (new_client)
|
||||
{
|
||||
ladish_client_destroy(client);
|
||||
}
|
||||
fail_destroy_port:
|
||||
ladish_port_destroy(port);
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef room_ptr
|
||||
|
||||
ladish_room_handle ladish_room_from_list_node(struct list_head * node_ptr)
|
||||
|
|
|
@ -78,4 +78,12 @@ bool ladish_room_start(ladish_room_handle room_handle, ladish_virtualizer_handle
|
|||
void ladish_room_initiate_stop(ladish_room_handle room_handle, bool clear_persist);
|
||||
bool ladish_room_stopped(ladish_room_handle room_handle);
|
||||
|
||||
ladish_port_handle
|
||||
ladish_room_add_port(
|
||||
ladish_room_handle room_handle,
|
||||
const uuid_t uuid_ptr,
|
||||
const char * name,
|
||||
uint32_t type,
|
||||
uint32_t flags);
|
||||
|
||||
#endif /* #ifndef ROOM_H__9A1CF253_0A17_402A_BDF8_9BD72B467118__INCLUDED */
|
||||
|
|
|
@ -229,12 +229,14 @@ void ladish_studio_emit_room_disappeared(ladish_room_handle room)
|
|||
|
||||
void ladish_studio_room_appeared(ladish_room_handle room)
|
||||
{
|
||||
log_info("Room \"%s\" appeared", ladish_room_get_name(room));
|
||||
list_add_tail(ladish_room_get_list_node(room), &g_studio.rooms);
|
||||
ladish_studio_emit_room_appeared(room);
|
||||
}
|
||||
|
||||
void ladish_studio_room_disappeared(ladish_room_handle room)
|
||||
{
|
||||
log_info("Room \"%s\" disappeared", ladish_room_get_name(room));
|
||||
list_del(ladish_room_get_list_node(room));
|
||||
ladish_studio_emit_room_disappeared(room);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue