clap

CLAP Audio Plugin API
Log | Files | Refs | README | LICENSE

commit 03828f497987726fec84017413c0f96707b67fff
parent 2a8efe1bac4e714179186c10c39aeac6c46d48b2
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Sat,  7 Aug 2021 21:39:35 +0200

More work

Diffstat:
Mexamples/gui/application.cc | 22++++++++++++++++++----
Mexamples/host/plugin-host.cc | 10+++++-----
Mexamples/io/remote-channel.cc | 8+++++++-
Mexamples/plugins/path-provider.cc | 22+++++++++++++++-------
Mexamples/plugins/path-provider.hh | 1+
Mexamples/plugins/plugin-helper.cc | 8++++++--
Mexamples/plugins/plugin-helper.hh | 6++++++
Mexamples/plugins/remote-gui.cc | 30++++++++++++++++++++++--------
Mexamples/plugins/remote-gui.hh | 2++
9 files changed, 82 insertions(+), 27 deletions(-)

diff --git a/examples/gui/application.cc b/examples/gui/application.cc @@ -24,21 +24,20 @@ Application::Application(int argc, char **argv) auto socket = parser.value(socketOpt).toULongLong(); socketReadNotifier_ = new QSocketNotifier(socket, QSocketNotifier::Read, this); - socketReadNotifier_->setEnabled(true); connect( socketReadNotifier_, &QSocketNotifier::activated, - [this](QSocketDescriptor socket, QSocketNotifier::Type type) { remoteChannel_->onRead(); }); + [this](QSocketDescriptor socket, QSocketNotifier::Type type) { + printf("ON READ\n"); + remoteChannel_->onRead(); }); socketWriteNotifier_ = new QSocketNotifier(socket, QSocketNotifier::Write, this); - socketWriteNotifier_->setEnabled(false); connect( socketWriteNotifier_, &QSocketNotifier::activated, [this](QSocketDescriptor socket, QSocketNotifier::Type type) { remoteChannel_->onWrite(); }); socketErrorNotifier_ = new QSocketNotifier(socket, QSocketNotifier::Exception, this); - socketErrorNotifier_->setEnabled(false); connect(socketErrorNotifier_, &QSocketNotifier::activated, [this](QSocketDescriptor socket, QSocketNotifier::Type type) { @@ -48,6 +47,10 @@ Application::Application(int argc, char **argv) remoteChannel_.reset(new clap::RemoteChannel( [this](const clap::RemoteChannel::Message &msg) { onMessage(msg); }, *this, socket, false)); + + socketReadNotifier_->setEnabled(true); + socketWriteNotifier_->setEnabled(false); + socketErrorNotifier_->setEnabled(false); } void Application::modifyFd(clap_fd_flags flags) { @@ -95,5 +98,16 @@ void Application::onMessage(const clap::RemoteChannel::Message &msg) { remoteChannel_->sendMessageAsync(rp); break; } + + case clap::messages::kSizeRequest: { + clap::messages::SizeRequest rq; + msg.get(rq); + + clap::messages::SizeResponse rp; + rp.width = quickView_->width(); + rp.height = quickView_->height(); + remoteChannel_->sendMessageAsync(rp); + break; + } } } diff --git a/examples/host/plugin-host.cc b/examples/host/plugin-host.cc @@ -416,8 +416,8 @@ bool PluginHost::clapEventLoopRegisterFd(const clap_host *host, clap_fd fd, uint h->initPluginExtensions(); if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_fd) throw std::logic_error( - "Called unregister_timer() without providing clap_plugin_event_loop to " - "receive the timer event."); + "Called register_fd() without providing clap_plugin_event_loop to " + "receive the fd event."); auto it = h->fds_.find(fd); if (it != h->fds_.end()) @@ -435,7 +435,7 @@ bool PluginHost::clapEventLoopModifyFd(const clap_host *host, clap_fd fd, uint32 auto h = fromHost(host); if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_fd) throw std::logic_error( - "Called unregister_timer() without providing clap_plugin_event_loop to " + "Called modify_fd() without providing clap_plugin_event_loop to " "receive the timer event."); auto it = h->fds_.find(fd); @@ -454,8 +454,8 @@ bool PluginHost::clapEventLoopUnregisterFd(const clap_host *host, clap_fd fd) { auto h = fromHost(host); if (!h->pluginEventLoop_ || !h->pluginEventLoop_->on_fd) throw std::logic_error( - "Called unregister_timer() without providing clap_plugin_event_loop to " - "receive the timer event."); + "Called unregister_fd() without providing clap_plugin_event_loop to " + "receive the fd event."); auto it = h->fds_.find(fd); if (it == h->fds_.end()) diff --git a/examples/io/remote-channel.cc b/examples/io/remote-channel.cc @@ -1,5 +1,6 @@ #ifdef __unix__ # include <errno.h> +# include <fcntl.h> # include <poll.h> # include <unistd.h> #endif @@ -12,7 +13,12 @@ namespace clap { EventControl &evControl, int socket, bool cookieHalf) - : cookieHalf_(cookieHalf), handler_(handler), evControl_(evControl), socket_(socket) {} + : cookieHalf_(cookieHalf), handler_(handler), evControl_(evControl), socket_(socket) { +#ifdef __unix__ + int flags = ::fcntl(socket_, F_GETFL); + ::fcntl(socket_, F_SETFL, flags | O_NONBLOCK); +#endif + } RemoteChannel::~RemoteChannel() { close(); } diff --git a/examples/plugins/path-provider.cc b/examples/plugins/path-provider.cc @@ -20,7 +20,9 @@ namespace clap { return m[1]; } - std::string getGuiExecutable() const override { return prefix_ / "/bin/clap-gui"; } + std::string getGuiExecutable() const override { return prefix_ / "bin/clap-gui"; } + + bool isValid() const noexcept override { return !prefix_.empty(); } private: const std::filesystem::path prefix_; @@ -51,10 +53,10 @@ namespace clap { } std::string getGuiExecutable() const override { - return buildRoot_ / "/examples/gui/clap-gui"; + return buildRoot_ / "examples/gui/clap-gui"; } - bool isValid() const noexcept { return !srcRoot_.empty() && !buildRoot_.empty(); } + bool isValid() const noexcept override { return !srcRoot_.empty() && !buildRoot_.empty(); } private: const std::filesystem::path srcRoot_; @@ -68,10 +70,16 @@ namespace clap { #ifdef __linux__ { - auto ptr = std::make_unique<LinuxDevelopmentPathProvider>(pluginPath); - if (ptr->isValid()) - return ptr.release(); - return new LinuxPathProvider(pluginPath); + instance_.reset(new LinuxDevelopmentPathProvider(pluginPath)); + if (instance_->isValid()) + return instance_.get(); + + instance_.reset(new LinuxPathProvider(pluginPath)); + if (instance_->isValid()) + return instance_.get(); + + instance_.reset(); + return nullptr; } #endif diff --git a/examples/plugins/path-provider.hh b/examples/plugins/path-provider.hh @@ -11,6 +11,7 @@ namespace clap { static const PathProvider *instance() { return instance_.get(); } virtual std::string getGuiExecutable() const = 0; + virtual bool isValid() const = 0; private: static std::unique_ptr<PathProvider> instance_; diff --git a/examples/plugins/plugin-helper.cc b/examples/plugins/plugin-helper.cc @@ -83,8 +83,7 @@ namespace clap { bool PluginHelper::guiCreate() noexcept { remoteGui_.reset(new RemoteGui(*this)); - if (!remoteGui_->spawn()) - { + if (!remoteGui_->spawn()) { remoteGui_.reset(); return false; } @@ -118,4 +117,9 @@ namespace clap { if (remoteGui_) remoteGui_->hide(); } + + void PluginHelper::eventLoopOnFd(clap_fd fd, uint32_t flags) noexcept { + if (remoteGui_ && fd == remoteGui_->fd()) + remoteGui_->onFd(flags); + } } // namespace clap \ No newline at end of file diff --git a/examples/plugins/plugin-helper.hh b/examples/plugins/plugin-helper.hh @@ -131,6 +131,12 @@ namespace clap { return hasTrackInfo_ ? trackInfo_.channel_map : CLAP_CHMAP_STEREO; } + //------------------------// + // clap_plugin_event_loop // + //------------------------// + bool implementsEventLoop() const noexcept override { return true; } + void eventLoopOnFd(clap_fd fd, uint32_t flags) noexcept override; + protected: friend class RemoteGui; diff --git a/examples/plugins/remote-gui.cc b/examples/plugins/remote-gui.cc @@ -7,12 +7,11 @@ #include "../io/messages.hh" #include "path-provider.hh" -#include "remote-gui.hh" #include "plugin-helper.hh" +#include "remote-gui.hh" namespace clap { - RemoteGui::~RemoteGui() - { + RemoteGui::~RemoteGui() { if (channel_) destroy(); @@ -30,6 +29,10 @@ namespace clap { return false; } + printf("About to start GUI: %s --socket %d\n", + PathProvider::instance()->getGuiExecutable().c_str(), + sockets[0]); + child_ = ::fork(); if (child_ == -1) { ::close(sockets[0]); @@ -42,15 +45,16 @@ namespace clap { ::close(sockets[0]); char socketStr[16]; ::snprintf(socketStr, sizeof(socketStr), "%d", sockets[1]); - ::execl(PathProvider::instance()->getGuiExecutable().c_str(), "--socket", socketStr); + auto path = PathProvider::instance()->getGuiExecutable(); + ::execl(path.c_str(), path.c_str(), "--socket", socketStr, nullptr); + printf("Failed to start child process: %m\n"); std::terminate(); } else { // Parent ::close(sockets[1]); } - plugin_.hostEventLoop_->register_fd(plugin_.host_, channel_->fd(), CLAP_FD_READ | CLAP_FD_ERROR); - + plugin_.hostEventLoop_->register_fd(plugin_.host_, sockets[0], CLAP_FD_READ | CLAP_FD_ERROR); channel_.reset(new RemoteChannel( [this](const RemoteChannel::Message &msg) { onMessage(msg); }, *this, sockets[0], true)); @@ -60,11 +64,21 @@ namespace clap { #endif } - void RemoteGui::modifyFd(clap_fd_flags flags) - { + void RemoteGui::modifyFd(clap_fd_flags flags) { plugin_.hostEventLoop_->modify_fd(plugin_.host_, channel_->fd(), flags); } + clap_fd RemoteGui::fd() const { return channel_ ? channel_->fd() : -1; } + + void RemoteGui::onFd(clap_fd_flags flags) { + if (flags & CLAP_FD_READ) + channel_->onRead(); + if (flags & CLAP_FD_WRITE) + channel_->onWrite(); + if (flags & CLAP_FD_ERROR) + channel_->onError(); + } + void RemoteGui::onMessage(const RemoteChannel::Message &msg) { switch (msg.type) {} } diff --git a/examples/plugins/remote-gui.hh b/examples/plugins/remote-gui.hh @@ -33,6 +33,8 @@ namespace clap { // RemoteChannel::EventControl void modifyFd(clap_fd_flags flags) override; + clap_fd fd() const; + void onFd(clap_fd_flags flags); private: void onMessage(const RemoteChannel::Message& msg);