add option --list-connections for listing JACK connections
the output can be later sent to the relpipe-out-jack to restore the connection graph
--- a/bash-completion.sh Wed Oct 07 22:29:38 2020 +0200
+++ b/bash-completion.sh Thu Oct 08 16:45:50 2020 +0200
@@ -43,6 +43,7 @@
elif [[ "$w1" == "--connect-to" ]]; then COMPREPLY=($(compgen -W "$(_relpipe_in_jack_completion_ports)" -- "$w0"))
elif [[ "$w1" == "--required-connections" && "x$w0" == "x" ]]; then COMPREPLY=("0")
elif [[ "$w1" == "--list-ports" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0"))
+ elif [[ "$w1" == "--list-connections" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0"))
elif [[ "$w1" == "--list-midi-messages" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0"))
else
OPTIONS=(
@@ -51,6 +52,7 @@
"--connect-to"
"--required-connections"
"--list-ports"
+ "--list-connections"
"--list-midi-messages"
)
COMPREPLY=($(compgen -W "${OPTIONS[*]}" -- "$w0"))
--- a/src/CLIParser.h Wed Oct 07 22:29:38 2020 +0200
+++ b/src/CLIParser.h Thu Oct 08 16:45:50 2020 +0200
@@ -53,6 +53,7 @@
static const relpipe::common::type::StringX OPTION_CONNECT_TO;
static const relpipe::common::type::StringX OPTION_REQUIRED_CONNECTIONS;
static const relpipe::common::type::StringX OPTION_LIST_PORTS;
+ static const relpipe::common::type::StringX OPTION_LIST_CONNECTIONS;
static const relpipe::common::type::StringX OPTION_LIST_MIDI_MESSAGES;
Configuration parse(const std::vector<relpipe::common::type::StringX>& arguments) {
@@ -71,6 +72,8 @@
c.requiredConnections = std::stoi(readNext(arguments, i));
} else if (option == OPTION_LIST_PORTS) {
c.listPorts = parseBoolean(readNext(arguments, i));
+ } else if (option == OPTION_LIST_CONNECTIONS) {
+ c.listConnections = parseBoolean(readNext(arguments, i));
} else if (option == OPTION_LIST_MIDI_MESSAGES) {
c.listMidiMessages = parseBoolean(readNext(arguments, i));
} else throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
@@ -88,6 +91,7 @@
const relpipe::common::type::StringX CLIParser::OPTION_CONNECT_TO = L"--connect-to";
const relpipe::common::type::StringX CLIParser::OPTION_REQUIRED_CONNECTIONS = L"--required-connections";
const relpipe::common::type::StringX CLIParser::OPTION_LIST_PORTS = L"--list-ports";
+const relpipe::common::type::StringX CLIParser::OPTION_LIST_CONNECTIONS = L"--list-connections";
const relpipe::common::type::StringX CLIParser::OPTION_LIST_MIDI_MESSAGES = L"--list-midi-messages";
}
--- a/src/Configuration.h Wed Oct 07 22:29:38 2020 +0200
+++ b/src/Configuration.h Thu Oct 08 16:45:50 2020 +0200
@@ -39,6 +39,7 @@
std::vector<relpipe::common::type::StringX> connectTo;
int requiredConnections = 0;
relpipe::common::type::Boolean listPorts = false;
+ relpipe::common::type::Boolean listConnections = false;
relpipe::common::type::Boolean listMidiMessages = true;
virtual ~Configuration() {
--- a/src/JackCommand.h Wed Oct 07 22:29:38 2020 +0200
+++ b/src/JackCommand.h Thu Oct 08 16:45:50 2020 +0200
@@ -187,7 +187,7 @@
writer->startRelation(L"port", metadata, true);
const char** portNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, 0);
-
+
std::regex midiTypePattern(".*midi$");
for (const char** portName = portNames; *portName; portName++) {
@@ -216,6 +216,36 @@
jack_free(portNames);
}
+ void listConnections(std::shared_ptr<relpipe::writer::RelationalWriter> writer) {
+ using namespace relpipe::writer;
+ vector<AttributeMetadata> metadata;
+
+ metadata.push_back({L"event", TypeId::STRING});
+ metadata.push_back({L"source_port", TypeId::STRING});
+ metadata.push_back({L"destination_port", TypeId::STRING});
+ writer->startRelation(L"connection", metadata, true);
+
+ const relpipe::common::type::StringX event = L"connect";
+
+ const char** sourcePortNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, JackPortFlags::JackPortIsOutput);
+
+ for (const char** sourcePortName = sourcePortNames; *sourcePortName; sourcePortName++) {
+ jack_port_t* sourcePort = jack_port_by_name(realTimeContext.jackClient, *sourcePortName);
+
+ const char** destinationPortNames = jack_port_get_all_connections(realTimeContext.jackClient, sourcePort);
+
+ for (const char** destinationPortName = destinationPortNames; destinationPortNames && *destinationPortName; destinationPortName++) {
+ writer->writeAttribute(event);
+ writer->writeAttribute(convertor.from_bytes(*sourcePortName));
+ writer->writeAttribute(convertor.from_bytes(*destinationPortName));
+ }
+
+ jack_free(destinationPortNames);
+ }
+
+ jack_free(sourcePortNames);
+ }
+
static void jackErrorCallback(const char * message) {
std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor; // TODO: local system encoding
std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl;
@@ -282,6 +312,7 @@
vector<AttributeMetadata> metadata;
if (configuration.listPorts) listPorts(writer);
+ if (configuration.listConnections) listConnections(writer);
if (!configuration.listMidiMessages) return;
metadata.push_back({L"event", TypeId::STRING});