@@ -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); | |||