| @@ -87,7 +87,7 @@ public: | |||||
| const char* readlineblock(const uint timeout) noexcept | const char* readlineblock(const uint timeout) noexcept | ||||
| { | { | ||||
| return CarlaPipeClient::readlineblock(timeout); | |||||
| return CarlaPipeClient::_readlineblock(timeout); | |||||
| } | } | ||||
| bool msgReceived(const char* const msg) noexcept | bool msgReceived(const char* const msg) noexcept | ||||
| @@ -115,7 +115,7 @@ CarlaPipeClientHandle carla_pipe_client_new(const char* argv[], CarlaPipeCallbac | |||||
| CarlaPipeClientPlugin* const pipe(new CarlaPipeClientPlugin(callbackFunc, callbackPtr)); | CarlaPipeClientPlugin* const pipe(new CarlaPipeClientPlugin(callbackFunc, callbackPtr)); | ||||
| if (! pipe->init(argv)) | |||||
| if (! pipe->initPipeClient(argv)) | |||||
| { | { | ||||
| delete pipe; | delete pipe; | ||||
| return nullptr; | return nullptr; | ||||
| @@ -128,28 +128,28 @@ void carla_pipe_client_idle(CarlaPipeClientHandle handle) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | ||||
| ((CarlaPipeClientPlugin*)handle)->idle(); | |||||
| ((CarlaPipeClientPlugin*)handle)->idlePipe(); | |||||
| } | } | ||||
| bool carla_pipe_client_is_running(CarlaPipeClientHandle handle) | bool carla_pipe_client_is_running(CarlaPipeClientHandle handle) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | ||||
| return ((CarlaPipeClientPlugin*)handle)->isRunning(); | |||||
| return ((CarlaPipeClientPlugin*)handle)->isPipeRunning(); | |||||
| } | } | ||||
| void carla_pipe_client_lock(CarlaPipeClientHandle handle) | void carla_pipe_client_lock(CarlaPipeClientHandle handle) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | ||||
| return ((CarlaPipeClientPlugin*)handle)->lock(); | |||||
| return ((CarlaPipeClientPlugin*)handle)->lockPipe(); | |||||
| } | } | ||||
| void carla_pipe_client_unlock(CarlaPipeClientHandle handle) | void carla_pipe_client_unlock(CarlaPipeClientHandle handle) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | ||||
| return ((CarlaPipeClientPlugin*)handle)->unlock(); | |||||
| return ((CarlaPipeClientPlugin*)handle)->unlockPipe(); | |||||
| } | } | ||||
| const char* carla_pipe_client_readlineblock(CarlaPipeClientHandle handle, uint timeout) | const char* carla_pipe_client_readlineblock(CarlaPipeClientHandle handle, uint timeout) | ||||
| @@ -163,21 +163,21 @@ bool carla_pipe_client_write_msg(CarlaPipeClientHandle handle, const char* msg) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | ||||
| return ((CarlaPipeClientPlugin*)handle)->writeMsg(msg); | |||||
| return ((CarlaPipeClientPlugin*)handle)->writeMessage(msg); | |||||
| } | } | ||||
| bool carla_pipe_client_write_and_fix_msg(CarlaPipeClientHandle handle, const char* msg) | bool carla_pipe_client_write_and_fix_msg(CarlaPipeClientHandle handle, const char* msg) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | ||||
| return ((CarlaPipeClientPlugin*)handle)->writeAndFixMsg(msg); | |||||
| return ((CarlaPipeClientPlugin*)handle)->writeAndFixMessage(msg); | |||||
| } | } | ||||
| bool carla_pipe_client_flush(CarlaPipeClientHandle handle) | bool carla_pipe_client_flush(CarlaPipeClientHandle handle) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | ||||
| return ((CarlaPipeClientPlugin*)handle)->flush(); | |||||
| return ((CarlaPipeClientPlugin*)handle)->flushMessages(); | |||||
| } | } | ||||
| bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle) | bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle) | ||||
| @@ -185,8 +185,8 @@ bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle) | |||||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | ||||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | ||||
| const bool ret(pipe->flush()); | |||||
| pipe->unlock(); | |||||
| const bool ret(pipe->flushMessages()); | |||||
| pipe->unlockPipe(); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -196,7 +196,7 @@ void carla_pipe_client_destroy(CarlaPipeClientHandle handle) | |||||
| carla_debug("carla_pipe_client_destroy(%p)", handle); | carla_debug("carla_pipe_client_destroy(%p)", handle); | ||||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | ||||
| pipe->close(); | |||||
| pipe->closePipeClient(); | |||||
| delete pipe; | delete pipe; | ||||
| } | } | ||||
| @@ -73,11 +73,18 @@ public: | |||||
| carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()"); | carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()"); | ||||
| } | } | ||||
| void show() noexcept | |||||
| void writeShowMessage() noexcept | |||||
| { | { | ||||
| const CarlaMutexLocker cml(getLock()); | |||||
| writeMsg("show\n", 5); | |||||
| flush(); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("show\n", 5); | |||||
| flushMessages(); | |||||
| } | |||||
| void writeFocusMessage() noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("focus\n", 6); | |||||
| flushMessages(); | |||||
| } | } | ||||
| protected: | protected: | ||||
| @@ -542,10 +549,10 @@ protected: | |||||
| if (! ok) | if (! ok) | ||||
| { | { | ||||
| const CarlaMutexLocker cml(getLock()); | |||||
| writeMsg("error\n", 6); | |||||
| writeAndFixMsg(fEngine->getLastError()); | |||||
| flush(); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("error\n", 6); | |||||
| writeAndFixMessage(fEngine->getLastError()); | |||||
| flushMessages(); | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -713,12 +720,12 @@ protected: | |||||
| return; | return; | ||||
| { | { | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| fUiServer.writeAndFixMsg("buffer-size"); | |||||
| fUiServer.writeAndFixMessage("buffer-size"); | |||||
| std::sprintf(fTmpBuf, "%i\n", newBufferSize); | std::sprintf(fTmpBuf, "%i\n", newBufferSize); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| pData->bufferSize = newBufferSize; | pData->bufferSize = newBufferSize; | ||||
| @@ -731,13 +738,13 @@ protected: | |||||
| return; | return; | ||||
| { | { | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| const ScopedLocale csl; | const ScopedLocale csl; | ||||
| fUiServer.writeAndFixMsg("sample-rate"); | |||||
| fUiServer.writeAndFixMessage("sample-rate"); | |||||
| std::sprintf(fTmpBuf, "%f\n", newSampleRate); | std::sprintf(fTmpBuf, "%f\n", newSampleRate); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| pData->sampleRate = newSampleRate; | pData->sampleRate = newSampleRate; | ||||
| @@ -748,64 +755,64 @@ protected: | |||||
| void uiServerSendPluginInfo(CarlaPlugin* const plugin) | void uiServerSendPluginInfo(CarlaPlugin* const plugin) | ||||
| { | { | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| const uint pluginId(plugin->getId()); | const uint pluginId(plugin->getId()); | ||||
| std::sprintf(fTmpBuf, "PLUGIN_INFO_%i\n", pluginId); | std::sprintf(fTmpBuf, "PLUGIN_INFO_%i\n", pluginId); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%i:%i:%i:" P_INT64 ":%i:%i\n", plugin->getType(), plugin->getCategory(), plugin->getHints(), plugin->getUniqueId(), plugin->getOptionsAvailable(), plugin->getOptionsEnabled()); | std::sprintf(fTmpBuf, "%i:%i:%i:" P_INT64 ":%i:%i\n", plugin->getType(), plugin->getCategory(), plugin->getHints(), plugin->getUniqueId(), plugin->getOptionsAvailable(), plugin->getOptionsEnabled()); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| if (const char* const filename = plugin->getFilename()) | if (const char* const filename = plugin->getFilename()) | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, "%s", filename); | std::sprintf(fTmpBuf, "%s", filename); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| } | } | ||||
| else | else | ||||
| fUiServer.writeMsg("\n"); | |||||
| fUiServer.writeMessage("\n"); | |||||
| if (const char* const name = plugin->getName()) | if (const char* const name = plugin->getName()) | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, "%s", name); | std::sprintf(fTmpBuf, "%s", name); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| } | } | ||||
| else | else | ||||
| fUiServer.writeMsg("\n"); | |||||
| fUiServer.writeMessage("\n"); | |||||
| if (const char* const iconName = plugin->getIconName()) | if (const char* const iconName = plugin->getIconName()) | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, "%s", iconName); | std::sprintf(fTmpBuf, "%s", iconName); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| } | } | ||||
| else | else | ||||
| fUiServer.writeMsg("\n"); | |||||
| fUiServer.writeMessage("\n"); | |||||
| plugin->getRealName(fTmpBuf); | plugin->getRealName(fTmpBuf); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| plugin->getLabel(fTmpBuf); | plugin->getLabel(fTmpBuf); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| plugin->getMaker(fTmpBuf); | plugin->getMaker(fTmpBuf); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| plugin->getCopyright(fTmpBuf); | plugin->getCopyright(fTmpBuf); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "AUDIO_COUNT_%i:%i:%i\n", pluginId, plugin->getAudioInCount(), plugin->getAudioOutCount()); | std::sprintf(fTmpBuf, "AUDIO_COUNT_%i:%i:%i\n", pluginId, plugin->getAudioInCount(), plugin->getAudioOutCount()); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "MIDI_COUNT_%i:%i:%i\n", pluginId, plugin->getMidiInCount(), plugin->getMidiOutCount()); | std::sprintf(fTmpBuf, "MIDI_COUNT_%i:%i:%i\n", pluginId, plugin->getMidiInCount(), plugin->getMidiOutCount()); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| void uiServerSendPluginParameters(CarlaPlugin* const plugin) | void uiServerSendPluginParameters(CarlaPlugin* const plugin) | ||||
| { | { | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| const ScopedLocale csl; | const ScopedLocale csl; | ||||
| const uint pluginId(plugin->getId()); | const uint pluginId(plugin->getId()); | ||||
| @@ -813,17 +820,17 @@ protected: | |||||
| for (int32_t i=PARAMETER_ACTIVE; i>PARAMETER_MAX; --i) | for (int32_t i=PARAMETER_ACTIVE; i>PARAMETER_MAX; --i) | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); | std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%f\n", plugin->getInternalParameterValue(i)); | std::sprintf(fTmpBuf, "%f\n", plugin->getInternalParameterValue(i)); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| uint32_t ins, outs, count; | uint32_t ins, outs, count; | ||||
| plugin->getParameterCountInfo(ins, outs); | plugin->getParameterCountInfo(ins, outs); | ||||
| count = plugin->getParameterCount(); | count = plugin->getParameterCount(); | ||||
| std::sprintf(fTmpBuf, "PARAMETER_COUNT_%i:%i:%i:%i\n", pluginId, ins, outs, count); | std::sprintf(fTmpBuf, "PARAMETER_COUNT_%i:%i:%i:%i\n", pluginId, ins, outs, count); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| for (uint32_t i=0; i<count; ++i) | for (uint32_t i=0; i<count; ++i) | ||||
| { | { | ||||
| @@ -831,72 +838,72 @@ protected: | |||||
| const ParameterRanges& paramRanges(plugin->getParameterRanges(i)); | const ParameterRanges& paramRanges(plugin->getParameterRanges(i)); | ||||
| std::sprintf(fTmpBuf, "PARAMETER_DATA_%i:%i\n", pluginId, i); | std::sprintf(fTmpBuf, "PARAMETER_DATA_%i:%i\n", pluginId, i); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%i:%i:%i:%i\n", paramData.type, paramData.hints, paramData.midiChannel, paramData.midiCC); | std::sprintf(fTmpBuf, "%i:%i:%i:%i\n", paramData.type, paramData.hints, paramData.midiChannel, paramData.midiCC); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| plugin->getParameterName(i, fTmpBuf); | plugin->getParameterName(i, fTmpBuf); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| plugin->getParameterUnit(i, fTmpBuf); | plugin->getParameterUnit(i, fTmpBuf); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "PARAMETER_RANGES_%i:%i\n", pluginId, i); | std::sprintf(fTmpBuf, "PARAMETER_RANGES_%i:%i\n", pluginId, i); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%f:%f:%f:%f:%f:%f\n", paramRanges.def, paramRanges.min, paramRanges.max, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge); | std::sprintf(fTmpBuf, "%f:%f:%f:%f:%f:%f\n", paramRanges.def, paramRanges.min, paramRanges.max, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); | std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(i)); | std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(i)); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| } | } | ||||
| fUiServer.flush(); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| void uiServerSendPluginPrograms(CarlaPlugin* const plugin) | void uiServerSendPluginPrograms(CarlaPlugin* const plugin) | ||||
| { | { | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| const uint pluginId(plugin->getId()); | const uint pluginId(plugin->getId()); | ||||
| uint32_t count = plugin->getProgramCount(); | uint32_t count = plugin->getProgramCount(); | ||||
| std::sprintf(fTmpBuf, "PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentProgram()); | std::sprintf(fTmpBuf, "PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentProgram()); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| for (uint32_t i=0; i<count; ++i) | for (uint32_t i=0; i<count; ++i) | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, "PROGRAM_NAME_%i:%i\n", pluginId, i); | std::sprintf(fTmpBuf, "PROGRAM_NAME_%i:%i\n", pluginId, i); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| plugin->getProgramName(i, fTmpBuf); | plugin->getProgramName(i, fTmpBuf); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| } | } | ||||
| fUiServer.flush(); | |||||
| fUiServer.flushMessages(); | |||||
| count = plugin->getMidiProgramCount(); | count = plugin->getMidiProgramCount(); | ||||
| std::sprintf(fTmpBuf, "MIDI_PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentMidiProgram()); | std::sprintf(fTmpBuf, "MIDI_PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentMidiProgram()); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| for (uint32_t i=0; i<count; ++i) | for (uint32_t i=0; i<count; ++i) | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, "MIDI_PROGRAM_DATA_%i:%i\n", pluginId, i); | std::sprintf(fTmpBuf, "MIDI_PROGRAM_DATA_%i:%i\n", pluginId, i); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| const MidiProgramData& mpData(plugin->getMidiProgramData(i)); | const MidiProgramData& mpData(plugin->getMidiProgramData(i)); | ||||
| std::sprintf(fTmpBuf, "%i:%i\n", mpData.bank, mpData.program); | std::sprintf(fTmpBuf, "%i:%i\n", mpData.bank, mpData.program); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%s", mpData.name); | std::sprintf(fTmpBuf, "%s", mpData.name); | ||||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||||
| } | } | ||||
| fUiServer.flush(); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| void uiServerCallback(const EngineCallbackOpcode action, const uint pluginId, const int value1, const int value2, const float value3, const char* const valueStr) | void uiServerCallback(const EngineCallbackOpcode action, const uint pluginId, const int value1, const int value2, const float value3, const char* const valueStr) | ||||
| { | { | ||||
| if (! fIsRunning) | if (! fIsRunning) | ||||
| return; | return; | ||||
| if (! fUiServer.isRunning()) | |||||
| if (! fUiServer.isPipeRunning()) | |||||
| return; | return; | ||||
| CarlaPlugin* plugin; | CarlaPlugin* plugin; | ||||
| @@ -950,138 +957,138 @@ protected: | |||||
| break; | break; | ||||
| } | } | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| const ScopedLocale csl; | const ScopedLocale csl; | ||||
| std::sprintf(fTmpBuf, "ENGINE_CALLBACK_%i\n", int(action)); | std::sprintf(fTmpBuf, "ENGINE_CALLBACK_%i\n", int(action)); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%u\n", pluginId); | std::sprintf(fTmpBuf, "%u\n", pluginId); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%i\n", value1); | std::sprintf(fTmpBuf, "%i\n", value1); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%i\n", value2); | std::sprintf(fTmpBuf, "%i\n", value2); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%f\n", value3); | std::sprintf(fTmpBuf, "%f\n", value3); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeAndFixMsg(valueStr != nullptr ? valueStr : ""); | |||||
| fUiServer.writeAndFixMessage(valueStr != nullptr ? valueStr : ""); | |||||
| fUiServer.flush(); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| void uiServerInfo() | void uiServerInfo() | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fIsRunning,); | CARLA_SAFE_ASSERT_RETURN(fIsRunning,); | ||||
| CARLA_SAFE_ASSERT_RETURN(fUiServer.isRunning(),); | |||||
| CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),); | |||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| fUiServer.writeAndFixMsg("complete-license"); | |||||
| fUiServer.writeAndFixMsg(carla_get_complete_license_text()); | |||||
| fUiServer.writeAndFixMessage("complete-license"); | |||||
| fUiServer.writeAndFixMessage(carla_get_complete_license_text()); | |||||
| fUiServer.writeAndFixMsg("juce-version"); | |||||
| fUiServer.writeAndFixMsg(carla_get_juce_version()); | |||||
| fUiServer.writeAndFixMessage("juce-version"); | |||||
| fUiServer.writeAndFixMessage(carla_get_juce_version()); | |||||
| fUiServer.writeAndFixMsg("file-exts"); | |||||
| fUiServer.writeAndFixMsg(carla_get_supported_file_extensions()); | |||||
| fUiServer.writeAndFixMessage("file-exts"); | |||||
| fUiServer.writeAndFixMessage(carla_get_supported_file_extensions()); | |||||
| fUiServer.writeAndFixMsg("max-plugin-number"); | |||||
| fUiServer.writeAndFixMessage("max-plugin-number"); | |||||
| std::sprintf(fTmpBuf, "%i\n", pData->maxPluginNumber); | std::sprintf(fTmpBuf, "%i\n", pData->maxPluginNumber); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeAndFixMsg("buffer-size"); | |||||
| fUiServer.writeAndFixMessage("buffer-size"); | |||||
| std::sprintf(fTmpBuf, "%i\n", pData->bufferSize); | std::sprintf(fTmpBuf, "%i\n", pData->bufferSize); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| const ScopedLocale csl; | const ScopedLocale csl; | ||||
| fUiServer.writeAndFixMsg("sample-rate"); | |||||
| fUiServer.writeAndFixMessage("sample-rate"); | |||||
| std::sprintf(fTmpBuf, "%f\n", pData->sampleRate); | std::sprintf(fTmpBuf, "%f\n", pData->sampleRate); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| void uiServerOptions() | void uiServerOptions() | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fIsRunning,); | CARLA_SAFE_ASSERT_RETURN(fIsRunning,); | ||||
| CARLA_SAFE_ASSERT_RETURN(fUiServer.isRunning(),); | |||||
| CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),); | |||||
| const EngineOptions& options(pData->options); | const EngineOptions& options(pData->options); | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| const char* const optionsForcedStr(fOptionsForced ? "true\n" : "false\n"); | const char* const optionsForcedStr(fOptionsForced ? "true\n" : "false\n"); | ||||
| const std::size_t optionsForcedStrSize(fOptionsForced ? 5 : 6); | const std::size_t optionsForcedStrSize(fOptionsForced ? 5 : 6); | ||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PROCESS_MODE); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PROCESS_MODE); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| std::sprintf(fTmpBuf, "%i\n", options.processMode); | std::sprintf(fTmpBuf, "%i\n", options.processMode); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_TRANSPORT_MODE); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_TRANSPORT_MODE); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| std::sprintf(fTmpBuf, "%i\n", options.transportMode); | std::sprintf(fTmpBuf, "%i\n", options.transportMode); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_FORCE_STEREO); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_FORCE_STEREO); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMsg(options.forceStereo ? "true\n" : "false\n"); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(options.forceStereo ? "true\n" : "false\n"); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_PLUGIN_BRIDGES); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_PLUGIN_BRIDGES); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMsg(options.preferPluginBridges ? "true\n" : "false\n"); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(options.preferPluginBridges ? "true\n" : "false\n"); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_UI_BRIDGES); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_UI_BRIDGES); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMsg(options.preferUiBridges ? "true\n" : "false\n"); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(options.preferUiBridges ? "true\n" : "false\n"); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UIS_ALWAYS_ON_TOP); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UIS_ALWAYS_ON_TOP); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMsg(options.uisAlwaysOnTop ? "true\n" : "false\n"); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(options.uisAlwaysOnTop ? "true\n" : "false\n"); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_MAX_PARAMETERS); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_MAX_PARAMETERS); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| std::sprintf(fTmpBuf, "%i\n", options.maxParameters); | std::sprintf(fTmpBuf, "%i\n", options.maxParameters); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UI_BRIDGES_TIMEOUT); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UI_BRIDGES_TIMEOUT); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||||
| std::sprintf(fTmpBuf, "%i\n", options.uiBridgesTimeout); | std::sprintf(fTmpBuf, "%i\n", options.uiBridgesTimeout); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_BINARIES); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_BINARIES); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg("true\n", 5); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage("true\n", 5); | |||||
| std::sprintf(fTmpBuf, "%s\n", options.binaryDir); | std::sprintf(fTmpBuf, "%s\n", options.binaryDir); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_RESOURCES); | std::sprintf(fTmpBuf, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_RESOURCES); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg("true\n", 5); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage("true\n", 5); | |||||
| std::sprintf(fTmpBuf, "%s\n", options.resourceDir); | std::sprintf(fTmpBuf, "%s\n", options.resourceDir); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -1413,10 +1420,9 @@ protected: | |||||
| { | { | ||||
| if (show) | if (show) | ||||
| { | { | ||||
| if (fUiServer.isRunning()) | |||||
| if (fUiServer.isPipeRunning()) | |||||
| { | { | ||||
| fUiServer.writeMsg("focus\n", 6); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeFocusMessage(); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -1432,13 +1438,13 @@ protected: | |||||
| carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer()); | carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer()); | ||||
| fUiServer.setData(path, pData->sampleRate, pHost->uiName); | fUiServer.setData(path, pData->sampleRate, pHost->uiName); | ||||
| fUiServer.start(false); | |||||
| fUiServer.startPipeServer(false); | |||||
| uiServerInfo(); | uiServerInfo(); | ||||
| uiServerOptions(); | uiServerOptions(); | ||||
| uiServerCallback(ENGINE_CALLBACK_ENGINE_STARTED, 0, pData->options.processMode, pData->options.transportMode, 0.0f, "Plugin"); | uiServerCallback(ENGINE_CALLBACK_ENGINE_STARTED, 0, pData->options.processMode, pData->options.transportMode, 0.0f, "Plugin"); | ||||
| fUiServer.show(); | |||||
| fUiServer.writeShowMessage(); | |||||
| for (uint i=0; i < pData->curPluginCount; ++i) | for (uint i=0; i < pData->curPluginCount; ++i) | ||||
| { | { | ||||
| @@ -1455,41 +1461,41 @@ protected: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| fUiServer.stop(5000); | |||||
| fUiServer.stopPipeServer(5000); | |||||
| } | } | ||||
| } | } | ||||
| void uiIdle() | void uiIdle() | ||||
| { | { | ||||
| CarlaEngine::idle(); | CarlaEngine::idle(); | ||||
| fUiServer.idle(); | |||||
| fUiServer.idlePipe(); | |||||
| if (fUiServer.isRunning()) | |||||
| if (fUiServer.isPipeRunning()) | |||||
| { | { | ||||
| const EngineTimeInfo& timeInfo(pData->timeInfo); | const EngineTimeInfo& timeInfo(pData->timeInfo); | ||||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||||
| const ScopedLocale csl; | const ScopedLocale csl; | ||||
| #ifndef CARLA_OS_WIN // FIXME | #ifndef CARLA_OS_WIN // FIXME | ||||
| // send transport | // send transport | ||||
| fUiServer.writeAndFixMsg("transport"); | |||||
| fUiServer.writeMsg(timeInfo.playing ? "true\n" : "false\n"); | |||||
| fUiServer.writeAndFixMessage("transport"); | |||||
| fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"); | |||||
| if (timeInfo.valid & EngineTimeInfo::kValidBBT) | if (timeInfo.valid & EngineTimeInfo::kValidBBT) | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, P_UINT64 ":%i:%i:%i\n", timeInfo.frame, timeInfo.bbt.bar, timeInfo.bbt.beat, timeInfo.bbt.tick); | std::sprintf(fTmpBuf, P_UINT64 ":%i:%i:%i\n", timeInfo.frame, timeInfo.bbt.bar, timeInfo.bbt.beat, timeInfo.bbt.tick); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%f\n", timeInfo.bbt.beatsPerMinute); | std::sprintf(fTmpBuf, "%f\n", timeInfo.bbt.beatsPerMinute); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| std::sprintf(fTmpBuf, P_UINT64 ":0:0:0\n", timeInfo.frame); | std::sprintf(fTmpBuf, P_UINT64 ":0:0:0\n", timeInfo.frame); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMsg("0.0\n"); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.writeMessage("0.0\n"); | |||||
| } | } | ||||
| fUiServer.flush(); | |||||
| fUiServer.flushMessages(); | |||||
| #endif | #endif | ||||
| // send peaks and param outputs for all plugins | // send peaks and param outputs for all plugins | ||||
| @@ -1499,11 +1505,11 @@ protected: | |||||
| const CarlaPlugin* const plugin(pData->plugins[i].plugin); | const CarlaPlugin* const plugin(pData->plugins[i].plugin); | ||||
| std::sprintf(fTmpBuf, "PEAKS_%i\n", i); | std::sprintf(fTmpBuf, "PEAKS_%i\n", i); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%f:%f:%f:%f\n", plugData.insPeak[0], plugData.insPeak[1], plugData.outsPeak[0], plugData.outsPeak[1]); | std::sprintf(fTmpBuf, "%f:%f:%f:%f\n", plugData.insPeak[0], plugData.insPeak[1], plugData.outsPeak[0], plugData.outsPeak[1]); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| for (uint32_t j=0, count=plugin->getParameterCount(); j < count; ++j) | for (uint32_t j=0, count=plugin->getParameterCount(); j < count; ++j) | ||||
| { | { | ||||
| @@ -1511,10 +1517,10 @@ protected: | |||||
| continue; | continue; | ||||
| std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", i, j); | std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", i, j); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(j)); | std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(j)); | ||||
| fUiServer.writeMsg(fTmpBuf); | |||||
| fUiServer.flush(); | |||||
| fUiServer.writeMessage(fTmpBuf); | |||||
| fUiServer.flushMessages(); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -1529,7 +1535,7 @@ protected: | |||||
| break; | break; | ||||
| case CarlaExternalUI::UiHide: | case CarlaExternalUI::UiHide: | ||||
| pHost->ui_closed(pHost->handle); | pHost->ui_closed(pHost->handle); | ||||
| fUiServer.stop(2000); | |||||
| fUiServer.stopPipeServer(2000); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1546,6 +1552,15 @@ protected: | |||||
| void setState(const char* const data) | void setState(const char* const data) | ||||
| { | { | ||||
| // remove all plugins first, no lock | |||||
| fIsRunning = false; | |||||
| removeAllPlugins(); | |||||
| fIsRunning = true; | |||||
| // stopped during removeAllPlugins() | |||||
| if (! pData->thread.isThreadRunning()) | |||||
| pData->thread.startThread(); | |||||
| fOptionsForced = true; | fOptionsForced = true; | ||||
| const String state(data); | const String state(data); | ||||
| XmlDocument xml(state); | XmlDocument xml(state); | ||||
| @@ -82,6 +82,7 @@ $(OBJDIR)/%.cpp.o: %.cpp | |||||
| @echo "Compiling $<" | @echo "Compiling $<" | ||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -MMD -c -o $@ | @$(CXX) $< $(BUILD_CXX_FLAGS) -MMD -c -o $@ | ||||
| -include $(OBJS:%.o=%.d) | |||||
| -include $(OBJSa:%.o=%.d) | |||||
| -include $(OBJDIR)/CarlaEngineNative.cpp.exp.d | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -2030,7 +2030,7 @@ def initHost(initName, libPrefixOrPluginClass, isControl, isPlugin, failError): | |||||
| gCarla.utils = CarlaUtils(os.path.join(pathBinaries, utilsname)) | gCarla.utils = CarlaUtils(os.path.join(pathBinaries, utilsname)) | ||||
| gCarla.utils.set_process_name(initName) | gCarla.utils.set_process_name(initName) | ||||
| gCarla.utils.set_locale_C() | |||||
| #gCarla.utils.set_locale_C() | |||||
| # -------------------------------------------------------------------------------------------------------- | # -------------------------------------------------------------------------------------------------------- | ||||
| # Done | # Done | ||||
| @@ -105,6 +105,9 @@ class ExternalUI(object): | |||||
| def uiShow(self): | def uiShow(self): | ||||
| return | return | ||||
| def uiFocus(self): | |||||
| return | |||||
| def uiHide(self): | def uiHide(self): | ||||
| return | return | ||||
| @@ -149,6 +152,9 @@ class ExternalUI(object): | |||||
| elif msg == "show": | elif msg == "show": | ||||
| self.uiShow() | self.uiShow() | ||||
| elif msg == "focus": | |||||
| self.uiFocus() | |||||
| elif msg == "hide": | elif msg == "hide": | ||||
| self.uiHide() | self.uiHide() | ||||
| @@ -47,10 +47,10 @@ protected: | |||||
| { | { | ||||
| if (show) | if (show) | ||||
| { | { | ||||
| if (isRunning()) | |||||
| if (isPipeRunning()) | |||||
| { | { | ||||
| writeMsg("focus\n", 6); | |||||
| flush(); | |||||
| writeMessage("focus\n", 6); | |||||
| flushMessages(); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -58,17 +58,17 @@ protected: | |||||
| carla_stdout("Trying to start UI using \"%s\"", path.buffer()); | carla_stdout("Trying to start UI using \"%s\"", path.buffer()); | ||||
| CarlaExternalUI::setData(path, getSampleRate(), getUiName()); | CarlaExternalUI::setData(path, getSampleRate(), getUiName()); | ||||
| CarlaExternalUI::start(); | |||||
| CarlaExternalUI::startPipeServer(); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| CarlaExternalUI::stop(5000); | |||||
| CarlaExternalUI::stopPipeServer(5000); | |||||
| } | } | ||||
| } | } | ||||
| void uiIdle() override | void uiIdle() override | ||||
| { | { | ||||
| CarlaExternalUI::idle(); | |||||
| CarlaExternalUI::idlePipe(); | |||||
| switch (CarlaExternalUI::getAndResetUiState()) | switch (CarlaExternalUI::getAndResetUiState()) | ||||
| { | { | ||||
| @@ -80,7 +80,7 @@ protected: | |||||
| break; | break; | ||||
| case CarlaExternalUI::UiHide: | case CarlaExternalUI::UiHide: | ||||
| uiClosed(); | uiClosed(); | ||||
| CarlaExternalUI::stop(2000); | |||||
| CarlaExternalUI::stopPipeServer(2000); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -90,15 +90,22 @@ protected: | |||||
| CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),); | CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),); | ||||
| char tmpBuf[0xff+1]; | char tmpBuf[0xff+1]; | ||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getLock()); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| const ScopedLocale csl; | |||||
| writeMsg("control\n", 8); | |||||
| std::sprintf(tmpBuf, "%i\n", index); | |||||
| writeMsg(tmpBuf); | |||||
| std::sprintf(tmpBuf, "%f\n", value); | |||||
| writeMsg(tmpBuf); | |||||
| flush(); | |||||
| writeMessage("control\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%f\n", value); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | } | ||||
| void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) override | void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) override | ||||
| @@ -106,17 +113,24 @@ protected: | |||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | ||||
| char tmpBuf[0xff+1]; | char tmpBuf[0xff+1]; | ||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| const CarlaMutexLocker cml(getLock()); | |||||
| writeMessage("program\n", 8); | |||||
| writeMsg("program\n", 8); | |||||
| std::sprintf(tmpBuf, "%i\n", channel); | |||||
| writeMsg(tmpBuf); | |||||
| std::sprintf(tmpBuf, "%i\n", bank); | |||||
| writeMsg(tmpBuf); | |||||
| std::sprintf(tmpBuf, "%i\n", program); | |||||
| writeMsg(tmpBuf); | |||||
| flush(); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", channel); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", bank); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", program); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | } | ||||
| void uiSetCustomData(const char* const key, const char* const value) override | void uiSetCustomData(const char* const key, const char* const value) override | ||||
| @@ -124,12 +138,14 @@ protected: | |||||
| CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); | CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); | ||||
| CARLA_SAFE_ASSERT_RETURN(value != nullptr,); | CARLA_SAFE_ASSERT_RETURN(value != nullptr,); | ||||
| const CarlaMutexLocker cml(getLock()); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("configure\n", 10); | |||||
| writeAndFixMessage(key); | |||||
| writeAndFixMessage(value); | |||||
| writeMsg("configure\n", 10); | |||||
| writeAndFixMsg(key); | |||||
| writeAndFixMsg(value); | |||||
| flush(); | |||||
| flushMessages(); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -16,6 +16,19 @@ | |||||
| # | # | ||||
| # For a full copy of the GNU General Public License see the doc/GPL.txt file. | # For a full copy of the GNU General Public License see the doc/GPL.txt file. | ||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Imports (Config) | |||||
| from carla_config import * | |||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Imports (Global) | |||||
| if config_UseQt5: | |||||
| from PyQt5.QtCore import Qt | |||||
| else: | |||||
| from PyQt4.QtCore import Qt | |||||
| # ----------------------------------------------------------------------- | # ----------------------------------------------------------------------- | ||||
| # Imports (Custom) | # Imports (Custom) | ||||
| @@ -81,6 +94,13 @@ class DistrhoUIBigMeter(ExternalUI, DigitalPeakMeter): | |||||
| def uiShow(self): | def uiShow(self): | ||||
| self.show() | self.show() | ||||
| def uiFocus(self): | |||||
| self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) | |||||
| self.show() | |||||
| self.raise_() | |||||
| self.activateWindow() | |||||
| def uiHide(self): | def uiHide(self): | ||||
| self.hide() | self.hide() | ||||
| @@ -110,8 +130,8 @@ if __name__ == '__main__': | |||||
| pathBinaries, pathResources = getPaths() | pathBinaries, pathResources = getPaths() | ||||
| gCarla.utils = CarlaUtils(os.path.join(pathBinaries, "libcarla_utils." + DLL_EXTENSION)) | gCarla.utils = CarlaUtils(os.path.join(pathBinaries, "libcarla_utils." + DLL_EXTENSION)) | ||||
| gCarla.utils.set_locale_C() | |||||
| gCarla.utils.set_process_name("BigMeter") | gCarla.utils.set_process_name("BigMeter") | ||||
| #gCarla.utils.set_locale_C() | |||||
| app = CarlaApplication("BigMeter") | app = CarlaApplication("BigMeter") | ||||
| gui = DistrhoUIBigMeter() | gui = DistrhoUIBigMeter() | ||||
| @@ -91,12 +91,24 @@ class CarlaMiniW(ExternalUI, HostWindow): | |||||
| # ExternalUI Callbacks | # ExternalUI Callbacks | ||||
| def uiShow(self): | def uiShow(self): | ||||
| if self.parent() is None: | |||||
| self.show() | |||||
| if self.parent() is not None: | |||||
| return | |||||
| self.show() | |||||
| def uiFocus(self): | |||||
| if self.parent() is not None: | |||||
| return | |||||
| self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) | |||||
| self.show() | |||||
| self.raise_() | |||||
| self.activateWindow() | |||||
| def uiHide(self): | def uiHide(self): | ||||
| if self.parent() is None: | |||||
| self.hide() | |||||
| if self.parent() is not None: | |||||
| return | |||||
| self.hide() | |||||
| def uiQuit(self): | def uiQuit(self): | ||||
| self.closeExternalUI() | self.closeExternalUI() | ||||
| @@ -340,6 +352,9 @@ class CarlaMiniW(ExternalUI, HostWindow): | |||||
| self.fFirstInit = False | self.fFirstInit = False | ||||
| self.uiShow() | self.uiShow() | ||||
| elif msg == "focus": | |||||
| self.uiFocus() | |||||
| elif msg == "hide": | elif msg == "hide": | ||||
| self.uiHide() | self.uiHide() | ||||
| @@ -25,10 +25,10 @@ from carla_config import * | |||||
| # Imports (Global) | # Imports (Global) | ||||
| if config_UseQt5: | if config_UseQt5: | ||||
| from PyQt5.QtCore import pyqtSlot | |||||
| from PyQt5.QtCore import pyqtSlot, Qt | |||||
| from PyQt5.QtWidgets import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget | from PyQt5.QtWidgets import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget | ||||
| else: | else: | ||||
| from PyQt4.QtCore import pyqtSlot | |||||
| from PyQt4.QtCore import pyqtSlot, Qt | |||||
| from PyQt4.QtGui import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget | from PyQt4.QtGui import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget | ||||
| # ----------------------------------------------------------------------- | # ----------------------------------------------------------------------- | ||||
| @@ -196,6 +196,13 @@ class DistrhoUINotes(ExternalUI, QWidget): | |||||
| def uiShow(self): | def uiShow(self): | ||||
| self.show() | self.show() | ||||
| def uiFocus(self): | |||||
| self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) | |||||
| self.show() | |||||
| self.raise_() | |||||
| self.activateWindow() | |||||
| def uiHide(self): | def uiHide(self): | ||||
| self.hide() | self.hide() | ||||
| @@ -243,8 +250,8 @@ if __name__ == '__main__': | |||||
| pathBinaries, pathResources = getPaths() | pathBinaries, pathResources = getPaths() | ||||
| gCarla.utils = CarlaUtils(os.path.join(pathBinaries, "libcarla_utils." + DLL_EXTENSION)) | gCarla.utils = CarlaUtils(os.path.join(pathBinaries, "libcarla_utils." + DLL_EXTENSION)) | ||||
| gCarla.utils.set_locale_C() | |||||
| gCarla.utils.set_process_name("Notes") | gCarla.utils.set_process_name("Notes") | ||||
| #gCarla.utils.set_locale_C() | |||||
| app = CarlaApplication("Notes") | app = CarlaApplication("Notes") | ||||
| gui = DistrhoUINotes() | gui = DistrhoUINotes() | ||||
| @@ -59,16 +59,16 @@ public: | |||||
| fUiTitle = uiTitle; | fUiTitle = uiTitle; | ||||
| } | } | ||||
| void start(const bool show = true) noexcept | |||||
| void startPipeServer(const bool show = true) noexcept | |||||
| { | { | ||||
| CarlaPipeServer::start(fFilename, fSampleRate, fUiTitle); | |||||
| CarlaPipeServer::startPipeServer(fFilename, fSampleRate, fUiTitle); | |||||
| if (! show) | if (! show) | ||||
| return; | return; | ||||
| const CarlaMutexLocker cml(getLock()); | |||||
| writeMsg("show\n", 5); | |||||
| flush(); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("show\n", 5); | |||||
| flushMessages(); | |||||
| } | } | ||||
| protected: | protected: | ||||
| @@ -77,7 +77,7 @@ protected: | |||||
| { | { | ||||
| if (std::strcmp(msg, "exiting") == 0) | if (std::strcmp(msg, "exiting") == 0) | ||||
| { | { | ||||
| close(); | |||||
| closePipeServer(); | |||||
| fUiState = UiHide; | fUiState = UiHide; | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -470,13 +470,18 @@ CarlaPipeCommon::~CarlaPipeCommon() noexcept | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void CarlaPipeCommon::idle() noexcept | |||||
| bool CarlaPipeCommon::isPipeRunning() const noexcept | |||||
| { | |||||
| return (pData->pipeRecv != INVALID_PIPE_VALUE && pData->pipeSend != INVALID_PIPE_VALUE); | |||||
| } | |||||
| void CarlaPipeCommon::idlePipe() noexcept | |||||
| { | { | ||||
| const char* locale = nullptr; | const char* locale = nullptr; | ||||
| for (;;) | for (;;) | ||||
| { | { | ||||
| const char* const msg(readline()); | |||||
| const char* const msg(_readline()); | |||||
| if (msg == nullptr) | if (msg == nullptr) | ||||
| break; | break; | ||||
| @@ -505,29 +510,24 @@ void CarlaPipeCommon::idle() noexcept | |||||
| } | } | ||||
| } | } | ||||
| bool CarlaPipeCommon::isRunning() const noexcept | |||||
| { | |||||
| return (pData->pipeRecv != INVALID_PIPE_VALUE && pData->pipeSend != INVALID_PIPE_VALUE); | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void CarlaPipeCommon::lock() const noexcept | |||||
| void CarlaPipeCommon::lockPipe() const noexcept | |||||
| { | { | ||||
| pData->writeLock.lock(); | pData->writeLock.lock(); | ||||
| } | } | ||||
| bool CarlaPipeCommon::tryLock() const noexcept | |||||
| bool CarlaPipeCommon::tryLockPipe() const noexcept | |||||
| { | { | ||||
| return pData->writeLock.tryLock(); | return pData->writeLock.tryLock(); | ||||
| } | } | ||||
| void CarlaPipeCommon::unlock() const noexcept | |||||
| void CarlaPipeCommon::unlockPipe() const noexcept | |||||
| { | { | ||||
| pData->writeLock.unlock(); | pData->writeLock.unlock(); | ||||
| } | } | ||||
| CarlaMutex& CarlaPipeCommon::getLock() noexcept | |||||
| CarlaMutex& CarlaPipeCommon::getPipeLock() noexcept | |||||
| { | { | ||||
| return pData->writeLock; | return pData->writeLock; | ||||
| } | } | ||||
| @@ -538,7 +538,7 @@ bool CarlaPipeCommon::readNextLineAsBool(bool& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| value = (std::strcmp(msg, "true") == 0); | value = (std::strcmp(msg, "true") == 0); | ||||
| delete[] msg; | delete[] msg; | ||||
| @@ -552,7 +552,7 @@ bool CarlaPipeCommon::readNextLineAsInt(int32_t& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| value = std::atoi(msg); | value = std::atoi(msg); | ||||
| delete[] msg; | delete[] msg; | ||||
| @@ -566,7 +566,7 @@ bool CarlaPipeCommon::readNextLineAsUInt(uint32_t& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| int32_t tmp = std::atoi(msg); | int32_t tmp = std::atoi(msg); | ||||
| delete[] msg; | delete[] msg; | ||||
| @@ -585,7 +585,7 @@ bool CarlaPipeCommon::readNextLineAsLong(int64_t& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| value = std::atol(msg); | value = std::atol(msg); | ||||
| delete[] msg; | delete[] msg; | ||||
| @@ -599,7 +599,7 @@ bool CarlaPipeCommon::readNextLineAsULong(uint64_t& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| int64_t tmp = std::atol(msg); | int64_t tmp = std::atol(msg); | ||||
| delete[] msg; | delete[] msg; | ||||
| @@ -618,7 +618,7 @@ bool CarlaPipeCommon::readNextLineAsFloat(float& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| value = static_cast<float>(std::atof(msg)); | value = static_cast<float>(std::atof(msg)); | ||||
| delete[] msg; | delete[] msg; | ||||
| @@ -632,7 +632,7 @@ bool CarlaPipeCommon::readNextLineAsDouble(double& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| value = std::atof(msg); | value = std::atof(msg); | ||||
| delete[] msg; | delete[] msg; | ||||
| @@ -646,7 +646,7 @@ bool CarlaPipeCommon::readNextLineAsString(const char*& value) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | ||||
| if (const char* const msg = readlineblock()) | |||||
| if (const char* const msg = _readlineblock()) | |||||
| { | { | ||||
| value = msg; | value = msg; | ||||
| return true; | return true; | ||||
| @@ -658,7 +658,7 @@ bool CarlaPipeCommon::readNextLineAsString(const char*& value) noexcept | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // must be locked before calling | // must be locked before calling | ||||
| bool CarlaPipeCommon::writeMsg(const char* const msg) const noexcept | |||||
| bool CarlaPipeCommon::writeMessage(const char* const msg) const noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false); | CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false); | ||||
| @@ -666,19 +666,19 @@ bool CarlaPipeCommon::writeMsg(const char* const msg) const noexcept | |||||
| CARLA_SAFE_ASSERT_RETURN(size > 0, false); | CARLA_SAFE_ASSERT_RETURN(size > 0, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false); | CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false); | ||||
| return writeMsgBuffer(msg, size); | |||||
| return _writeMsgBuffer(msg, size); | |||||
| } | } | ||||
| bool CarlaPipeCommon::writeMsg(const char* const msg, std::size_t size) const noexcept | |||||
| bool CarlaPipeCommon::writeMessage(const char* const msg, std::size_t size) const noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false); | CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size > 0, false); | CARLA_SAFE_ASSERT_RETURN(size > 0, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false); | CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false); | ||||
| return writeMsgBuffer(msg, size); | |||||
| return _writeMsgBuffer(msg, size); | |||||
| } | } | ||||
| bool CarlaPipeCommon::writeAndFixMsg(const char* const msg) const noexcept | |||||
| bool CarlaPipeCommon::writeAndFixMessage(const char* const msg) const noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(msg != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(msg != nullptr, false); | ||||
| @@ -714,10 +714,10 @@ bool CarlaPipeCommon::writeAndFixMsg(const char* const msg) const noexcept | |||||
| fixedMsg[1] = '\0'; | fixedMsg[1] = '\0'; | ||||
| } | } | ||||
| return writeMsgBuffer(fixedMsg, size+1); | |||||
| return _writeMsgBuffer(fixedMsg, size+1); | |||||
| } | } | ||||
| bool CarlaPipeCommon::flush() const noexcept | |||||
| bool CarlaPipeCommon::flushMessages() const noexcept | |||||
| { | { | ||||
| // TESTING remove later (replace with trylock scope) | // TESTING remove later (replace with trylock scope) | ||||
| if (pData->writeLock.tryLock()) | if (pData->writeLock.tryLock()) | ||||
| @@ -741,7 +741,7 @@ bool CarlaPipeCommon::flush() const noexcept | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // internal | // internal | ||||
| const char* CarlaPipeCommon::readline() noexcept | |||||
| const char* CarlaPipeCommon::_readline() noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv != INVALID_PIPE_VALUE, nullptr); | CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv != INVALID_PIPE_VALUE, nullptr); | ||||
| @@ -797,13 +797,13 @@ const char* CarlaPipeCommon::readline() noexcept | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| const char* CarlaPipeCommon::readlineblock(const uint32_t timeOutMilliseconds) noexcept | |||||
| const char* CarlaPipeCommon::_readlineblock(const uint32_t timeOutMilliseconds) noexcept | |||||
| { | { | ||||
| const uint32_t timeoutEnd(juce::Time::getMillisecondCounter() + timeOutMilliseconds); | const uint32_t timeoutEnd(juce::Time::getMillisecondCounter() + timeOutMilliseconds); | ||||
| for (;;) | for (;;) | ||||
| { | { | ||||
| if (const char* const msg = readline()) | |||||
| if (const char* const msg = _readline()) | |||||
| return msg; | return msg; | ||||
| if (juce::Time::getMillisecondCounter() >= timeoutEnd) | if (juce::Time::getMillisecondCounter() >= timeoutEnd) | ||||
| @@ -816,7 +816,7 @@ const char* CarlaPipeCommon::readlineblock(const uint32_t timeOutMilliseconds) n | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| bool CarlaPipeCommon::writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept | |||||
| bool CarlaPipeCommon::_writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept | |||||
| { | { | ||||
| // TESTING remove later (replace with trylock scope) | // TESTING remove later (replace with trylock scope) | ||||
| if (pData->writeLock.tryLock()) | if (pData->writeLock.tryLock()) | ||||
| @@ -854,12 +854,12 @@ CarlaPipeServer::~CarlaPipeServer() noexcept | |||||
| { | { | ||||
| carla_debug("CarlaPipeServer::~CarlaPipeServer()"); | carla_debug("CarlaPipeServer::~CarlaPipeServer()"); | ||||
| stop(5*1000); | |||||
| stopPipeServer(5*1000); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| bool CarlaPipeServer::start(const char* const filename, const char* const arg1, const char* const arg2) noexcept | |||||
| bool CarlaPipeServer::startPipeServer(const char* const filename, const char* const arg1, const char* const arg2) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false); | CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false); | CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false); | ||||
| @@ -872,7 +872,7 @@ bool CarlaPipeServer::start(const char* const filename, const char* const arg1, | |||||
| CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false); | CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false); | ||||
| CARLA_SAFE_ASSERT_RETURN(arg1 != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(arg1 != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(arg2 != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(arg2 != nullptr, false); | ||||
| carla_debug("CarlaPipeServer::start(\"%s\", \"%s\", \"%s\")", filename, arg1, arg2); | |||||
| carla_debug("CarlaPipeServer::startPipeServer(\"%s\", \"%s\", \"%s\")", filename, arg1, arg2); | |||||
| const CarlaMutexLocker cml(pData->writeLock); | const CarlaMutexLocker cml(pData->writeLock); | ||||
| @@ -1108,9 +1108,9 @@ bool CarlaPipeServer::start(const char* const filename, const char* const arg1, | |||||
| return false; | return false; | ||||
| } | } | ||||
| void CarlaPipeServer::stop(const uint32_t timeOutMilliseconds) noexcept | |||||
| void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcept | |||||
| { | { | ||||
| carla_debug("CarlaPipeServer::stop(%i)", timeOutMilliseconds); | |||||
| carla_debug("CarlaPipeServer::stopPipeServer(%i)", timeOutMilliseconds); | |||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| if (pData->processInfo.hProcess != INVALID_HANDLE_VALUE) | if (pData->processInfo.hProcess != INVALID_HANDLE_VALUE) | ||||
| @@ -1118,7 +1118,7 @@ void CarlaPipeServer::stop(const uint32_t timeOutMilliseconds) noexcept | |||||
| const CarlaMutexLocker cml(pData->writeLock); | const CarlaMutexLocker cml(pData->writeLock); | ||||
| if (pData->pipeSend != INVALID_PIPE_VALUE) | if (pData->pipeSend != INVALID_PIPE_VALUE) | ||||
| writeMsgBuffer("quit\n", 5); | |||||
| _writeMsgBuffer("quit\n", 5); | |||||
| waitForProcessToStopOrKillIt(pData->processInfo, timeOutMilliseconds); | waitForProcessToStopOrKillIt(pData->processInfo, timeOutMilliseconds); | ||||
| try { CloseHandle(pData->processInfo.hThread); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->processInfo.hThread)"); | try { CloseHandle(pData->processInfo.hThread); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->processInfo.hThread)"); | ||||
| @@ -1131,19 +1131,19 @@ void CarlaPipeServer::stop(const uint32_t timeOutMilliseconds) noexcept | |||||
| const CarlaMutexLocker cml(pData->writeLock); | const CarlaMutexLocker cml(pData->writeLock); | ||||
| if (pData->pipeSend != INVALID_PIPE_VALUE) | if (pData->pipeSend != INVALID_PIPE_VALUE) | ||||
| writeMsgBuffer("quit\n", 5); | |||||
| _writeMsgBuffer("quit\n", 5); | |||||
| waitForChildToStopOrKillIt(pData->pid, timeOutMilliseconds); | waitForChildToStopOrKillIt(pData->pid, timeOutMilliseconds); | ||||
| pData->pid = -1; | pData->pid = -1; | ||||
| } | } | ||||
| #endif | #endif | ||||
| close(); | |||||
| closePipeServer(); | |||||
| } | } | ||||
| void CarlaPipeServer::close() noexcept | |||||
| void CarlaPipeServer::closePipeServer() noexcept | |||||
| { | { | ||||
| carla_debug("CarlaPipeServer::close()"); | |||||
| carla_debug("CarlaPipeServer::closePipeServer()"); | |||||
| const CarlaMutexLocker cml(pData->writeLock); | const CarlaMutexLocker cml(pData->writeLock); | ||||
| @@ -1181,13 +1181,14 @@ CarlaPipeClient::~CarlaPipeClient() noexcept | |||||
| { | { | ||||
| carla_debug("CarlaPipeClient::~CarlaPipeClient()"); | carla_debug("CarlaPipeClient::~CarlaPipeClient()"); | ||||
| close(); | |||||
| closePipeClient(); | |||||
| } | } | ||||
| bool CarlaPipeClient::init(const char* argv[]) noexcept | |||||
| bool CarlaPipeClient::initPipeClient(const char* argv[]) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false); | CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false); | CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false); | ||||
| carla_debug("CarlaPipeClient::initPipeClient(%p)", argv); | |||||
| const CarlaMutexLocker cml(pData->writeLock); | const CarlaMutexLocker cml(pData->writeLock); | ||||
| @@ -1248,15 +1249,15 @@ bool CarlaPipeClient::init(const char* argv[]) noexcept | |||||
| pData->pipeRecv = pipeRecvServer; | pData->pipeRecv = pipeRecvServer; | ||||
| pData->pipeSend = pipeSendServer; | pData->pipeSend = pipeSendServer; | ||||
| writeMsg("\n"); | |||||
| flush(); | |||||
| writeMessage("\n", 1); | |||||
| flushMessages(); | |||||
| return true; | return true; | ||||
| } | } | ||||
| void CarlaPipeClient::close() noexcept | |||||
| void CarlaPipeClient::closePipeClient() noexcept | |||||
| { | { | ||||
| carla_debug("CarlaPipeClient::close()"); | |||||
| carla_debug("CarlaPipeClient::closePipeClient()"); | |||||
| const CarlaMutexLocker cml(pData->writeLock); | const CarlaMutexLocker cml(pData->writeLock); | ||||
| @@ -22,53 +22,141 @@ | |||||
| #include "CarlaMutex.hpp" | #include "CarlaMutex.hpp" | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // CarlaPipeCommon class | |||||
| class CarlaPipeCommon | class CarlaPipeCommon | ||||
| { | { | ||||
| protected: | protected: | ||||
| /*! | |||||
| * Constructor. | |||||
| */ | |||||
| CarlaPipeCommon() noexcept; | CarlaPipeCommon() noexcept; | ||||
| /*! | |||||
| * Destructor. | |||||
| */ | |||||
| virtual ~CarlaPipeCommon() noexcept; | virtual ~CarlaPipeCommon() noexcept; | ||||
| // returns true if msg handled | |||||
| /*! | |||||
| * A message has been received (in the context of idlePipe()). | |||||
| * If extra data is required, use any of the readNextLineAs* functions. | |||||
| * Returning true means the message has been handled and should not propagate to subclasses. | |||||
| */ | |||||
| virtual bool msgReceived(const char* const msg) noexcept = 0; | virtual bool msgReceived(const char* const msg) noexcept = 0; | ||||
| // to possibly send errors somewhere | |||||
| /*! | |||||
| * An error has occurred during the current requested operation. | |||||
| * Reimplementing this method allows to catch these errors as strings. | |||||
| * By default the error is simply printed to stderr. | |||||
| */ | |||||
| virtual void fail(const char* const error) noexcept | virtual void fail(const char* const error) noexcept | ||||
| { | { | ||||
| carla_stderr2(error); | carla_stderr2(error); | ||||
| } | } | ||||
| public: | public: | ||||
| void idle() noexcept; | |||||
| bool isRunning() const noexcept; | |||||
| /*! | |||||
| * Check if the pipe is running. | |||||
| */ | |||||
| bool isPipeRunning() const noexcept; | |||||
| /*! | |||||
| * Check the pipe for new messages and send them to msgReceived(). | |||||
| */ | |||||
| void idlePipe() noexcept; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // write lock | // write lock | ||||
| void lock() const noexcept; | |||||
| bool tryLock() const noexcept; | |||||
| void unlock() const noexcept; | |||||
| /*! | |||||
| * Lock the pipe write mutex. | |||||
| */ | |||||
| void lockPipe() const noexcept; | |||||
| /*! | |||||
| * Try locking the pipe write mutex. | |||||
| * Returns true if successful. | |||||
| */ | |||||
| bool tryLockPipe() const noexcept; | |||||
| CarlaMutex& getLock() noexcept; | |||||
| /*! | |||||
| * Unlock the pipe write mutex. | |||||
| */ | |||||
| void unlockPipe() const noexcept; | |||||
| /*! | |||||
| * Get the pipe write lock. | |||||
| */ | |||||
| CarlaMutex& getPipeLock() noexcept; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // read lines, must only be called in the context of msgReceived() | |||||
| /*! | |||||
| * Read the next line as a boolean. | |||||
| */ | |||||
| bool readNextLineAsBool(bool& value) noexcept; | bool readNextLineAsBool(bool& value) noexcept; | ||||
| /*! | |||||
| * Read the next line as an integer. | |||||
| */ | |||||
| bool readNextLineAsInt(int32_t& value) noexcept; | bool readNextLineAsInt(int32_t& value) noexcept; | ||||
| /*! | |||||
| * Read the next line as an unsigned integer. | |||||
| */ | |||||
| bool readNextLineAsUInt(uint32_t& value) noexcept; | bool readNextLineAsUInt(uint32_t& value) noexcept; | ||||
| /*! | |||||
| * Read the next line as a long integer. | |||||
| */ | |||||
| bool readNextLineAsLong(int64_t& value) noexcept; | bool readNextLineAsLong(int64_t& value) noexcept; | ||||
| /*! | |||||
| * Read the next line as a long unsigned integer. | |||||
| */ | |||||
| bool readNextLineAsULong(uint64_t& value) noexcept; | bool readNextLineAsULong(uint64_t& value) noexcept; | ||||
| /*! | |||||
| * Read the next line as a floating point number (single precision). | |||||
| */ | |||||
| bool readNextLineAsFloat(float& value) noexcept; | bool readNextLineAsFloat(float& value) noexcept; | ||||
| /*! | |||||
| * Read the next line as a floating point number (double precision). | |||||
| */ | |||||
| bool readNextLineAsDouble(double& value) noexcept; | bool readNextLineAsDouble(double& value) noexcept; | ||||
| /*! | |||||
| * Read the next line as a string. | |||||
| * @note: @a value must be deleted if valid. | |||||
| */ | |||||
| bool readNextLineAsString(const char*& value) noexcept; | bool readNextLineAsString(const char*& value) noexcept; | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // must be locked before calling | |||||
| bool writeMsg(const char* const msg) const noexcept; | |||||
| bool writeMsg(const char* const msg, std::size_t size) const noexcept; | |||||
| bool writeAndFixMsg(const char* const msg) const noexcept; | |||||
| bool flush() const noexcept; | |||||
| // write messages, must be locked before calling | |||||
| /*! | |||||
| * Write a valid message with unknown size. | |||||
| * A valid message has only one '\n' character and it's at the end. | |||||
| */ | |||||
| bool writeMessage(const char* const msg) const noexcept; | |||||
| /*! | |||||
| * Write a valid message with known size. | |||||
| * A valid message has only one '\n' character and it's at the end. | |||||
| */ | |||||
| bool writeMessage(const char* const msg, std::size_t size) const noexcept; | |||||
| /*! | |||||
| * Write and fix a message. | |||||
| */ | |||||
| bool writeAndFixMessage(const char* const msg) const noexcept; | |||||
| /*! | |||||
| * Flush all messages currently in cache. | |||||
| */ | |||||
| bool flushMessages() const noexcept; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -78,44 +166,86 @@ protected: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // internal | |||||
| const char* readline() noexcept; | |||||
| const char* readlineblock(const uint32_t timeOutMilliseconds = 50) noexcept; | |||||
| bool writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept; | |||||
| /*! @internal */ | |||||
| const char* _readline() noexcept; | |||||
| /*! @internal */ | |||||
| const char* _readlineblock(const uint32_t timeOutMilliseconds = 50) noexcept; | |||||
| /*! @internal */ | |||||
| bool _writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept; | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon) | CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon) | ||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // CarlaPipeServer class | |||||
| class CarlaPipeServer : public CarlaPipeCommon | class CarlaPipeServer : public CarlaPipeCommon | ||||
| { | { | ||||
| public: | public: | ||||
| /*! | |||||
| * Constructor. | |||||
| */ | |||||
| CarlaPipeServer() noexcept; | CarlaPipeServer() noexcept; | ||||
| /*! | |||||
| * Destructor. | |||||
| */ | |||||
| ~CarlaPipeServer() noexcept override; | ~CarlaPipeServer() noexcept override; | ||||
| bool start(const char* const filename, const char* const arg1, const char* const arg2) noexcept; | |||||
| void stop(const uint32_t timeOutMilliseconds) noexcept; | |||||
| void close() noexcept; | |||||
| /*! | |||||
| * Start the pipe server using @a filename with 2 arguments. | |||||
| * @see fail() | |||||
| */ | |||||
| bool startPipeServer(const char* const filename, const char* const arg1, const char* const arg2) noexcept; | |||||
| /*! | |||||
| * Stop the pipe server. | |||||
| * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes. | |||||
| */ | |||||
| void stopPipeServer(const uint32_t timeOutMilliseconds) noexcept; | |||||
| /*! | |||||
| * Close the pipes without waiting for the child process to terminate. | |||||
| */ | |||||
| void closePipeServer() noexcept; | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer) | CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer) | ||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // CarlaPipeClient class | |||||
| class CarlaPipeClient : public CarlaPipeCommon | class CarlaPipeClient : public CarlaPipeCommon | ||||
| { | { | ||||
| public: | public: | ||||
| /*! | |||||
| * Constructor. | |||||
| */ | |||||
| CarlaPipeClient() noexcept; | CarlaPipeClient() noexcept; | ||||
| /*! | |||||
| * Destructor. | |||||
| */ | |||||
| ~CarlaPipeClient() noexcept override; | ~CarlaPipeClient() noexcept override; | ||||
| bool init(const char* argv[]) noexcept; | |||||
| void close() noexcept; | |||||
| /*! | |||||
| * Initialize the pipes used by a server. | |||||
| * @a argv must match the arguments set the by server. | |||||
| */ | |||||
| bool initPipeClient(const char* argv[]) noexcept; | |||||
| /*! | |||||
| * Close the pipes. | |||||
| */ | |||||
| void closePipeClient() noexcept; | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient) | CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient) | ||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // ScopedLocale class | |||||
| class ScopedLocale { | class ScopedLocale { | ||||
| public: | public: | ||||