summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Action.hpp51
-rw-r--r--src/ActionSink.hpp17
-rw-r--r--src/AlsaDriver.cpp66
-rw-r--r--src/AlsaStubDriver.cpp18
-rw-r--r--src/AudioDriver.hpp17
-rw-r--r--src/Canvas.cpp137
-rw-r--r--src/Canvas.hpp27
-rw-r--r--src/CanvasModule.cpp33
-rw-r--r--src/CanvasModule.hpp28
-rw-r--r--src/CanvasPort.hpp66
-rw-r--r--src/ClientID.hpp44
-rw-r--r--src/ClientInfo.hpp17
-rw-r--r--src/ClientType.hpp42
-rw-r--r--src/Configuration.cpp139
-rw-r--r--src/Configuration.hpp64
-rw-r--r--src/Coord.hpp17
-rw-r--r--src/Driver.hpp21
-rw-r--r--src/Drivers.cpp30
-rw-r--r--src/Drivers.hpp27
-rw-r--r--src/Event.hpp37
-rw-r--r--src/ILog.hpp21
-rw-r--r--src/JackDbusDriver.cpp166
-rw-r--r--src/JackLibDriver.cpp74
-rw-r--r--src/JackStubDriver.cpp18
-rw-r--r--src/Legend.cpp34
-rw-r--r--src/Legend.hpp21
-rw-r--r--src/Metadata.cpp24
-rw-r--r--src/Metadata.hpp24
-rw-r--r--src/Options.hpp17
-rw-r--r--src/Patchage.cpp326
-rw-r--r--src/Patchage.hpp35
-rw-r--r--src/PortID.hpp35
-rw-r--r--src/PortInfo.hpp29
-rw-r--r--src/PortNames.hpp17
-rw-r--r--src/PortType.hpp48
-rw-r--r--src/Reactor.cpp69
-rw-r--r--src/Reactor.hpp27
-rw-r--r--src/Setting.hpp108
-rw-r--r--src/SignalDirection.hpp44
-rw-r--r--src/TextViewLog.cpp28
-rw-r--r--src/TextViewLog.hpp21
-rw-r--r--src/UIFile.hpp46
-rw-r--r--src/Widget.hpp23
-rw-r--r--src/binary_location.h60
-rw-r--r--src/event_to_string.cpp69
-rw-r--r--src/event_to_string.hpp17
-rw-r--r--src/handle_event.cpp28
-rw-r--r--src/handle_event.hpp17
-rw-r--r--src/i18n.hpp12
-rw-r--r--src/jackey.h17
-rw-r--r--src/main.cpp48
-rw-r--r--src/make_alsa_driver.hpp30
-rw-r--r--src/make_jack_driver.hpp30
-rw-r--r--src/patchage.ui.in (renamed from src/patchage.ui)31
-rw-r--r--src/patchage_config.h112
-rw-r--r--src/warnings.hpp17
56 files changed, 1136 insertions, 1505 deletions
diff --git a/src/Action.hpp b/src/Action.hpp
index 0a13216..c791445 100644
--- a/src/Action.hpp
+++ b/src/Action.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_ACTION_HPP
#define PATCHAGE_ACTION_HPP
@@ -22,7 +9,7 @@
#include "Setting.hpp"
#include "SignalDirection.hpp"
-#include <boost/variant/variant.hpp>
+#include <variant>
namespace patchage {
namespace action {
@@ -81,22 +68,22 @@ struct ZoomOut {};
} // namespace action
/// A high-level action from the user
-using Action = boost::variant<action::ChangeSetting,
- action::ConnectPorts,
- action::DecreaseFontSize,
- action::DisconnectClient,
- action::DisconnectPort,
- action::DisconnectPorts,
- action::IncreaseFontSize,
- action::MoveModule,
- action::Refresh,
- action::ResetFontSize,
- action::SplitModule,
- action::UnsplitModule,
- action::ZoomFull,
- action::ZoomIn,
- action::ZoomNormal,
- action::ZoomOut>;
+using Action = std::variant<action::ChangeSetting,
+ action::ConnectPorts,
+ action::DecreaseFontSize,
+ action::DisconnectClient,
+ action::DisconnectPort,
+ action::DisconnectPorts,
+ action::IncreaseFontSize,
+ action::MoveModule,
+ action::Refresh,
+ action::ResetFontSize,
+ action::SplitModule,
+ action::UnsplitModule,
+ action::ZoomFull,
+ action::ZoomIn,
+ action::ZoomNormal,
+ action::ZoomOut>;
} // namespace patchage
diff --git a/src/ActionSink.hpp b/src/ActionSink.hpp
index c0d92ec..7e023f8 100644
--- a/src/ActionSink.hpp
+++ b/src/ActionSink.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_ACTION_SINK_HPP
#define PATCHAGE_ACTION_SINK_HPP
diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp
index 8ad3569..d320135 100644
--- a/src/AlsaDriver.cpp
+++ b/src/AlsaDriver.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "make_alsa_driver.hpp"
@@ -30,23 +17,21 @@
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
-#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
#include <alsa/asoundlib.h>
#include <pthread.h>
-#include <boost/optional/optional.hpp>
-
#include <cassert>
#include <cstdint>
#include <functional>
-#include <iosfwd>
#include <limits>
#include <memory>
+#include <optional>
#include <set>
#include <string>
#include <utility>
+#include <variant>
namespace patchage {
namespace {
@@ -57,10 +42,10 @@ class AlsaDriver : public Driver
public:
explicit AlsaDriver(ILog& log, EventSink emit_event);
- AlsaDriver(const AlsaDriver&) = delete;
+ AlsaDriver(const AlsaDriver&) = delete;
AlsaDriver& operator=(const AlsaDriver&) = delete;
- AlsaDriver(AlsaDriver&&) = delete;
+ AlsaDriver(AlsaDriver&&) = delete;
AlsaDriver& operator=(AlsaDriver&&) = delete;
~AlsaDriver() override;
@@ -82,8 +67,8 @@ private:
void _refresh_main();
ILog& _log;
- snd_seq_t* _seq;
- pthread_t _refresh_thread;
+ snd_seq_t* _seq{nullptr};
+ pthread_t _refresh_thread{};
struct SeqAddrComparator {
bool operator()(const snd_seq_addr_t& a, const snd_seq_addr_t& b) const
@@ -109,7 +94,7 @@ addr_to_id(const snd_seq_addr_t& addr, const bool is_input)
SignalDirection
port_direction(const snd_seq_port_info_t* const pinfo)
{
- const int caps = snd_seq_port_info_get_capability(pinfo);
+ const unsigned caps = snd_seq_port_info_get_capability(pinfo);
if ((caps & SND_SEQ_PORT_CAP_READ) && (caps & SND_SEQ_PORT_CAP_WRITE)) {
return SignalDirection::duplex;
@@ -135,7 +120,7 @@ client_info(snd_seq_client_info_t* const cinfo)
PortInfo
port_info(const snd_seq_port_info_t* const pinfo)
{
- const int type = snd_seq_port_info_get_type(pinfo);
+ const unsigned type = snd_seq_port_info_get_type(pinfo);
return {snd_seq_port_info_get_name(pinfo),
PortType::alsa_midi,
@@ -147,14 +132,9 @@ port_info(const snd_seq_port_info_t* const pinfo)
AlsaDriver::AlsaDriver(ILog& log, EventSink emit_event)
: Driver{std::move(emit_event)}
, _log(log)
- , _seq(nullptr)
- , _refresh_thread{}
{}
-AlsaDriver::~AlsaDriver()
-{
- detach();
-}
+AlsaDriver::~AlsaDriver() = default;
void
AlsaDriver::attach(bool /*launch_daemon*/)
@@ -299,8 +279,8 @@ AlsaDriver::ignore(const snd_seq_addr_t& addr, bool add)
snd_seq_port_info_set_port(pinfo, addr.port);
snd_seq_get_any_port_info(_seq, addr.client, addr.port, pinfo);
- const int type = snd_seq_port_info_get_type(pinfo);
- const int caps = snd_seq_port_info_get_capability(pinfo);
+ const unsigned type = snd_seq_port_info_get_type(pinfo);
+ const unsigned caps = snd_seq_port_info_get_capability(pinfo);
if (caps & SND_SEQ_PORT_CAP_NO_EXPORT) {
_ignored.insert(addr);
@@ -357,7 +337,7 @@ AlsaDriver::connect(const PortID& tail_id, const PortID& head_id)
result = false;
}
- int ret = snd_seq_subscribe_port(_seq, subs);
+ const int ret = snd_seq_subscribe_port(_seq, subs);
if (ret < 0) {
_log.error(
fmt::format("[ALSA] Subscription failed ({})", snd_strerror(ret)));
@@ -398,7 +378,7 @@ AlsaDriver::disconnect(const PortID& tail_id, const PortID& head_id)
return false;
}
- int ret = snd_seq_unsubscribe_port(_seq, subs);
+ const int ret = snd_seq_unsubscribe_port(_seq, subs);
if (ret < 0) {
_log.error(fmt::format("[ALSA] Failed to disconnect {} => {} ({})",
tail_id,
@@ -413,16 +393,16 @@ AlsaDriver::disconnect(const PortID& tail_id, const PortID& head_id)
bool
AlsaDriver::create_refresh_port()
{
- snd_seq_port_info_t* port_info = nullptr;
- snd_seq_port_info_alloca(&port_info);
- snd_seq_port_info_set_name(port_info, "System Announcement Receiver");
- snd_seq_port_info_set_type(port_info, SND_SEQ_PORT_TYPE_APPLICATION);
- snd_seq_port_info_set_capability(port_info,
+ snd_seq_port_info_t* info = nullptr;
+ snd_seq_port_info_alloca(&info);
+ snd_seq_port_info_set_name(info, "System Announcement Receiver");
+ snd_seq_port_info_set_type(info, SND_SEQ_PORT_TYPE_APPLICATION);
+ snd_seq_port_info_set_capability(info,
SND_SEQ_PORT_CAP_WRITE |
SND_SEQ_PORT_CAP_SUBS_WRITE |
SND_SEQ_PORT_CAP_NO_EXPORT);
- int ret = snd_seq_create_port(_seq, port_info);
+ int ret = snd_seq_create_port(_seq, info);
if (ret) {
_log.error(
fmt::format("[ALSA] Error creating port ({})", snd_strerror(ret)));
@@ -431,7 +411,7 @@ AlsaDriver::create_refresh_port()
// Subscribe the port to the system announcer
ret = snd_seq_connect_from(_seq,
- snd_seq_port_info_get_port(port_info),
+ snd_seq_port_info_get_port(info),
SND_SEQ_CLIENT_SYSTEM,
SND_SEQ_PORT_SYSTEM_ANNOUNCE);
if (ret) {
@@ -460,7 +440,7 @@ AlsaDriver::_refresh_main()
return;
}
- int caps = 0;
+ unsigned caps = 0U;
snd_seq_client_info_t* cinfo = nullptr;
snd_seq_client_info_alloca(&cinfo);
diff --git a/src/AlsaStubDriver.cpp b/src/AlsaStubDriver.cpp
new file mode 100644
index 0000000..5dc8f0b
--- /dev/null
+++ b/src/AlsaStubDriver.cpp
@@ -0,0 +1,18 @@
+// Copyright 2007-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "AudioDriver.hpp"
+#include "Driver.hpp"
+#include "make_alsa_driver.hpp"
+
+#include <memory>
+
+namespace patchage {
+
+std::unique_ptr<Driver>
+make_alsa_driver(ILog&, Driver::EventSink)
+{
+ return nullptr;
+}
+
+} // namespace patchage
diff --git a/src/AudioDriver.hpp b/src/AudioDriver.hpp
index 06cfe7f..ac3d5ec 100644
--- a/src/AudioDriver.hpp
+++ b/src/AudioDriver.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_AUDIODRIVER_HPP
#define PATCHAGE_AUDIODRIVER_HPP
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
index d86049d..ae8c51d 100644
--- a/src/Canvas.cpp
+++ b/src/Canvas.cpp
@@ -1,29 +1,20 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "Canvas.hpp"
#include "Action.hpp"
+#include "ActionSink.hpp"
#include "CanvasModule.hpp"
#include "CanvasPort.hpp"
+#include "ClientID.hpp"
#include "ClientInfo.hpp"
+#include "ClientType.hpp"
#include "Configuration.hpp"
#include "Coord.hpp"
#include "ILog.hpp"
#include "Metadata.hpp"
+#include "PortID.hpp"
#include "PortInfo.hpp"
#include "PortNames.hpp"
#include "Setting.hpp"
@@ -31,37 +22,84 @@
#include "warnings.hpp"
PATCHAGE_DISABLE_GANV_WARNINGS
-#include "ganv/Edge.hpp"
-#include "ganv/Module.hpp"
-#include "ganv/Node.hpp"
-#include "ganv/Port.hpp"
-#include "ganv/module.h"
+#include <ganv/Canvas.hpp>
+#include <ganv/Edge.hpp>
+#include <ganv/Module.hpp>
+#include <ganv/Node.hpp>
+#include <ganv/Port.hpp>
+#include <ganv/module.h>
+#include <ganv/types.h>
PATCHAGE_RESTORE_WARNINGS
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
-#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
-#include <boost/optional/optional.hpp>
#include <gdk/gdkkeysyms.h>
#include <sigc++/functors/mem_fun.h>
#include <sigc++/signal.h>
#include <cassert>
-#include <cstdlib>
#include <functional>
-#include <iosfwd>
+#include <optional>
#include <set>
#include <string>
#include <utility>
+#include <variant>
namespace patchage {
+namespace {
+
+struct RemovePortsData {
+ using Predicate = bool (*)(const CanvasPort*);
+
+ explicit RemovePortsData(Predicate p)
+ : pred(p)
+ {}
+
+ Predicate pred;
+ std::set<ClientID> empty_clients;
+};
+
+void
+delete_port_if_matches(GanvPort* port, void* cdata)
+{
+ auto* data = static_cast<RemovePortsData*>(cdata);
+ auto* pport = dynamic_cast<CanvasPort*>(Glib::wrap(port));
+ if (pport && data->pred(pport)) {
+ delete pport;
+ }
+}
+
+void
+remove_ports_matching(GanvNode* node, void* cdata)
+{
+ if (!GANV_IS_MODULE(node)) {
+ return;
+ }
+
+ Ganv::Module* cmodule = Glib::wrap(GANV_MODULE(node));
+ auto* pmodule = dynamic_cast<CanvasModule*>(cmodule);
+ if (!pmodule) {
+ return;
+ }
+
+ auto* data = static_cast<RemovePortsData*>(cdata);
+
+ pmodule->for_each_port(delete_port_if_matches, data);
+
+ if (pmodule->num_ports() == 0) {
+ data->empty_clients.insert(pmodule->id());
+ }
+}
+
+} // namespace
Canvas::Canvas(ILog& log, ActionSink& action_sink, int width, int height)
: Ganv::Canvas(width, height)
, _log(log)
, _action_sink(action_sink)
+ , _rng(width + height)
{
signal_event.connect(sigc::mem_fun(this, &Canvas::on_event));
signal_connect.connect(sigc::mem_fun(this, &Canvas::on_connect));
@@ -85,7 +123,7 @@ Canvas::create_port(Configuration& conf,
const auto client_info = metadata.client(client_id);
if (!client_info) {
_log.error(fmt::format(
- R"(Unable to add port "{}", client "{}" is unknown)", id, client_id));
+ u8"(Unable to add port “{}”, client “{}” is unknown)", id, client_id));
return nullptr;
}
@@ -108,8 +146,8 @@ Canvas::create_port(Configuration& conf,
Coord loc;
if (!conf.get_module_location(client_name, module_type, loc)) {
// No position saved, come up with a pseudo-random one
- loc.x = 20 + rand() % 640;
- loc.y = 20 + rand() % 480;
+ loc.x = static_cast<double>(20 + (_rng() % 640));
+ loc.y = static_cast<double>(20 + (_rng() % 480));
conf.set_module_location(client_name, module_type, loc);
}
@@ -123,7 +161,7 @@ Canvas::create_port(Configuration& conf,
if (parent->get_port(id)) {
// TODO: Update existing port?
_log.error(fmt::format(
- R"(Module "{}" already has port "{}")", client_name, port_name));
+ u8"(Module “{}” already has port “{}”)", client_name, port_name));
return nullptr;
}
@@ -192,49 +230,6 @@ Canvas::remove_port(const PortID& id)
delete port;
}
-struct RemovePortsData {
- using Predicate = bool (*)(const CanvasPort*);
-
- explicit RemovePortsData(Predicate p)
- : pred(p)
- {}
-
- Predicate pred;
- std::set<ClientID> empty_clients;
-};
-
-static void
-delete_port_if_matches(GanvPort* port, void* cdata)
-{
- auto* data = static_cast<RemovePortsData*>(cdata);
- auto* pport = dynamic_cast<CanvasPort*>(Glib::wrap(port));
- if (pport && data->pred(pport)) {
- delete pport;
- }
-}
-
-static void
-remove_ports_matching(GanvNode* node, void* cdata)
-{
- if (!GANV_IS_MODULE(node)) {
- return;
- }
-
- Ganv::Module* cmodule = Glib::wrap(GANV_MODULE(node));
- auto* pmodule = dynamic_cast<CanvasModule*>(cmodule);
- if (!pmodule) {
- return;
- }
-
- auto* data = static_cast<RemovePortsData*>(cdata);
-
- pmodule->for_each_port(delete_port_if_matches, data);
-
- if (pmodule->num_ports() == 0) {
- data->empty_clients.insert(pmodule->id());
- }
-}
-
void
Canvas::remove_ports(bool (*pred)(const CanvasPort*))
{
diff --git a/src/Canvas.hpp b/src/Canvas.hpp
index 943b399..5ab8a7e 100644
--- a/src/Canvas.hpp
+++ b/src/Canvas.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_CANVAS_HPP
#define PATCHAGE_CANVAS_HPP
@@ -20,17 +7,17 @@
#include "ActionSink.hpp"
#include "ClientID.hpp"
#include "PortID.hpp"
-#include "SignalDirection.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_GANV_WARNINGS
-#include "ganv/Canvas.hpp"
-#include "ganv/types.h"
+#include <ganv/Canvas.hpp>
+#include <ganv/types.h>
PATCHAGE_RESTORE_WARNINGS
#include <gdk/gdk.h>
#include <map>
+#include <random>
namespace Ganv {
class Node;
@@ -38,6 +25,8 @@ class Node;
namespace patchage {
+enum class SignalDirection;
+
struct PortInfo;
class CanvasModule;
@@ -86,6 +75,8 @@ private:
ActionSink& _action_sink;
PortIndex _port_index;
ModuleIndex _module_index;
+
+ std::minstd_rand _rng;
};
} // namespace patchage
diff --git a/src/CanvasModule.cpp b/src/CanvasModule.cpp
index d9e3c9c..43d2c8d 100644
--- a/src/CanvasModule.cpp
+++ b/src/CanvasModule.cpp
@@ -1,33 +1,23 @@
-/* This file is part of Patchage.
- * Copyright 2010-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2010-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "CanvasModule.hpp"
#include "Action.hpp"
+#include "ActionSink.hpp"
#include "Canvas.hpp"
#include "CanvasPort.hpp"
+#include "ClientID.hpp"
#include "PortID.hpp"
#include "SignalDirection.hpp"
+#include "i18n.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_GANV_WARNINGS
-#include "ganv/Port.hpp"
+#include <ganv/Module.hpp>
+#include <ganv/Port.hpp>
PATCHAGE_RESTORE_WARNINGS
-#include <glibmm/helperlist.h>
#include <gtkmm/menu.h>
#include <gtkmm/menu_elems.h>
#include <gtkmm/menuitem.h>
@@ -39,6 +29,7 @@ PATCHAGE_RESTORE_WARNINGS
#include <functional>
#include <memory>
#include <utility>
+#include <variant>
namespace patchage {
@@ -94,21 +85,21 @@ CanvasModule::update_menu()
bool
CanvasModule::show_menu(GdkEventButton* ev)
{
- _menu = std::unique_ptr<Gtk::Menu>{new Gtk::Menu()};
+ _menu = std::make_unique<Gtk::Menu>();
Gtk::Menu::MenuList& items = _menu->items();
if (_type == SignalDirection::duplex) {
items.push_back(Gtk::Menu_Helpers::MenuElem(
- "_Split", sigc::mem_fun(this, &CanvasModule::on_split)));
+ T("_Split"), sigc::mem_fun(this, &CanvasModule::on_split)));
update_menu();
} else {
items.push_back(Gtk::Menu_Helpers::MenuElem(
- "_Join", sigc::mem_fun(this, &CanvasModule::on_join)));
+ T("_Join"), sigc::mem_fun(this, &CanvasModule::on_join)));
}
items.push_back(Gtk::Menu_Helpers::MenuElem(
- "_Disconnect", sigc::mem_fun(this, &CanvasModule::on_disconnect)));
+ T("_Disconnect"), sigc::mem_fun(this, &CanvasModule::on_disconnect)));
_menu->popup(ev->button, ev->time);
return true;
diff --git a/src/CanvasModule.hpp b/src/CanvasModule.hpp
index e86699c..2ba7570 100644
--- a/src/CanvasModule.hpp
+++ b/src/CanvasModule.hpp
@@ -1,29 +1,15 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_CANVASMODULE_HPP
#define PATCHAGE_CANVASMODULE_HPP
#include "ActionSink.hpp"
#include "ClientID.hpp"
-#include "SignalDirection.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_GANV_WARNINGS
-#include "ganv/Module.hpp"
+#include <ganv/Module.hpp>
PATCHAGE_RESTORE_WARNINGS
#include <gdk/gdk.h>
@@ -34,6 +20,8 @@ PATCHAGE_RESTORE_WARNINGS
namespace patchage {
+enum class SignalDirection;
+
struct PortID;
class Canvas;
@@ -50,10 +38,10 @@ public:
double x,
double y);
- CanvasModule(const CanvasModule&) = delete;
+ CanvasModule(const CanvasModule&) = delete;
CanvasModule& operator=(const CanvasModule&) = delete;
- CanvasModule(CanvasModule&&) = delete;
+ CanvasModule(CanvasModule&&) = delete;
CanvasModule& operator=(CanvasModule&&) = delete;
~CanvasModule() override = default;
@@ -64,7 +52,7 @@ public:
CanvasPort* get_port(const PortID& id);
SignalDirection type() const { return _type; }
- ClientID id() const { return _id; }
+ const ClientID& id() const { return _id; }
const std::string& name() const { return _name; }
protected:
diff --git a/src/CanvasPort.hpp b/src/CanvasPort.hpp
index 3376e15..1210519 100644
--- a/src/CanvasPort.hpp
+++ b/src/CanvasPort.hpp
@@ -1,31 +1,18 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_CANVASPORT_HPP
#define PATCHAGE_CANVASPORT_HPP
#include "PortID.hpp"
#include "PortType.hpp"
+#include "i18n.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_GANV_WARNINGS
-#include "ganv/Port.hpp"
+#include <ganv/Port.hpp>
PATCHAGE_RESTORE_WARNINGS
-#include <boost/optional/optional.hpp>
#include <gdk/gdk.h>
#include <gtkmm/menu.h>
#include <gtkmm/menu_elems.h>
@@ -35,6 +22,7 @@ PATCHAGE_RESTORE_WARNINGS
#include <sigc++/signal.h>
#include <cstdint>
+#include <optional>
#include <string>
#include <utility>
@@ -48,15 +36,15 @@ namespace patchage {
class CanvasPort : public Ganv::Port
{
public:
- CanvasPort(Ganv::Module& module,
- PortType type,
- PortID id,
- const std::string& name,
- const std::string& human_name,
- bool is_input,
- uint32_t color,
- bool show_human_name,
- boost::optional<int> order = boost::optional<int>())
+ CanvasPort(Ganv::Module& module,
+ PortType type,
+ PortID id,
+ const std::string& name,
+ const std::string& human_name,
+ bool is_input,
+ uint32_t color,
+ bool show_human_name,
+ std::optional<int> order = std::optional<int>())
: Port(module,
(show_human_name && !human_name.empty()) ? human_name : name,
is_input,
@@ -70,10 +58,10 @@ public:
signal_event().connect(sigc::mem_fun(this, &CanvasPort::on_event));
}
- CanvasPort(const CanvasPort&) = delete;
+ CanvasPort(const CanvasPort&) = delete;
CanvasPort& operator=(const CanvasPort&) = delete;
- CanvasPort(CanvasPort&&) = delete;
+ CanvasPort(CanvasPort&&) = delete;
CanvasPort& operator=(CanvasPort&&) = delete;
~CanvasPort() override = default;
@@ -95,24 +83,24 @@ public:
Gtk::Menu* menu = Gtk::manage(new Gtk::Menu());
menu->items().push_back(Gtk::Menu_Helpers::MenuElem(
- "Disconnect", sigc::mem_fun(this, &Port::disconnect)));
+ T("Disconnect"), sigc::mem_fun(this, &Port::disconnect)));
menu->popup(ev->button.button, ev->button.time);
return true;
}
- PortType type() const { return _type; }
- PortID id() const { return _id; }
- const std::string& name() const { return _name; }
- const std::string& human_name() const { return _human_name; }
- const boost::optional<int>& order() const { return _order; }
+ PortType type() const { return _type; }
+ const PortID& id() const { return _id; }
+ const std::string& name() const { return _name; }
+ const std::string& human_name() const { return _human_name; }
+ const std::optional<int>& order() const { return _order; }
private:
- PortType _type;
- PortID _id;
- std::string _name;
- std::string _human_name;
- boost::optional<int> _order;
+ PortType _type;
+ PortID _id;
+ std::string _name;
+ std::string _human_name;
+ std::optional<int> _order;
};
} // namespace patchage
diff --git a/src/ClientID.hpp b/src/ClientID.hpp
index 911d2ec..dbe5b75 100644
--- a/src/ClientID.hpp
+++ b/src/ClientID.hpp
@@ -1,23 +1,16 @@
-/* This file is part of Patchage.
- * Copyright 2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_CLIENTID_HPP
#define PATCHAGE_CLIENTID_HPP
#include "ClientType.hpp"
+#include "warnings.hpp"
+
+PATCHAGE_DISABLE_FMT_WARNINGS
+#include <fmt/core.h>
+#include <fmt/ostream.h>
+PATCHAGE_RESTORE_WARNINGS
#include <cassert>
#include <cstdint>
@@ -31,10 +24,10 @@ namespace patchage {
struct ClientID {
using Type = ClientType;
- ClientID(const ClientID& copy) = default;
+ ClientID(const ClientID& copy) = default;
ClientID& operator=(const ClientID& copy) = default;
- ClientID(ClientID&& id) = default;
+ ClientID(ClientID&& id) = default;
ClientID& operator=(ClientID&& id) = default;
~ClientID() = default;
@@ -67,26 +60,26 @@ private:
assert(_type == Type::alsa);
}
- Type _type; ///< Determines which field is active
- std::string _jack_name{}; ///< Client name for Type::jack
- uint8_t _alsa_id{}; ///< Client ID for Type::alsa
+ Type _type; ///< Determines which field is active
+ std::string _jack_name; ///< Client name for Type::jack
+ uint8_t _alsa_id{}; ///< Client ID for Type::alsa
};
-static inline std::ostream&
+inline std::ostream&
operator<<(std::ostream& os, const ClientID& id)
{
switch (id.type()) {
case ClientID::Type::jack:
return os << "jack:" << id.jack_name();
case ClientID::Type::alsa:
- return os << "alsa:" << int(id.alsa_id());
+ return os << "alsa:" << static_cast<int>(id.alsa_id());
}
assert(false);
return os;
}
-static inline bool
+inline bool
operator==(const ClientID& lhs, const ClientID& rhs)
{
if (lhs.type() != rhs.type()) {
@@ -104,7 +97,7 @@ operator==(const ClientID& lhs, const ClientID& rhs)
return false;
}
-static inline bool
+inline bool
operator<(const ClientID& lhs, const ClientID& rhs)
{
if (lhs.type() != rhs.type()) {
@@ -124,4 +117,7 @@ operator<(const ClientID& lhs, const ClientID& rhs)
} // namespace patchage
+template<>
+struct fmt::formatter<patchage::ClientID> : fmt::ostream_formatter {};
+
#endif // PATCHAGE_CLIENTID_HPP
diff --git a/src/ClientInfo.hpp b/src/ClientInfo.hpp
index 8acddfe..2dd755e 100644
--- a/src/ClientInfo.hpp
+++ b/src/ClientInfo.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_CLIENTINFO_HPP
#define PATCHAGE_CLIENTINFO_HPP
diff --git a/src/ClientType.hpp b/src/ClientType.hpp
index 4785501..7a3f87a 100644
--- a/src/ClientType.hpp
+++ b/src/ClientType.hpp
@@ -1,22 +1,18 @@
-/* This file is part of Patchage.
- * Copyright 2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_CLIENTTYPE_HPP
#define PATCHAGE_CLIENTTYPE_HPP
+#include "warnings.hpp"
+
+PATCHAGE_DISABLE_FMT_WARNINGS
+#include <fmt/core.h>
+#include <fmt/ostream.h>
+PATCHAGE_RESTORE_WARNINGS
+
+#include <ostream>
+
namespace patchage {
/// A type of client (program) with supported ports
@@ -25,6 +21,22 @@ enum class ClientType {
alsa,
};
+inline std::ostream&
+operator<<(std::ostream& os, const ClientType type)
+{
+ switch (type) {
+ case ClientType::jack:
+ return os << "JACK";
+ case ClientType::alsa:
+ return os << "ALSA";
+ }
+
+ return os;
+}
+
} // namespace patchage
+template<>
+struct fmt::formatter<patchage::ClientType> : fmt::ostream_formatter {};
+
#endif // PATCHAGE_CLIENTTYPE_HPP
diff --git a/src/Configuration.cpp b/src/Configuration.cpp
index e498487..f77f825 100644
--- a/src/Configuration.cpp
+++ b/src/Configuration.cpp
@@ -1,21 +1,9 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "Configuration.hpp"
+#include "Coord.hpp"
#include "PortType.hpp"
#include "Setting.hpp"
#include "SignalDirection.hpp"
@@ -24,19 +12,45 @@
#include <cctype>
#include <cstdlib>
#include <fstream>
-#include <ios>
#include <iostream>
#include <limits>
#include <utility>
#include <vector>
namespace patchage {
+namespace {
+
+/// Return a vector of filenames in descending order by preference
+std::vector<std::string>
+get_filenames()
+{
+ std::vector<std::string> filenames;
+
+ const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
+ const char* home = getenv("HOME");
+
+ // XDG spec
+ if (xdg_config_home) {
+ filenames.push_back(std::string(xdg_config_home) + "/patchagerc");
+ } else if (home) {
+ filenames.push_back(std::string(home) + "/.config/patchagerc");
+ }
+
+ // Old location
+ if (home) {
+ filenames.push_back(std::string(home) + "/.patchagerc");
+ }
+
+ // Current directory (bundle or last-ditch effort)
+ filenames.emplace_back("patchagerc");
+
+ return filenames;
+}
-static const char* const port_type_names[N_PORT_TYPES] = {"JACK_AUDIO",
- "JACK_MIDI",
- "ALSA_MIDI",
- "JACK_OSC",
- "JACK_CV"};
+} // namespace
+
+static const char* const port_type_names[Configuration::n_port_types] =
+ {"JACK_AUDIO", "JACK_MIDI", "ALSA_MIDI", "JACK_OSC", "JACK_CV"};
Configuration::Configuration(std::function<void(const Setting&)> on_change)
: _on_change(std::move(on_change))
@@ -46,7 +60,7 @@ Configuration::Configuration(std::function<void(const Setting&)> on_change)
std::get<setting::WindowSize>(_settings).value = Coord{960.0, 540.0};
std::get<setting::Zoom>(_settings).value = 1.0f;
-#ifdef PATCHAGE_USE_LIGHT_THEME
+#if PATCHAGE_USE_LIGHT_THEME
_port_colors[static_cast<unsigned>(PortType::jack_audio)] =
_default_port_colors[static_cast<unsigned>(PortType::jack_audio)] =
0xA4BC8CFF;
@@ -166,34 +180,6 @@ Configuration::set_module_split(const std::string& name, bool split)
}
}
-/** Return a vector of filenames in descending order by preference. */
-static std::vector<std::string>
-get_filenames()
-{
- std::vector<std::string> filenames;
- std::string prefix;
-
- const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
- const char* home = getenv("HOME");
-
- // XDG spec
- if (xdg_config_home) {
- filenames.push_back(std::string(xdg_config_home) + "/patchagerc");
- } else if (home) {
- filenames.push_back(std::string(home) + "/.config/patchagerc");
- }
-
- // Old location
- if (home) {
- filenames.push_back(std::string(home) + "/.patchagerc");
- }
-
- // Current directory (bundle or last-ditch effort)
- filenames.emplace_back("patchagerc");
-
- return filenames;
-}
-
void
Configuration::load()
{
@@ -203,13 +189,13 @@ Configuration::load()
for (const auto& filename : filenames) {
file.open(filename.c_str(), std::ios::in);
if (file.good()) {
- std::cout << "Loading configuration from " << filename << std::endl;
+ std::cout << "Loading configuration from " << filename << "\n";
break;
}
}
if (!file.good()) {
- std::cout << "No configuration file present" << std::endl;
+ std::cout << "No configuration file present\n";
return;
}
@@ -248,7 +234,7 @@ Configuration::load()
file >> std::get<setting::HumanNames>(_settings).value;
} else if (key == "port_color") {
std::string type_name;
- uint32_t rgba = 0u;
+ uint32_t rgba = 0U;
file >> type_name;
file.ignore(1, '#');
file >> std::hex >> std::uppercase;
@@ -256,7 +242,7 @@ Configuration::load()
file >> std::dec >> std::nouppercase;
bool found = false;
- for (int i = 0; i < N_PORT_TYPES; ++i) {
+ for (unsigned i = 0U; i < n_port_types; ++i) {
if (type_name == port_type_names[i]) {
_port_colors[i] = rgba;
found = true;
@@ -264,8 +250,8 @@ Configuration::load()
}
}
if (!found) {
- std::cerr << "error: color for unknown port type `" << type_name << "'"
- << std::endl;
+ std::cerr << "error: color for unknown port type `" << type_name
+ << "'\n";
}
} else if (key == "module_position") {
Coord loc;
@@ -284,7 +270,7 @@ Configuration::load()
type = SignalDirection::duplex;
} else {
std::cerr << "error: bad position type `" << type_str
- << "' for module `" << name << "'" << std::endl;
+ << "' for module `" << name << "'\n";
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
@@ -294,8 +280,7 @@ Configuration::load()
set_module_location(name, type, loc);
} else {
- std::cerr << "warning: unknown configuration key `" << key << "'"
- << std::endl;
+ std::cerr << "warning: unknown configuration key `" << key << "'\n";
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
@@ -308,16 +293,20 @@ Configuration::load()
file.close();
}
-static inline void
+namespace {
+
+inline void
write_module_position(std::ofstream& os,
const std::string& name,
const char* type,
const Coord& loc)
{
os << "module_position \"" << name << "\""
- << " " << type << " " << loc.x << " " << loc.y << std::endl;
+ << " " << type << " " << loc.x << " " << loc.y << "\n";
}
+} // namespace
+
void
Configuration::save()
{
@@ -327,36 +316,36 @@ Configuration::save()
for (const std::string& filename : filenames) {
file.open(filename.c_str(), std::ios::out);
if (file.good()) {
- std::cout << "Writing configuration to " << filename << std::endl;
+ std::cout << "Writing configuration to " << filename << "\n";
break;
}
}
if (!file.good()) {
- std::cout << "Unable to open configuration file to write" << std::endl;
+ std::cout << "Unable to open configuration file to write\n";
return;
}
file << "window_location " << get<setting::WindowLocation>().x << " "
- << get<setting::WindowLocation>().y << std::endl;
+ << get<setting::WindowLocation>().y << "\n";
file << "window_size " << get<setting::WindowSize>().x << " "
- << get<setting::WindowSize>().y << std::endl;
+ << get<setting::WindowSize>().y << "\n";
- file << "zoom_level " << get<setting::Zoom>() << std::endl;
- file << "font_size " << get<setting::FontSize>() << std::endl;
- file << "show_toolbar " << get<setting::ToolbarVisible>() << std::endl;
- file << "sprung_layout " << get<setting::SprungLayout>() << std::endl;
- file << "show_messages " << get<setting::MessagesVisible>() << std::endl;
- file << "sort_ports " << get<setting::SortedPorts>() << std::endl;
- file << "messages_height " << get<setting::MessagesHeight>() << std::endl;
- file << "human_names " << get<setting::HumanNames>() << std::endl;
+ file << "zoom_level " << get<setting::Zoom>() << "\n";
+ file << "font_size " << get<setting::FontSize>() << "\n";
+ file << "show_toolbar " << get<setting::ToolbarVisible>() << "\n";
+ file << "sprung_layout " << get<setting::SprungLayout>() << "\n";
+ file << "show_messages " << get<setting::MessagesVisible>() << "\n";
+ file << "sort_ports " << get<setting::SortedPorts>() << "\n";
+ file << "messages_height " << get<setting::MessagesHeight>() << "\n";
+ file << "human_names " << get<setting::HumanNames>() << "\n";
file << std::hex << std::uppercase;
- for (int i = 0; i < N_PORT_TYPES; ++i) {
+ for (unsigned i = 0U; i < n_port_types; ++i) {
if (_port_colors[i] != _default_port_colors[i]) {
file << "port_color " << port_type_names[i] << " " << _port_colors[i]
- << std::endl;
+ << "\n";
}
}
file << std::dec << std::nouppercase;
diff --git a/src/Configuration.hpp b/src/Configuration.hpp
index d98968f..59039fc 100644
--- a/src/Configuration.hpp
+++ b/src/Configuration.hpp
@@ -1,43 +1,31 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_CONFIGURATION_HPP
#define PATCHAGE_CONFIGURATION_HPP
#include "Coord.hpp"
-#include "PortType.hpp"
#include "Setting.hpp"
-#include "SignalDirection.hpp"
-
-#include <boost/optional/optional.hpp>
#include <cstdint>
#include <functional>
#include <map>
+#include <optional>
#include <string>
#include <tuple>
#include <utility>
-
-#define N_PORT_TYPES 5
+#include <variant>
namespace patchage {
+enum class SignalDirection;
+enum class PortType;
+
class Configuration
{
public:
+ static constexpr unsigned n_port_types = 5U;
+
explicit Configuration(std::function<void(const Setting&)> on_change);
void load();
@@ -67,7 +55,7 @@ public:
// Set a global configuration setting
template<class S>
- void set(typename S::Value value)
+ void set(decltype(S::value) value)
{
S& setting = std::get<S>(_settings);
@@ -77,9 +65,25 @@ public:
}
}
+ // Set a global configuration setting
+ template<class S>
+ void set_setting(S new_setting)
+ {
+ set<S>(new_setting.value);
+ }
+
+ // Set a global port color setting
+ void set_setting(setting::PortColor new_setting)
+ {
+ const auto& color = _port_colors[static_cast<unsigned>(new_setting.type)];
+ if (color != new_setting.color) {
+ set_port_color(new_setting.type, new_setting.color);
+ }
+ }
+
// Get a global configuration setting
template<class S>
- typename S::Value get() const
+ decltype(S::value) get() const
{
return std::get<S>(_settings).value;
}
@@ -99,7 +103,7 @@ public:
visitor(std::get<setting::WindowSize>(_settings));
visitor(std::get<setting::Zoom>(_settings));
- for (auto i = 0u; i < N_PORT_TYPES; ++i) {
+ for (auto i = 0U; i < n_port_types; ++i) {
visitor(setting::PortColor{static_cast<PortType>(i), _port_colors[i]});
}
}
@@ -110,16 +114,16 @@ private:
: split(s)
{}
- boost::optional<Coord> input_location;
- boost::optional<Coord> output_location;
- boost::optional<Coord> inout_location;
- bool split;
+ std::optional<Coord> input_location;
+ std::optional<Coord> output_location;
+ std::optional<Coord> inout_location;
+ bool split;
};
std::map<std::string, ModuleSettings> _module_settings;
- uint32_t _default_port_colors[N_PORT_TYPES] = {};
- uint32_t _port_colors[N_PORT_TYPES] = {};
+ uint32_t _default_port_colors[n_port_types] = {};
+ uint32_t _port_colors[n_port_types] = {};
using Settings = std::tuple<setting::AlsaAttached,
setting::FontSize,
diff --git a/src/Coord.hpp b/src/Coord.hpp
index 2d6a85a..b24d7dc 100644
--- a/src/Coord.hpp
+++ b/src/Coord.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_COORD_HPP
#define PATCHAGE_COORD_HPP
diff --git a/src/Driver.hpp b/src/Driver.hpp
index da11765..4cb890b 100644
--- a/src/Driver.hpp
+++ b/src/Driver.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_DRIVER_HPP
#define PATCHAGE_DRIVER_HPP
@@ -36,10 +23,10 @@ public:
: _emit_event{std::move(emit_event)}
{}
- Driver(const Driver&) = delete;
+ Driver(const Driver&) = delete;
Driver& operator=(const Driver&) = delete;
- Driver(Driver&&) = delete;
+ Driver(Driver&&) = delete;
Driver& operator=(Driver&&) = delete;
virtual ~Driver() = default;
diff --git a/src/Drivers.cpp b/src/Drivers.cpp
index 4f57f34..7104b00 100644
--- a/src/Drivers.cpp
+++ b/src/Drivers.cpp
@@ -1,22 +1,10 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "Drivers.hpp"
#include "AudioDriver.hpp"
+#include "ClientType.hpp"
#include "Driver.hpp"
#include "Event.hpp"
#include "make_alsa_driver.hpp"
@@ -24,6 +12,7 @@
#include <functional>
#include <utility>
+#include <variant>
namespace patchage {
@@ -38,6 +27,17 @@ Drivers::Drivers(ILog& log, Driver::EventSink emit_event)
})}
{}
+Drivers::~Drivers()
+{
+ if (_alsa_driver) {
+ _alsa_driver->detach();
+ }
+
+ if (_jack_driver) {
+ _jack_driver->detach();
+ }
+}
+
void
Drivers::refresh()
{
diff --git a/src/Drivers.hpp b/src/Drivers.hpp
index ae3c063..a281d2e 100644
--- a/src/Drivers.hpp
+++ b/src/Drivers.hpp
@@ -1,31 +1,18 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_DRIVERS_HPP
#define PATCHAGE_DRIVERS_HPP
-#include "AudioDriver.hpp"
-#include "ClientType.hpp"
#include "Driver.hpp"
#include <memory>
namespace patchage {
+class AudioDriver;
class ILog;
+enum class ClientType;
/// Manager for all drivers
class Drivers
@@ -33,13 +20,13 @@ class Drivers
public:
Drivers(ILog& log, Driver::EventSink emit_event);
- Drivers(const Drivers&) = delete;
+ Drivers(const Drivers&) = delete;
Drivers& operator=(const Drivers&) = delete;
- Drivers(Drivers&&) = delete;
+ Drivers(Drivers&&) = delete;
Drivers& operator=(Drivers&&) = delete;
- ~Drivers() = default;
+ ~Drivers();
/// Refresh all drivers and emit results to the event sink
void refresh();
diff --git a/src/Event.hpp b/src/Event.hpp
index 233d1a1..36166e7 100644
--- a/src/Event.hpp
+++ b/src/Event.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_EVENT_HPP
#define PATCHAGE_EVENT_HPP
@@ -23,7 +10,7 @@
#include "PortID.hpp"
#include "PortInfo.hpp"
-#include <boost/variant/variant.hpp>
+#include <variant>
namespace patchage {
namespace event {
@@ -69,15 +56,15 @@ struct PortsDisconnected {
} // namespace event
/// An event from drivers that represents a change to the system
-using Event = boost::variant<event::Cleared,
- event::ClientCreated,
- event::ClientDestroyed,
- event::DriverAttached,
- event::DriverDetached,
- event::PortCreated,
- event::PortDestroyed,
- event::PortsConnected,
- event::PortsDisconnected>;
+using Event = std::variant<event::Cleared,
+ event::ClientCreated,
+ event::ClientDestroyed,
+ event::DriverAttached,
+ event::DriverDetached,
+ event::PortCreated,
+ event::PortDestroyed,
+ event::PortsConnected,
+ event::PortsDisconnected>;
} // namespace patchage
diff --git a/src/ILog.hpp b/src/ILog.hpp
index d71059a..5e00602 100644
--- a/src/ILog.hpp
+++ b/src/ILog.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_ILOG_HPP
#define PATCHAGE_ILOG_HPP
@@ -27,10 +14,10 @@ class ILog
public:
ILog() = default;
- ILog(const ILog&) = default;
+ ILog(const ILog&) = default;
ILog& operator=(const ILog&) = default;
- ILog(ILog&&) = default;
+ ILog(ILog&&) = default;
ILog& operator=(ILog&&) = default;
virtual ~ILog() = default;
diff --git a/src/JackDbusDriver.cpp b/src/JackDbusDriver.cpp
index 23c12f2..f84cb51 100644
--- a/src/JackDbusDriver.cpp
+++ b/src/JackDbusDriver.cpp
@@ -1,24 +1,15 @@
-/* This file is part of Patchage.
- * Copyright 2008-2020 David Robillard <d@drobilla.net>
- * Copyright 2008 Nedko Arnaudov <nedko@arnaudov.name>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2008-2020 David Robillard <d@drobilla.net>
+// Copyright 2008 Nedko Arnaudov <nedko@arnaudov.name>
+// SPDX-License-Identifier: GPL-3.0-or-later
+#include "AudioDriver.hpp"
+#include "ClientID.hpp"
#include "ClientType.hpp"
#include "Driver.hpp"
#include "Event.hpp"
#include "ILog.hpp"
+#include "PortID.hpp"
+#include "PortInfo.hpp"
#include "PortNames.hpp"
#include "PortType.hpp"
#include "SignalDirection.hpp"
@@ -27,35 +18,42 @@
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
-#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-shared.h>
#include <dbus/dbus.h>
-#include <glib.h>
#include <cassert>
+#include <cstdarg>
#include <cstdint>
#include <cstring>
-#include <set>
+#include <functional>
+#include <memory>
+#include <optional>
+#include <stdexcept>
#include <string>
+#include <utility>
+#include <variant>
#define JACKDBUS_SERVICE "org.jackaudio.service"
#define JACKDBUS_OBJECT "/org/jackaudio/Controller"
#define JACKDBUS_IFACE_CONTROL "org.jackaudio.JackControl"
#define JACKDBUS_IFACE_PATCHBAY "org.jackaudio.JackPatchbay"
-#define JACKDBUS_CALL_DEFAULT_TIMEOUT 1000 // in milliseconds
+namespace patchage {
+namespace {
-#define JACKDBUS_PORT_FLAG_INPUT 0x00000001
-#define JACKDBUS_PORT_FLAG_TERMINAL 0x00000010
+constexpr auto default_timeout = 1000; // in milliseconds
-#define JACKDBUS_PORT_TYPE_AUDIO 0
-#define JACKDBUS_PORT_TYPE_MIDI 1
+constexpr auto port_flag_input = 0x00000001U;
+constexpr auto port_flag_terminal = 0x00000010U;
-namespace patchage {
-namespace {
+enum JackDBusPortType {
+ AUDIO = 0,
+ MIDI = 1,
+};
/// Driver for JACK audio and midi ports that uses D-Bus
class JackDriver : public AudioDriver
@@ -63,10 +61,10 @@ class JackDriver : public AudioDriver
public:
explicit JackDriver(ILog& log, EventSink emit_event);
- JackDriver(const JackDriver&) = delete;
+ JackDriver(const JackDriver&) = delete;
JackDriver& operator=(const JackDriver&) = delete;
- JackDriver(JackDriver&&) = delete;
+ JackDriver(JackDriver&&) = delete;
JackDriver& operator=(JackDriver&&) = delete;
~JackDriver() override;
@@ -121,22 +119,18 @@ private:
ILog& _log;
DBusError _dbus_error;
- DBusConnection* _dbus_connection;
+ DBusConnection* _dbus_connection{};
- mutable bool _server_responding;
- bool _server_started;
+ mutable bool _server_responding{};
+ bool _server_started{};
- dbus_uint64_t _graph_version;
+ dbus_uint64_t _graph_version{};
};
JackDriver::JackDriver(ILog& log, EventSink emit_event)
: AudioDriver{std::move(emit_event)}
, _log(log)
, _dbus_error()
- , _dbus_connection(nullptr)
- , _server_responding(false)
- , _server_started(false)
- , _graph_version(0)
{
dbus_error_init(&_dbus_error);
}
@@ -155,23 +149,23 @@ JackDriver::~JackDriver()
void
JackDriver::update_attached()
{
- bool was_attached = _server_started;
- _server_started = is_started();
+ const bool was_attached = _server_started;
+ _server_started = is_started();
if (!_server_responding) {
if (was_attached) {
- _emit_event(DriverDetachmentEvent{ClientType::jack});
+ _emit_event(event::DriverDetached{ClientType::jack});
}
return;
}
if (_server_started && !was_attached) {
- _emit_event(DriverAttachmentEvent{ClientType::jack});
+ _emit_event(event::DriverAttached{ClientType::jack});
return;
}
if (!_server_started && was_attached) {
- _emit_event(DriverDetachmentEvent{ClientType::jack});
+ _emit_event(event::DriverDetached{ClientType::jack});
return;
}
}
@@ -194,7 +188,7 @@ JackDriver::on_jack_disappeared()
_server_responding = false;
if (_server_started) {
- _emit_event(DriverDetachmentEvent{ClientType::jack});
+ _emit_event(event::DriverDetached{ClientType::jack});
}
_server_started = false;
@@ -212,14 +206,14 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
const char* old_owner = nullptr;
const char* port2_name = nullptr;
const char* port_name = nullptr;
- dbus_uint32_t port_flags = 0u;
- dbus_uint32_t port_type = 0u;
- dbus_uint64_t client2_id = 0u;
- dbus_uint64_t client_id = 0u;
- dbus_uint64_t connection_id = 0u;
- dbus_uint64_t new_graph_version = 0u;
- dbus_uint64_t port2_id = 0u;
- dbus_uint64_t port_id = 0u;
+ dbus_uint32_t port_flags = 0U;
+ dbus_uint32_t port_type = 0U;
+ dbus_uint64_t client2_id = 0U;
+ dbus_uint64_t client_id = 0U;
+ dbus_uint64_t connection_id = 0U;
+ dbus_uint64_t new_graph_version = 0U;
+ dbus_uint64_t port2_id = 0U;
+ dbus_uint64_t port_id = 0U;
assert(jack_driver);
auto* me = static_cast<JackDriver*>(jack_driver);
@@ -279,12 +273,12 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
if (!me->_server_started) {
me->_server_started = true;
- me->_emit_event(DriverAttachmentEvent{ClientType::jack});
+ me->_emit_event(event::DriverAttached{ClientType::jack});
}
me->_emit_event(
- PortCreationEvent{PortID::jack(client_name, port_name),
- me->port_info(port_name, port_type, port_flags)});
+ event::PortCreated{PortID::jack(client_name, port_name),
+ me->port_info(port_name, port_type, port_flags)});
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -313,10 +307,10 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
if (!me->_server_started) {
me->_server_started = true;
- me->_emit_event(DriverAttachmentEvent{ClientType::jack});
+ me->_emit_event(event::DriverAttached{ClientType::jack});
}
- me->_emit_event(PortDestructionEvent{PortID::jack(client_name, port_name)});
+ me->_emit_event(event::PortDestroyed{PortID::jack(client_name, port_name)});
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -355,11 +349,12 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
if (!me->_server_started) {
me->_server_started = true;
- me->_emit_event(DriverAttachmentEvent{ClientType::jack});
+ me->_emit_event(event::DriverAttached{ClientType::jack});
}
- me->_emit_event(ConnectionEvent{PortID::jack(client_name, port_name),
- PortID::jack(client2_name, port2_name)});
+ me->_emit_event(
+ event::PortsConnected{PortID::jack(client_name, port_name),
+ PortID::jack(client2_name, port2_name)});
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -398,11 +393,12 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
if (!me->_server_started) {
me->_server_started = true;
- me->_emit_event(DriverAttachmentEvent{ClientType::jack});
+ me->_emit_event(event::DriverAttached{ClientType::jack});
}
- me->_emit_event(DisconnectionEvent{PortID::jack(client_name, port_name),
- PortID::jack(client2_name, port2_name)});
+ me->_emit_event(
+ event::PortsDisconnected{PortID::jack(client_name, port_name),
+ PortID::jack(client2_name, port2_name)});
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -436,7 +432,7 @@ JackDriver::call(bool response_expected,
// send message and get a handle for a reply
reply_ptr = dbus_connection_send_with_reply_and_block(
- _dbus_connection, request_ptr, JACKDBUS_CALL_DEFAULT_TIMEOUT, &_dbus_error);
+ _dbus_connection, request_ptr, default_timeout, &_dbus_error);
dbus_message_unref(request_ptr);
@@ -518,7 +514,7 @@ JackDriver::stop_server()
}
dbus_message_unref(reply_ptr);
- _emit_event(DriverDetachmentEvent{ClientType::jack});
+ _emit_event(event::DriverDetached{ClientType::jack});
}
void
@@ -588,7 +584,7 @@ JackDriver::refresh(const EventSink& sink)
{
DBusMessage* reply_ptr = nullptr;
DBusMessageIter iter = {};
- dbus_uint64_t version = 0u;
+ dbus_uint64_t version = 0U;
const char* reply_signature = nullptr;
DBusMessageIter clients_array_iter = {};
DBusMessageIter client_struct_iter = {};
@@ -596,17 +592,17 @@ JackDriver::refresh(const EventSink& sink)
DBusMessageIter port_struct_iter = {};
DBusMessageIter connections_array_iter = {};
DBusMessageIter connection_struct_iter = {};
- dbus_uint64_t client_id = 0u;
+ dbus_uint64_t client_id = 0U;
const char* client_name = nullptr;
- dbus_uint64_t port_id = 0u;
+ dbus_uint64_t port_id = 0U;
const char* port_name = nullptr;
- dbus_uint32_t port_flags = 0u;
- dbus_uint32_t port_type = 0u;
- dbus_uint64_t client2_id = 0u;
+ dbus_uint32_t port_flags = 0U;
+ dbus_uint32_t port_type = 0U;
+ dbus_uint64_t client2_id = 0U;
const char* client2_name = nullptr;
- dbus_uint64_t port2_id = 0u;
+ dbus_uint64_t port2_id = 0U;
const char* port2_name = nullptr;
- dbus_uint64_t connection_id = 0u;
+ dbus_uint64_t connection_id = 0U;
if (!call(true,
JACKDBUS_IFACE_PATCHBAY,
@@ -648,7 +644,7 @@ JackDriver::refresh(const EventSink& sink)
dbus_message_iter_next(&client_struct_iter);
// TODO: Pretty name?
- sink({ClientCreationEvent{ClientID::jack(client_name), {client_name}}});
+ sink({event::ClientCreated{ClientID::jack(client_name), {client_name}}});
for (dbus_message_iter_recurse(&client_struct_iter, &ports_array_iter);
dbus_message_iter_get_arg_type(&ports_array_iter) != DBUS_TYPE_INVALID;
@@ -667,8 +663,8 @@ JackDriver::refresh(const EventSink& sink)
dbus_message_iter_get_basic(&port_struct_iter, &port_type);
dbus_message_iter_next(&port_struct_iter);
- sink({PortCreationEvent{PortID::jack(client_name, port_name),
- port_info(port_name, port_type, port_flags)}});
+ sink({event::PortCreated{PortID::jack(client_name, port_name),
+ port_info(port_name, port_type, port_flags)}});
}
dbus_message_iter_next(&client_struct_iter);
@@ -710,8 +706,8 @@ JackDriver::refresh(const EventSink& sink)
dbus_message_iter_get_basic(&connection_struct_iter, &connection_id);
dbus_message_iter_next(&connection_struct_iter);
- sink({ConnectionEvent{PortID::jack(client_name, port_name),
- PortID::jack(client2_name, port2_name)}});
+ sink({event::PortsConnected{PortID::jack(client_name, port_name),
+ PortID::jack(client2_name, port2_name)}});
}
}
@@ -783,7 +779,7 @@ uint32_t
JackDriver::xruns()
{
DBusMessage* reply_ptr = nullptr;
- dbus_uint32_t xruns = 0u;
+ dbus_uint32_t xruns = 0U;
if (_server_responding && !_server_started) {
return 0;
@@ -830,7 +826,7 @@ uint32_t
JackDriver::buffer_size()
{
DBusMessage* reply_ptr = nullptr;
- dbus_uint32_t buffer_size = 0u;
+ dbus_uint32_t buffer_size = 0U;
if (_server_responding && !_server_started) {
return 4096;
@@ -885,7 +881,7 @@ uint32_t
JackDriver::sample_rate()
{
DBusMessage* reply_ptr = nullptr;
- dbus_uint32_t sample_rate = 0u;
+ dbus_uint32_t sample_rate = 0U;
if (!call(true,
JACKDBUS_IFACE_CONTROL,
@@ -915,9 +911,9 @@ PortType
JackDriver::patchage_port_type(const dbus_uint32_t dbus_port_type) const
{
switch (dbus_port_type) {
- case JACKDBUS_PORT_TYPE_AUDIO:
+ case JackDBusPortType::AUDIO:
return PortType::jack_audio;
- case JACKDBUS_PORT_TYPE_MIDI:
+ case JackDBusPortType::MIDI:
return PortType::jack_midi;
default:
break;
@@ -933,15 +929,15 @@ JackDriver::port_info(const std::string& port_name,
const dbus_uint32_t port_flags) const
{
const SignalDirection direction =
- ((port_flags & JACKDBUS_PORT_FLAG_INPUT) ? SignalDirection::input
- : SignalDirection::output);
+ ((port_flags & port_flag_input) ? SignalDirection::input
+ : SignalDirection::output);
// TODO: Metadata?
return {port_name,
patchage_port_type(port_type),
direction,
{},
- bool(port_flags & JACKDBUS_PORT_FLAG_TERMINAL)};
+ static_cast<bool>(port_flags & port_flag_terminal)};
}
void
diff --git a/src/JackLibDriver.cpp b/src/JackLibDriver.cpp
index 8728222..b540347 100644
--- a/src/JackLibDriver.cpp
+++ b/src/JackLibDriver.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "AudioDriver.hpp"
#include "ClientID.hpp"
@@ -31,7 +18,7 @@
#include "patchage_config.h"
#include "warnings.hpp"
-#ifdef HAVE_JACK_METADATA
+#if USE_JACK_METADATA
# include <jack/metadata.h>
#endif
@@ -39,7 +26,6 @@ PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
PATCHAGE_RESTORE_WARNINGS
-#include <boost/optional/optional.hpp>
#include <jack/jack.h>
#include <jack/types.h>
@@ -48,10 +34,12 @@ PATCHAGE_RESTORE_WARNINGS
#include <functional>
#include <memory>
#include <mutex>
+#include <optional>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
+#include <variant>
namespace patchage {
namespace {
@@ -62,10 +50,10 @@ class JackLibDriver : public AudioDriver
public:
explicit JackLibDriver(ILog& log, EventSink emit_event);
- JackLibDriver(const JackLibDriver&) = delete;
+ JackLibDriver(const JackLibDriver&) = delete;
JackLibDriver& operator=(const JackLibDriver&) = delete;
- JackLibDriver(JackLibDriver&&) = delete;
+ JackLibDriver(JackLibDriver&&) = delete;
JackLibDriver& operator=(JackLibDriver&&) = delete;
~JackLibDriver() override;
@@ -86,8 +74,8 @@ public:
uint32_t sample_rate() override;
private:
- ClientInfo get_client_info(const char* name);
- PortInfo get_port_info(const jack_port_t* port);
+ static ClientInfo get_client_info(const char* name);
+ PortInfo get_port_info(const jack_port_t* port);
static void on_client(const char* name, int registered, void* driver);
@@ -106,8 +94,8 @@ private:
std::mutex _shutdown_mutex;
jack_client_t* _client = nullptr;
- jack_nframes_t _buffer_size = 0u;
- uint32_t _xruns = 0u;
+ jack_nframes_t _buffer_size = 0U;
+ uint32_t _xruns = 0U;
bool _is_activated = false;
};
@@ -116,10 +104,7 @@ JackLibDriver::JackLibDriver(ILog& log, EventSink emit_event)
, _log{log}
{}
-JackLibDriver::~JackLibDriver()
-{
- detach();
-}
+JackLibDriver::~JackLibDriver() = default;
void
JackLibDriver::attach(const bool launch_daemon)
@@ -159,7 +144,7 @@ JackLibDriver::attach(const bool launch_daemon)
void
JackLibDriver::detach()
{
- std::lock_guard<std::mutex> lock{_shutdown_mutex};
+ const std::lock_guard<std::mutex> lock{_shutdown_mutex};
if (_client) {
jack_deactivate(_client);
@@ -182,7 +167,7 @@ get_property(const jack_uuid_t subject, const char* const key)
{
std::string result;
-#ifdef HAVE_JACK_METADATA
+#if USE_JACK_METADATA
char* value = nullptr;
char* datatype = nullptr;
if (!jack_get_property(subject, key, &value, &datatype)) {
@@ -208,12 +193,12 @@ PortInfo
JackLibDriver::get_port_info(const jack_port_t* const port)
{
const auto uuid = jack_port_uuid(port);
- const auto flags = jack_port_flags(port);
+ const auto flags = static_cast<unsigned>(jack_port_flags(port));
const std::string name = jack_port_name(port);
auto label = PortNames{name}.port();
// Get pretty name to use as a label, if present
-#ifdef HAVE_JACK_METADATA
+#if USE_JACK_METADATA
const auto pretty_name = get_property(uuid, JACK_METADATA_PRETTY_NAME);
if (!pretty_name.empty()) {
label = pretty_name;
@@ -243,19 +228,23 @@ JackLibDriver::get_port_info(const jack_port_t* const port)
: SignalDirection::output);
// Get port order from metadata if possible
- boost::optional<int> order;
- const std::string order_str = get_property(uuid, JACKEY_ORDER);
+ std::optional<int> order;
+ const std::string order_str = get_property(uuid, JACKEY_ORDER);
if (!order_str.empty()) {
order = std::stoi(order_str);
}
- return {label, type, direction, order, bool(flags & JackPortIsTerminal)};
+ return {label,
+ type,
+ direction,
+ order,
+ static_cast<bool>(flags & JackPortIsTerminal)};
}
void
JackLibDriver::refresh(const EventSink& sink)
{
- std::lock_guard<std::mutex> lock{_shutdown_mutex};
+ const std::lock_guard<std::mutex> lock{_shutdown_mutex};
if (!_client) {
return;
@@ -269,7 +258,7 @@ JackLibDriver::refresh(const EventSink& sink)
// Get all client names (to only send a creation event once for each)
std::unordered_set<std::string> client_names;
- for (auto i = 0u; ports[i]; ++i) {
+ for (auto i = 0U; ports[i]; ++i) {
client_names.insert(PortID::jack(ports[i]).client().jack_name());
}
@@ -280,7 +269,7 @@ JackLibDriver::refresh(const EventSink& sink)
}
// Emit all ports
- for (auto i = 0u; ports[i]; ++i) {
+ for (auto i = 0U; ports[i]; ++i) {
const jack_port_t* const port = jack_port_by_name(_client, ports[i]);
sink({event::PortCreated{PortID::jack(ports[i]), get_port_info(port)}});
@@ -288,17 +277,18 @@ JackLibDriver::refresh(const EventSink& sink)
// Get all connections (again to only create them once)
std::set<std::pair<std::string, std::string>> connections;
- for (auto i = 0u; ports[i]; ++i) {
+ for (auto i = 0U; ports[i]; ++i) {
const jack_port_t* const port = jack_port_by_name(_client, ports[i]);
const char** const peers = jack_port_get_all_connections(_client, port);
if (peers) {
- if (jack_port_flags(port) & JackPortIsInput) {
- for (auto j = 0u; peers[j]; ++j) {
+ const auto flags = static_cast<unsigned>(jack_port_flags(port));
+ if (flags & JackPortIsInput) {
+ for (auto j = 0U; peers[j]; ++j) {
connections.emplace(peers[j], ports[i]);
}
} else {
- for (auto j = 0u; peers[j]; ++j) {
+ for (auto j = 0U; peers[j]; ++j) {
connections.emplace(ports[i], peers[j]);
}
}
@@ -483,7 +473,7 @@ JackLibDriver::on_shutdown(void* const driver)
So, since JACK is a hot mess and it's impossible to gracefully handle
this situation, just leak the client. */
- std::lock_guard<std::mutex> lock{me->_shutdown_mutex};
+ const std::lock_guard<std::mutex> lock{me->_shutdown_mutex};
me->_client = nullptr;
me->_is_activated = false;
diff --git a/src/JackStubDriver.cpp b/src/JackStubDriver.cpp
new file mode 100644
index 0000000..a062df1
--- /dev/null
+++ b/src/JackStubDriver.cpp
@@ -0,0 +1,18 @@
+// Copyright 2020-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "AudioDriver.hpp"
+#include "Driver.hpp"
+#include "make_jack_driver.hpp"
+
+#include <memory>
+
+namespace patchage {
+
+std::unique_ptr<AudioDriver>
+make_jack_driver(ILog&, Driver::EventSink)
+{
+ return nullptr;
+}
+
+} // namespace patchage
diff --git a/src/Legend.cpp b/src/Legend.cpp
index e8e4743..ff0f7fe 100644
--- a/src/Legend.cpp
+++ b/src/Legend.cpp
@@ -1,27 +1,15 @@
-/* This file is part of Patchage.
- * Copyright 2014-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2014-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "Legend.hpp"
#include "Configuration.hpp"
#include "PortType.hpp"
+#include "i18n.hpp"
#include "patchage_config.h"
#include <gdkmm/color.h>
-#include <glibmm/signalproxy.h>
+#include <glibmm/ustring.h>
#include <gtkmm/box.h>
#include <gtkmm/colorbutton.h>
#include <gtkmm/label.h>
@@ -36,10 +24,10 @@ namespace patchage {
Legend::Legend(const Configuration& configuration)
{
add_button(PortType::jack_audio,
- "Audio",
+ T("Audio"),
configuration.get_port_color(PortType::jack_audio));
-#ifdef HAVE_JACK_METADATA
+#if USE_JACK_METADATA
add_button(
PortType::jack_cv, "CV", configuration.get_port_color(PortType::jack_cv));
add_button(PortType::jack_osc,
@@ -62,9 +50,9 @@ void
Legend::add_button(const PortType id, const std::string& label, uint32_t rgba)
{
Gdk::Color col;
- col.set_rgb(((rgba >> 24) & 0xFF) * 0x100,
- ((rgba >> 16) & 0xFF) * 0x100,
- ((rgba >> 8) & 0xFF) * 0x100);
+ col.set_rgb(((rgba >> 24U) & 0xFFU) * 0x100U,
+ ((rgba >> 16U) & 0xFFU) * 0x100U,
+ ((rgba >> 8U) & 0xFFU) * 0x100U);
auto* box = new Gtk::HBox();
auto* but = new Gtk::ColorButton(col);
@@ -85,8 +73,8 @@ Legend::on_color_set(const PortType id,
{
const Gdk::Color col = but->get_color();
const uint32_t rgba =
- (((col.get_red() / 0x100) << 24) | ((col.get_green() / 0x100) << 16) |
- ((col.get_blue() / 0x100) << 8) | 0xFF);
+ (((col.get_red() / 0x100U) << 24U) | ((col.get_green() / 0x100U) << 16U) |
+ ((col.get_blue() / 0x100U) << 8U) | 0xFFU);
signal_color_changed.emit(id, label, rgba);
}
diff --git a/src/Legend.hpp b/src/Legend.hpp
index 81fbd86..c73a74e 100644
--- a/src/Legend.hpp
+++ b/src/Legend.hpp
@@ -1,24 +1,9 @@
-/* This file is part of Patchage.
- * Copyright 2014-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2014-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_LEGEND_HPP
#define PATCHAGE_LEGEND_HPP
-#include "PortType.hpp"
-
#include <gtkmm/box.h>
#include <sigc++/signal.h>
@@ -31,6 +16,8 @@ class ColorButton;
namespace patchage {
+enum class PortType;
+
class Configuration;
class Legend : public Gtk::HBox
diff --git a/src/Metadata.cpp b/src/Metadata.cpp
index e75cf19..929b090 100644
--- a/src/Metadata.cpp
+++ b/src/Metadata.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2014-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2014-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "Metadata.hpp"
@@ -21,13 +8,12 @@
#include "PortID.hpp"
#include "PortInfo.hpp"
-#include <boost/optional/optional.hpp>
-
+#include <optional>
#include <utility>
namespace patchage {
-boost::optional<ClientInfo>
+std::optional<ClientInfo>
Metadata::client(const ClientID& id) const
{
const auto i = _client_data.find(id);
@@ -38,7 +24,7 @@ Metadata::client(const ClientID& id) const
return i->second;
}
-boost::optional<PortInfo>
+std::optional<PortInfo>
Metadata::port(const PortID& id) const
{
const auto i = _port_data.find(id);
diff --git a/src/Metadata.hpp b/src/Metadata.hpp
index 489c0b2..520b0ce 100644
--- a/src/Metadata.hpp
+++ b/src/Metadata.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_METADATA_HPP
#define PATCHAGE_METADATA_HPP
@@ -22,9 +9,8 @@
#include "PortID.hpp"
#include "PortInfo.hpp"
-#include <boost/optional/optional.hpp>
-
#include <map>
+#include <optional>
namespace patchage {
@@ -34,8 +20,8 @@ class Metadata
public:
Metadata() = default;
- boost::optional<ClientInfo> client(const ClientID& id) const;
- boost::optional<PortInfo> port(const PortID& id) const;
+ std::optional<ClientInfo> client(const ClientID& id) const;
+ std::optional<PortInfo> port(const PortID& id) const;
void set_client(const ClientID& id, const ClientInfo& info);
void set_port(const PortID& id, const PortInfo& info);
diff --git a/src/Options.hpp b/src/Options.hpp
index dd143fe..76846aa 100644
--- a/src/Options.hpp
+++ b/src/Options.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_OPTIONS_HPP
#define PATCHAGE_OPTIONS_HPP
diff --git a/src/Patchage.cpp b/src/Patchage.cpp
index 7997354..349fbf0 100644
--- a/src/Patchage.cpp
+++ b/src/Patchage.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "Patchage.hpp"
@@ -24,38 +11,40 @@
#include "Configuration.hpp"
#include "Coord.hpp"
#include "Driver.hpp"
+#include "Drivers.hpp"
#include "Event.hpp"
#include "Legend.hpp"
+#include "Options.hpp"
+#include "PortType.hpp"
+#include "Reactor.hpp"
#include "Setting.hpp"
+#include "TextViewLog.hpp"
#include "UIFile.hpp"
+#include "Widget.hpp"
#include "event_to_string.hpp"
#include "handle_event.hpp"
-#include "patchage_config.h" // IWYU pragma: keep
+#include "i18n.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_GANV_WARNINGS
-#include "ganv/Edge.hpp"
-#include "ganv/Module.hpp"
-#include "ganv/Node.hpp"
-#include "ganv/Port.hpp"
-#include "ganv/module.h"
-#include "ganv/types.h"
+#include <ganv/Edge.hpp>
+#include <ganv/Module.hpp>
+#include <ganv/Node.hpp>
+#include <ganv/Port.hpp>
+#include <ganv/module.h>
+#include <ganv/types.h>
PATCHAGE_RESTORE_WARNINGS
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
PATCHAGE_RESTORE_WARNINGS
-#include <boost/optional/optional.hpp>
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/variant.hpp>
#include <glib-object.h>
#include <glib.h>
#include <glibmm/fileutils.h>
#include <glibmm/main.h>
#include <glibmm/miscutils.h>
#include <glibmm/propertyproxy.h>
-#include <glibmm/signalproxy.h>
#include <glibmm/ustring.h>
#include <gobject/gclosure.h>
#include <gtk/gtk.h>
@@ -93,6 +82,8 @@ PATCHAGE_RESTORE_WARNINGS
#include <gtkmm/window.h>
#include <sigc++/adaptors/bind.h>
#include <sigc++/functors/mem_fun.h>
+#include <sigc++/functors/ptr_fun.h>
+#include <sigc++/functors/slot.h>
#include <sigc++/signal.h>
#include <algorithm>
@@ -101,7 +92,9 @@ PATCHAGE_RESTORE_WARNINGS
#include <cstdlib>
#include <functional>
#include <map>
+#include <optional>
#include <utility>
+#include <variant>
#ifdef PATCHAGE_GTK_OSX
@@ -145,8 +138,10 @@ port_order(const GanvPort* a, const GanvPort* b, void*)
const auto* pa = dynamic_cast<const CanvasPort*>(Glib::wrap(a));
const auto* pb = dynamic_cast<const CanvasPort*>(Glib::wrap(b));
if (pa && pb) {
- if (pa->order() && pb->order()) {
- return *pa->order() - *pb->order();
+ const auto oa = pa->order();
+ const auto ob = pb->order();
+ if (oa && ob) {
+ return *oa - *ob;
}
if (pa->order()) {
@@ -162,6 +157,79 @@ port_order(const GanvPort* a, const GanvPort* b, void*)
return 0;
}
+template<class S>
+void
+on_setting_toggled(Reactor* const reactor, const Gtk::CheckMenuItem* const item)
+{
+ (*reactor)(action::ChangeSetting{{S{item->get_active()}}});
+}
+
+void
+update_labels(GanvNode* node, void* data)
+{
+ const bool human_names = *static_cast<const bool*>(data);
+ if (GANV_IS_MODULE(node)) {
+ Ganv::Module* gmod = Glib::wrap(GANV_MODULE(node));
+ if (dynamic_cast<const CanvasModule*>(gmod)) {
+ for (Ganv::Port* gport : *gmod) {
+ auto* pport = dynamic_cast<CanvasPort*>(gport);
+ if (pport) {
+ pport->show_human_name(human_names);
+ }
+ }
+ }
+ }
+}
+
+inline guint
+highlight_color(guint c, guint delta)
+{
+ const guint max_char = 255U;
+ const guint r = MIN((c >> 24U) + delta, max_char);
+ const guint g = MIN(((c >> 16U) & 0xFFU) + delta, max_char);
+ const guint b = MIN(((c >> 8U) & 0xFFU) + delta, max_char);
+ const guint a = c & 0xFFU;
+
+ return ((r << 24U) | (g << 16U) | (b << 8U) | a);
+}
+
+void
+update_port_colors(GanvNode* node, void* data)
+{
+ auto* patchage = static_cast<Patchage*>(data);
+ if (!GANV_IS_MODULE(node)) {
+ return;
+ }
+
+ Ganv::Module* gmod = Glib::wrap(GANV_MODULE(node));
+ if (!dynamic_cast<CanvasModule*>(gmod)) {
+ return;
+ }
+
+ for (Ganv::Port* p : *gmod) {
+ auto* port = dynamic_cast<CanvasPort*>(p);
+ if (port) {
+ const uint32_t rgba = patchage->conf().get_port_color(port->type());
+ port->set_fill_color(rgba);
+ port->set_border_color(highlight_color(rgba, 0x20));
+ }
+ }
+}
+
+void
+update_edge_color(GanvEdge* edge, void* data)
+{
+ auto* patchage = static_cast<Patchage*>(data);
+ Ganv::Edge* edgemm = Glib::wrap(edge);
+
+ if (edgemm) {
+ const auto* tail = dynamic_cast<const CanvasPort*>((edgemm)->get_tail());
+ if (tail) {
+ edgemm->set_color(patchage->conf().get_port_color(tail->type()));
+ }
+ }
+}
+
} // namespace
#define INIT_WIDGET(x) x(_xml, (#x) + 1)
@@ -206,12 +274,10 @@ Patchage::Patchage(Options options)
, _conf([this](const Setting& setting) { on_conf_change(setting); })
, _log(_status_text)
, _canvas(new Canvas{_log, _action_sink, 1600 * 2, 1200 * 2})
- , _legend(nullptr)
, _drivers(_log, [this](const Event& event) { on_driver_event(event); })
, _reactor(_conf, _drivers, *_canvas, _log)
, _action_sink([this](const Action& action) { _reactor(action); })
, _options{options}
- , _attach(true)
{
Glib::set_application_name("Patchage");
_about_win->property_program_name() = "Patchage";
@@ -219,11 +285,11 @@ Patchage::Patchage(Options options)
gtk_window_set_default_icon_name("patchage");
// Create list model for buffer size selector
- Glib::RefPtr<Gtk::ListStore> buf_size_store =
+ const Glib::RefPtr<Gtk::ListStore> buf_size_store =
Gtk::ListStore::create(_buf_size_columns);
for (size_t i = 32; i <= 4096; i *= 2) {
- Gtk::TreeModel::Row row = *(buf_size_store->append());
- row[_buf_size_columns.label] = std::to_string(i);
+ const Gtk::TreeModel::Row row = *(buf_size_store->append());
+ row[_buf_size_columns.label] = std::to_string(i);
}
_buf_size_combo->set_model(buf_size_store);
@@ -235,7 +301,7 @@ Patchage::Patchage(Options options)
_main_scrolledwin->property_vadjustment().get_value()->set_step_increment(10);
_main_scrolledwin->signal_scroll_event().connect(
- sigc::mem_fun(this, &Patchage::on_scroll));
+ sigc::ptr_fun(&Patchage::on_scroll));
_clear_load_but->signal_clicked().connect(
sigc::mem_fun(this, &Patchage::clear_load));
_buf_size_combo->signal_changed().connect(
@@ -249,18 +315,35 @@ Patchage::Patchage(Options options)
sigc::mem_fun(this, &Patchage::on_export_image));
_menu_view_refresh->signal_activate().connect(sigc::bind(
sigc::mem_fun(this, &Patchage::on_menu_action), Action{action::Refresh{}}));
+
_menu_view_human_names->signal_activate().connect(
- sigc::mem_fun(this, &Patchage::on_view_human_names));
+ sigc::bind(sigc::ptr_fun(&on_setting_toggled<setting::HumanNames>),
+ &_reactor,
+ _menu_view_human_names.get()));
+
_menu_view_sort_ports->signal_activate().connect(
- sigc::mem_fun(this, &Patchage::on_view_sort_ports));
+ sigc::bind(sigc::ptr_fun(&on_setting_toggled<setting::SortedPorts>),
+ &_reactor,
+ _menu_view_sort_ports.get()));
+
_menu_view_arrange->signal_activate().connect(
sigc::mem_fun(this, &Patchage::on_arrange));
+
_menu_view_sprung_layout->signal_activate().connect(
- sigc::mem_fun(this, &Patchage::on_sprung_layout_toggled));
+ sigc::bind(sigc::ptr_fun(&on_setting_toggled<setting::SprungLayout>),
+ &_reactor,
+ _menu_view_sprung_layout.get()));
+
_menu_view_messages->signal_activate().connect(
- sigc::mem_fun(this, &Patchage::on_view_messages));
+ sigc::bind(sigc::ptr_fun(&on_setting_toggled<setting::MessagesVisible>),
+ &_reactor,
+ _menu_view_messages.get()));
+
_menu_view_toolbar->signal_activate().connect(
- sigc::mem_fun(this, &Patchage::on_view_toolbar));
+ sigc::bind(sigc::ptr_fun(&on_setting_toggled<setting::ToolbarVisible>),
+ &_reactor,
+ _menu_view_toolbar.get()));
+
_menu_help_about->signal_activate().connect(
sigc::mem_fun(this, &Patchage::on_help_about));
@@ -296,7 +379,8 @@ Patchage::Patchage(Options options)
_main_win->present();
// Set the default font size based on the current GUI environment
- _conf.set<setting::FontSize>(_canvas->get_default_font_size());
+ _conf.set<setting::FontSize>(
+ static_cast<float>(_canvas->get_default_font_size()));
// Load configuration file (but do not apply it yet, see below)
_conf.load();
@@ -430,13 +514,17 @@ Patchage::update_toolbar()
const auto buffer_size = _drivers.jack()->buffer_size();
const auto sample_rate = _drivers.jack()->sample_rate();
if (sample_rate != 0) {
- const auto latency_ms = buffer_size * 1000 / float(sample_rate);
+ const auto sample_rate_khz = sample_rate / 1000.0;
+ const auto latency_ms = buffer_size / sample_rate_khz;
+
+ _latency_label->set_label(" " +
+ fmt::format(T("frames at {} kHz ({:0.2f} ms)"),
+ sample_rate_khz,
+ latency_ms));
- _latency_label->set_label(fmt::format(
- " frames @ {} kHz ({:0.2f} ms)", sample_rate / 1000, latency_ms));
_latency_label->set_visible(true);
- _buf_size_combo->set_active(
- static_cast<int>(log2f(_drivers.jack()->buffer_size()) - 5));
+ _buf_size_combo->set_active(static_cast<int>(
+ log2f(static_cast<float>(_drivers.jack()->buffer_size())) - 5));
updating = false;
return;
}
@@ -451,12 +539,13 @@ Patchage::update_load()
{
if (_drivers.jack() && _drivers.jack()->is_attached()) {
const auto xruns = _drivers.jack()->xruns();
- if (xruns > 0u) {
- _dropouts_label->set_text(fmt::format(" Dropouts: {}", xruns));
+
+ _dropouts_label->set_text(" " + fmt::format(T("Dropouts: {}"), xruns));
+
+ if (xruns > 0U) {
_dropouts_label->show();
_clear_load_but->show();
} else {
- _dropouts_label->set_text(" Dropouts: 0");
_dropouts_label->hide();
_clear_load_but->hide();
}
@@ -476,14 +565,17 @@ Patchage::store_window_location()
int size_y = 0;
_main_win->get_size(size_x, size_y);
- _conf.set<setting::WindowLocation>({double(loc_x), double(loc_y)});
- _conf.set<setting::WindowSize>({double(size_x), double(size_y)});
+ _conf.set<setting::WindowLocation>(
+ {static_cast<double>(loc_x), static_cast<double>(loc_y)});
+
+ _conf.set<setting::WindowSize>(
+ {static_cast<double>(size_x), static_cast<double>(size_y)});
}
void
Patchage::clear_load()
{
- _dropouts_label->set_text(" Dropouts: 0");
+ _dropouts_label->set_text(" " + fmt::format(T("Dropouts: {}"), 0U));
_dropouts_label->hide();
_clear_load_but->hide();
if (_drivers.jack()) {
@@ -546,24 +638,6 @@ Patchage::operator()(const setting::FontSize& setting)
}
}
-static void
-update_labels(GanvNode* node, void* data)
-{
- const bool human_names = *static_cast<const bool*>(data);
- if (GANV_IS_MODULE(node)) {
- Ganv::Module* gmod = Glib::wrap(GANV_MODULE(node));
- auto* pmod = dynamic_cast<CanvasModule*>(gmod);
- if (pmod) {
- for (Ganv::Port* gport : *gmod) {
- auto* pport = dynamic_cast<CanvasPort*>(gport);
- if (pport) {
- pport->show_human_name(human_names);
- }
- }
- }
- }
-}
-
void
Patchage::operator()(const setting::HumanNames& setting)
{
@@ -598,56 +672,6 @@ Patchage::operator()(const setting::MessagesVisible& setting)
_menu_view_messages->set_active(setting.value);
}
-static inline guint
-highlight_color(guint c, guint delta)
-{
- const guint max_char = 255;
- const guint r = MIN((c >> 24) + delta, max_char);
- const guint g = MIN(((c >> 16) & 0xFF) + delta, max_char);
- const guint b = MIN(((c >> 8) & 0xFF) + delta, max_char);
- const guint a = c & 0xFF;
-
- return ((r << 24u) | (g << 16u) | (b << 8u) | a);
-}
-
-static void
-update_port_colors(GanvNode* node, void* data)
-{
- auto* patchage = static_cast<Patchage*>(data);
- if (!GANV_IS_MODULE(node)) {
- return;
- }
-
- Ganv::Module* gmod = Glib::wrap(GANV_MODULE(node));
- auto* pmod = dynamic_cast<CanvasModule*>(gmod);
- if (!pmod) {
- return;
- }
-
- for (Ganv::Port* p : *pmod) {
- auto* port = dynamic_cast<CanvasPort*>(p);
- if (port) {
- const uint32_t rgba = patchage->conf().get_port_color(port->type());
- port->set_fill_color(rgba);
- port->set_border_color(highlight_color(rgba, 0x20));
- }
- }
-}
-
-static void
-update_edge_color(GanvEdge* edge, void* data)
-{
- auto* patchage = static_cast<Patchage*>(data);
- Ganv::Edge* edgemm = Glib::wrap(edge);
-
- if (edgemm) {
- auto* tail = dynamic_cast<CanvasPort*>((edgemm)->get_tail());
- if (tail) {
- edgemm->set_color(patchage->conf().get_port_color(tail->type()));
- }
- }
-}
-
void
Patchage::operator()(const setting::PortColor&)
{
@@ -726,7 +750,7 @@ Patchage::operator()(const setting::Zoom& setting)
void
Patchage::on_driver_event(const Event& event)
{
- std::lock_guard<std::mutex> lock{_events_mutex};
+ const std::lock_guard<std::mutex> lock{_events_mutex};
_driver_events.emplace(event);
}
@@ -734,7 +758,7 @@ Patchage::on_driver_event(const Event& event)
void
Patchage::process_events()
{
- std::lock_guard<std::mutex> lock{_events_mutex};
+ const std::lock_guard<std::mutex> lock{_events_mutex};
while (!_driver_events.empty()) {
const Event& event = _driver_events.front();
@@ -749,7 +773,7 @@ Patchage::process_events()
void
Patchage::on_conf_change(const Setting& setting)
{
- boost::apply_visitor(*this, setting);
+ std::visit(*this, setting);
}
void
@@ -761,12 +785,6 @@ Patchage::on_arrange()
}
void
-Patchage::on_sprung_layout_toggled()
-{
- _conf.set<setting::SprungLayout>(_menu_view_sprung_layout->get_active());
-}
-
-void
Patchage::on_help_about()
{
_about_win->run();
@@ -774,22 +792,9 @@ Patchage::on_help_about()
}
void
-Patchage::on_view_human_names()
-{
- _conf.set<setting::HumanNames>(_menu_view_human_names->get_active());
-}
-
-void
-Patchage::on_view_sort_ports()
-{
- _conf.set<setting::SortedPorts>(_menu_view_sort_ports->get_active());
- _reactor(action::Refresh{});
-}
-
-void
Patchage::on_legend_color_change(PortType id, const std::string&, uint32_t rgba)
{
- _conf.set_port_color(id, rgba);
+ _reactor(action::ChangeSetting{{setting::PortColor{id, rgba}}});
}
void
@@ -803,7 +808,8 @@ Patchage::on_messages_resized(Gtk::Allocation&)
void
Patchage::save()
{
- _conf.set<setting::Zoom>(_canvas->get_zoom()); // Can be changed by ganv
+ // Zoom can be changed by ganv
+ _conf.set<setting::Zoom>(static_cast<float>(_canvas->get_zoom()));
_conf.save();
}
@@ -830,7 +836,9 @@ Patchage::on_quit()
void
Patchage::on_export_image()
{
- Gtk::FileChooserDialog dialog("Export Image", Gtk::FILE_CHOOSER_ACTION_SAVE);
+ Gtk::FileChooserDialog dialog(T("Export Image"),
+ Gtk::FILE_CHOOSER_ACTION_SAVE);
+
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
dialog.set_default_response(Gtk::RESPONSE_OK);
@@ -850,7 +858,7 @@ Patchage::on_export_image()
dialog.add_filter(filt);
}
- auto* bg_but = new Gtk::CheckButton("Draw _Background", true);
+ auto* bg_but = new Gtk::CheckButton(T("Draw _Background"), true);
auto* extra = new Gtk::Alignment(1.0, 0.5, 0.0, 0.0);
bg_but->set_active(true);
extra->add(*Gtk::manage(bg_but));
@@ -860,12 +868,12 @@ Patchage::on_export_image()
if (dialog.run() == Gtk::RESPONSE_OK) {
const std::string filename = dialog.get_filename();
if (Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) {
- Gtk::MessageDialog confirm(std::string("File exists! Overwrite ") +
- filename + "?",
- true,
- Gtk::MESSAGE_WARNING,
- Gtk::BUTTONS_YES_NO,
- true);
+ Gtk::MessageDialog confirm(
+ fmt::format(T("File exists! Overwrite {}?"), filename),
+ true,
+ Gtk::MESSAGE_WARNING,
+ Gtk::BUTTONS_YES_NO,
+ true);
confirm.set_transient_for(dialog);
if (confirm.run() != Gtk::RESPONSE_YES) {
return;
@@ -875,18 +883,6 @@ Patchage::on_export_image()
}
}
-void
-Patchage::on_view_messages()
-{
- _conf.set<setting::MessagesVisible>(_menu_view_messages->get_active());
-}
-
-void
-Patchage::on_view_toolbar()
-{
- _conf.set<setting::ToolbarVisible>(_menu_view_toolbar->get_active());
-}
-
bool
Patchage::on_scroll(GdkEventScroll*)
{
@@ -905,10 +901,10 @@ Patchage::buffer_size_changed()
if (_drivers.jack()) {
const int selected = _buf_size_combo->get_active_row_number();
- if (selected == -1) {
+ if (selected < 0) {
update_toolbar();
} else {
- const uint32_t buffer_size = 1u << (selected + 5);
+ const uint32_t buffer_size = 1U << (static_cast<unsigned>(selected) + 5U);
_drivers.jack()->set_buffer_size(buffer_size);
update_toolbar();
}
diff --git a/src/Patchage.hpp b/src/Patchage.hpp
index c3ed61d..720a57c 100644
--- a/src/Patchage.hpp
+++ b/src/Patchage.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_PATCHAGE_HPP
#define PATCHAGE_PATCHAGE_HPP
@@ -30,7 +17,6 @@
#include "Event.hpp"
#include "Metadata.hpp"
#include "Options.hpp"
-#include "PortType.hpp"
#include "Reactor.hpp"
#include "Setting.hpp"
#include "TextViewLog.hpp"
@@ -68,6 +54,8 @@ class Window;
namespace patchage {
+enum class PortType;
+
class Canvas;
class ILog;
class Legend;
@@ -79,10 +67,10 @@ public:
explicit Patchage(Options options);
~Patchage();
- Patchage(const Patchage&) = delete;
+ Patchage(const Patchage&) = delete;
Patchage& operator=(const Patchage&) = delete;
- Patchage(Patchage&&) = delete;
+ Patchage(Patchage&&) = delete;
Patchage& operator=(Patchage&&) = delete;
void operator()(const setting::AlsaAttached& setting);
@@ -127,15 +115,10 @@ protected:
void on_conf_change(const Setting& setting);
void on_arrange();
- void on_sprung_layout_toggled();
void on_help_about();
void on_quit();
void on_export_image();
- void on_view_messages();
- void on_view_toolbar();
void on_store_positions();
- void on_view_human_names();
- void on_view_sort_ports();
void on_legend_color_change(PortType id,
const std::string& label,
@@ -143,7 +126,7 @@ protected:
void on_messages_resized(Gtk::Allocation& alloc);
- bool on_scroll(GdkEventScroll* ev);
+ static bool on_scroll(GdkEventScroll* ev);
void on_menu_action(const Action& action);
@@ -198,7 +181,7 @@ protected:
std::mutex _events_mutex;
std::queue<Event> _driver_events;
BufferSizeColumns _buf_size_columns;
- Legend* _legend;
+ Legend* _legend{nullptr};
Metadata _metadata;
Drivers _drivers;
Reactor _reactor;
@@ -208,7 +191,7 @@ protected:
Glib::RefPtr<Gtk::TextTag> _warning_tag;
Options _options;
- bool _attach;
+ bool _attach{true};
};
} // namespace patchage
diff --git a/src/PortID.hpp b/src/PortID.hpp
index 2ef7a0c..e22e670 100644
--- a/src/PortID.hpp
+++ b/src/PortID.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2008-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2008-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_PORTID_HPP
#define PATCHAGE_PORTID_HPP
@@ -36,10 +23,10 @@ namespace patchage {
struct PortID {
using Type = ClientType;
- PortID(const PortID& copy) = default;
+ PortID(const PortID& copy) = default;
PortID& operator=(const PortID& copy) = default;
- PortID(PortID&& id) = default;
+ PortID(PortID&& id) = default;
PortID& operator=(PortID&& id) = default;
~PortID() = default;
@@ -114,22 +101,23 @@ private:
bool _alsa_is_input{}; ///< Input flag for Type::alsa
};
-static inline std::ostream&
+inline std::ostream&
operator<<(std::ostream& os, const PortID& id)
{
switch (id.type()) {
case PortID::Type::jack:
return os << "jack:" << id.jack_name();
case PortID::Type::alsa:
- return os << "alsa:" << int(id.alsa_client()) << ":" << int(id.alsa_port())
- << ":" << (id.alsa_is_input() ? "in" : "out");
+ return os << "alsa:" << static_cast<int>(id.alsa_client()) << ":"
+ << static_cast<int>(id.alsa_port()) << ":"
+ << (id.alsa_is_input() ? "in" : "out");
}
assert(false);
return os;
}
-static inline bool
+inline bool
operator==(const PortID& lhs, const PortID& rhs)
{
if (lhs.type() != rhs.type()) {
@@ -150,7 +138,7 @@ operator==(const PortID& lhs, const PortID& rhs)
return false;
}
-static inline bool
+inline bool
operator<(const PortID& lhs, const PortID& rhs)
{
if (lhs.type() != rhs.type()) {
@@ -185,4 +173,7 @@ struct hash<patchage::PortID::Type> {
} // namespace std
+template<>
+struct fmt::formatter<patchage::PortID> : fmt::ostream_formatter {};
+
#endif // PATCHAGE_PORTID_HPP
diff --git a/src/PortInfo.hpp b/src/PortInfo.hpp
index 3a4103d..b6d88b5 100644
--- a/src/PortInfo.hpp
+++ b/src/PortInfo.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_PORTINFO_HPP
#define PATCHAGE_PORTINFO_HPP
@@ -20,18 +7,18 @@
#include "PortType.hpp"
#include "SignalDirection.hpp"
-#include <boost/optional/optional.hpp>
+#include <optional>
#include <string>
namespace patchage {
/// Extra information about a port not expressed in its ID
struct PortInfo {
- std::string label; ///< Human-friendly label
- PortType type; ///< Detailed port type
- SignalDirection direction; ///< Signal direction
- boost::optional<int> order; ///< Order key on client
- bool is_terminal; ///< True if this is a system port
+ std::string label; ///< Human-friendly label
+ PortType type; ///< Detailed port type
+ SignalDirection direction; ///< Signal direction
+ std::optional<int> order; ///< Order key on client
+ bool is_terminal; ///< True if this is a system port
};
} // namespace patchage
diff --git a/src/PortNames.hpp b/src/PortNames.hpp
index 1ec7685..4dce7c6 100644
--- a/src/PortNames.hpp
+++ b/src/PortNames.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2008-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2008-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_PORTNAMES_HPP
#define PATCHAGE_PORTNAMES_HPP
diff --git a/src/PortType.hpp b/src/PortType.hpp
index 9db0c1f..97ecaab 100644
--- a/src/PortType.hpp
+++ b/src/PortType.hpp
@@ -1,22 +1,18 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_PORTTYPE_HPP
#define PATCHAGE_PORTTYPE_HPP
+#include "warnings.hpp"
+
+PATCHAGE_DISABLE_FMT_WARNINGS
+#include <fmt/core.h>
+#include <fmt/ostream.h>
+PATCHAGE_RESTORE_WARNINGS
+
+#include <ostream>
+
namespace patchage {
enum class PortType {
@@ -27,6 +23,28 @@ enum class PortType {
jack_cv,
};
+inline std::ostream&
+operator<<(std::ostream& os, const PortType port_type)
+{
+ switch (port_type) {
+ case PortType::jack_audio:
+ return os << "JACK audio";
+ case PortType::jack_midi:
+ return os << "JACK MIDI";
+ case PortType::alsa_midi:
+ return os << "ALSA MIDI";
+ case PortType::jack_osc:
+ return os << "JACK OSC";
+ case PortType::jack_cv:
+ return os << "JACK CV";
+ }
+
+ PATCHAGE_UNREACHABLE();
+}
+
} // namespace patchage
+template<>
+struct fmt::formatter<patchage::PortType> : fmt::ostream_formatter {};
+
#endif // PATCHAGE_PORTTYPE_HPP
diff --git a/src/Reactor.cpp b/src/Reactor.cpp
index b48d85d..eb7300e 100644
--- a/src/Reactor.cpp
+++ b/src/Reactor.cpp
@@ -1,21 +1,9 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "Reactor.hpp"
+#include "Action.hpp"
#include "Canvas.hpp"
#include "CanvasModule.hpp"
#include "CanvasPort.hpp"
@@ -26,34 +14,35 @@
#include "ILog.hpp"
#include "PortID.hpp"
#include "Setting.hpp"
+#include "SignalDirection.hpp"
#include "warnings.hpp"
-#include "ganv/Module.hpp"
-#include "ganv/Port.hpp"
+#include <ganv/Port.hpp>
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
-#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
-#include <boost/variant/apply_visitor.hpp>
-
-#include <ostream>
+#include <variant>
namespace patchage {
-inline std::ostream&
-operator<<(std::ostream& os, const ClientType type)
+class SettingVisitor
{
- switch (type) {
- case ClientType::jack:
- return os << "JACK";
- case ClientType::alsa:
- return os << "ALSA";
+public:
+ explicit SettingVisitor(Configuration& conf)
+ : _conf{conf}
+ {}
+
+ template<class S>
+ void operator()(const S& setting) const
+ {
+ _conf.set_setting(setting);
}
- return os;
-}
+private:
+ Configuration& _conf;
+};
Reactor::Reactor(Configuration& conf,
Drivers& drivers,
@@ -66,6 +55,13 @@ Reactor::Reactor(Configuration& conf,
{}
void
+Reactor::operator()(const action::ChangeSetting& action)
+{
+ const SettingVisitor visitor{_conf};
+ std::visit(visitor, action.setting);
+}
+
+void
Reactor::operator()(const action::ConnectPorts& action)
{
if (action.tail.type() == action.head.type()) {
@@ -112,7 +108,7 @@ Reactor::operator()(const action::DisconnectPorts& action)
if (auto* d = _drivers.driver(action.tail.type())) {
d->disconnect(action.tail, action.head);
} else {
- _log.error(fmt::format("No driver for {}", action.tail.type()));
+ _log.error(fmt::format("No driver available to disconnect ports"));
}
} else {
_log.error("Unable to disconnect incompatible ports");
@@ -141,7 +137,8 @@ Reactor::operator()(const action::Refresh&)
void
Reactor::operator()(const action::ResetFontSize&)
{
- _conf.set<setting::FontSize>(_canvas.get_default_font_size());
+ _conf.set<setting::FontSize>(
+ static_cast<float>(_canvas.get_default_font_size()));
}
void
@@ -162,7 +159,7 @@ void
Reactor::operator()(const action::ZoomFull&)
{
_canvas.zoom_full();
- _conf.set<setting::Zoom>(_canvas.get_zoom());
+ _conf.set<setting::Zoom>(static_cast<float>(_canvas.get_zoom()));
}
void
@@ -186,7 +183,7 @@ Reactor::operator()(const action::ZoomOut&)
void
Reactor::operator()(const Action& action)
{
- boost::apply_visitor(*this, action);
+ std::visit(*this, action);
}
std::string
@@ -194,11 +191,11 @@ Reactor::module_name(const ClientID& client)
{
// Note that split modules always have the same name
- if (CanvasModule* mod = find_module(client, SignalDirection::input)) {
+ if (const CanvasModule* mod = find_module(client, SignalDirection::input)) {
return mod->name();
}
- if (CanvasModule* mod = find_module(client, SignalDirection::output)) {
+ if (const CanvasModule* mod = find_module(client, SignalDirection::output)) {
return mod->name();
}
diff --git a/src/Reactor.hpp b/src/Reactor.hpp
index 58b1ffc..a5bc9e9 100644
--- a/src/Reactor.hpp
+++ b/src/Reactor.hpp
@@ -1,29 +1,17 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_REACTOR_HPP
#define PATCHAGE_REACTOR_HPP
#include "Action.hpp"
-#include "SignalDirection.hpp"
#include <string>
namespace patchage {
+enum class SignalDirection;
+
struct ClientID;
struct PortID;
@@ -38,21 +26,20 @@ class ILog;
class Reactor
{
public:
- using result_type = void; ///< For boost::apply_visitor
-
explicit Reactor(Configuration& conf,
Drivers& drivers,
Canvas& canvas,
ILog& log);
- Reactor(const Reactor&) = delete;
+ Reactor(const Reactor&) = delete;
Reactor& operator=(const Reactor&) = delete;
- Reactor(Reactor&&) = delete;
+ Reactor(Reactor&&) = delete;
Reactor& operator=(Reactor&&) = delete;
~Reactor() = default;
+ void operator()(const action::ChangeSetting& action);
void operator()(const action::ConnectPorts& action);
void operator()(const action::DecreaseFontSize& action);
void operator()(const action::DisconnectClient& action);
diff --git a/src/Setting.hpp b/src/Setting.hpp
index 90fb124..4bcfc81 100644
--- a/src/Setting.hpp
+++ b/src/Setting.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_SETTING_HPP
#define PATCHAGE_SETTING_HPP
@@ -20,54 +7,81 @@
#include "Coord.hpp"
#include "PortType.hpp"
-#include <boost/variant/variant.hpp>
-
#include <cstdint>
+#include <variant>
namespace patchage {
namespace setting {
-template<class T>
-struct Setting {
- using Value = T;
+struct AlsaAttached {
+ bool value{};
+};
+
+struct FontSize {
+ float value{};
+};
+
+struct HumanNames {
+ bool value{};
+};
- Value value{};
+struct JackAttached {
+ bool value{};
+};
+
+struct MessagesHeight {
+ int value{};
+};
+
+struct MessagesVisible {
+ bool value{};
};
struct PortColor {
PortType type{};
- uint32_t value{};
+ uint32_t color{};
};
-struct AlsaAttached : Setting<bool> {};
-struct FontSize : Setting<float> {};
-struct HumanNames : Setting<bool> {};
-struct JackAttached : Setting<bool> {};
-struct MessagesHeight : Setting<int> {};
-struct MessagesVisible : Setting<bool> {};
-struct SortedPorts : Setting<bool> {};
-struct SprungLayout : Setting<bool> {};
-struct ToolbarVisible : Setting<bool> {};
-struct WindowLocation : Setting<Coord> {};
-struct WindowSize : Setting<Coord> {};
-struct Zoom : Setting<float> {};
+struct SortedPorts {
+ bool value{};
+};
+
+struct SprungLayout {
+ bool value{};
+};
+
+struct ToolbarVisible {
+ bool value{};
+};
+
+struct WindowLocation {
+ Coord value{};
+};
+
+struct WindowSize {
+ Coord value{};
+};
+
+struct Zoom {
+ float value{};
+};
} // namespace setting
/// A configuration setting
-using Setting = boost::variant<setting::AlsaAttached,
- setting::FontSize,
- setting::HumanNames,
- setting::JackAttached,
- setting::MessagesHeight,
- setting::MessagesVisible,
- setting::PortColor,
- setting::SortedPorts,
- setting::SprungLayout,
- setting::ToolbarVisible,
- setting::WindowLocation,
- setting::WindowSize,
- setting::Zoom>;
+using Setting = std::variant<setting::AlsaAttached,
+ setting::FontSize,
+ setting::HumanNames,
+ setting::JackAttached,
+ setting::MessagesHeight,
+ setting::MessagesVisible,
+ setting::PortColor,
+ setting::SortedPorts,
+ setting::SprungLayout,
+ setting::ToolbarVisible,
+ setting::WindowLocation,
+ setting::WindowSize,
+ setting::Zoom>;
} // namespace patchage
diff --git a/src/SignalDirection.hpp b/src/SignalDirection.hpp
index 94f5126..84c3cc2 100644
--- a/src/SignalDirection.hpp
+++ b/src/SignalDirection.hpp
@@ -1,22 +1,18 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_SIGNALDIRECTION_HPP
#define PATCHAGE_SIGNALDIRECTION_HPP
+#include "warnings.hpp"
+
+PATCHAGE_DISABLE_FMT_WARNINGS
+#include <fmt/core.h>
+#include <fmt/ostream.h>
+PATCHAGE_RESTORE_WARNINGS
+
+#include <ostream>
+
namespace patchage {
enum class SignalDirection {
@@ -25,6 +21,24 @@ enum class SignalDirection {
duplex,
};
+inline std::ostream&
+operator<<(std::ostream& os, const SignalDirection direction)
+{
+ switch (direction) {
+ case SignalDirection::input:
+ return os << "input";
+ case SignalDirection::output:
+ return os << "output";
+ case SignalDirection::duplex:
+ return os << "duplex";
+ }
+
+ PATCHAGE_UNREACHABLE();
+}
+
} // namespace patchage
+template<>
+struct fmt::formatter<patchage::SignalDirection> : fmt::ostream_formatter {};
+
#endif // PATCHAGE_SIGNALDIRECTION_HPP
diff --git a/src/TextViewLog.cpp b/src/TextViewLog.cpp
index 33b7d22..ad20c37 100644
--- a/src/TextViewLog.cpp
+++ b/src/TextViewLog.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "TextViewLog.hpp"
@@ -21,6 +8,7 @@
#include <gdkmm/color.h>
#include <glibmm/propertyproxy.h>
#include <glibmm/refptr.h>
+#include <glibmm/ustring.h>
#include <gtkmm/enums.h>
#include <gtkmm/textbuffer.h>
#include <gtkmm/texttag.h>
@@ -58,7 +46,7 @@ TextViewLog::TextViewLog(Widget<Gtk::TextView>& text_view)
void
TextViewLog::info(const std::string& msg)
{
- Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
+ const Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
buffer->insert(buffer->end(), std::string("\n") + msg);
_text_view->scroll_to_mark(buffer->get_insert(), 0);
}
@@ -66,7 +54,7 @@ TextViewLog::info(const std::string& msg)
void
TextViewLog::warning(const std::string& msg)
{
- Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
+ const Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
buffer->insert_with_tag(buffer->end(), std::string("\n") + msg, _warning_tag);
_text_view->scroll_to_mark(buffer->get_insert(), 0);
}
@@ -74,7 +62,7 @@ TextViewLog::warning(const std::string& msg)
void
TextViewLog::error(const std::string& msg)
{
- Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
+ const Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
buffer->insert_with_tag(buffer->end(), std::string("\n") + msg, _error_tag);
_text_view->scroll_to_mark(buffer->get_insert(), 0);
}
@@ -82,13 +70,13 @@ TextViewLog::error(const std::string& msg)
int
TextViewLog::min_height() const
{
- Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
+ const Glib::RefPtr<Gtk::TextBuffer> buffer = _text_view->get_buffer();
int y = 0;
int line_height = 0;
_text_view->get_line_yrange(buffer->begin(), y, line_height);
- return line_height + 2 * _text_view->get_pixels_inside_wrap();
+ return line_height + (2 * _text_view->get_pixels_inside_wrap());
}
} // namespace patchage
diff --git a/src/TextViewLog.hpp b/src/TextViewLog.hpp
index 5a91853..40d0782 100644
--- a/src/TextViewLog.hpp
+++ b/src/TextViewLog.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_TEXTVIEWLOG_HPP
#define PATCHAGE_TEXTVIEWLOG_HPP
@@ -39,10 +26,10 @@ class TextViewLog : public ILog
public:
explicit TextViewLog(Widget<Gtk::TextView>& text_view);
- TextViewLog(const TextViewLog&) = delete;
+ TextViewLog(const TextViewLog&) = delete;
TextViewLog& operator=(const TextViewLog&) = delete;
- TextViewLog(TextViewLog&&) = delete;
+ TextViewLog(TextViewLog&&) = delete;
TextViewLog& operator=(TextViewLog&&) = delete;
~TextViewLog() override = default;
diff --git a/src/UIFile.hpp b/src/UIFile.hpp
index ee0c4b7..1f2c39f 100644
--- a/src/UIFile.hpp
+++ b/src/UIFile.hpp
@@ -1,34 +1,19 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_UIFILE_HPP
#define PATCHAGE_UIFILE_HPP
#include "patchage_config.h"
-#ifdef PATCHAGE_BINLOC
+#if PATCHAGE_BUNDLED
# include "binary_location.h"
#endif
#include <glibmm/refptr.h>
#include <gtkmm/builder.h>
-#include <fstream>
#include <iostream>
-#include <sstream>
#include <stdexcept>
#include <string>
@@ -37,7 +22,7 @@ namespace patchage {
class UIFile
{
public:
- inline static bool is_readable(const std::string& filename)
+ static bool is_readable(const std::string& filename)
{
std::ifstream fs(filename.c_str());
const bool fail = fs.fail();
@@ -47,27 +32,26 @@ public:
static Glib::RefPtr<Gtk::Builder> open(const std::string& base_name)
{
- std::string ui_filename;
-#ifdef PATCHAGE_BINLOC
+ std::string ui_filename = base_name + ".ui";
+
+#if PATCHAGE_BUNDLED
const std::string bundle = bundle_location();
if (!bundle.empty()) {
- ui_filename = bundle + "/" + base_name + ".ui";
- if (is_readable(ui_filename)) {
- std::cout << "Loading UI file " << ui_filename << std::endl;
- return Gtk::Builder::create_from_file(ui_filename);
+ const std::string bundle_ui_filename = bundle + "/" + ui_filename;
+ if (is_readable(bundle_ui_filename)) {
+ std::cout << "Loading UI file " << bundle_ui_filename << "\n";
+ return Gtk::Builder::create_from_file(bundle_ui_filename);
}
}
#endif
- ui_filename = std::string(PATCHAGE_DATA_DIR) + "/" + base_name + ".ui";
+
+ ui_filename = std::string(PATCHAGE_DATA_DIR) + "/" + ui_filename;
if (is_readable(ui_filename)) {
- std::cout << "Loading UI file " << ui_filename << std::endl;
+ std::cout << "Loading UI file " << ui_filename << "\n";
return Gtk::Builder::create_from_file(ui_filename);
}
- std::stringstream ss;
- ss << "Unable to find " << base_name << std::endl;
- throw std::runtime_error(ss.str());
- return Glib::RefPtr<Gtk::Builder>();
+ throw std::runtime_error("Unable to find " + ui_filename);
}
};
diff --git a/src/Widget.hpp b/src/Widget.hpp
index 3d13b91..0f813da 100644
--- a/src/Widget.hpp
+++ b/src/Widget.hpp
@@ -1,24 +1,11 @@
-/* This file is part of Patchage
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_WIDGET_HPP
#define PATCHAGE_WIDGET_HPP
#include <glibmm/refptr.h>
-#include <gtkmm/builder.h> // IWYU pragma: keep
+#include <gtkmm/builder.h>
#include <string>
@@ -33,10 +20,10 @@ public:
xml->get_widget(name, _me);
}
- Widget(const Widget&) = delete;
+ Widget(const Widget&) = delete;
Widget& operator=(const Widget&) = delete;
- Widget(Widget&&) = delete;
+ Widget(Widget&&) = delete;
Widget& operator=(Widget&&) = delete;
~Widget() = default;
diff --git a/src/binary_location.h b/src/binary_location.h
index 220c534..e298775 100644
--- a/src/binary_location.h
+++ b/src/binary_location.h
@@ -1,26 +1,8 @@
-/* This file is part of Patchage.
- * Copyright 2008-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
+// Copyright 2008-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include <dlfcn.h>
-#include <climits>
#include <cstdlib>
#include <string>
@@ -30,31 +12,31 @@ namespace patchage {
inline std::string
binary_location()
{
- Dl_info dli = {};
- const int ret = dladdr(reinterpret_cast<void*>(&binary_location), &dli);
- if (!ret) {
- return "";
- }
-
- char* const bin_loc = realpath(dli.dli_fname, nullptr);
- if (!bin_loc) {
- return "";
- }
-
- std::string loc{bin_loc};
- free(bin_loc);
- return loc;
+ Dl_info dli = {};
+ const int ret = dladdr(reinterpret_cast<void*>(&binary_location), &dli);
+ if (!ret) {
+ return "";
+ }
+
+ char* const bin_loc = realpath(dli.dli_fname, nullptr);
+ if (!bin_loc) {
+ return "";
+ }
+
+ std::string loc{bin_loc};
+ free(bin_loc);
+ return loc;
}
/** Return the absolute path of the bundle (binary parent directory). */
inline std::string
bundle_location()
{
- const std::string binary = binary_location();
- if (binary.empty()) {
- return "";
- }
- return binary.substr(0, binary.find_last_of('/'));
+ const std::string binary = binary_location();
+ if (binary.empty()) {
+ return "";
+ }
+ return binary.substr(0, binary.find_last_of('/'));
}
} // namespace patchage
diff --git a/src/event_to_string.cpp b/src/event_to_string.cpp
index c8a6c42..8212b9d 100644
--- a/src/event_to_string.cpp
+++ b/src/event_to_string.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "event_to_string.hpp"
@@ -28,22 +15,18 @@
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
-#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
-#include <boost/optional/optional.hpp>
-#include <boost/variant/apply_visitor.hpp>
-
-#include <ostream> // IWYU pragma: keep
+#include <optional>
+#include <ostream>
#include <string>
+#include <variant>
namespace patchage {
namespace {
struct EventPrinter {
- using result_type = std::string; ///< For boost::apply_visitor
-
std::string operator()(const ClientType type)
{
switch (type) {
@@ -78,44 +61,12 @@ struct EventPrinter {
return fmt::format(R"(Remove client "{}")", event.id);
}
- std::string operator()(const PortType port_type)
- {
- switch (port_type) {
- case PortType::jack_audio:
- return "JACK audio";
- case PortType::jack_midi:
- return "JACK MIDI";
- case PortType::alsa_midi:
- return "ALSA MIDI";
- case PortType::jack_osc:
- return "JACK OSC";
- case PortType::jack_cv:
- return "JACK CV";
- }
-
- PATCHAGE_UNREACHABLE();
- }
-
- std::string operator()(const SignalDirection direction)
- {
- switch (direction) {
- case SignalDirection::input:
- return "input";
- case SignalDirection::output:
- return "output";
- case SignalDirection::duplex:
- return "duplex";
- }
-
- PATCHAGE_UNREACHABLE();
- }
-
std::string operator()(const event::PortCreated& event)
{
- auto result = fmt::format(R"(Add{} {} {} port "{}" ("{}"))",
+ auto result = fmt::format(R"(Add {}{} {} "{}" ("{}"))",
+ event.info.type,
event.info.is_terminal ? " terminal" : "",
- (*this)(event.info.type),
- (*this)(event.info.direction),
+ event.info.direction,
event.id,
event.info.label);
@@ -128,7 +79,7 @@ struct EventPrinter {
std::string operator()(const event::PortDestroyed& event)
{
- return fmt::format(R"("Remove port "{}")", event.id);
+ return fmt::format(R"(Remove port "{}")", event.id);
}
std::string operator()(const event::PortsConnected& event)
@@ -148,7 +99,7 @@ std::string
event_to_string(const Event& event)
{
EventPrinter printer;
- return boost::apply_visitor(printer, event);
+ return std::visit(printer, event);
}
std::ostream&
diff --git a/src/event_to_string.hpp b/src/event_to_string.hpp
index db55733..926065c 100644
--- a/src/event_to_string.hpp
+++ b/src/event_to_string.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_EVENT_TO_STRING_HPP
#define PATCHAGE_EVENT_TO_STRING_HPP
diff --git a/src/handle_event.cpp b/src/handle_event.cpp
index fa543e6..4564a27 100644
--- a/src/handle_event.cpp
+++ b/src/handle_event.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#include "handle_event.hpp"
@@ -29,12 +16,9 @@
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
-#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
-#include <boost/variant/apply_visitor.hpp>
-
-#include <iosfwd>
+#include <variant>
namespace patchage {
@@ -43,8 +27,6 @@ namespace {
class EventHandler
{
public:
- using result_type = void; ///< For boost::apply_visitor
-
explicit EventHandler(Configuration& conf,
Metadata& metadata,
Canvas& canvas,
@@ -97,7 +79,7 @@ public:
{
_metadata.set_port(event.id, event.info);
- auto* const port =
+ const auto* const port =
_canvas.create_port(_conf, _metadata, event.id, event.info);
if (!port) {
@@ -161,7 +143,7 @@ handle_event(Configuration& conf,
const Event& event)
{
EventHandler handler{conf, metadata, canvas, log};
- boost::apply_visitor(handler, event);
+ std::visit(handler, event);
}
} // namespace patchage
diff --git a/src/handle_event.hpp b/src/handle_event.hpp
index 5cf15ef..fae6d78 100644
--- a/src/handle_event.hpp
+++ b/src/handle_event.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2021 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_HANDLE_EVENT_HPP
#define PATCHAGE_HANDLE_EVENT_HPP
diff --git a/src/i18n.hpp b/src/i18n.hpp
new file mode 100644
index 0000000..ebf8fd1
--- /dev/null
+++ b/src/i18n.hpp
@@ -0,0 +1,12 @@
+// Copyright 2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef PATCHAGE_I18N_HPP
+#define PATCHAGE_I18N_HPP
+
+#include <libintl.h>
+
+/// Mark a string literal as translatable
+#define T(msgid) gettext(msgid)
+
+#endif // PATCHAGE_I18N_HPP
diff --git a/src/jackey.h b/src/jackey.h
index 2c0e298..607eadb 100644
--- a/src/jackey.h
+++ b/src/jackey.h
@@ -1,18 +1,5 @@
-/*
- Copyright 2014-2020 David Robillard <d@drobilla.net>
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+// Copyright 2014-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef JACKEY_H
#define JACKEY_H
diff --git a/src/main.cpp b/src/main.cpp
index 499db30..289242f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifdef __APPLE__
# include "binary_location.h"
@@ -34,6 +21,12 @@
#include <glibmm/ustring.h>
#include <gtkmm/main.h>
+#if USE_GETTEXT
+# include <libintl.h>
+
+# include <clocale>
+#endif
+
#include <cstring>
#include <exception>
#include <iostream>
@@ -82,16 +75,16 @@ print_usage()
std::cout << "Usage: patchage [OPTION]...\n";
std::cout << "Visually connect JACK and ALSA Audio and MIDI ports.\n\n";
std::cout << "Options:\n";
- std::cout << " -h, --help Display this help and exit.\n";
- std::cout << " -A, --no-alsa Do not automatically attach to ALSA.\n";
- std::cout << " -J, --no-jack Do not automatically attack to JACK.\n";
+ std::cout << " -h, --help Display this help and exit\n";
+ std::cout << " -A, --no-alsa Do not automatically attach to ALSA\n";
+ std::cout << " -J, --no-jack Do not automatically attack to JACK\n";
}
void
print_version()
{
std::cout << "Patchage " PATCHAGE_VERSION << R"(
-Copyright 2007-2020 David Robillard <d@drobilla.net>.
+Copyright 2007-2022 David Robillard <d@drobilla.net>.
License GPLv3+: <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
@@ -107,10 +100,20 @@ main(int argc, char** argv)
set_bundle_environment();
#endif
+#if USE_GETTEXT
+ if (!setlocale(LC_ALL, "")) {
+ std::cerr << "patchage: failed to set locale\n";
+ }
+
+ bindtextdomain("patchage", PATCHAGE_LOCALE_DIR);
+ bind_textdomain_codeset("patchage", "UTF-8");
+ textdomain("patchage");
+#endif
+
try {
Glib::thread_init();
- Gtk::Main app(argc, argv);
+ const Gtk::Main app(argc, argv);
++argv;
--argc;
@@ -143,12 +146,11 @@ main(int argc, char** argv)
patchage::Patchage patchage(options);
Gtk::Main::run(*patchage.window());
patchage.save();
-
} catch (std::exception& e) {
- std::cerr << "patchage: error: " << e.what() << std::endl;
+ std::cerr << "patchage: error: " << e.what() << "\n";
return 1;
} catch (Glib::Exception& e) {
- std::cerr << "patchage: error: " << e.what() << std::endl;
+ std::cerr << "patchage: error: " << e.what() << "\n";
return 1;
}
diff --git a/src/make_alsa_driver.hpp b/src/make_alsa_driver.hpp
index f72da99..7f3b594 100644
--- a/src/make_alsa_driver.hpp
+++ b/src/make_alsa_driver.hpp
@@ -1,24 +1,10 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_MAKE_ALSA_DRIVER_HPP
#define PATCHAGE_MAKE_ALSA_DRIVER_HPP
#include "Driver.hpp"
-#include "patchage_config.h"
#include <memory>
@@ -26,21 +12,9 @@ namespace patchage {
class ILog;
-#if defined(HAVE_ALSA)
-
std::unique_ptr<Driver>
make_alsa_driver(ILog& log, Driver::EventSink emit_event);
-#else
-
-inline std::unique_ptr<Driver>
-make_alsa_driver(ILog&, Driver::EventSink)
-{
- return nullptr;
-}
-
-#endif
-
} // namespace patchage
#endif // PATCHAGE_MAKE_ALSA_DRIVER_HPP
diff --git a/src/make_jack_driver.hpp b/src/make_jack_driver.hpp
index abd1ba1..79c6eb5 100644
--- a/src/make_jack_driver.hpp
+++ b/src/make_jack_driver.hpp
@@ -1,24 +1,10 @@
-/* This file is part of Patchage.
- * Copyright 2007-2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_MAKE_JACK_DRIVER_HPP
#define PATCHAGE_MAKE_JACK_DRIVER_HPP
#include "Driver.hpp"
-#include "patchage_config.h"
#include <memory>
@@ -27,21 +13,9 @@ namespace patchage {
class AudioDriver;
class ILog;
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
-
std::unique_ptr<AudioDriver>
make_jack_driver(ILog& log, Driver::EventSink emit_event);
-#else
-
-inline std::unique_ptr<AudioDriver>
-make_jack_driver(ILog&, Driver::EventSink)
-{
- return nullptr;
-}
-
-#endif
-
} // namespace patchage
#endif // PATCHAGE_MAKE_JACK_DRIVER_HPP
diff --git a/src/patchage.ui b/src/patchage.ui.in
index d86fb80..a7078d5 100644
--- a/src/patchage.ui
+++ b/src/patchage.ui.in
@@ -5,7 +5,7 @@
<object class="GtkWindow" id="main_win">
<property name="can_focus">False</property>
<property name="border_width">1</property>
- <property name="title" translatable="yes">Patchage</property>
+ <property name="title" translatable="no">Patchage</property>
<child>
<object class="GtkVBox" id="main_vbox">
<property name="visible">True</property>
@@ -27,7 +27,7 @@
<object class="GtkMenuItem" id="menu_export_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">_Export Image...</property>
+ <property name="label" translatable="yes">_Export Image…</property>
<property name="use_underline">True</property>
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
@@ -64,7 +64,7 @@
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="menu_jack_connect">
- <property name="label">Connect to _Jack</property>
+ <property name="label" translatable="yes">Connect to _JACK</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -75,7 +75,7 @@
</child>
<child>
<object class="GtkImageMenuItem" id="menu_jack_disconnect">
- <property name="label">Disconnect from Jack</property>
+ <property name="label" translatable="yes">Disconnect from JACK</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
@@ -92,7 +92,7 @@
</child>
<child>
<object class="GtkImageMenuItem" id="menu_alsa_connect">
- <property name="label">Connect to _Alsa</property>
+ <property name="label" translatable="yes">Connect to _ALSA</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -103,7 +103,7 @@
</child>
<child>
<object class="GtkImageMenuItem" id="menu_alsa_disconnect">
- <property name="label">Disconnect from ALSA</property>
+ <property name="label" translatable="yes">Disconnect from ALSA</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
@@ -269,7 +269,7 @@
</child>
<child>
<object class="GtkImageMenuItem" id="menu_view_arrange">
- <property name="label">_Arrange</property>
+ <property name="label" translatable="yes">_Arrange</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -284,6 +284,7 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes">Sprung Layou_t</property>
<property name="use_underline">True</property>
+ <property name="active">False</property>
<accelerator key="t" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
</child>
@@ -338,7 +339,7 @@
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Jack buffer size and sample rate.</property>
+ <property name="tooltip_text" translatable="yes">JACK buffer size and sample rate.</property>
<property name="yscale">0</property>
<child>
<object class="GtkHBox" id="hbox4">
@@ -349,8 +350,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_tooltip">True</property>
- <property name="tooltip_markup">Jack buffer length in frames</property>
- <property name="tooltip_text" translatable="yes">Jack buffer length in frames.</property>
+ <property name="tooltip_markup">JACK buffer length in frames</property>
+ <property name="tooltip_text" translatable="yes">JACK buffer length in frames.</property>
<property name="border_width">1</property>
</object>
<packing>
@@ -362,7 +363,7 @@
<child>
<object class="GtkLabel" id="latency_label">
<property name="can_focus">False</property>
- <property name="label" translatable="yes">frames @ ? kHz (? ms)</property>
+ <property name="label" translatable="yes">frames at ? kHz (? ms)</property>
</object>
<packing>
<property name="expand">False</property>
@@ -388,7 +389,7 @@
<object class="GtkLabel" id="dropouts_label">
<property name="can_focus">False</property>
<property name="visible">False</property>
- <property name="label" translatable="yes"> Dropouts: 0</property>
+ <property name="label" translatable="yes">Dropouts: {}</property>
</object>
</child>
</object>
@@ -500,11 +501,11 @@
<property name="transient_for">main_win</property>
<property name="program_name">Patchage</property>
<property name="version">@PATCHAGE_VERSION@</property>
- <property name="copyright" translatable="yes">© 2005-2020 David Robillard
+ <property name="copyright" translatable="no">© 2005-2022 David Robillard
© 2008 Nedko Arnaudov</property>
- <property name="comments" translatable="yes">A JACK and ALSA front-end.</property>
+ <property name="comments" translatable="yes">A modular patchbay for JACK and ALSA applications.</property>
<property name="website">http://drobilla.net/software/patchage</property>
- <property name="license" translatable="yes"> GNU GENERAL PUBLIC LICENSE
+ <property name="license" translatable="no"> GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
diff --git a/src/patchage_config.h b/src/patchage_config.h
new file mode 100644
index 0000000..6c4f09f
--- /dev/null
+++ b/src/patchage_config.h
@@ -0,0 +1,112 @@
+// Copyright 2021-2023 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+/*
+ Configuration header that defines reasonable defaults at compile-time.
+
+ This allows configuration from the command-line (usually by the build system)
+ while still allowing the code to compile "as-is" with reasonable default
+ features on supported platforms.
+
+ This system is designed so that, ideally, no command-line or build-system
+ configuration is needed, but automatic feature detection can be disabled or
+ overridden for maximum control. It should never be necessary to edit the
+ source code to achieve a given configuration.
+
+ Usage:
+
+ - By default, features are enabled if they can be detected or assumed to be
+ available from the build environment, unless `PATCHAGE_NO_DEFAULT_CONFIG`
+ is defined, which disables everything by default.
+
+ - If a symbol like `HAVE_SOMETHING` is defined to non-zero, then the
+ "something" feature is assumed to be available.
+
+ Code rules:
+
+ - To check for a feature, this header must be included, and the symbol
+ `USE_SOMETHING` used as a boolean in an `#if` expression.
+
+ - None of the other configuration symbols described here may be used
+ directly. In particular, this header should be the only place in the
+ source code that touches `HAVE` symbols.
+*/
+
+#ifndef PATCHAGE_CONFIG_H
+#define PATCHAGE_CONFIG_H
+
+// Define version unconditionally so a warning will catch a mismatch
+#define PATCHAGE_VERSION "1.0.11"
+
+#if !defined(PATCHAGE_NO_DEFAULT_CONFIG)
+
+// Classic UNIX: dladdr()
+# ifndef HAVE_DLADDR
+# ifdef __has_include
+# if __has_include(<dlfcn.h>)
+# define HAVE_DLADDR 1
+# endif
+# elif defined(__unix__) || defined(__APPLE__)
+# define HAVE_DLADDR 1
+# endif
+# endif
+
+// GNU gettext()
+# ifndef HAVE_GETTEXT
+# ifdef __has_include
+# if __has_include(<libintl.h>)
+# define HAVE_GETTEXT 1
+# endif
+# endif
+# endif
+
+// JACK metadata API
+# ifndef HAVE_JACK_METADATA
+# ifdef __has_include
+# if __has_include(<jack/metadata.h>)
+# define HAVE_JACK_METADATA 1
+# endif
+# endif
+# endif
+
+#endif // !defined(PATCHAGE_NO_DEFAULT_CONFIG)
+
+/*
+ Make corresponding USE_FEATURE defines based on the HAVE_FEATURE defines from
+ above or the command line. The code checks for these using #if (not #ifdef),
+ so there will be an undefined warning if it checks for an unknown feature,
+ and this header is always required by any code that checks for features, even
+ if the build system defines them all.
+*/
+
+#if defined(HAVE_DLADDR) && HAVE_DLADDR
+# define USE_DLADDR 1
+#else
+# define USE_DLADDR 0
+#endif
+
+#if defined(HAVE_GETTEXT) && HAVE_GETTEXT
+# define USE_GETTEXT 1
+#else
+# define USE_GETTEXT 0
+#endif
+
+#if defined(HAVE_JACK_METADATA) && HAVE_JACK_METADATA
+# define USE_JACK_METADATA 1
+#else
+# define USE_JACK_METADATA 0
+#endif
+
+#if !defined(PATCHAGE_USE_LIGHT_THEME)
+# define PATCHAGE_USE_LIGHT_THEME 0
+#endif
+
+#ifndef PATCHAGE_BUNDLED
+# ifdef __APPLE__
+# define PATCHAGE_BUNDLED 1
+# else
+# define PATCHAGE_BUNDLED 0
+# endif
+#endif
+
+#endif // PATCHAGE_CONFIG_H
diff --git a/src/warnings.hpp b/src/warnings.hpp
index e8337a1..ee9b3d8 100644
--- a/src/warnings.hpp
+++ b/src/warnings.hpp
@@ -1,18 +1,5 @@
-/* This file is part of Patchage.
- * Copyright 2020 David Robillard <d@drobilla.net>
- *
- * Patchage 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 3 of the License, or (at your option)
- * any later version.
- *
- * Patchage 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 details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Patchage. If not, see <http://www.gnu.org/licenses/>.
- */
+// Copyright 2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PATCHAGE_WARNINGS_HPP
#define PATCHAGE_WARNINGS_HPP