From 4e41ef9719de02e039fcbb1eb10b9842c00d036f Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 4 Feb 2014 08:33:48 +0000 Subject: [PATCH] Move static host stuff to engine, so it works for carla-plugin --- source/backend/CarlaBackend.h | 40 ++++++++++++++- source/backend/CarlaEngine.hpp | 21 +++++++- source/backend/CarlaHost.h | 41 +-------------- source/backend/engine/CarlaEngine.cpp | 34 +++++++++++++ source/backend/engine/CarlaEngineInternal.cpp | 5 +- source/backend/engine/CarlaEngineInternal.hpp | 3 ++ source/backend/plugin/CarlaPlugin.cpp | 6 +-- source/backend/plugin/CarlaPluginUi.cpp | 22 ++++---- source/backend/plugin/CarlaPluginUi.hpp | 8 +-- source/backend/plugin/Lv2Plugin.cpp | 7 +-- source/backend/plugin/Makefile | 2 +- source/backend/plugin/NativePlugin.cpp | 5 +- source/backend/plugin/VstPlugin.cpp | 9 ++-- source/backend/standalone/CarlaStandalone.cpp | 50 ++++++++----------- source/carla | 4 +- source/carla-patchbay | 4 +- source/carla-plugin | 11 +++- source/carla-rack | 4 +- source/carla_backend.py | 43 ++++++++-------- source/utils/CarlaBackendUtils.hpp | 2 + 20 files changed, 193 insertions(+), 128 deletions(-) diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h index 5f3b668e6..fd92e8edb 100644 --- a/source/backend/CarlaBackend.h +++ b/source/backend/CarlaBackend.h @@ -1021,7 +1021,12 @@ typedef enum { * Default unset. * @note Must be set for some internal plugins to work */ - ENGINE_OPTION_PATH_RESOURCES = 14 + ENGINE_OPTION_PATH_RESOURCES = 14, + + /*! + * Set frontend winId, used to define as parent window for plugin UIs. + */ + ENGINE_OPTION_FRONTEND_WIN_ID = 15 } EngineOption; @@ -1094,6 +1099,33 @@ typedef enum { } EngineTransportMode; +/* ------------------------------------------------------------------------------------------------------------ + * File Callback Opcode */ + +/*! + * File callback opcodes.\n + * Front-ends must always block-wait for user input. + * @see FileCallbackFunc, CarlaEngine::setFileCallback() and carla_set_file_callback() + */ +typedef enum { + /*! + * Debug.\n + * This opcode is undefined and used only for testing purposes. + */ + FILE_CALLBACK_DEBUG = 0, + + /*! + * Open file or folder. + */ + FILE_CALLBACK_OPEN = 1, + + /*! + * Save file or folder. + */ + FILE_CALLBACK_SAVE = 2 + +} FileCallbackOpcode; + /* ------------------------------------------------------------------------------------------------------------ * Patchbay Icon */ @@ -1148,6 +1180,12 @@ enum PatchbayIcon { */ typedef void (*EngineCallbackFunc)(void* ptr, EngineCallbackOpcode action, uint pluginId, int value1, int value2, float value3, const char* valueStr); +/*! + * File callback function. + * @see FileCallbackOpcode + */ +typedef const char* (*FileCallbackFunc)(void* ptr, FileCallbackOpcode action, bool isDir, const char* title, const char* filter); + /*! * Parameter data. */ diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 3d6d2b9d5..12ae4bcfc 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -242,6 +242,8 @@ struct EngineOptions { const char* binaryDir; const char* resourceDir; + uintptr_t frontendWinId; + #ifndef DOXYGEN EngineOptions() noexcept; ~EngineOptions(); @@ -874,15 +876,30 @@ public: // Callback /*! - * TODO. + * Run the main engine callback, if set. + * May be called by plugins. */ void callback(const EngineCallbackOpcode action, const unsigned int pluginId, const int value1, const int value2, const float value3, const char* const valueStr) noexcept; /*! - * TODO. + * Set the main engine callback. */ void setCallback(const EngineCallbackFunc func, void* const ptr) noexcept; + // ------------------------------------------------------------------- + // Callback + + /*! + * Run the file callback, if set. + * May be called by plugins. + */ + const char* runFileCallback(const FileCallbackOpcode action, const bool isDir, const char* const title, const char* const filter) noexcept; + + /*! + * Set the file callback. + */ + void setFileCallback(const FileCallbackFunc func, void* const ptr) noexcept; + #ifndef BUILD_BRIDGE // ------------------------------------------------------------------- // Patchbay diff --git a/source/backend/CarlaHost.h b/source/backend/CarlaHost.h index 8daf8d8c5..e776b91cc 100644 --- a/source/backend/CarlaHost.h +++ b/source/backend/CarlaHost.h @@ -29,7 +29,9 @@ using CarlaBackend::EngineCallbackOpcode; using CarlaBackend::EngineOption; using CarlaBackend::EngineProcessMode; using CarlaBackend::EngineTransportMode; +using CarlaBackend::FileCallbackOpcode; using CarlaBackend::EngineCallbackFunc; +using CarlaBackend::FileCallbackFunc; using CarlaBackend::ParameterData; using CarlaBackend::ParameterRanges; using CarlaBackend::MidiProgramData; @@ -51,42 +53,9 @@ using CarlaBackend::CarlaPlugin; * @{ */ -/* ------------------------------------------------------------------------------------------------------------ - * File Callback Opcode */ - -/*! - * File callback opcodes.\n - * Front-ends must always block-wait for user input. - * @see FileCallbackFunc and carla_set_file_callback() - */ -typedef enum { - /*! - * Debug.\n - * This opcode is undefined and used only for testing purposes. - */ - FILE_CALLBACK_DEBUG = 0, - - /*! - * Open file or folder. - */ - FILE_CALLBACK_OPEN = 1, - - /*! - * Save file or folder. - */ - FILE_CALLBACK_SAVE = 2 - -} FileCallbackOpcode; - /* ------------------------------------------------------------------------------------------------------------ * Carla Host API (C stuff) */ -/*! - * File callback function. - * @see FileCallbackOpcode - */ -typedef const char* (*FileCallbackFunc)(void* ptr, FileCallbackOpcode action, bool isDir, const char* title, const char* filter); - /*! * Information about a loaded plugin. * @see carla_get_plugin_info() @@ -1069,10 +1038,4 @@ CARLA_EXPORT const char* carla_get_host_osc_url_udp(); /** @} */ -/*! - * Implemented in standalone. - */ -extern ulong carla_standalone_get_transient_win_id(); -extern const char* carla_standalone_file_callback(FileCallbackOpcode action, bool isDir, const char* title, const char* filter); - #endif /* CARLA_HOST_H_INCLUDED */ diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 9c641e3f7..486eb53ae 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -1604,6 +1604,33 @@ void CarlaEngine::setCallback(const EngineCallbackFunc func, void* const ptr) no pData->callbackPtr = ptr; } +// ----------------------------------------------------------------------- +// File Callback + +const char* CarlaEngine::runFileCallback(const FileCallbackOpcode action, const bool isDir, const char* const title, const char* const filter) noexcept +{ + CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0', nullptr); + CARLA_SAFE_ASSERT_RETURN(filter != nullptr && filter[0] != '\0', nullptr); + carla_debug("CarlaEngine::runFileCallback(%i:%s, %s, \"%s\", \"%s\")", action, FileCallbackOpcode2Str(action), bool2str(isDir), title, filter); + + const char* ret = nullptr; + + if (pData->fileCallback != nullptr) + { + try { + ret = pData->fileCallback(pData->fileCallbackPtr, action, isDir, title, filter); + } catch(...) {} + } + + return ret; +} + +void CarlaEngine::setFileCallback(const FileCallbackFunc func, void* const ptr) noexcept +{ + pData->fileCallback = func; + pData->fileCallbackPtr = ptr; +} + #ifndef BUILD_BRIDGE // ----------------------------------------------------------------------- // Patchbay @@ -1937,6 +1964,13 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch pData->options.resourceDir = carla_strdup(valueStr); break; + + case ENGINE_OPTION_FRONTEND_WIN_ID: + CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); + const long winId(std::atol(valueStr)); + CARLA_SAFE_ASSERT_RETURN(winId >= 0,); + pData->options.frontendWinId = static_cast(winId); + break; } } diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index 1cff051f6..11d17f52d 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -211,7 +211,8 @@ EngineOptions::EngineOptions() noexcept audioSampleRate(44100), audioDevice(nullptr), binaryDir(nullptr), - resourceDir(nullptr) {} + resourceDir(nullptr), + frontendWinId(0) {} EngineOptions::~EngineOptions() { @@ -597,6 +598,8 @@ CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine) oscData(nullptr), callback(nullptr), callbackPtr(nullptr), + fileCallback(nullptr), + fileCallbackPtr(nullptr), hints(0x0), bufferSize(0), sampleRate(0.0), diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 4a1285272..aa7052583 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -211,6 +211,9 @@ struct CarlaEngineProtectedData { EngineCallbackFunc callback; void* callbackPtr; + FileCallbackFunc fileCallback; + void* fileCallbackPtr; + unsigned int hints; uint32_t bufferSize; double sampleRate; diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index cecd760ca..0d2468799 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -67,7 +67,7 @@ struct ParamSymbol { void CarlaPluginProtectedData::tryTransient() { - if (carla_standalone_get_transient_win_id() != 0) + if (engine->getOptions().frontendWinId != 0) transientTryCounter = 1; } @@ -1381,7 +1381,7 @@ void CarlaPlugin::idle() carla_stdout("Trying to get window..."); QString uiTitle(QString("%1 (GUI)").arg(pData->name)); - if (CarlaPluginUi::tryTransientWinIdMatch(pData->osc.data.target != nullptr ? pData->osc.thread.getPid() : 0, uiTitle.toUtf8().constData(), carla_standalone_get_transient_win_id())) + if (CarlaPluginUi::tryTransientWinIdMatch(pData->osc.data.target != nullptr ? pData->osc.thread.getPid() : 0, uiTitle.toUtf8().constData(), pData->engine->getOptions().frontendWinId)) pData->transientTryCounter = 0; } @@ -1672,7 +1672,7 @@ void CarlaPlugin::updateOscData(const lo_address& source, const char* const url) for (uint32_t i=0; i < pData->param.count; ++i) osc_send_control(pData->osc.data, pData->param.data[i].rindex, getParameterValue(i)); - if ((pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0 && carla_standalone_get_transient_win_id() != 0) + if ((pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0 && pData->engine->getOptions().frontendWinId != 0) pData->transientTryCounter = 1; carla_stdout("CarlaPlugin::updateOscData() - done"); diff --git a/source/backend/plugin/CarlaPluginUi.cpp b/source/backend/plugin/CarlaPluginUi.cpp index ee26cc5e5..a231d4c4b 100644 --- a/source/backend/plugin/CarlaPluginUi.cpp +++ b/source/backend/plugin/CarlaPluginUi.cpp @@ -31,12 +31,12 @@ class X11PluginUi : public CarlaPluginUi { public: - X11PluginUi(CloseCallback* cb) noexcept - : CarlaPluginUi(cb), + X11PluginUi(CloseCallback* const cb, const uintptr_t parentId) noexcept + : CarlaPluginUi(cb, parentId), fDisplay(nullptr), fWindow(0) { - fDisplay = XOpenDisplay(0); + fDisplay = XOpenDisplay(nullptr); CARLA_SAFE_ASSERT_RETURN(fDisplay != nullptr,); const int screen = DefaultScreen(fDisplay); @@ -56,8 +56,8 @@ public: Atom wmDelete = XInternAtom(fDisplay, "WM_DELETE_WINDOW", True); XSetWMProtocols(fDisplay, fWindow, &wmDelete, 1); - if (const uintptr_t transientId = carla_standalone_get_transient_win_id()) - setTransientWinId(transientId); + if (parentId != 0) + setTransientWinId(parentId); } ~X11PluginUi() override @@ -292,27 +292,27 @@ bool CarlaPluginUi::tryTransientWinIdMatch(const ulong pid, const char* const ui // ----------------------------------------------------- #ifdef CARLA_OS_MAC -CarlaPluginUi* CarlaPluginUi::newCocoa(CloseCallback* cb) +CarlaPluginUi* CarlaPluginUi::newCocoa(CloseCallback* cb, uintptr_t) { - //return new CocoaPluginUi(cb); + //return new CocoaPluginUi(cb, parentId); return nullptr; (void)cb; } #endif #ifdef CARLA_OS_WIN -CarlaPluginUi* CarlaPluginUi::newWindows(CloseCallback* cb) +CarlaPluginUi* CarlaPluginUi::newWindows(CloseCallback* cb, uintptr_t) { - //return new WindowsPluginUi(cb); + //return new WindowsPluginUi(cb, parentId); return nullptr; (void)cb; } #endif #ifdef HAVE_X11 -CarlaPluginUi* CarlaPluginUi::newX11(CloseCallback* cb) +CarlaPluginUi* CarlaPluginUi::newX11(CloseCallback* cb, uintptr_t parentId) { - return new X11PluginUi(cb); + return new X11PluginUi(cb, parentId); } #endif diff --git a/source/backend/plugin/CarlaPluginUi.hpp b/source/backend/plugin/CarlaPluginUi.hpp index 29bb3ad76..0ddd0395b 100644 --- a/source/backend/plugin/CarlaPluginUi.hpp +++ b/source/backend/plugin/CarlaPluginUi.hpp @@ -44,18 +44,18 @@ public: static bool tryTransientWinIdMatch(const ulong pid, const char* const uiTitle, const uintptr_t winId); #ifdef CARLA_OS_MAC - static CarlaPluginUi* newCocoa(CloseCallback*); + static CarlaPluginUi* newCocoa(CloseCallback*, uintptr_t); #endif #ifdef CARLA_OS_WIN - static CarlaPluginUi* newWindows(CloseCallback*); + static CarlaPluginUi* newWindows(CloseCallback*, uintptr_t); #endif #ifdef HAVE_X11 - static CarlaPluginUi* newX11(CloseCallback*); + static CarlaPluginUi* newX11(CloseCallback*, uintptr_t); #endif protected: CloseCallback* fCallback; - CarlaPluginUi(CloseCallback* cb) noexcept : fCallback(cb) {} + CarlaPluginUi(CloseCallback* const cb, const uintptr_t) noexcept : fCallback(cb) {} }; // ----------------------------------------------------- diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 6abdc1fca..fc90f157a 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -1129,6 +1129,7 @@ public: if (fUi.type == UI::TYPE_EMBED) { const char* msg = nullptr; + const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId); switch (fUi.rdfDescriptor->Type) { @@ -1143,7 +1144,7 @@ public: case LV2_UI_COCOA: # ifdef CARLA_OS_MAC - fUi.window = CarlaPluginUi::newCocoa(this); + fUi.window = CarlaPluginUi::newCocoa(this, frontendWinId); # else msg = "UI is for MacOS only"; # endif @@ -1151,7 +1152,7 @@ public: case LV2_UI_WINDOWS: # ifdef CARLA_OS_WIN - fUi.window = CarlaPluginUi::newWindows(this); + fUi.window = CarlaPluginUi::newWindows(this, frontendWinId); # else msg = "UI is for Windows only"; # endif @@ -1159,7 +1160,7 @@ public: case LV2_UI_X11: # ifdef HAVE_X11 - fUi.window = CarlaPluginUi::newX11(this); + fUi.window = CarlaPluginUi::newX11(this, frontendWinId); # else msg = "UI is only for systems with X11"; # endif diff --git a/source/backend/plugin/Makefile b/source/backend/plugin/Makefile index d19fadd88..e503ac8b2 100644 --- a/source/backend/plugin/Makefile +++ b/source/backend/plugin/Makefile @@ -67,7 +67,7 @@ CarlaPluginThread.cpp.o: CarlaPluginThread.cpp $(CARLA_PLUGIN_HPP) $(CARLA_PLUGI CarlaPluginUi.cpp.o: CarlaPluginUi.cpp $(CARLA_PLUGIN_UI_HPP) $(CARLA_HOST_H) $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ -NativePlugin.cpp.o: NativePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_NATIVE_H) $(CARLA_HOST_H) +NativePlugin.cpp.o: NativePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_NATIVE_H) $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ BridgePlugin.cpp.o: BridgePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_BRIDGE_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_SHM_UTILS_HPP) $(JACK_BRIDGE_HPP) diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index b83d5873b..2092c7df6 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -23,7 +23,6 @@ #include "CarlaMathUtils.hpp" #include "CarlaNative.h" -#include "CarlaHost.h" #include @@ -2082,12 +2081,12 @@ protected: const char* handleUiOpenFile(const bool isDir, const char* const title, const char* const filter) { - return carla_standalone_file_callback(FILE_CALLBACK_OPEN, isDir, title, filter); + return pData->engine->runFileCallback(FILE_CALLBACK_OPEN, isDir, title, filter); } const char* handleUiSaveFile(const bool isDir, const char* const title, const char* const filter) { - return carla_standalone_file_callback(FILE_CALLBACK_SAVE, isDir, title, filter); + return pData->engine->runFileCallback(FILE_CALLBACK_SAVE, isDir, title, filter); } intptr_t handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) diff --git a/source/backend/plugin/VstPlugin.cpp b/source/backend/plugin/VstPlugin.cpp index 42e595fe6..c4ff8085f 100644 --- a/source/backend/plugin/VstPlugin.cpp +++ b/source/backend/plugin/VstPlugin.cpp @@ -414,21 +414,22 @@ public: if (fUi.window == nullptr) { const char* msg = nullptr; + const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId); #if defined(CARLA_OS_LINUX) # ifdef HAVE_X11 - fUi.window = CarlaPluginUi::newX11(this); + fUi.window = CarlaPluginUi::newX11(this, frontendWinId); # else msg = "UI is only for systems with X11"; # endif #elif defined(CARLA_OS_MAC) # ifdef __LP64__ - fUi.window = CarlaPluginUi::newCocoa(this); + fUi.window = CarlaPluginUi::newCocoa(this, frontendWinId); # else - fUi.window = CarlaPluginUi::newCarbon(this); + fUi.window = CarlaPluginUi::newCarbon(this, frontendWinId); # endif #elif defined(CARLA_OS_WIN) - fUi.window = CarlaPluginUi::newWindows(this); + fUi.window = CarlaPluginUi::newWindows(this, frontendWinId); #else msg = "Unknown UI type"; #endif diff --git a/source/backend/standalone/CarlaStandalone.cpp b/source/backend/standalone/CarlaStandalone.cpp index c887b78ad..f2e9fbddd 100644 --- a/source/backend/standalone/CarlaStandalone.cpp +++ b/source/backend/standalone/CarlaStandalone.cpp @@ -117,15 +117,6 @@ struct CarlaBackendStandalone { static CarlaBackendStandalone gStandalone; -// ------------------------------------------------------------------------------------------------------------------- - -static ulong gTransientWinId = 0; - -ulong carla_standalone_get_transient_win_id() -{ - return gTransientWinId; -} - // ------------------------------------------------------------------------------------------------------------------- // API @@ -406,6 +397,7 @@ bool carla_engine_init(const char* driverName, const char* clientName) } gStandalone.engine->setCallback(gStandalone.engineCallback, gStandalone.engineCallbackPtr); + gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr); #ifdef BUILD_BRIDGE gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, nullptr); @@ -434,6 +426,15 @@ bool carla_engine_init(const char* driverName, const char* clientName) if (gStandalone.engineOptions.resourceDir != nullptr) gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, gStandalone.engineOptions.resourceDir); + if (gStandalone.engineOptions.frontendWinId != 0) + { + char strBuf[STR_MAX+1]; + std::sprintf(strBuf, P_INTPTR, gStandalone.engineOptions.frontendWinId); + gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, strBuf); + } + else + gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); + if (gStandalone.engine->init(clientName)) { gStandalone.lastError = "No error"; @@ -476,6 +477,7 @@ bool carla_engine_init_bridge(const char audioBaseName[6+1], const char controlB } gStandalone.engine->setCallback(gStandalone.engineCallback, gStandalone.engineCallbackPtr); + gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr); // forced options for bridge mode gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_BRIDGE, nullptr); @@ -490,6 +492,7 @@ bool carla_engine_init_bridge(const char audioBaseName[6+1], const char controlB gStandalone.engine->setOption(CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT, static_cast(gStandalone.engineOptions.uiBridgesTimeout), nullptr); gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, (const char*)gStandalone.engineOptions.binaryDir); gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, (const char*)gStandalone.engineOptions.resourceDir); + // frontend winId here if (gStandalone.engine->init(clientName)) { @@ -584,13 +587,6 @@ void carla_set_engine_option(EngineOption option, int value, const char* valueSt switch (option) { case CB::ENGINE_OPTION_DEBUG: - if (value == -1729) - { - CARLA_SAFE_ASSERT_BREAK(valueStr != nullptr && valueStr[0] != '\0'); - const long winId(std::atol(valueStr)); - CARLA_SAFE_ASSERT_BREAK(winId != 0); - gTransientWinId = static_cast(winId); - } break; case CB::ENGINE_OPTION_PROCESS_MODE: @@ -674,6 +670,13 @@ void carla_set_engine_option(EngineOption option, int value, const char* valueSt gStandalone.engineOptions.resourceDir = carla_strdup(valueStr); break; + + case CB::ENGINE_OPTION_FRONTEND_WIN_ID: + CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); + const long winId(std::atol(valueStr)); + CARLA_SAFE_ASSERT_RETURN(winId >= 0,); + gStandalone.engineOptions.frontendWinId = static_cast(winId); + break; } if (gStandalone.engine != nullptr) @@ -681,26 +684,15 @@ void carla_set_engine_option(EngineOption option, int value, const char* valueSt } #endif -// ------------------------------------------------------------------------------------------------------------------- - void carla_set_file_callback(FileCallbackFunc func, void* ptr) { carla_debug("carla_set_file_callback(%p, %p)", func, ptr); gStandalone.fileCallback = func; gStandalone.fileCallbackPtr = ptr; -} -const char* carla_standalone_file_callback(FileCallbackOpcode action, bool isDir, const char* title, const char* filter) -{ - CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0', nullptr); - CARLA_SAFE_ASSERT_RETURN(filter != nullptr && filter[0] != '\0', nullptr); - carla_debug("carla_standalone_file_callback(%i:%s, %s, \"%s\", \"%s\")", action, CB::FileCallbackOpcode2Str(action), bool2str(isDir), title, filter); - - if (gStandalone.fileCallback == nullptr) - return nullptr; - - return gStandalone.fileCallback(gStandalone.fileCallbackPtr, action, isDir, title, filter); + if (gStandalone.engine != nullptr) + gStandalone.engine->setFileCallback(func, ptr); } // ------------------------------------------------------------------------------------------------------------------- diff --git a/source/carla b/source/carla index f1474e0c6..383441727 100755 --- a/source/carla +++ b/source/carla @@ -333,8 +333,8 @@ if __name__ == '__main__': Carla.gui = CarlaHostW() - # set our gui as transient for all plugins UIs - Carla.host.set_engine_option(ENGINE_OPTION_DEBUG, -1729, str(Carla.gui.winId())) + # set our gui as parent for all plugins UIs + Carla.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, str(Carla.gui.winId())) # ------------------------------------------------------------- # Load project file if set diff --git a/source/carla-patchbay b/source/carla-patchbay index 415410937..28cb444ab 100755 --- a/source/carla-patchbay +++ b/source/carla-patchbay @@ -87,8 +87,8 @@ if __name__ == '__main__': Carla.gui = CarlaHostW() - # set our gui as transient for all plugins UIs - Carla.host.set_engine_option(ENGINE_OPTION_DEBUG, -1729, str(Carla.gui.winId())) + # set our gui as parent for all plugins UIs + Carla.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, str(Carla.gui.winId())) # ------------------------------------------------------------- # Load project file if set diff --git a/source/carla-plugin b/source/carla-plugin index 852b6fa88..31f6e30c8 100755 --- a/source/carla-plugin +++ b/source/carla-plugin @@ -742,9 +742,18 @@ if __name__ == '__main__': initHost("Carla-Plugin") + # set our gui as parent for all plugins UIs + Carla.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, str(Carla.gui.winId())) + + # simulate an engire started callback engineCallback(None, ENGINE_CALLBACK_ENGINE_STARTED, 0, ENGINE_PROCESS_MODE_CONTINUOUS_RACK, ENGINE_TRANSPORT_MODE_PLUGIN, 0.0, "Plugin") # ------------------------------------------------------------- # App-Loop - sys.exit(app.exec_()) + ret = app.exec_() + + # disable parenting + Carla.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0") + + sys.exit(ret) diff --git a/source/carla-rack b/source/carla-rack index 930e700e4..668078571 100755 --- a/source/carla-rack +++ b/source/carla-rack @@ -87,8 +87,8 @@ if __name__ == '__main__': Carla.gui = CarlaHostW() - # set our gui as transient for all plugins UIs - Carla.host.set_engine_option(ENGINE_OPTION_DEBUG, -1729, str(Carla.gui.winId())) + # set our gui as parent for all plugins UIs + Carla.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, str(Carla.gui.winId())) # ------------------------------------------------------------- # Load project file if set diff --git a/source/carla_backend.py b/source/carla_backend.py index c5a3ada6d..348e8b066 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -726,6 +726,9 @@ ENGINE_OPTION_PATH_BINARIES = 13 # @note Must be set for some internal plugins to work ENGINE_OPTION_PATH_RESOURCES = 14 +# Set frontend winId, used to define as parent window for plugin UIs. +ENGINE_OPTION_FRONTEND_WIN_ID = 15 + # ------------------------------------------------------------------------------------------------------------ # Engine Process Mode # Engine process mode. @@ -767,6 +770,22 @@ ENGINE_TRANSPORT_MODE_PLUGIN = 2 # Special mode, used in plugin-bridges only. ENGINE_TRANSPORT_MODE_BRIDGE = 3 +# ------------------------------------------------------------------------------------------------------------ +# File Callback Opcode +# File callback opcodes. +# Front-ends must always block-wait for user input. +# @see FileCallbackFunc and carla_set_file_callback() + +# Debug. +# This opcode is undefined and used only for testing purposes. +FILE_CALLBACK_DEBUG = 0 + +# Open file or folder. +FILE_CALLBACK_OPEN = 1 + +# Save file or folder. +FILE_CALLBACK_SAVE = 2 + # ------------------------------------------------------------------------------------------------------------ # Patchbay Icon # The icon of a patchbay client/group. @@ -803,6 +822,10 @@ PATCHBAY_ICON_FILE = 5 # @see EngineCallbackOpcode and carla_set_engine_callback() EngineCallbackFunc = CFUNCTYPE(None, c_void_p, c_enum, c_uint, c_int, c_int, c_float, c_char_p) +# File callback function. +# @see FileCallbackOpcode +FileCallbackFunc = CFUNCTYPE(c_char_p, c_void_p, c_enum, c_bool, c_char_p, c_char_p) + # Parameter data. class ParameterData(Structure): _fields_ = [ @@ -939,29 +962,9 @@ PyEngineDriverDeviceInfo = { 'sampleRates': [] } -# ------------------------------------------------------------------------------------------------------------ -# File Callback Opcode -# File callback opcodes. -# Front-ends must always block-wait for user input. -# @see FileCallbackFunc and carla_set_file_callback() - -# Debug. -# This opcode is undefined and used only for testing purposes. -FILE_CALLBACK_DEBUG = 0 - -# Open file or folder. -FILE_CALLBACK_OPEN = 1 - -# Save file or folder. -FILE_CALLBACK_SAVE = 2 - # ------------------------------------------------------------------------------------------------------------ # Carla Host API (C stuff) -# File callback function. -# @see FileCallbackOpcode -FileCallbackFunc = CFUNCTYPE(c_char_p, c_void_p, c_enum, c_bool, c_char_p, c_char_p) - # Information about a loaded plugin. # @see carla_get_plugin_info() class CarlaPluginInfo(Structure): diff --git a/source/utils/CarlaBackendUtils.hpp b/source/utils/CarlaBackendUtils.hpp index cdbed4101..a0d594402 100644 --- a/source/utils/CarlaBackendUtils.hpp +++ b/source/utils/CarlaBackendUtils.hpp @@ -314,6 +314,8 @@ const char* EngineOption2Str(const EngineOption option) noexcept return "ENGINE_OPTION_PATH_BINARIES"; case ENGINE_OPTION_PATH_RESOURCES: return "ENGINE_OPTION_PATH_RESOURCES"; + case ENGINE_OPTION_FRONTEND_WIN_ID: + return "ENGINE_OPTION_FRONTEND_WIN_ID"; } carla_stderr("CarlaBackend::EngineOption2Str(%i) - invalid option", option);