diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h index 84300333c..9010073a9 100644 --- a/source/backend/CarlaBackend.h +++ b/source/backend/CarlaBackend.h @@ -1056,10 +1056,16 @@ typedef enum { */ ENGINE_OPTION_PATH_RESOURCES = 16, + /*! + * Prevent bad plugin and UI behaviour. + * @note: Linux only + */ + ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR = 17, + /*! * Set frontend winId, used to define as parent window for plugin UIs. */ - ENGINE_OPTION_FRONTEND_WIN_ID = 17 + ENGINE_OPTION_FRONTEND_WIN_ID = 18 } EngineOption; diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 0628a58ba..18720fd76 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -251,6 +251,7 @@ struct EngineOptions { const char* binaryDir; const char* resourceDir; + bool preventBadBehaviour; uintptr_t frontendWinId; #ifndef DOXYGEN diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp index 1f21d2d24..0e2146da6 100644 --- a/source/backend/CarlaStandalone.cpp +++ b/source/backend/CarlaStandalone.cpp @@ -780,6 +780,8 @@ bool carla_engine_init(const char* driverName, const char* clientName) if (gStandalone.engineOptions.resourceDir != nullptr && gStandalone.engineOptions.resourceDir[0] != '\0') gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, gStandalone.engineOptions.resourceDir); + gStandalone.engine->setOption(CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR, gStandalone.engineOptions.preventBadBehaviour ? 1 : 0, nullptr); + if (gStandalone.engineOptions.frontendWinId != 0) { char strBuf[STR_MAX+1]; @@ -884,6 +886,9 @@ bool carla_engine_init_bridge(const char audioBaseName[6+1], const char rtBaseNa if (const char* const resourceDir = std::getenv("ENGINE_OPTION_PATH_RESOURCES")) gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, resourceDir); + if (const char* const preventBadBehaviour = std::getenv("ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR")) + gStandalone.engine->setOption(CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR, (std::strcmp(preventBadBehaviour, "true") == 0) ? 1 : 0, nullptr); + if (const char* const frontendWinId = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID")) gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, frontendWinId); @@ -1119,6 +1124,11 @@ void carla_set_engine_option(EngineOption option, int value, const char* valueSt gStandalone.engineOptions.resourceDir = carla_strdup_safe(valueStr); break; + case CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR: + CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,); + gStandalone.engineOptions.preventBadBehaviour = (value != 0); + break; + case CB::ENGINE_OPTION_FRONTEND_WIN_ID: CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); const long long winId(std::strtoll(valueStr, nullptr, 16)); diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 3ea479567..87dea8888 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -1352,6 +1352,21 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch pData->options.resourceDir = carla_strdup_safe(valueStr); break; + case ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR: + CARLA_SAFE_ASSERT_RETURN(pData->options.binaryDir != nullptr && pData->options.binaryDir[0] != '\0',); +#ifdef CARLA_OS_LINUX + if (value != 0) + { + CarlaString interposerPath(CarlaString(pData->options.binaryDir) + CARLA_OS_SEP_STR "libcarlainterposer.so"); + ::setenv("LD_PRELOAD", interposerPath.buffer(), 1); + } + else + { + ::unsetenv("LD_PRELOAD"); + } +#endif + break; + case ENGINE_OPTION_FRONTEND_WIN_ID: CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); const long long winId(std::strtoll(valueStr, nullptr, 16)); diff --git a/source/backend/engine/CarlaEngineData.cpp b/source/backend/engine/CarlaEngineData.cpp index ddb5cff25..c7c24eb37 100644 --- a/source/backend/engine/CarlaEngineData.cpp +++ b/source/backend/engine/CarlaEngineData.cpp @@ -211,6 +211,7 @@ EngineOptions::EngineOptions() noexcept pathSFZ(nullptr), binaryDir(nullptr), resourceDir(nullptr), + preventBadBehaviour(false), frontendWinId(0) {} EngineOptions::~EngineOptions() noexcept diff --git a/source/backend/plugin/CarlaPluginThread.cpp b/source/backend/plugin/CarlaPluginThread.cpp index b6e35dc29..9bf12b764 100644 --- a/source/backend/plugin/CarlaPluginThread.cpp +++ b/source/backend/plugin/CarlaPluginThread.cpp @@ -235,9 +235,16 @@ void CarlaPluginThread::run() else carla_setenv("ENGINE_OPTION_PATH_RESOURCES", ""); + carla_setenv("ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR", bool2str(options.preventBadBehaviour)); + std::snprintf(strBuf, STR_MAX, P_UINTPTR, options.frontendWinId); carla_setenv("ENGINE_OPTION_FRONTEND_WIN_ID", strBuf); +#ifdef CARLA_OS_LINUX + const char* const oldPreload(std::getenv("LD_PRELOAD")); + ::unsetenv("LD_PRELOAD"); +#endif + switch (fMode) { case PLUGIN_THREAD_NULL: @@ -280,6 +287,11 @@ void CarlaPluginThread::run() fProcess->start(arguments); +#ifdef CARLA_OS_LINUX + if (oldPreload != nullptr) + ::setenv("LD_PRELOAD", oldPreload, 1); +#endif + sEnvMutex.unlock(); switch (fMode) diff --git a/source/carla_backend.py b/source/carla_backend.py index 42d718eb8..933cae9f3 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -777,8 +777,12 @@ ENGINE_OPTION_PATH_BINARIES = 15 # @note Must be set for some internal plugins to work ENGINE_OPTION_PATH_RESOURCES = 16 +# Prevent bad plugin and UI behaviour. +# @note: Linux only +ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR = 17 + # Set frontend winId, used to define as parent window for plugin UIs. -ENGINE_OPTION_FRONTEND_WIN_ID = 17 +ENGINE_OPTION_FRONTEND_WIN_ID = 18 # ------------------------------------------------------------------------------------------------------------ # Engine Process Mode @@ -1315,6 +1319,7 @@ class CarlaHostMeta(QObject): self.forceStereo = False self.preferPluginBridges = False self.preferUIBridges = False + self.preventBadBehaviour = False self.uisAlwaysOnTop = False self.maxParameters = 0 self.uiBridgesTimeout = 0 diff --git a/source/carla_host.py b/source/carla_host.py index bfdc7a6cc..0a695fc78 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -1347,12 +1347,16 @@ def setHostSettings(host): # kdevelop likes this :) if False: host = CarlaHostMeta() + # TEST + host.preventBadBehaviour = True + host.set_engine_option(ENGINE_OPTION_FORCE_STEREO, host.forceStereo, "") host.set_engine_option(ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, host.preferPluginBridges, "") host.set_engine_option(ENGINE_OPTION_PREFER_UI_BRIDGES, host.preferUIBridges, "") host.set_engine_option(ENGINE_OPTION_UIS_ALWAYS_ON_TOP, host.uisAlwaysOnTop, "") host.set_engine_option(ENGINE_OPTION_MAX_PARAMETERS, host.maxParameters, "") host.set_engine_option(ENGINE_OPTION_UI_BRIDGES_TIMEOUT, host.uiBridgesTimeout, "") + host.set_engine_option(ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR, host.preventBadBehaviour, "") if host.isPlugin: return diff --git a/source/utils/CarlaBackendUtils.hpp b/source/utils/CarlaBackendUtils.hpp index d030fd28b..a523cc290 100644 --- a/source/utils/CarlaBackendUtils.hpp +++ b/source/utils/CarlaBackendUtils.hpp @@ -324,6 +324,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_PREVENT_BAD_BEHAVIOUR: + return "ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR"; case ENGINE_OPTION_FRONTEND_WIN_ID: return "ENGINE_OPTION_FRONTEND_WIN_ID"; }