clap

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

commit 3ac3716a1716f3238c7cf91d89710b68597f8be2
parent c21ae76174119c108e50e926df0d735bef576e7e
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Thu, 29 Jul 2021 16:47:31 +0200

More work on the gui interfaces

Diffstat:
Mexamples/glue/clap-plugin.cc | 18++++++++++++++++--
Mexamples/glue/clap-plugin.hh | 17+++++++++++++----
Mexamples/io/remote-channel.hh | 2+-
Mexamples/plugins/plugin-helper.cc | 9+++++++++
Mexamples/plugins/plugin-helper.hh | 43+++++++++++++++++++++++++++++++++++++++++++
Mexamples/plugins/remote-gui.hh | 6+++++-
Minclude/clap/ext/gui.h | 50++++++++++++++++++++++++++++++++++++++++++++------
Minclude/clap/version.h | 2+-
8 files changed, 132 insertions(+), 15 deletions(-)

diff --git a/examples/glue/clap-plugin.cc b/examples/glue/clap-plugin.cc @@ -575,11 +575,11 @@ namespace clap { //-----------------// // clap_plugin_gui // //-----------------// - void Plugin::clapGuiSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept { + bool Plugin::clapGuiSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_gui.size"); - self.guiSize(width, height); + return self.guiSize(width, height); } bool Plugin::clapGuiCanResize(const clap_plugin *plugin) noexcept { @@ -596,6 +596,13 @@ namespace clap { self.guiRoundSize(width, height); } + bool Plugin::clapGuiSetSize(const clap_plugin *plugin, uint32_t width, uint32_t height) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_gui.set_size"); + + return self.guiSetSize(width, height); + } + void Plugin::clapGuiSetScale(const clap_plugin *plugin, double scale) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_gui.set_scale"); @@ -617,6 +624,13 @@ namespace clap { self.guiHide(); } + bool Plugin::clapGuiCreate(const clap_plugin *plugin) noexcept { + auto &self = from(plugin); + self.ensureMainThread("clap_plugin_gui.create"); + + return self.guiCreate(); + } + void Plugin::clapGuiClose(const clap_plugin *plugin) noexcept { auto &self = from(plugin); self.ensureMainThread("clap_plugin_gui.close"); diff --git a/examples/glue/clap-plugin.hh b/examples/glue/clap-plugin.hh @@ -147,8 +147,10 @@ namespace clap { // clap_plugin_gui // //-----------------// virtual bool implementsGui() const noexcept { return false; } + virtual bool guiCreate() noexcept { return false; } virtual bool guiCanResize() const noexcept { return false; } - virtual void guiSize(uint32_t *width, uint32_t *height) noexcept {} + virtual bool guiSize(uint32_t *width, uint32_t *height) noexcept { return false; } + virtual bool guiSetSize(uint32_t width, uint32_t height) noexcept { return false; } virtual void guiRoundSize(uint32_t *width, uint32_t *height) noexcept { guiSize(width, height); } @@ -332,11 +334,16 @@ namespace clap { static void clapEventLoopOnFd(const clap_plugin *plugin, clap_fd fd, uint32_t flags) noexcept; // clap_plugin_gui + static bool clapGuiCreate(const clap_plugin *plugin) noexcept; static void clapGuiSetScale(const clap_plugin *plugin, double scale) noexcept; - static void clapGuiSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept; + static bool + clapGuiSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept; + static bool + clapGuiSetSize(const clap_plugin *plugin, uint32_t width, uint32_t height) noexcept; static void clapGuiShow(const clap_plugin *plugin) noexcept; static bool clapGuiCanResize(const clap_plugin *plugin) noexcept; - static void clapGuiRoundSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept; + static void + clapGuiRoundSize(const clap_plugin *plugin, uint32_t *width, uint32_t *height) noexcept; static void clapGuiHide(const clap_plugin *plugin) noexcept; static void clapGuiClose(const clap_plugin *plugin) noexcept; @@ -414,13 +421,15 @@ namespace clap { }; static const constexpr clap_plugin_gui pluginGui_ = { + clapGuiCreate, + clapGuiClose, clapGuiSetScale, clapGuiSize, clapGuiCanResize, clapGuiRoundSize, + clapGuiSetSize, clapGuiShow, clapGuiHide, - clapGuiClose, }; static const constexpr clap_plugin_gui_x11 pluginGuiX11_ = { diff --git a/examples/io/remote-channel.hh b/examples/io/remote-channel.hh @@ -12,7 +12,7 @@ namespace clap { public: class EventControl { public: - virtual void modifyFd(clap_fd_flags flags); + virtual void modifyFd(clap_fd_flags flags) = 0; }; class Handler { diff --git a/examples/plugins/plugin-helper.cc b/examples/plugins/plugin-helper.cc @@ -79,4 +79,13 @@ namespace clap { } return true; } + + bool PluginHelper::guiSize(uint32_t *width, uint32_t *height) noexcept + { + if (!remoteGui_) + return false; + + // TODO: synchronous call + return false; + } } // namespace clap \ No newline at end of file diff --git a/examples/plugins/plugin-helper.hh b/examples/plugins/plugin-helper.hh @@ -3,6 +3,7 @@ #include <clap-plugin.hh> #include "parameters.hh" +#include "remote-gui.hh" namespace clap { class PluginHelper : public Plugin { @@ -74,6 +75,46 @@ namespace clap { bool stateSave(clap_ostream *stream) noexcept override; bool stateLoad(clap_istream *stream) noexcept override; + //-----------------// + // clap_plugin_gui // + //-----------------// + bool implementsGui() const noexcept override { return true; } + bool guiCanResize() const noexcept override { return false; } + bool guiSize(uint32_t *width, uint32_t *height) noexcept override; + void guiRoundSize(uint32_t *width, uint32_t *height) noexcept override { + guiSize(width, height); + } + void guiSetScale(double scale) noexcept override {} + void guiShow() noexcept override {} + void guiHide() noexcept override {} + void guiClose() noexcept override {} + + //---------------------// + // clap_plugin_gui_x11 // + //---------------------// + bool implementsGuiX11() const noexcept override { return false; } + bool guiX11Attach(const char *displayName, unsigned long window) noexcept override { + return false; + } + + //-----------------------// + // clap_plugin_gui_win32 // + //-----------------------// + bool implementsGuiWin32() const noexcept override { return false; } + bool guiWin32Attach(clap_hwnd window) noexcept override { return false; } + + //-----------------------// + // clap_plugin_gui_cocoa // + //-----------------------// + bool implementsGuiCocoa() const noexcept override { return false; } + bool guiCocoaAttach(void *nsView) noexcept override { return false; } + + //-------------------------------// + // clap_plugin_gui_free_standing // + //-------------------------------// + bool implementsGuiFreeStanding() const noexcept override { return false; } + bool guiFreeStandingOpen() noexcept override { return false; } + ////////////////////// // Cached Host Info // ////////////////////// @@ -97,6 +138,8 @@ namespace clap { std::vector<clap_audio_port_info> audioOutputs_; std::vector<clap_audio_ports_config> audioConfigs_; + std::unique_ptr<RemoteGui> remoteGui_; + Parameters parameters_; }; } // namespace clap \ No newline at end of file diff --git a/examples/plugins/remote-gui.hh b/examples/plugins/remote-gui.hh @@ -32,13 +32,17 @@ namespace clap { void adjust(clap_id paramId, double value) override; void endAdjust(clap_id paramId) override; + // RemoteChannel::EventControl + void modifyFd(clap_fd_flags flags) override; + private: std::unique_ptr<RemoteChannel> channel_; #ifdef __unix__ pid_t child_ = -1; #else - HANDLE socket_ = nullptr; + STARTUPINFO si; + PROCESS_INFORMATION childInfo_; #endif }; } // namespace clap \ No newline at end of file diff --git a/include/clap/ext/gui.h b/include/clap/ext/gui.h @@ -2,6 +2,27 @@ #include "../clap.h" +/// @page GUI +/// +/// This extension is splet in two interfaces: +/// - `gui` which is the generic part +/// - `gui_XXX` which is the platform specific interfaces; @see clap_gui_win32. +/// +/// Showing the GUI works as follow: +/// 1. clap_plugin_gui->create(), allocates gui resources +/// 2. clap_plugin_gui->set_scale() +/// 3. clap_plugin_gui->get_size(), gets initial size +/// 4. clap_plugin_gui_win32->embed(), or any other platform specific interface +/// 5. clap_plugin_gui->show() +/// 6. clap_plugin_gui->hide()/show() ... +/// 7. clap_plugin_gui->close() when done with the gui +/// +/// Resizing the window: +/// 1. Only possible if clap_plugin_gui->can_resize() returns true +/// 2. Mouse drag -> new_size +/// 3. clap_plugin_gui->round_size(new_size) -> working_size +/// 4. clap_plugin_gui->set_size(working_size) + static CLAP_CONSTEXPR const char CLAP_EXT_GUI[] = "clap.gui"; #ifdef __cplusplus @@ -9,31 +30,48 @@ extern "C" { #endif typedef struct clap_plugin_gui { - // Set the GUI scaling factor. + // Create and allocate all resources necessary for the gui. + // After this call, the GUI is ready to be shown but it is not yet visible. + // [main-thread] + bool (*create)(const clap_plugin *plugin); + + // Free all resources associated with the gui. + // [main-thread] + void (*close)(const clap_plugin *plugin); + + // Set the absolute GUI scaling factor. // [main-thread] void (*set_scale)(const clap_plugin *plugin, double scale); // Get the current size of the plugin UI, with the scaling applied. + // clap_plugin_gui->create() must have been called prior to asking the size. // [main-thread] - void (*size)(const clap_plugin *plugin, uint32_t *width, uint32_t *height); + bool (*size)(const clap_plugin *plugin, uint32_t *width, uint32_t *height); // [main-thread] bool (*can_resize)(const clap_plugin *plugin); - // If the plugin gui is resizable, then the plugin will return the closest + // If the plugin gui is resizable, then the plugin will calculate the closest // usable size to the given arguments. + // The scaling is applied. + // This method does not change the size. // // [main-thread] void (*round_size)(const clap_plugin *plugin, uint32_t *width, uint32_t *height); + // Sets the window size + // Returns true if the size is supported. // [main-thread] - void (*show)(const clap_plugin *plugin); + bool (*set_size)(const clap_plugin *plugin, uint32_t width, uint32_t height); + // Show the window. // [main-thread] - void (*hide)(const clap_plugin *plugin); + void (*show)(const clap_plugin *plugin); + // Hide the window, this method do not free the resources, it just hides + // the window content. Yet it maybe a good idea to stop painting timers. // [main-thread] - void (*close)(const clap_plugin *plugin); + void (*hide)(const clap_plugin *plugin); } clap_plugin_gui; typedef struct clap_host_gui { diff --git a/include/clap/version.h b/include/clap/version.h @@ -22,7 +22,7 @@ typedef struct clap_version { } #endif -static CLAP_CONSTEXPR const clap_version CLAP_VERSION = {0, 9, 0}; +static CLAP_CONSTEXPR const clap_version CLAP_VERSION = {0, 10, 0}; static CLAP_CONSTEXPR inline bool clap_version_is_compatible(const clap_version &v) { // For version 0, we require the same minor version because