| @@ -87,7 +87,7 @@ public: | |||
| const char* readlineblock(const uint timeout) noexcept | |||
| { | |||
| return CarlaPipeClient::readlineblock(timeout); | |||
| return CarlaPipeClient::_readlineblock(timeout); | |||
| } | |||
| 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)); | |||
| if (! pipe->init(argv)) | |||
| if (! pipe->initPipeClient(argv)) | |||
| { | |||
| delete pipe; | |||
| return nullptr; | |||
| @@ -128,28 +128,28 @@ void carla_pipe_client_idle(CarlaPipeClientHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||
| ((CarlaPipeClientPlugin*)handle)->idle(); | |||
| ((CarlaPipeClientPlugin*)handle)->idlePipe(); | |||
| } | |||
| bool carla_pipe_client_is_running(CarlaPipeClientHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||
| return ((CarlaPipeClientPlugin*)handle)->isRunning(); | |||
| return ((CarlaPipeClientPlugin*)handle)->isPipeRunning(); | |||
| } | |||
| void carla_pipe_client_lock(CarlaPipeClientHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||
| return ((CarlaPipeClientPlugin*)handle)->lock(); | |||
| return ((CarlaPipeClientPlugin*)handle)->lockPipe(); | |||
| } | |||
| void carla_pipe_client_unlock(CarlaPipeClientHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||
| return ((CarlaPipeClientPlugin*)handle)->unlock(); | |||
| return ((CarlaPipeClientPlugin*)handle)->unlockPipe(); | |||
| } | |||
| 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); | |||
| return ((CarlaPipeClientPlugin*)handle)->writeMsg(msg); | |||
| return ((CarlaPipeClientPlugin*)handle)->writeMessage(msg); | |||
| } | |||
| bool carla_pipe_client_write_and_fix_msg(CarlaPipeClientHandle handle, const char* msg) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||
| return ((CarlaPipeClientPlugin*)handle)->writeAndFixMsg(msg); | |||
| return ((CarlaPipeClientPlugin*)handle)->writeAndFixMessage(msg); | |||
| } | |||
| bool carla_pipe_client_flush(CarlaPipeClientHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false); | |||
| return ((CarlaPipeClientPlugin*)handle)->flush(); | |||
| return ((CarlaPipeClientPlugin*)handle)->flushMessages(); | |||
| } | |||
| 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); | |||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | |||
| const bool ret(pipe->flush()); | |||
| pipe->unlock(); | |||
| const bool ret(pipe->flushMessages()); | |||
| pipe->unlockPipe(); | |||
| return ret; | |||
| } | |||
| @@ -196,7 +196,7 @@ void carla_pipe_client_destroy(CarlaPipeClientHandle handle) | |||
| carla_debug("carla_pipe_client_destroy(%p)", handle); | |||
| CarlaPipeClientPlugin* const pipe((CarlaPipeClientPlugin*)handle); | |||
| pipe->close(); | |||
| pipe->closePipeClient(); | |||
| delete pipe; | |||
| } | |||
| @@ -73,11 +73,18 @@ public: | |||
| 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: | |||
| @@ -542,10 +549,10 @@ protected: | |||
| 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; | |||
| @@ -713,12 +720,12 @@ protected: | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flushMessages(); | |||
| } | |||
| pData->bufferSize = newBufferSize; | |||
| @@ -731,13 +738,13 @@ protected: | |||
| return; | |||
| { | |||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||
| const ScopedLocale csl; | |||
| fUiServer.writeAndFixMsg("sample-rate"); | |||
| fUiServer.writeAndFixMessage("sample-rate"); | |||
| std::sprintf(fTmpBuf, "%f\n", newSampleRate); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flushMessages(); | |||
| } | |||
| pData->sampleRate = newSampleRate; | |||
| @@ -748,64 +755,64 @@ protected: | |||
| void uiServerSendPluginInfo(CarlaPlugin* const plugin) | |||
| { | |||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||
| const uint pluginId(plugin->getId()); | |||
| 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()); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| if (const char* const filename = plugin->getFilename()) | |||
| { | |||
| std::sprintf(fTmpBuf, "%s", filename); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| } | |||
| else | |||
| fUiServer.writeMsg("\n"); | |||
| fUiServer.writeMessage("\n"); | |||
| if (const char* const name = plugin->getName()) | |||
| { | |||
| std::sprintf(fTmpBuf, "%s", name); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| } | |||
| else | |||
| fUiServer.writeMsg("\n"); | |||
| fUiServer.writeMessage("\n"); | |||
| if (const char* const iconName = plugin->getIconName()) | |||
| { | |||
| std::sprintf(fTmpBuf, "%s", iconName); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| } | |||
| else | |||
| fUiServer.writeMsg("\n"); | |||
| fUiServer.writeMessage("\n"); | |||
| plugin->getRealName(fTmpBuf); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| plugin->getLabel(fTmpBuf); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| plugin->getMaker(fTmpBuf); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| plugin->getCopyright(fTmpBuf); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| 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()); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.flushMessages(); | |||
| } | |||
| void uiServerSendPluginParameters(CarlaPlugin* const plugin) | |||
| { | |||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||
| const ScopedLocale csl; | |||
| const uint pluginId(plugin->getId()); | |||
| @@ -813,17 +820,17 @@ protected: | |||
| for (int32_t i=PARAMETER_ACTIVE; i>PARAMETER_MAX; --i) | |||
| { | |||
| std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| std::sprintf(fTmpBuf, "%f\n", plugin->getInternalParameterValue(i)); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flushMessages(); | |||
| } | |||
| uint32_t ins, outs, count; | |||
| plugin->getParameterCountInfo(ins, outs); | |||
| count = plugin->getParameterCount(); | |||
| 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) | |||
| { | |||
| @@ -831,72 +838,72 @@ protected: | |||
| const ParameterRanges& paramRanges(plugin->getParameterRanges(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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| plugin->getParameterName(i, fTmpBuf); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| plugin->getParameterUnit(i, fTmpBuf); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", pluginId, i); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(i)); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| } | |||
| fUiServer.flush(); | |||
| fUiServer.flushMessages(); | |||
| } | |||
| void uiServerSendPluginPrograms(CarlaPlugin* const plugin) | |||
| { | |||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||
| const uint pluginId(plugin->getId()); | |||
| uint32_t count = plugin->getProgramCount(); | |||
| 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) | |||
| { | |||
| std::sprintf(fTmpBuf, "PROGRAM_NAME_%i:%i\n", pluginId, i); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| plugin->getProgramName(i, fTmpBuf); | |||
| fUiServer.writeAndFixMsg(fTmpBuf); | |||
| fUiServer.writeAndFixMessage(fTmpBuf); | |||
| } | |||
| fUiServer.flush(); | |||
| fUiServer.flushMessages(); | |||
| count = plugin->getMidiProgramCount(); | |||
| 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) | |||
| { | |||
| std::sprintf(fTmpBuf, "MIDI_PROGRAM_DATA_%i:%i\n", pluginId, i); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| const MidiProgramData& mpData(plugin->getMidiProgramData(i)); | |||
| std::sprintf(fTmpBuf, "%i:%i\n", mpData.bank, mpData.program); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| 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) | |||
| { | |||
| if (! fIsRunning) | |||
| return; | |||
| if (! fUiServer.isRunning()) | |||
| if (! fUiServer.isPipeRunning()) | |||
| return; | |||
| CarlaPlugin* plugin; | |||
| @@ -950,138 +957,138 @@ protected: | |||
| break; | |||
| } | |||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||
| const ScopedLocale csl; | |||
| std::sprintf(fTmpBuf, "ENGINE_CALLBACK_%i\n", int(action)); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| std::sprintf(fTmpBuf, "%u\n", pluginId); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| std::sprintf(fTmpBuf, "%i\n", value1); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| std::sprintf(fTmpBuf, "%i\n", value2); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| 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() | |||
| { | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.writeAndFixMsg("buffer-size"); | |||
| fUiServer.writeAndFixMessage("buffer-size"); | |||
| std::sprintf(fTmpBuf, "%i\n", pData->bufferSize); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| const ScopedLocale csl; | |||
| fUiServer.writeAndFixMsg("sample-rate"); | |||
| fUiServer.writeAndFixMessage("sample-rate"); | |||
| std::sprintf(fTmpBuf, "%f\n", pData->sampleRate); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.flushMessages(); | |||
| } | |||
| void uiServerOptions() | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fIsRunning,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUiServer.isRunning(),); | |||
| CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),); | |||
| 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 std::size_t optionsForcedStrSize(fOptionsForced ? 5 : 6); | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flushMessages(); | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flushMessages(); | |||
| 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); | |||
| 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); | |||
| 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); | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMsg(optionsForcedStr, optionsForcedStrSize); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize); | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMsg("true\n", 5); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.writeMessage("true\n", 5); | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMsg("true\n", 5); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.writeMessage("true\n", 5); | |||
| 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 (fUiServer.isRunning()) | |||
| if (fUiServer.isPipeRunning()) | |||
| { | |||
| fUiServer.writeMsg("focus\n", 6); | |||
| fUiServer.flush(); | |||
| fUiServer.writeFocusMessage(); | |||
| return; | |||
| } | |||
| @@ -1432,13 +1438,13 @@ protected: | |||
| carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer()); | |||
| fUiServer.setData(path, pData->sampleRate, pHost->uiName); | |||
| fUiServer.start(false); | |||
| fUiServer.startPipeServer(false); | |||
| uiServerInfo(); | |||
| uiServerOptions(); | |||
| 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) | |||
| { | |||
| @@ -1455,41 +1461,41 @@ protected: | |||
| } | |||
| else | |||
| { | |||
| fUiServer.stop(5000); | |||
| fUiServer.stopPipeServer(5000); | |||
| } | |||
| } | |||
| void uiIdle() | |||
| { | |||
| CarlaEngine::idle(); | |||
| fUiServer.idle(); | |||
| fUiServer.idlePipe(); | |||
| if (fUiServer.isRunning()) | |||
| if (fUiServer.isPipeRunning()) | |||
| { | |||
| const EngineTimeInfo& timeInfo(pData->timeInfo); | |||
| const CarlaMutexLocker cml(fUiServer.getLock()); | |||
| const CarlaMutexLocker cml(fUiServer.getPipeLock()); | |||
| const ScopedLocale csl; | |||
| #ifndef CARLA_OS_WIN // FIXME | |||
| // 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) | |||
| { | |||
| 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); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| } | |||
| else | |||
| { | |||
| 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 | |||
| // send peaks and param outputs for all plugins | |||
| @@ -1499,11 +1505,11 @@ protected: | |||
| const CarlaPlugin* const plugin(pData->plugins[i].plugin); | |||
| 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]); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flushMessages(); | |||
| for (uint32_t j=0, count=plugin->getParameterCount(); j < count; ++j) | |||
| { | |||
| @@ -1511,10 +1517,10 @@ protected: | |||
| continue; | |||
| std::sprintf(fTmpBuf, "PARAMVAL_%i:%i\n", i, j); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| std::sprintf(fTmpBuf, "%f\n", plugin->getParameterValue(j)); | |||
| fUiServer.writeMsg(fTmpBuf); | |||
| fUiServer.flush(); | |||
| fUiServer.writeMessage(fTmpBuf); | |||
| fUiServer.flushMessages(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1529,7 +1535,7 @@ protected: | |||
| break; | |||
| case CarlaExternalUI::UiHide: | |||
| pHost->ui_closed(pHost->handle); | |||
| fUiServer.stop(2000); | |||
| fUiServer.stopPipeServer(2000); | |||
| break; | |||
| } | |||
| } | |||
| @@ -1546,6 +1552,15 @@ protected: | |||
| 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; | |||
| const String state(data); | |||
| XmlDocument xml(state); | |||
| @@ -82,6 +82,7 @@ $(OBJDIR)/%.cpp.o: %.cpp | |||
| @echo "Compiling $<" | |||
| @$(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.set_process_name(initName) | |||
| gCarla.utils.set_locale_C() | |||
| #gCarla.utils.set_locale_C() | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| # Done | |||
| @@ -105,6 +105,9 @@ class ExternalUI(object): | |||
| def uiShow(self): | |||
| return | |||
| def uiFocus(self): | |||
| return | |||
| def uiHide(self): | |||
| return | |||
| @@ -149,6 +152,9 @@ class ExternalUI(object): | |||
| elif msg == "show": | |||
| self.uiShow() | |||
| elif msg == "focus": | |||
| self.uiFocus() | |||
| elif msg == "hide": | |||
| self.uiHide() | |||
| @@ -47,10 +47,10 @@ protected: | |||
| { | |||
| if (show) | |||
| { | |||
| if (isRunning()) | |||
| if (isPipeRunning()) | |||
| { | |||
| writeMsg("focus\n", 6); | |||
| flush(); | |||
| writeMessage("focus\n", 6); | |||
| flushMessages(); | |||
| return; | |||
| } | |||
| @@ -58,17 +58,17 @@ protected: | |||
| carla_stdout("Trying to start UI using \"%s\"", path.buffer()); | |||
| CarlaExternalUI::setData(path, getSampleRate(), getUiName()); | |||
| CarlaExternalUI::start(); | |||
| CarlaExternalUI::startPipeServer(); | |||
| } | |||
| else | |||
| { | |||
| CarlaExternalUI::stop(5000); | |||
| CarlaExternalUI::stopPipeServer(5000); | |||
| } | |||
| } | |||
| void uiIdle() override | |||
| { | |||
| CarlaExternalUI::idle(); | |||
| CarlaExternalUI::idlePipe(); | |||
| switch (CarlaExternalUI::getAndResetUiState()) | |||
| { | |||
| @@ -80,7 +80,7 @@ protected: | |||
| break; | |||
| case CarlaExternalUI::UiHide: | |||
| uiClosed(); | |||
| CarlaExternalUI::stop(2000); | |||
| CarlaExternalUI::stopPipeServer(2000); | |||
| break; | |||
| } | |||
| } | |||
| @@ -90,15 +90,22 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),); | |||
| 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 | |||
| @@ -106,17 +113,24 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||
| 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 | |||
| @@ -124,12 +138,14 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); | |||
| 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. | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Imports (Config) | |||
| from carla_config import * | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Imports (Global) | |||
| if config_UseQt5: | |||
| from PyQt5.QtCore import Qt | |||
| else: | |||
| from PyQt4.QtCore import Qt | |||
| # ----------------------------------------------------------------------- | |||
| # Imports (Custom) | |||
| @@ -81,6 +94,13 @@ class DistrhoUIBigMeter(ExternalUI, DigitalPeakMeter): | |||
| def uiShow(self): | |||
| self.show() | |||
| def uiFocus(self): | |||
| self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) | |||
| self.show() | |||
| self.raise_() | |||
| self.activateWindow() | |||
| def uiHide(self): | |||
| self.hide() | |||
| @@ -110,8 +130,8 @@ if __name__ == '__main__': | |||
| pathBinaries, pathResources = getPaths() | |||
| 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_locale_C() | |||
| app = CarlaApplication("BigMeter") | |||
| gui = DistrhoUIBigMeter() | |||
| @@ -91,12 +91,24 @@ class CarlaMiniW(ExternalUI, HostWindow): | |||
| # ExternalUI Callbacks | |||
| 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): | |||
| if self.parent() is None: | |||
| self.hide() | |||
| if self.parent() is not None: | |||
| return | |||
| self.hide() | |||
| def uiQuit(self): | |||
| self.closeExternalUI() | |||
| @@ -340,6 +352,9 @@ class CarlaMiniW(ExternalUI, HostWindow): | |||
| self.fFirstInit = False | |||
| self.uiShow() | |||
| elif msg == "focus": | |||
| self.uiFocus() | |||
| elif msg == "hide": | |||
| self.uiHide() | |||
| @@ -25,10 +25,10 @@ from carla_config import * | |||
| # Imports (Global) | |||
| if config_UseQt5: | |||
| from PyQt5.QtCore import pyqtSlot | |||
| from PyQt5.QtCore import pyqtSlot, Qt | |||
| from PyQt5.QtWidgets import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget | |||
| else: | |||
| from PyQt4.QtCore import pyqtSlot | |||
| from PyQt4.QtCore import pyqtSlot, Qt | |||
| from PyQt4.QtGui import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget | |||
| # ----------------------------------------------------------------------- | |||
| @@ -196,6 +196,13 @@ class DistrhoUINotes(ExternalUI, QWidget): | |||
| def uiShow(self): | |||
| self.show() | |||
| def uiFocus(self): | |||
| self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive) | |||
| self.show() | |||
| self.raise_() | |||
| self.activateWindow() | |||
| def uiHide(self): | |||
| self.hide() | |||
| @@ -243,8 +250,8 @@ if __name__ == '__main__': | |||
| pathBinaries, pathResources = getPaths() | |||
| 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_locale_C() | |||
| app = CarlaApplication("Notes") | |||
| gui = DistrhoUINotes() | |||
| @@ -59,16 +59,16 @@ public: | |||
| 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) | |||
| return; | |||
| const CarlaMutexLocker cml(getLock()); | |||
| writeMsg("show\n", 5); | |||
| flush(); | |||
| const CarlaMutexLocker cml(getPipeLock()); | |||
| writeMessage("show\n", 5); | |||
| flushMessages(); | |||
| } | |||
| protected: | |||
| @@ -77,7 +77,7 @@ protected: | |||
| { | |||
| if (std::strcmp(msg, "exiting") == 0) | |||
| { | |||
| close(); | |||
| closePipeServer(); | |||
| fUiState = UiHide; | |||
| 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; | |||
| for (;;) | |||
| { | |||
| const char* const msg(readline()); | |||
| const char* const msg(_readline()); | |||
| if (msg == nullptr) | |||
| 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(); | |||
| } | |||
| bool CarlaPipeCommon::tryLock() const noexcept | |||
| bool CarlaPipeCommon::tryLockPipe() const noexcept | |||
| { | |||
| return pData->writeLock.tryLock(); | |||
| } | |||
| void CarlaPipeCommon::unlock() const noexcept | |||
| void CarlaPipeCommon::unlockPipe() const noexcept | |||
| { | |||
| pData->writeLock.unlock(); | |||
| } | |||
| CarlaMutex& CarlaPipeCommon::getLock() noexcept | |||
| CarlaMutex& CarlaPipeCommon::getPipeLock() noexcept | |||
| { | |||
| return pData->writeLock; | |||
| } | |||
| @@ -538,7 +538,7 @@ bool CarlaPipeCommon::readNextLineAsBool(bool& value) noexcept | |||
| { | |||
| 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); | |||
| delete[] msg; | |||
| @@ -552,7 +552,7 @@ bool CarlaPipeCommon::readNextLineAsInt(int32_t& value) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | |||
| if (const char* const msg = readlineblock()) | |||
| if (const char* const msg = _readlineblock()) | |||
| { | |||
| value = std::atoi(msg); | |||
| delete[] msg; | |||
| @@ -566,7 +566,7 @@ bool CarlaPipeCommon::readNextLineAsUInt(uint32_t& value) noexcept | |||
| { | |||
| 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); | |||
| delete[] msg; | |||
| @@ -585,7 +585,7 @@ bool CarlaPipeCommon::readNextLineAsLong(int64_t& value) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | |||
| if (const char* const msg = readlineblock()) | |||
| if (const char* const msg = _readlineblock()) | |||
| { | |||
| value = std::atol(msg); | |||
| delete[] msg; | |||
| @@ -599,7 +599,7 @@ bool CarlaPipeCommon::readNextLineAsULong(uint64_t& value) noexcept | |||
| { | |||
| 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); | |||
| delete[] msg; | |||
| @@ -618,7 +618,7 @@ bool CarlaPipeCommon::readNextLineAsFloat(float& value) noexcept | |||
| { | |||
| 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)); | |||
| delete[] msg; | |||
| @@ -632,7 +632,7 @@ bool CarlaPipeCommon::readNextLineAsDouble(double& value) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | |||
| if (const char* const msg = readlineblock()) | |||
| if (const char* const msg = _readlineblock()) | |||
| { | |||
| value = std::atof(msg); | |||
| delete[] msg; | |||
| @@ -646,7 +646,7 @@ bool CarlaPipeCommon::readNextLineAsString(const char*& value) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->isReading, false); | |||
| if (const char* const msg = readlineblock()) | |||
| if (const char* const msg = _readlineblock()) | |||
| { | |||
| value = msg; | |||
| return true; | |||
| @@ -658,7 +658,7 @@ bool CarlaPipeCommon::readNextLineAsString(const char*& value) noexcept | |||
| // ------------------------------------------------------------------- | |||
| // 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); | |||
| @@ -666,19 +666,19 @@ bool CarlaPipeCommon::writeMsg(const char* const msg) const noexcept | |||
| CARLA_SAFE_ASSERT_RETURN(size > 0, 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(size > 0, 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); | |||
| @@ -714,10 +714,10 @@ bool CarlaPipeCommon::writeAndFixMsg(const char* const msg) const noexcept | |||
| 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) | |||
| if (pData->writeLock.tryLock()) | |||
| @@ -741,7 +741,7 @@ bool CarlaPipeCommon::flush() const noexcept | |||
| // ------------------------------------------------------------------- | |||
| // internal | |||
| const char* CarlaPipeCommon::readline() noexcept | |||
| const char* CarlaPipeCommon::_readline() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv != INVALID_PIPE_VALUE, nullptr); | |||
| @@ -797,13 +797,13 @@ const char* CarlaPipeCommon::readline() noexcept | |||
| 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); | |||
| for (;;) | |||
| { | |||
| if (const char* const msg = readline()) | |||
| if (const char* const msg = _readline()) | |||
| return msg; | |||
| if (juce::Time::getMillisecondCounter() >= timeoutEnd) | |||
| @@ -816,7 +816,7 @@ const char* CarlaPipeCommon::readlineblock(const uint32_t timeOutMilliseconds) n | |||
| 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) | |||
| if (pData->writeLock.tryLock()) | |||
| @@ -854,12 +854,12 @@ CarlaPipeServer::~CarlaPipeServer() noexcept | |||
| { | |||
| 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->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(arg1 != 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); | |||
| @@ -1108,9 +1108,9 @@ bool CarlaPipeServer::start(const char* const filename, const char* const arg1, | |||
| 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 | |||
| if (pData->processInfo.hProcess != INVALID_HANDLE_VALUE) | |||
| @@ -1118,7 +1118,7 @@ void CarlaPipeServer::stop(const uint32_t timeOutMilliseconds) noexcept | |||
| const CarlaMutexLocker cml(pData->writeLock); | |||
| if (pData->pipeSend != INVALID_PIPE_VALUE) | |||
| writeMsgBuffer("quit\n", 5); | |||
| _writeMsgBuffer("quit\n", 5); | |||
| waitForProcessToStopOrKillIt(pData->processInfo, timeOutMilliseconds); | |||
| 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); | |||
| if (pData->pipeSend != INVALID_PIPE_VALUE) | |||
| writeMsgBuffer("quit\n", 5); | |||
| _writeMsgBuffer("quit\n", 5); | |||
| waitForChildToStopOrKillIt(pData->pid, timeOutMilliseconds); | |||
| pData->pid = -1; | |||
| } | |||
| #endif | |||
| close(); | |||
| closePipeServer(); | |||
| } | |||
| void CarlaPipeServer::close() noexcept | |||
| void CarlaPipeServer::closePipeServer() noexcept | |||
| { | |||
| carla_debug("CarlaPipeServer::close()"); | |||
| carla_debug("CarlaPipeServer::closePipeServer()"); | |||
| const CarlaMutexLocker cml(pData->writeLock); | |||
| @@ -1181,13 +1181,14 @@ CarlaPipeClient::~CarlaPipeClient() noexcept | |||
| { | |||
| 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->pipeSend == INVALID_PIPE_VALUE, false); | |||
| carla_debug("CarlaPipeClient::initPipeClient(%p)", argv); | |||
| const CarlaMutexLocker cml(pData->writeLock); | |||
| @@ -1248,15 +1249,15 @@ bool CarlaPipeClient::init(const char* argv[]) noexcept | |||
| pData->pipeRecv = pipeRecvServer; | |||
| pData->pipeSend = pipeSendServer; | |||
| writeMsg("\n"); | |||
| flush(); | |||
| writeMessage("\n", 1); | |||
| flushMessages(); | |||
| return true; | |||
| } | |||
| void CarlaPipeClient::close() noexcept | |||
| void CarlaPipeClient::closePipeClient() noexcept | |||
| { | |||
| carla_debug("CarlaPipeClient::close()"); | |||
| carla_debug("CarlaPipeClient::closePipeClient()"); | |||
| const CarlaMutexLocker cml(pData->writeLock); | |||
| @@ -22,53 +22,141 @@ | |||
| #include "CarlaMutex.hpp" | |||
| // ----------------------------------------------------------------------- | |||
| // CarlaPipeCommon class | |||
| class CarlaPipeCommon | |||
| { | |||
| protected: | |||
| /*! | |||
| * Constructor. | |||
| */ | |||
| CarlaPipeCommon() noexcept; | |||
| /*! | |||
| * Destructor. | |||
| */ | |||
| 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; | |||
| // 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 | |||
| { | |||
| carla_stderr2(error); | |||
| } | |||
| 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 | |||
| 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; | |||
| /*! | |||
| * Read the next line as an integer. | |||
| */ | |||
| bool readNextLineAsInt(int32_t& value) noexcept; | |||
| /*! | |||
| * Read the next line as an unsigned integer. | |||
| */ | |||
| bool readNextLineAsUInt(uint32_t& value) noexcept; | |||
| /*! | |||
| * Read the next line as a long integer. | |||
| */ | |||
| bool readNextLineAsLong(int64_t& value) noexcept; | |||
| /*! | |||
| * Read the next line as a long unsigned integer. | |||
| */ | |||
| bool readNextLineAsULong(uint64_t& value) noexcept; | |||
| /*! | |||
| * Read the next line as a floating point number (single precision). | |||
| */ | |||
| bool readNextLineAsFloat(float& value) noexcept; | |||
| /*! | |||
| * Read the next line as a floating point number (double precision). | |||
| */ | |||
| 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; | |||
| // ------------------------------------------------------------------- | |||
| // 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) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // CarlaPipeServer class | |||
| class CarlaPipeServer : public CarlaPipeCommon | |||
| { | |||
| public: | |||
| /*! | |||
| * Constructor. | |||
| */ | |||
| CarlaPipeServer() noexcept; | |||
| /*! | |||
| * Destructor. | |||
| */ | |||
| ~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) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // CarlaPipeClient class | |||
| class CarlaPipeClient : public CarlaPipeCommon | |||
| { | |||
| public: | |||
| /*! | |||
| * Constructor. | |||
| */ | |||
| CarlaPipeClient() noexcept; | |||
| /*! | |||
| * Destructor. | |||
| */ | |||
| ~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) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // ScopedLocale class | |||
| class ScopedLocale { | |||
| public: | |||