@@ -1478,6 +1478,9 @@ | |||
<layout class="QGridLayout" name="gridLayout_6"> | |||
<item row="0" column="0" colspan="2"> | |||
<widget class="QCheckBox" name="cb_wine_prefix_detect"> | |||
<property name="enabled"> | |||
<bool>false</bool> | |||
</property> | |||
<property name="text"> | |||
<string>Auto-detect Wine prefix based on plugin filename</string> | |||
</property> | |||
@@ -1496,6 +1499,16 @@ | |||
<item row="1" column="1"> | |||
<widget class="QLineEdit" name="le_wine_prefix_fallback"/> | |||
</item> | |||
<item row="2" column="0" colspan="2"> | |||
<widget class="QLabel" name="label_30"> | |||
<property name="text"> | |||
<string>Note: WINEPREFIX env var is prefered over this fallback</string> | |||
</property> | |||
<property name="alignment"> | |||
<set>Qt::AlignCenter</set> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
</item> | |||
@@ -1667,7 +1680,7 @@ | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>115</height> | |||
<height>96</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
@@ -1101,12 +1101,12 @@ typedef enum { | |||
ENGINE_OPTION_WINE_AUTO_PREFIX = 19, | |||
/*! | |||
* Fallback wineprefix to use if automatic detection fails or is diabled, and WINEPREFIX is not set. | |||
* Fallback wineprefix to use if automatic detection fails or is disabled, and WINEPREFIX is not set. | |||
*/ | |||
ENGINE_OPTION_WINE_FALLBACK_PREFIX = 20, | |||
/*! | |||
* Enable realtie priority for Wine application and server threads. | |||
* Enable realtime priority for Wine application and server threads. | |||
*/ | |||
ENGINE_OPTION_WINE_RT_PRIO_ENABLED = 21, | |||
@@ -255,7 +255,7 @@ struct CARLA_API EngineOptions { | |||
uintptr_t frontendWinId; | |||
struct Wine { | |||
const char* exec; | |||
const char* executable; | |||
bool autoPrefix; | |||
const char* fallbackPrefix; | |||
@@ -264,13 +264,8 @@ struct CARLA_API EngineOptions { | |||
int baseRtPrio; | |||
int serverRtPrio; | |||
Wine() | |||
: exec(nullptr), | |||
autoPrefix(true), | |||
fallbackPrefix(nullptr), | |||
rtPrio(true), | |||
baseRtPrio(15), | |||
serverRtPrio(10) {} | |||
Wine() noexcept; | |||
~Wine() noexcept; | |||
} wine; | |||
#ifndef DOXYGEN | |||
@@ -269,7 +269,22 @@ static void carla_engine_init_common() | |||
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.engineOptions.wine.executable != nullptr && gStandalone.engineOptions.wine.executable[0] != '\0') | |||
gStandalone.engine->setOption(CB::ENGINE_OPTION_WINE_EXECUTABLE, 0, gStandalone.engineOptions.wine.executable); | |||
gStandalone.engine->setOption(CB::ENGINE_OPTION_WINE_AUTO_PREFIX, gStandalone.engineOptions.wine.autoPrefix ? 1 : 0, nullptr); | |||
if (gStandalone.engineOptions.wine.fallbackPrefix != nullptr && gStandalone.engineOptions.wine.fallbackPrefix[0] != '\0') | |||
gStandalone.engine->setOption(CB::ENGINE_OPTION_WINE_FALLBACK_PREFIX, 0, gStandalone.engineOptions.wine.fallbackPrefix); | |||
gStandalone.engine->setOption(CB::ENGINE_OPTION_WINE_RT_PRIO_ENABLED, gStandalone.engineOptions.wine.rtPrio ? 1 : 0, nullptr); | |||
gStandalone.engine->setOption(CB::ENGINE_OPTION_WINE_BASE_RT_PRIO, gStandalone.engineOptions.wine.baseRtPrio, nullptr); | |||
gStandalone.engine->setOption(CB::ENGINE_OPTION_WINE_SERVER_RT_PRIO, gStandalone.engineOptions.wine.serverRtPrio, nullptr); | |||
#endif | |||
} | |||
@@ -290,13 +305,6 @@ bool carla_engine_init(const char* driverName, const char* clientName) | |||
carla_setenv("WINEASIO_CLIENT_NAME", clientName); | |||
#endif | |||
// TODO: make this an option, put somewhere else | |||
if (std::getenv("WINE_RT") == nullptr) | |||
{ | |||
carla_setenv("WINE_RT", "55"); | |||
carla_setenv("WINE_SVR_RT", "70"); | |||
} | |||
gStandalone.engine = CarlaEngine::newDriverByName(driverName); | |||
if (gStandalone.engine == nullptr) | |||
@@ -626,6 +634,44 @@ void carla_set_engine_option(EngineOption option, int value, const char* valueSt | |||
gStandalone.engineOptions.frontendWinId = static_cast<uintptr_t>(winId); | |||
} break; | |||
case CB::ENGINE_OPTION_WINE_EXECUTABLE: | |||
CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); | |||
if (gStandalone.engineOptions.wine.executable != nullptr) | |||
delete[] gStandalone.engineOptions.wine.executable; | |||
gStandalone.engineOptions.wine.executable = carla_strdup_safe(valueStr); | |||
break; | |||
case CB::ENGINE_OPTION_WINE_AUTO_PREFIX: | |||
CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,); | |||
gStandalone.engineOptions.wine.autoPrefix = (value != 0); | |||
break; | |||
case CB::ENGINE_OPTION_WINE_FALLBACK_PREFIX: | |||
CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); | |||
if (gStandalone.engineOptions.wine.fallbackPrefix != nullptr) | |||
delete[] gStandalone.engineOptions.wine.fallbackPrefix; | |||
gStandalone.engineOptions.wine.fallbackPrefix = carla_strdup_safe(valueStr); | |||
break; | |||
case CB::ENGINE_OPTION_WINE_RT_PRIO_ENABLED: | |||
CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,); | |||
gStandalone.engineOptions.wine.rtPrio = (value != 0); | |||
break; | |||
case CB::ENGINE_OPTION_WINE_BASE_RT_PRIO: | |||
CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 89,); | |||
gStandalone.engineOptions.wine.baseRtPrio = value; | |||
break; | |||
case CB::ENGINE_OPTION_WINE_SERVER_RT_PRIO: | |||
CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 99,); | |||
gStandalone.engineOptions.wine.serverRtPrio = value; | |||
break; | |||
case CB::ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT: | |||
gStandalone.logThreadEnabled = (value != 0); | |||
break; | |||
@@ -1587,9 +1587,12 @@ 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: | |||
case ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR: { | |||
CARLA_SAFE_ASSERT_RETURN(pData->options.binaryDir != nullptr && pData->options.binaryDir[0] != '\0',); | |||
#ifdef CARLA_OS_LINUX | |||
const ScopedEngineEnvironmentLocker _seel(this); | |||
if (value != 0) | |||
{ | |||
CarlaString interposerPath(CarlaString(pData->options.binaryDir) + "/libcarla_interposer-safe.so"); | |||
@@ -1600,7 +1603,7 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch | |||
::unsetenv("LD_PRELOAD"); | |||
} | |||
#endif | |||
break; | |||
} break; | |||
case ENGINE_OPTION_FRONTEND_WIN_ID: { | |||
CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); | |||
@@ -1609,6 +1612,44 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch | |||
pData->options.frontendWinId = static_cast<uintptr_t>(winId); | |||
} break; | |||
case ENGINE_OPTION_WINE_EXECUTABLE: | |||
CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); | |||
if (pData->options.wine.executable != nullptr) | |||
delete[] pData->options.wine.executable; | |||
pData->options.wine.executable = carla_strdup_safe(valueStr); | |||
break; | |||
case ENGINE_OPTION_WINE_AUTO_PREFIX: | |||
CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,); | |||
pData->options.wine.autoPrefix = (value != 0); | |||
break; | |||
case ENGINE_OPTION_WINE_FALLBACK_PREFIX: | |||
CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',); | |||
if (pData->options.wine.fallbackPrefix != nullptr) | |||
delete[] pData->options.wine.fallbackPrefix; | |||
pData->options.wine.fallbackPrefix = carla_strdup_safe(valueStr); | |||
break; | |||
case ENGINE_OPTION_WINE_RT_PRIO_ENABLED: | |||
CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,); | |||
pData->options.wine.rtPrio = (value != 0); | |||
break; | |||
case ENGINE_OPTION_WINE_BASE_RT_PRIO: | |||
CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 89,); | |||
pData->options.wine.baseRtPrio = value; | |||
break; | |||
case ENGINE_OPTION_WINE_SERVER_RT_PRIO: | |||
CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 99,); | |||
pData->options.wine.serverRtPrio = value; | |||
break; | |||
case ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT: | |||
break; | |||
} | |||
@@ -287,6 +287,29 @@ EngineOptions::~EngineOptions() noexcept | |||
} | |||
} | |||
EngineOptions::Wine::Wine() noexcept | |||
: executable(nullptr), | |||
autoPrefix(true), | |||
fallbackPrefix(nullptr), | |||
rtPrio(true), | |||
baseRtPrio(15), | |||
serverRtPrio(10) {} | |||
EngineOptions::Wine::~Wine() noexcept | |||
{ | |||
if (executable != nullptr) | |||
{ | |||
delete[] executable; | |||
executable = nullptr; | |||
} | |||
if (fallbackPrefix != nullptr) | |||
{ | |||
delete[] fallbackPrefix; | |||
fallbackPrefix = nullptr; | |||
} | |||
} | |||
// ----------------------------------------------------------------------- | |||
// EngineTimeInfoBBT | |||
@@ -111,6 +111,11 @@ protected: | |||
carla_stderr("CarlaPluginBridgeThread::run() - already running"); | |||
} | |||
char strBuf[STR_MAX+1]; | |||
strBuf[STR_MAX] = '\0'; | |||
const EngineOptions& options(kEngine->getOptions()); | |||
String name(kPlugin->getName()); | |||
String filename(kPlugin->getFilename()); | |||
@@ -125,7 +130,47 @@ protected: | |||
#ifndef CARLA_OS_WIN | |||
// start with "wine" if needed | |||
if (fBinary.endsWithIgnoreCase(".exe")) | |||
arguments.add("wine"); | |||
{ | |||
if (options.wine.executable != nullptr && options.wine.executable[0] != '\0') | |||
arguments.add(options.wine.executable); | |||
else | |||
arguments.add("wine"); | |||
#if 0 | |||
if (options.wine.autoPrefix) | |||
{ | |||
// TODO | |||
} | |||
else | |||
#endif | |||
if (std::getenv("WINEPREFIX") == nullptr && | |||
options.wine.fallbackPrefix != nullptr && | |||
options.wine.fallbackPrefix[0] != '\0') | |||
{ | |||
carla_setenv("WINEPREFIX", options.wine.fallbackPrefix); | |||
} | |||
if (options.wine.rtPrio) | |||
{ | |||
carla_setenv("STAGING_SHARED_MEMORY", "1"); | |||
std::snprintf(strBuf, STR_MAX, "%i", options.wine.baseRtPrio); | |||
carla_setenv("STAGING_RT_PRIORITY_BASE", strBuf); | |||
carla_setenv("WINE_RT", strBuf); | |||
std::snprintf(strBuf, STR_MAX, "%i", options.wine.serverRtPrio); | |||
carla_setenv("STAGING_RT_PRIORITY_SERVER", strBuf); | |||
carla_setenv("WINE_SVR_RT", strBuf); | |||
} | |||
else | |||
{ | |||
carla_unsetenv("STAGING_SHARED_MEMORY"); | |||
carla_unsetenv("STAGING_RT_PRIORITY_BASE"); | |||
carla_unsetenv("STAGING_RT_PRIORITY_SERVER"); | |||
carla_unsetenv("WINE_RT"); | |||
carla_unsetenv("WINE_SVR_RT"); | |||
} | |||
} | |||
#endif | |||
// binary | |||
@@ -146,10 +191,6 @@ protected: | |||
bool started; | |||
{ | |||
char strBuf[STR_MAX+1]; | |||
strBuf[STR_MAX] = '\0'; | |||
const EngineOptions& options(kEngine->getOptions()); | |||
const ScopedEngineEnvironmentLocker _seel(kEngine); | |||
#ifdef CARLA_OS_LINUX | |||
@@ -790,8 +790,26 @@ ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR = 16 | |||
# Set frontend winId, used to define as parent window for plugin UIs. | |||
ENGINE_OPTION_FRONTEND_WIN_ID = 17 | |||
# Set path to wine executable. | |||
ENGINE_OPTION_WINE_EXECUTABLE = 18 | |||
# Enable automatic wineprefix detection. | |||
ENGINE_OPTION_WINE_AUTO_PREFIX = 19 | |||
# Fallback wineprefix to use if automatic detection fails or is disabled, and WINEPREFIX is not set. | |||
ENGINE_OPTION_WINE_FALLBACK_PREFIX = 20 | |||
# Enable realtime priority for Wine application and server threads. | |||
ENGINE_OPTION_WINE_RT_PRIO_ENABLED = 21 | |||
# Base realtime priority for Wine threads. | |||
ENGINE_OPTION_WINE_BASE_RT_PRIO = 22 | |||
# Wine server realtime priority. | |||
ENGINE_OPTION_WINE_SERVER_RT_PRIO = 23 | |||
# Capture console output into debug callbacks | |||
ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT = 18 | |||
ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT = 24 | |||
# ------------------------------------------------------------------------------------------------------------ | |||
# Engine Process Mode | |||
@@ -2459,8 +2459,6 @@ def initHost(initName, libPrefix, isControl, isPlugin, failError, HostClass = No | |||
# -------------------------------------------------------------------------------------------------------- | |||
# Init host | |||
if failError: | |||
# no try | |||
host = HostClass() if HostClass is not None else CarlaHostQtDLL(libname, loadGlobal) | |||
@@ -2726,6 +2724,23 @@ def setEngineSettings(host): | |||
host.transportMode = ENGINE_TRANSPORT_MODE_INTERNAL | |||
host.set_engine_option(ENGINE_OPTION_TRANSPORT_MODE, ENGINE_TRANSPORT_MODE_INTERNAL, "") | |||
# -------------------------------------------------------------------------------------------------------- | |||
# wine settings | |||
optWineExecutable = settings.value(CARLA_KEY_WINE_EXECUTABLE, CARLA_DEFAULT_WINE_EXECUTABLE, type=str) | |||
optWineAutoPrefix = settings.value(CARLA_KEY_WINE_AUTO_PREFIX, CARLA_DEFAULT_WINE_AUTO_PREFIX, type=bool) | |||
optWineFallbackPrefix = settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX, CARLA_DEFAULT_WINE_FALLBACK_PREFIX, type=str) | |||
optWineRtPrioEnabled = settings.value(CARLA_KEY_WINE_RT_PRIO_ENABLED, CARLA_DEFAULT_WINE_RT_PRIO_ENABLED, type=bool) | |||
optWineBaseRtPrio = settings.value(CARLA_KEY_WINE_BASE_RT_PRIO, CARLA_DEFAULT_WINE_BASE_RT_PRIO, type=int) | |||
optWineServerRtPrio = settings.value(CARLA_KEY_WINE_SERVER_RT_PRIO, CARLA_DEFAULT_WINE_SERVER_RT_PRIO, type=int) | |||
host.set_engine_option(ENGINE_OPTION_WINE_EXECUTABLE, 0, optWineExecutable) | |||
host.set_engine_option(ENGINE_OPTION_WINE_AUTO_PREFIX, 1 if optWineAutoPrefix else 0, "") | |||
host.set_engine_option(ENGINE_OPTION_WINE_FALLBACK_PREFIX, 0, os.path.expanduser(optWineFallbackPrefix)) | |||
host.set_engine_option(ENGINE_OPTION_WINE_RT_PRIO_ENABLED, 1 if optWineRtPrioEnabled else 0, "") | |||
host.set_engine_option(ENGINE_OPTION_WINE_BASE_RT_PRIO, optWineBaseRtPrio, "") | |||
host.set_engine_option(ENGINE_OPTION_WINE_SERVER_RT_PRIO, optWineServerRtPrio, "") | |||
# -------------------------------------------------------------------------------------------------------- | |||
# return selected driver name | |||
@@ -331,6 +331,18 @@ const char* EngineOption2Str(const EngineOption option) noexcept | |||
return "ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR"; | |||
case ENGINE_OPTION_FRONTEND_WIN_ID: | |||
return "ENGINE_OPTION_FRONTEND_WIN_ID"; | |||
case ENGINE_OPTION_WINE_EXECUTABLE: | |||
return "ENGINE_OPTION_WINE_EXECUTABLE"; | |||
case ENGINE_OPTION_WINE_AUTO_PREFIX: | |||
return "ENGINE_OPTION_WINE_AUTO_PREFIX"; | |||
case ENGINE_OPTION_WINE_FALLBACK_PREFIX: | |||
return "ENGINE_OPTION_WINE_FALLBACK_PREFIX"; | |||
case ENGINE_OPTION_WINE_RT_PRIO_ENABLED: | |||
return "ENGINE_OPTION_WINE_RT_PRIO_ENABLED"; | |||
case ENGINE_OPTION_WINE_BASE_RT_PRIO: | |||
return "ENGINE_OPTION_WINE_BASE_RT_PRIO"; | |||
case ENGINE_OPTION_WINE_SERVER_RT_PRIO: | |||
return "ENGINE_OPTION_WINE_SERVER_RT_PRIO"; | |||
case ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT: | |||
return "ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT"; | |||
} | |||