| @@ -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. | |||
| */ | |||
| @@ -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 | |||
| @@ -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 */ | |||
| @@ -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<uintptr_t>(winId); | |||
| break; | |||
| } | |||
| } | |||
| @@ -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), | |||
| @@ -211,6 +211,9 @@ struct CarlaEngineProtectedData { | |||
| EngineCallbackFunc callback; | |||
| void* callbackPtr; | |||
| FileCallbackFunc fileCallback; | |||
| void* fileCallbackPtr; | |||
| unsigned int hints; | |||
| uint32_t bufferSize; | |||
| double sampleRate; | |||
| @@ -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"); | |||
| @@ -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 | |||
| @@ -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) {} | |||
| }; | |||
| // ----------------------------------------------------- | |||
| @@ -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 | |||
| @@ -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) | |||
| @@ -23,7 +23,6 @@ | |||
| #include "CarlaMathUtils.hpp" | |||
| #include "CarlaNative.h" | |||
| #include "CarlaHost.h" | |||
| #include <QtCore/QStringList> | |||
| @@ -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) | |||
| @@ -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 | |||
| @@ -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<int>(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<ulong>(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<uintptr_t>(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); | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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) | |||
| @@ -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 | |||
| @@ -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): | |||
| @@ -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); | |||