Signed-off-by: falkTX <falktx@falktx.com>tags/v2.2.0-RC1
@@ -1060,8 +1060,15 @@ public: | |||||
bool saveProject(const char* filename, bool setAsCurrentProject); | bool saveProject(const char* filename, bool setAsCurrentProject); | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
/*! | |||||
* Get the currently set project folder. | |||||
* @note Valid for both standalone and plugin versions. | |||||
*/ | |||||
virtual const char* getCurrentProjectFolder() const noexcept; | |||||
/*! | /*! | ||||
* Get the currently set project filename. | * Get the currently set project filename. | ||||
* @note Valid only for both standalone version. | |||||
*/ | */ | ||||
const char* getCurrentProjectFilename() const noexcept; | const char* getCurrentProjectFilename() const noexcept; | ||||
@@ -528,6 +528,18 @@ CARLA_EXPORT bool carla_load_project(CarlaHostHandle handle, const char* filenam | |||||
CARLA_EXPORT bool carla_save_project(CarlaHostHandle handle, const char* filename); | CARLA_EXPORT bool carla_save_project(CarlaHostHandle handle, const char* filename); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
/*! | |||||
* Get the currently set project folder. | |||||
* @note Valid for both standalone and plugin versions. | |||||
*/ | |||||
CARLA_EXPORT const char* carla_get_current_project_folder(CarlaHostHandle handle); | |||||
/*! | |||||
* Get the currently set project filename. | |||||
* @note Valid only for both standalone version. | |||||
*/ | |||||
CARLA_EXPORT const char* carla_get_current_project_filename(CarlaHostHandle handle); | |||||
/*! | /*! | ||||
* Clear the currently set project filename. | * Clear the currently set project filename. | ||||
*/ | */ | ||||
@@ -944,6 +944,30 @@ bool carla_save_project(CarlaHostHandle handle, const char* filename) | |||||
} | } | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
const char* carla_get_current_project_folder(CarlaHostHandle handle) | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr); | |||||
carla_debug("carla_get_current_project_folder(%p)", handle); | |||||
if (const char* const ret = handle->engine->getCurrentProjectFolder()) | |||||
return ret; | |||||
return gNullCharPtr; | |||||
} | |||||
const char* carla_get_current_project_filename(CarlaHostHandle handle) | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->isStandalone, gNullCharPtr); | |||||
carla_debug("carla_get_current_project_filename(%p)", handle); | |||||
if (const char* const ret = handle->engine->getCurrentProjectFilename()) | |||||
return ret; | |||||
return gNullCharPtr; | |||||
} | |||||
void carla_clear_project_filename(CarlaHostHandle handle) | void carla_clear_project_filename(CarlaHostHandle handle) | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,); | CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,); | ||||
@@ -1254,13 +1254,29 @@ bool CarlaEngine::loadProject(const char* const filename, const bool setAsCurren | |||||
carla_debug("CarlaEngine::loadProject(\"%s\")", filename); | carla_debug("CarlaEngine::loadProject(\"%s\")", filename); | ||||
const String jfilename = String(CharPointer_UTF8(filename)); | const String jfilename = String(CharPointer_UTF8(filename)); | ||||
File file(jfilename); | |||||
const File file(jfilename); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(file.existsAsFile(), "Requested file does not exist or is not a readable file"); | CARLA_SAFE_ASSERT_RETURN_ERR(file.existsAsFile(), "Requested file does not exist or is not a readable file"); | ||||
if (setAsCurrentProject) | if (setAsCurrentProject) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
pData->currentProjectFilename = filename; | |||||
if (pData->currentProjectFilename != filename) | |||||
{ | |||||
pData->currentProjectFilename = filename; | |||||
bool found; | |||||
const size_t r = pData->currentProjectFilename.rfind(CARLA_OS_SEP, &found); | |||||
if (found) | |||||
{ | |||||
pData->currentProjectFolder = filename; | |||||
pData->currentProjectFolder[r] = '\0'; | |||||
} | |||||
else | |||||
{ | |||||
pData->currentProjectFolder.clear(); | |||||
} | |||||
} | |||||
#endif | #endif | ||||
} | } | ||||
@@ -1282,7 +1298,23 @@ bool CarlaEngine::saveProject(const char* const filename, const bool setAsCurren | |||||
if (setAsCurrentProject) | if (setAsCurrentProject) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
pData->currentProjectFilename = filename; | |||||
if (pData->currentProjectFilename != filename) | |||||
{ | |||||
pData->currentProjectFilename = filename; | |||||
bool found; | |||||
const size_t r = pData->currentProjectFilename.rfind(CARLA_OS_SEP, &found); | |||||
if (found) | |||||
{ | |||||
pData->currentProjectFolder = filename; | |||||
pData->currentProjectFolder[r] = '\0'; | |||||
} | |||||
else | |||||
{ | |||||
pData->currentProjectFolder.clear(); | |||||
} | |||||
} | |||||
#endif | #endif | ||||
} | } | ||||
@@ -1294,6 +1326,11 @@ bool CarlaEngine::saveProject(const char* const filename, const bool setAsCurren | |||||
} | } | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
const char* CarlaEngine::getCurrentProjectFolder() const noexcept | |||||
{ | |||||
return pData->currentProjectFolder; | |||||
} | |||||
const char* CarlaEngine::getCurrentProjectFilename() const noexcept | const char* CarlaEngine::getCurrentProjectFilename() const noexcept | ||||
{ | { | ||||
return pData->currentProjectFilename; | return pData->currentProjectFilename; | ||||
@@ -1302,6 +1339,7 @@ const char* CarlaEngine::getCurrentProjectFilename() const noexcept | |||||
void CarlaEngine::clearCurrentProjectFilename() noexcept | void CarlaEngine::clearCurrentProjectFilename() noexcept | ||||
{ | { | ||||
pData->currentProjectFilename.clear(); | pData->currentProjectFilename.clear(); | ||||
pData->currentProjectFolder.clear(); | |||||
} | } | ||||
#endif | #endif | ||||
@@ -386,6 +386,7 @@ CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) | |||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
loadingProject(false), | loadingProject(false), | ||||
currentProjectFilename(), | currentProjectFilename(), | ||||
currentProjectFolder(), | |||||
#endif | #endif | ||||
bufferSize(0), | bufferSize(0), | ||||
sampleRate(0.0), | sampleRate(0.0), | ||||
@@ -247,6 +247,7 @@ struct CarlaEngine::ProtectedData { | |||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
bool loadingProject; | bool loadingProject; | ||||
CarlaString currentProjectFilename; | CarlaString currentProjectFilename; | ||||
CarlaString currentProjectFolder; | |||||
#endif | #endif | ||||
uint32_t bufferSize; | uint32_t bufferSize; | ||||
@@ -184,6 +184,7 @@ public: | |||||
fIsRunning(false), | fIsRunning(false), | ||||
fUiServer(this), | fUiServer(this), | ||||
fLastScaleFactor(1.0f), | fLastScaleFactor(1.0f), | ||||
fLastProjectFolder(), | |||||
fOptionsForced(false) | fOptionsForced(false) | ||||
{ | { | ||||
carla_debug("CarlaEngineNative::CarlaEngineNative()"); | carla_debug("CarlaEngineNative::CarlaEngineNative()"); | ||||
@@ -319,6 +320,21 @@ public: | |||||
return "Plugin"; | return "Plugin"; | ||||
} | } | ||||
const char* getCurrentProjectFolder() const noexcept override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, nullptr); | |||||
static char filetype[] = "carla\0"; | |||||
try { | |||||
return (const char*)(uintptr_t)pHost->dispatcher(pHost->handle, | |||||
NATIVE_HOST_OPCODE_GET_FILE_PATH, | |||||
0, 0, | |||||
(void*)filetype, | |||||
0.0f); | |||||
} CARLA_SAFE_EXCEPTION_RETURN("get_file_path", nullptr); | |||||
} | |||||
void callback(const bool sendHost, const bool sendOsc, | void callback(const bool sendHost, const bool sendOsc, | ||||
const EngineCallbackOpcode action, const uint pluginId, | const EngineCallbackOpcode action, const uint pluginId, | ||||
const int value1, const int value2, const int value3, | const int value1, const int value2, const int value3, | ||||
@@ -420,7 +436,7 @@ protected: | |||||
{ | { | ||||
const CarlaMutexLocker cml(fUiServer.getPipeLock()); | const CarlaMutexLocker cml(fUiServer.getPipeLock()); | ||||
if (fUiServer.writeAndFixMessage("buffer-size")) | |||||
if (fUiServer.writeMessage("buffer-size\n")) | |||||
{ | { | ||||
char tmpBuf[STR_MAX+1]; | char tmpBuf[STR_MAX+1]; | ||||
carla_zeroChars(tmpBuf, STR_MAX+1); | carla_zeroChars(tmpBuf, STR_MAX+1); | ||||
@@ -444,7 +460,7 @@ protected: | |||||
{ | { | ||||
const CarlaMutexLocker cml(fUiServer.getPipeLock()); | const CarlaMutexLocker cml(fUiServer.getPipeLock()); | ||||
if (fUiServer.writeAndFixMessage("sample-rate")) | |||||
if (fUiServer.writeMessage("sample-rate\n")) | |||||
{ | { | ||||
char tmpBuf[STR_MAX+1]; | char tmpBuf[STR_MAX+1]; | ||||
carla_zeroChars(tmpBuf, STR_MAX+1); | carla_zeroChars(tmpBuf, STR_MAX+1); | ||||
@@ -485,8 +501,7 @@ protected: | |||||
if (const char* const filename = plugin->getFilename()) | if (const char* const filename = plugin->getFilename()) | ||||
{ | { | ||||
std::snprintf(tmpBuf, STR_MAX, "%s", filename); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(filename),); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -495,8 +510,7 @@ protected: | |||||
if (const char* const name = plugin->getName()) | if (const char* const name = plugin->getName()) | ||||
{ | { | ||||
std::snprintf(tmpBuf, STR_MAX, "%s", name); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(name),); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -505,8 +519,7 @@ protected: | |||||
if (const char* const iconName = plugin->getIconName()) | if (const char* const iconName = plugin->getIconName()) | ||||
{ | { | ||||
std::snprintf(tmpBuf, STR_MAX, "%s", iconName); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(iconName),); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -680,8 +693,7 @@ protected: | |||||
std::snprintf(tmpBuf, STR_MAX, "%i:%i\n", mpData.bank, mpData.program); | std::snprintf(tmpBuf, STR_MAX, "%i:%i\n", mpData.bank, mpData.program); | ||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),); | CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),); | ||||
std::snprintf(tmpBuf, STR_MAX, "%s", mpData.name); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(mpData.name),); | |||||
} | } | ||||
fUiServer.flushMessages(); | fUiServer.flushMessages(); | ||||
@@ -1409,16 +1421,27 @@ protected: | |||||
// ------------------------------------------------------------------------------------------------------------ | // ------------------------------------------------------------------------------------------------------------ | ||||
// send engine info | // send engine info | ||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage("runtime-info"),); | |||||
std::snprintf(tmpBuf, STR_MAX, "%.12g:0\n", static_cast<double>(getDSPLoad())); | std::snprintf(tmpBuf, STR_MAX, "%.12g:0\n", static_cast<double>(getDSPLoad())); | ||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("runtime-info\n"),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),); | CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),); | ||||
fUiServer.flushMessages(); | fUiServer.flushMessages(); | ||||
if (const char* const projFolder = getCurrentProjectFolder()) | |||||
{ | |||||
if (fLastProjectFolder != projFolder) | |||||
{ | |||||
fLastProjectFolder = projFolder; | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("project-folder\n"),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(projFolder),); | |||||
fUiServer.flushMessages(); | |||||
} | |||||
} | |||||
// ------------------------------------------------------------------------------------------------------------ | // ------------------------------------------------------------------------------------------------------------ | ||||
// send transport | // send transport | ||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage("transport"),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("transport\n"),); | |||||
CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"),); | CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"),); | ||||
if (timeInfo.bbt.valid) | if (timeInfo.bbt.valid) | ||||
@@ -1676,6 +1699,7 @@ private: | |||||
float fParameters[kNumInParams+kNumOutParams]; | float fParameters[kNumInParams+kNumOutParams]; | ||||
float fLastScaleFactor; | float fLastScaleFactor; | ||||
CarlaString fLastProjectFolder; | |||||
bool fOptionsForced; | bool fOptionsForced; | ||||
@@ -164,6 +164,11 @@ public: | |||||
return ret.releaseBufferPointer(); | return ret.releaseBufferPointer(); | ||||
} | } | ||||
const CarlaString& getAppName() const noexcept | |||||
{ | |||||
return fProject.appName; | |||||
} | |||||
protected: | protected: | ||||
#ifdef HAVE_LIBLO | #ifdef HAVE_LIBLO | ||||
static void _osc_error_handler(int num, const char* msg, const char* path) | static void _osc_error_handler(int num, const char* msg, const char* path) | ||||
@@ -184,7 +189,9 @@ protected: | |||||
if (fSetupLabel.length() <= 6) | if (fSetupLabel.length() <= 6) | ||||
return; | return; | ||||
if (fProject.path.isNotEmpty() || fProject.init(kEngine->getCurrentProjectFilename(), &fSetupLabel[6])) | |||||
if (fProject.path.isNotEmpty() || fProject.init(kPlugin->getName(), | |||||
kEngine->getCurrentProjectFolder(), | |||||
&fSetupLabel[6])) | |||||
{ | { | ||||
carla_stdout("Sending open signal %s %s %s", | carla_stdout("Sending open signal %s %s %s", | ||||
fProject.path.buffer(), fProject.display.buffer(), fProject.clientName.buffer()); | fProject.path.buffer(), fProject.display.buffer(), fProject.clientName.buffer()); | ||||
@@ -465,17 +472,23 @@ private: | |||||
display(), | display(), | ||||
clientName() {} | clientName() {} | ||||
bool init(const char* const engineProjectFilename, const char* const uniqueCodeID) | |||||
bool init(const char* const pluginName, | |||||
const char* const engineProjectFolder, | |||||
const char* const uniqueCodeID) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(engineProjectFilename != nullptr && engineProjectFilename[0] != '\0', false); | |||||
CARLA_SAFE_ASSERT_RETURN(engineProjectFolder != nullptr && engineProjectFolder[0] != '\0', false); | |||||
CARLA_SAFE_ASSERT_RETURN(uniqueCodeID != nullptr && uniqueCodeID[0] != '\0', false); | CARLA_SAFE_ASSERT_RETURN(uniqueCodeID != nullptr && uniqueCodeID[0] != '\0', false); | ||||
CARLA_SAFE_ASSERT_RETURN(appName.isNotEmpty(), false); | CARLA_SAFE_ASSERT_RETURN(appName.isNotEmpty(), false); | ||||
const File file(File(engineProjectFilename).withFileExtension(uniqueCodeID)); | |||||
String child(pluginName); | |||||
child += "."; | |||||
child += uniqueCodeID; | |||||
const File file(File(engineProjectFolder).getChildFile(child)); | |||||
clientName = appName + "." + uniqueCodeID; | |||||
path = file.getFullPathName().toRawUTF8(); | path = file.getFullPathName().toRawUTF8(); | ||||
display = file.getFileNameWithoutExtension().toRawUTF8(); | display = file.getFileNameWithoutExtension().toRawUTF8(); | ||||
clientName = appName + "." + uniqueCodeID; | |||||
return true; | return true; | ||||
} | } | ||||
@@ -630,8 +643,6 @@ public: | |||||
#ifdef HAVE_LIBLO | #ifdef HAVE_LIBLO | ||||
if (fInfo.setupLabel.length() == 6) | if (fInfo.setupLabel.length() == 6) | ||||
setupUniqueProjectID(); | setupUniqueProjectID(); | ||||
fBridgeThread.nsmSave(fInfo.setupLabel); | |||||
#endif | #endif | ||||
{ | { | ||||
@@ -640,6 +651,10 @@ public: | |||||
fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPrepareForSave); | fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPrepareForSave); | ||||
fShmNonRtClientControl.commitWrite(); | fShmNonRtClientControl.commitWrite(); | ||||
} | } | ||||
#ifdef HAVE_LIBLO | |||||
fBridgeThread.nsmSave(fInfo.setupLabel); | |||||
#endif | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -1776,19 +1791,20 @@ private: | |||||
void setupUniqueProjectID() | void setupUniqueProjectID() | ||||
{ | { | ||||
const char* const engineProjectFilename = pData->engine->getCurrentProjectFilename(); | |||||
carla_stdout("setupUniqueProjectID %s", engineProjectFilename); | |||||
const char* const engineProjectFolder = pData->engine->getCurrentProjectFolder(); | |||||
carla_stdout("setupUniqueProjectID %s", engineProjectFolder); | |||||
if (engineProjectFilename == nullptr || engineProjectFilename[0] == '\0') | |||||
if (engineProjectFolder == nullptr || engineProjectFolder[0] == '\0') | |||||
return; | return; | ||||
const File file(engineProjectFilename); | |||||
CARLA_SAFE_ASSERT_RETURN(file.existsAsFile(),); | |||||
CARLA_SAFE_ASSERT_RETURN(file.getFileExtension().isNotEmpty(),); | |||||
const File file(engineProjectFolder); | |||||
CARLA_SAFE_ASSERT_RETURN(file.exists(),); | |||||
char code[6]; | char code[6]; | ||||
code[5] = '\0'; | code[5] = '\0'; | ||||
String child; | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
static const char* const kValidChars = | static const char* const kValidChars = | ||||
@@ -1804,7 +1820,10 @@ private: | |||||
code[3] = kValidChars[safe_rand(kValidCharsLen)]; | code[3] = kValidChars[safe_rand(kValidCharsLen)]; | ||||
code[4] = kValidChars[safe_rand(kValidCharsLen)]; | code[4] = kValidChars[safe_rand(kValidCharsLen)]; | ||||
const File newFile(file.withFileExtension(code)); | |||||
child = pData->name; | |||||
child += "."; | |||||
child += code; | |||||
const File newFile(file.getChildFile(child)); | |||||
if (newFile.existsAsFile()) | if (newFile.existsAsFile()) | ||||
continue; | continue; | ||||
@@ -256,6 +256,8 @@ public: | |||||
fNeedsIdle(false), | fNeedsIdle(false), | ||||
fInlineDisplayNeedsRedraw(false), | fInlineDisplayNeedsRedraw(false), | ||||
fInlineDisplayLastRedrawTime(0), | fInlineDisplayLastRedrawTime(0), | ||||
fLastProjectFilename(), | |||||
fLastProjectFolder(), | |||||
fAudioAndCvInBuffers(nullptr), | fAudioAndCvInBuffers(nullptr), | ||||
fAudioAndCvOutBuffers(nullptr), | fAudioAndCvOutBuffers(nullptr), | ||||
fMidiEventInCount(0), | fMidiEventInCount(0), | ||||
@@ -2690,70 +2692,107 @@ protected: | |||||
carla_debug("CarlaPluginNative::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)", | carla_debug("CarlaPluginNative::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)", | ||||
opcode, index, value, ptr, static_cast<double>(opt)); | opcode, index, value, ptr, static_cast<double>(opt)); | ||||
intptr_t ret = 0; | |||||
switch (opcode) | switch (opcode) | ||||
{ | { | ||||
case NATIVE_HOST_OPCODE_NULL: | case NATIVE_HOST_OPCODE_NULL: | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_UPDATE_PARAMETER: | case NATIVE_HOST_OPCODE_UPDATE_PARAMETER: | ||||
// TODO | // TODO | ||||
pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0, 0.0f, nullptr); | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM: | case NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM: | ||||
// TODO | // TODO | ||||
pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0, 0.0f, nullptr); | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_RELOAD_PARAMETERS: | case NATIVE_HOST_OPCODE_RELOAD_PARAMETERS: | ||||
reloadParameters(nullptr, nullptr); | reloadParameters(nullptr, nullptr); | ||||
pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_ALL, pData->id, -1, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_ALL, pData->id, -1, 0, 0, 0.0f, nullptr); | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS: | case NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS: | ||||
reloadPrograms(false); | reloadPrograms(false); | ||||
pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, -1, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, -1, 0, 0, 0.0f, nullptr); | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_RELOAD_ALL: | case NATIVE_HOST_OPCODE_RELOAD_ALL: | ||||
reload(); | reload(); | ||||
pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_ALL, pData->id, -1, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_ALL, pData->id, -1, 0, 0, 0.0f, nullptr); | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_UI_UNAVAILABLE: | case NATIVE_HOST_OPCODE_UI_UNAVAILABLE: | ||||
pData->engine->callback(true, true, ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, true, ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0, 0.0f, nullptr); | ||||
fIsUiAvailable = false; | fIsUiAvailable = false; | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_HOST_IDLE: | case NATIVE_HOST_OPCODE_HOST_IDLE: | ||||
pData->engine->callback(true, false, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, false, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr); | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_INTERNAL_PLUGIN: | case NATIVE_HOST_OPCODE_INTERNAL_PLUGIN: | ||||
ret = 1; | |||||
break; | |||||
return 1; | |||||
case NATIVE_HOST_OPCODE_QUEUE_INLINE_DISPLAY: | case NATIVE_HOST_OPCODE_QUEUE_INLINE_DISPLAY: | ||||
fInlineDisplayNeedsRedraw = true; | fInlineDisplayNeedsRedraw = true; | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_UI_TOUCH_PARAMETER: | case NATIVE_HOST_OPCODE_UI_TOUCH_PARAMETER: | ||||
CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); | CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); | ||||
pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), value != 0); | pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), value != 0); | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_REQUEST_IDLE: | case NATIVE_HOST_OPCODE_REQUEST_IDLE: | ||||
fNeedsIdle = true; | fNeedsIdle = true; | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_GET_FILE_PATH: | case NATIVE_HOST_OPCODE_GET_FILE_PATH: | ||||
CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0); | CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0); | ||||
{ | { | ||||
const EngineOptions& opts(pData->engine->getOptions()); | const EngineOptions& opts(pData->engine->getOptions()); | ||||
const char* const filetype = (const char*)ptr; | const char* const filetype = (const char*)ptr; | ||||
const char* ret = nullptr; | |||||
if (std::strcmp(filetype, "carla") == 0) | |||||
{ | |||||
ret = pData->engine->getCurrentProjectFilename(); | |||||
if (std::strcmp(filetype, "audio") == 0) | |||||
return static_cast<intptr_t>((uintptr_t)opts.pathAudio); | |||||
if (std::strcmp(filetype, "midi") == 0) | |||||
return static_cast<intptr_t>((uintptr_t)opts.pathMIDI); | |||||
if (fLastProjectFilename != ret) | |||||
{ | |||||
fLastProjectFilename = ret; | |||||
bool found; | |||||
const size_t r = fLastProjectFilename.rfind(CARLA_OS_SEP, &found); | |||||
if (found) | |||||
{ | |||||
fLastProjectFolder = ret; | |||||
fLastProjectFolder[r] = '\0'; | |||||
} | |||||
else | |||||
{ | |||||
fLastProjectFolder.clear(); | |||||
} | |||||
} | |||||
ret = fLastProjectFolder.buffer(); | |||||
} | |||||
else if (std::strcmp(filetype, "audio") == 0) | |||||
ret = opts.pathAudio; | |||||
else if (std::strcmp(filetype, "midi") == 0) | |||||
ret = opts.pathMIDI; | |||||
return static_cast<intptr_t>((uintptr_t)ret); | |||||
} | } | ||||
break; | break; | ||||
case NATIVE_HOST_OPCODE_UI_RESIZE: | case NATIVE_HOST_OPCODE_UI_RESIZE: | ||||
// unused here | // unused here | ||||
break; | break; | ||||
} | } | ||||
return ret; | |||||
return 0; | |||||
// unused for now | // unused for now | ||||
(void)opt; | (void)opt; | ||||
@@ -2956,6 +2995,9 @@ private: | |||||
bool fInlineDisplayNeedsRedraw; | bool fInlineDisplayNeedsRedraw; | ||||
int64_t fInlineDisplayLastRedrawTime; | int64_t fInlineDisplayLastRedrawTime; | ||||
CarlaString fLastProjectFilename; | |||||
CarlaString fLastProjectFolder; | |||||
float** fAudioAndCvInBuffers; | float** fAudioAndCvInBuffers; | ||||
float** fAudioAndCvOutBuffers; | float** fAudioAndCvOutBuffers; | ||||
uint32_t fMidiEventInCount; | uint32_t fMidiEventInCount; | ||||
@@ -174,6 +174,9 @@ class CarlaMiniW(ExternalUI, HostWindow): | |||||
xruns = int(values[1]) | xruns = int(values[1]) | ||||
self.host._set_runtime_info(load, xruns) | self.host._set_runtime_info(load, xruns) | ||||
elif msg == "project-folder": | |||||
self.fProjectFilename = self.readlineblock() | |||||
elif msg == "transport": | elif msg == "transport": | ||||
playing = self.readlineblock_bool() | playing = self.readlineblock_bool() | ||||
frame, bar, beat, tick = [int(i) for i in self.readlineblock().split(":")] | frame, bar, beat, tick = [int(i) for i in self.readlineblock().split(":")] | ||||