| @@ -64,7 +64,8 @@ struct BridgeAudioPool { | |||
| char shm[32]; | |||
| BridgeAudioPool() noexcept | |||
| : data(nullptr) | |||
| : filename(), | |||
| data(nullptr) | |||
| { | |||
| carla_zeroChar(shm, 32); | |||
| jackbridge_shm_init(shm); | |||
| @@ -106,7 +107,8 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> { | |||
| char shm[32]; | |||
| BridgeRtControl() noexcept | |||
| : data(nullptr) | |||
| : filename(), | |||
| data(nullptr) | |||
| { | |||
| carla_zeroChar(shm, 32); | |||
| jackbridge_shm_init(shm); | |||
| @@ -166,7 +168,7 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> { | |||
| char shm[32]; | |||
| BridgeNonRtControl() noexcept | |||
| : CarlaRingBuffer<BigStackBuffer>(), | |||
| : filename(), | |||
| data(nullptr) | |||
| { | |||
| carla_zeroChar(shm, 32); | |||
| @@ -228,8 +230,12 @@ public: | |||
| CarlaEngineBridge(const char* const audioPoolBaseName, const char* const rtBaseName, const char* const nonRtBaseName) | |||
| : CarlaEngine(), | |||
| CarlaThread("CarlaEngineBridge"), | |||
| fShmAudioPool(), | |||
| fShmRtControl(), | |||
| fShmNonRtControl(), | |||
| fIsRunning(false), | |||
| fIsOffline(false) | |||
| fIsOffline(false), | |||
| leakDetector_CarlaEngineBridge() | |||
| { | |||
| carla_stdout("CarlaEngineBridge::CarlaEngineBridge(\"%s\", \"%s\", \"%s\")", audioPoolBaseName, rtBaseName, nonRtBaseName); | |||
| @@ -575,7 +581,7 @@ public: | |||
| String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); | |||
| filePath += OS_SEP_STR; | |||
| filePath += CARLA_OS_SEP_STR; | |||
| filePath += ".CarlaChunk_"; | |||
| filePath += fShmNonRtControl.filename.buffer() + 24; | |||
| @@ -103,14 +103,13 @@ struct BridgeAudioPool { | |||
| size_t size; | |||
| shm_t shm; | |||
| BridgeAudioPool() | |||
| : data(nullptr), | |||
| size(0) | |||
| { | |||
| carla_shm_init(shm); | |||
| } | |||
| BridgeAudioPool() noexcept | |||
| : filename(), | |||
| data(nullptr), | |||
| size(0), | |||
| shm(shm_t_INIT) {} | |||
| ~BridgeAudioPool() | |||
| ~BridgeAudioPool() noexcept | |||
| { | |||
| // should be cleared by now | |||
| CARLA_SAFE_ASSERT(data == nullptr); | |||
| @@ -118,7 +117,7 @@ struct BridgeAudioPool { | |||
| clear(); | |||
| } | |||
| void clear() | |||
| void clear() noexcept | |||
| { | |||
| filename.clear(); | |||
| @@ -135,7 +134,7 @@ struct BridgeAudioPool { | |||
| carla_shm_close(shm); | |||
| } | |||
| void resize(const uint32_t bufferSize, const uint32_t portCount) | |||
| void resize(const uint32_t bufferSize, const uint32_t portCount) noexcept | |||
| { | |||
| if (data != nullptr) | |||
| carla_shm_unmap(shm, data, size); | |||
| @@ -159,11 +158,9 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> { | |||
| shm_t shm; | |||
| BridgeRtControl() | |||
| : CarlaRingBuffer<StackBuffer>(), | |||
| data(nullptr) | |||
| { | |||
| carla_shm_init(shm); | |||
| } | |||
| : filename(), | |||
| data(nullptr), | |||
| shm(shm_t_INIT) {} | |||
| ~BridgeRtControl() | |||
| { | |||
| @@ -173,7 +170,7 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> { | |||
| clear(); | |||
| } | |||
| void clear() | |||
| void clear() noexcept | |||
| { | |||
| filename.clear(); | |||
| @@ -189,9 +186,9 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> { | |||
| carla_shm_close(shm); | |||
| } | |||
| bool mapData() | |||
| bool mapData() noexcept | |||
| { | |||
| CARLA_ASSERT(data == nullptr); | |||
| CARLA_SAFE_ASSERT(data == nullptr); | |||
| if (carla_shm_map<BridgeRtData>(shm, data)) | |||
| { | |||
| @@ -202,7 +199,7 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> { | |||
| return false; | |||
| } | |||
| void unmapData() | |||
| void unmapData() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr,); | |||
| @@ -212,7 +209,7 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> { | |||
| setRingBuffer(nullptr, false); | |||
| } | |||
| bool waitForServer(const int secs) | |||
| bool waitForServer(const int secs) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
| @@ -237,14 +234,13 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> { | |||
| BridgeNonRtData* data; | |||
| shm_t shm; | |||
| BridgeNonRtControl() | |||
| : CarlaRingBuffer<BigStackBuffer>(), | |||
| data(nullptr) | |||
| { | |||
| carla_shm_init(shm); | |||
| } | |||
| BridgeNonRtControl() noexcept | |||
| : mutex(), | |||
| filename(), | |||
| data(nullptr), | |||
| shm(shm_t_INIT) {} | |||
| ~BridgeNonRtControl() | |||
| ~BridgeNonRtControl() noexcept | |||
| { | |||
| // should be cleared by now | |||
| CARLA_SAFE_ASSERT(data == nullptr); | |||
| @@ -252,7 +248,7 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> { | |||
| clear(); | |||
| } | |||
| void clear() | |||
| void clear() noexcept | |||
| { | |||
| filename.clear(); | |||
| @@ -268,7 +264,7 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> { | |||
| carla_shm_close(shm); | |||
| } | |||
| bool mapData() | |||
| bool mapData() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT(data == nullptr); | |||
| @@ -281,7 +277,7 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> { | |||
| return false; | |||
| } | |||
| void unmapData() | |||
| void unmapData() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr,); | |||
| @@ -307,7 +303,9 @@ struct BridgeParamInfo { | |||
| CarlaString unit; | |||
| BridgeParamInfo() noexcept | |||
| : value(0.0f) {} | |||
| : value(0.0f), | |||
| name(), | |||
| unit() {} | |||
| CARLA_DECLARE_NON_COPY_STRUCT(BridgeParamInfo) | |||
| }; | |||
| @@ -327,7 +325,13 @@ public: | |||
| fNeedsSemDestroy(false), | |||
| fTimedOut(false), | |||
| fLastPongCounter(-1), | |||
| fParams(nullptr) | |||
| fBridgeBinary(), | |||
| fShmAudioPool(), | |||
| fShmRtControl(), | |||
| fShmNonRtControl(), | |||
| fInfo(), | |||
| fParams(nullptr), | |||
| leakDetector_BridgePlugin() | |||
| { | |||
| carla_debug("BridgePlugin::BridgePlugin(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype)); | |||
| @@ -666,7 +670,7 @@ public: | |||
| String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName()); | |||
| filePath += OS_SEP_STR; | |||
| filePath += CARLA_OS_SEP_STR; | |||
| filePath += ".CarlaChunk_"; | |||
| filePath += fShmAudioPool.filename.buffer() + 18; | |||
| @@ -2123,7 +2127,12 @@ private: | |||
| mOuts(0), | |||
| category(PLUGIN_CATEGORY_NONE), | |||
| optionsAvailable(0), | |||
| uniqueId(0) {} | |||
| uniqueId(0), | |||
| name(), | |||
| label(), | |||
| maker(), | |||
| copyright(), | |||
| chunk() {} | |||
| } fInfo; | |||
| BridgeParamInfo* fParams; | |||
| @@ -359,7 +359,8 @@ const MidiProgramData& PluginMidiProgramData::getCurrent() const noexcept | |||
| // ProtectedData::ExternalNotes | |||
| CarlaPlugin::ProtectedData::ExternalNotes::ExternalNotes() noexcept | |||
| : dataPool(32, 152), | |||
| : mutex(), | |||
| dataPool(32, 152), | |||
| data(dataPool) {} | |||
| CarlaPlugin::ProtectedData::ExternalNotes::~ExternalNotes() noexcept | |||
| @@ -385,7 +386,8 @@ void CarlaPlugin::ProtectedData::ExternalNotes::clear() noexcept | |||
| // ProtectedData::PostRtEvents | |||
| CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() noexcept | |||
| : dataPool(128, 128), | |||
| : mutex(), | |||
| dataPool(128, 128), | |||
| data(dataPool), | |||
| dataPendingRT(dataPool) {} | |||
| @@ -431,7 +433,8 @@ CarlaPlugin::ProtectedData::PostProc::PostProc() noexcept | |||
| // ----------------------------------------------------------------------- | |||
| CarlaPlugin::ProtectedData::OSC::OSC(CarlaEngine* const eng, CarlaPlugin* const plug) noexcept | |||
| : thread(eng, plug) {} | |||
| : data(), | |||
| thread(eng, plug) {} | |||
| // ----------------------------------------------------------------------- | |||
| @@ -456,6 +459,21 @@ CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx | |||
| name(nullptr), | |||
| filename(nullptr), | |||
| iconName(nullptr), | |||
| audioIn(), | |||
| audioOut(), | |||
| event(), | |||
| param(), | |||
| prog(), | |||
| midiprog(), | |||
| custom(), | |||
| masterMutex(), | |||
| singleMutex(), | |||
| stateSave(), | |||
| extNotes(), | |||
| postRtEvents(), | |||
| #ifndef BUILD_BRIDGE | |||
| postProc(), | |||
| #endif | |||
| osc(eng, plug) {} | |||
| CarlaPlugin::ProtectedData::~ProtectedData() noexcept | |||
| @@ -58,7 +58,12 @@ CarlaPluginThread::CarlaPluginThread(CarlaBackend::CarlaEngine* const engine, Ca | |||
| fEngine(engine), | |||
| fPlugin(plugin), | |||
| fMode(mode), | |||
| fProcess(nullptr) | |||
| fBinary(), | |||
| fLabel(), | |||
| fExtra1(), | |||
| fExtra2(), | |||
| fProcess(nullptr), | |||
| leakDetector_CarlaPluginThread() | |||
| { | |||
| carla_debug("CarlaPluginThread::CarlaPluginThread(%p, %p, %s)", engine, plugin, PluginThreadMode2str(mode)); | |||
| } | |||
| @@ -40,7 +40,8 @@ public: | |||
| fAudioOutBuffers(nullptr), | |||
| fParamBuffers(nullptr), | |||
| fLatencyChanged(false), | |||
| fLatencyIndex(-1) | |||
| fLatencyIndex(-1), | |||
| leakDetector_DssiPlugin() | |||
| { | |||
| carla_debug("DssiPlugin::DssiPlugin(%p, %i)", engine, id); | |||
| @@ -49,7 +49,8 @@ public: | |||
| fSynth(nullptr), | |||
| fSynthId(0), | |||
| fAudio16Buffers(nullptr), | |||
| fLabel(nullptr) | |||
| fLabel(nullptr), | |||
| leakDetector_FluidSynthPlugin() | |||
| { | |||
| carla_debug("FluidSynthPlugin::FluidSynthPlugin(%p, %i, %s)", engine, id, bool2str(use16Outs)); | |||
| @@ -38,7 +38,8 @@ public: | |||
| fAudioOutBuffers(nullptr), | |||
| fParamBuffers(nullptr), | |||
| fLatencyChanged(false), | |||
| fLatencyIndex(-1) | |||
| fLatencyIndex(-1), | |||
| leakDetector_LadspaPlugin() | |||
| { | |||
| carla_debug("LadspaPlugin::LadspaPlugin(%p, %i)", engine, id); | |||
| } | |||
| @@ -55,7 +55,8 @@ public: | |||
| AudioOutputDevicePlugin(const CarlaEngine* const engine, const CarlaPlugin* const plugin, const bool uses16Outs) | |||
| : AudioOutputDevice(std::map<std::string, DeviceCreationParameter*>()), | |||
| kEngine(engine), | |||
| kPlugin(plugin) | |||
| kPlugin(plugin), | |||
| leakDetector_AudioOutputDevicePlugin() | |||
| { | |||
| CARLA_ASSERT(engine != nullptr); | |||
| CARLA_ASSERT(plugin != nullptr); | |||
| @@ -114,6 +115,8 @@ public: | |||
| private: | |||
| const CarlaEngine* const kEngine; | |||
| const CarlaPlugin* const kPlugin; | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioOutputDevicePlugin) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -123,9 +126,12 @@ class MidiInputPortPlugin : public MidiInputPort | |||
| { | |||
| public: | |||
| MidiInputPortPlugin(MidiInputDevice* const device, const int portNum) | |||
| : MidiInputPort(device, portNum) {} | |||
| : MidiInputPort(device, portNum), | |||
| leakDetector_MidiInputPortPlugin() {} | |||
| ~MidiInputPortPlugin() override {} | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiInputPortPlugin) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -135,7 +141,8 @@ class MidiInputDevicePlugin : public MidiInputDevice | |||
| { | |||
| public: | |||
| MidiInputDevicePlugin(Sampler* const sampler) | |||
| : MidiInputDevice(std::map<std::string, DeviceCreationParameter*>(), sampler) {} | |||
| : MidiInputDevice(std::map<std::string, DeviceCreationParameter*>(), sampler), | |||
| leakDetector_MidiInputDevicePlugin() {} | |||
| // ------------------------------------------------------------------- | |||
| // LinuxSampler virtual methods | |||
| @@ -164,6 +171,8 @@ public: | |||
| { | |||
| return new MidiInputPortPlugin(this, int(Ports.size())); | |||
| } | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiInputDevicePlugin) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -203,7 +212,10 @@ public: | |||
| fRealName(nullptr), | |||
| fAudioOutputDevice(nullptr), | |||
| fMidiInputPort(nullptr), | |||
| fInstrument(nullptr) | |||
| fInstrument(nullptr), | |||
| fInstrumentIds(), | |||
| sSampler(), | |||
| leakDetector_LinuxSamplerPlugin() | |||
| { | |||
| carla_debug("LinuxSamplerPlugin::LinuxSamplerPlugin(%p, %i, %s, %s)", engine, id, bool2str(isGIG), bool2str(use16Outs)); | |||
| @@ -420,17 +432,19 @@ public: | |||
| LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[channel]); | |||
| CARLA_SAFE_ASSERT_CONTINUE(engineChannel != nullptr); | |||
| const uint32_t uindex(static_cast<uint32_t>(index)); | |||
| if (pData->engine->isOffline()) | |||
| { | |||
| try { | |||
| engineChannel->PrepareLoadInstrument(pData->filename, index); | |||
| engineChannel->PrepareLoadInstrument(pData->filename, uindex); | |||
| engineChannel->LoadInstrument(); | |||
| } CARLA_SAFE_EXCEPTION("LoadInstrument"); | |||
| } | |||
| else | |||
| { | |||
| try { | |||
| fInstrument->LoadInstrumentInBackground(fInstrumentIds[index], engineChannel); | |||
| fInstrument->LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel); | |||
| } CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); | |||
| } | |||
| @@ -464,19 +478,21 @@ public: | |||
| LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[channel]); | |||
| CARLA_SAFE_ASSERT_RETURN(engineChannel != nullptr,); | |||
| const uint32_t uindex(static_cast<uint32_t>(index)); | |||
| const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback)); | |||
| if (pData->engine->isOffline()) | |||
| { | |||
| try { | |||
| engineChannel->PrepareLoadInstrument(pData->filename, index); | |||
| engineChannel->PrepareLoadInstrument(pData->filename, uindex); | |||
| engineChannel->LoadInstrument(); | |||
| } CARLA_SAFE_EXCEPTION("LoadInstrument"); | |||
| } | |||
| else | |||
| { | |||
| try { | |||
| fInstrument->LoadInstrumentInBackground(fInstrumentIds[index], engineChannel); | |||
| fInstrument->LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel); | |||
| } CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); | |||
| } | |||
| @@ -374,6 +374,8 @@ struct Lv2PluginOptions { | |||
| windowTitle = nullptr; | |||
| } | |||
| } | |||
| CARLA_DECLARE_NON_COPY_STRUCT(Lv2PluginOptions); | |||
| }; | |||
| // ----------------------------------------------------- | |||
| @@ -396,8 +398,21 @@ public: | |||
| fCanInit2(true), | |||
| fLatencyChanged(false), | |||
| fLatencyIndex(-1), | |||
| fAtomBufferIn(), | |||
| fAtomBufferOut(), | |||
| fAtomForge(), | |||
| fCvIn(), | |||
| fCvOut(), | |||
| fEventsIn(), | |||
| fEventsOut(), | |||
| fLv2Options(), | |||
| fCustomURIDs(), | |||
| fFirstActive(true), | |||
| fLastStateChunk(nullptr) | |||
| fLastStateChunk(nullptr), | |||
| fLastTimeInfo(), | |||
| fExt(), | |||
| fUI(), | |||
| leakDetector_Lv2Plugin() | |||
| { | |||
| carla_debug("Lv2Plugin::Lv2Plugin(%p, %i)", engine, id); | |||
| @@ -445,11 +460,11 @@ public: | |||
| carla_debug("Lv2Plugin::~Lv2Plugin()"); | |||
| // close UI | |||
| if (fUi.type != UI::TYPE_NULL) | |||
| if (fUI.type != UI::TYPE_NULL) | |||
| { | |||
| showCustomUI(false); | |||
| if (fUi.type == UI::TYPE_OSC) | |||
| if (fUI.type == UI::TYPE_OSC) | |||
| { | |||
| pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | |||
| } | |||
| @@ -467,19 +482,19 @@ public: | |||
| if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr) | |||
| delete (LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data; | |||
| fUi.descriptor = nullptr; | |||
| fUI.descriptor = nullptr; | |||
| pData->uiLibClose(); | |||
| } | |||
| #ifndef LV2_UIS_ONLY_BRIDGES | |||
| if (fUi.window != nullptr) | |||
| if (fUI.window != nullptr) | |||
| { | |||
| delete fUi.window; | |||
| fUi.window = nullptr; | |||
| delete fUI.window; | |||
| fUI.window = nullptr; | |||
| } | |||
| #endif | |||
| fUi.rdfDescriptor = nullptr; | |||
| fUI.rdfDescriptor = nullptr; | |||
| } | |||
| pData->singleMutex.lock(); | |||
| @@ -978,8 +993,8 @@ public: | |||
| ((LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data)->plugin_human_id = fLv2Options.windowTitle; | |||
| #ifndef LV2_UIS_ONLY_BRIDGES | |||
| if (fUi.window != nullptr) | |||
| fUi.window->setTitle(fLv2Options.windowTitle); | |||
| if (fUI.window != nullptr) | |||
| fUI.window->setTitle(fLv2Options.windowTitle); | |||
| #endif | |||
| } | |||
| @@ -1112,12 +1127,12 @@ public: | |||
| void showCustomUI(const bool yesNo) override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL,); | |||
| if (! yesNo) | |||
| pData->transientTryCounter = 0; | |||
| if (fUi.type == UI::TYPE_OSC) | |||
| if (fUI.type == UI::TYPE_OSC) | |||
| { | |||
| if (yesNo) | |||
| { | |||
| @@ -1139,31 +1154,31 @@ public: | |||
| } | |||
| // take some precautions | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.descriptor != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.rdfDescriptor != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr,); | |||
| if (yesNo) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.descriptor->instantiate != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.descriptor->cleanup != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->instantiate != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->cleanup != nullptr,); | |||
| } | |||
| else | |||
| { | |||
| if (fUi.handle == nullptr) | |||
| if (fUI.handle == nullptr) | |||
| return; | |||
| } | |||
| if (yesNo) | |||
| { | |||
| if (fUi.handle == nullptr) | |||
| if (fUI.handle == nullptr) | |||
| { | |||
| #ifndef LV2_UIS_ONLY_BRIDGES | |||
| if (fUi.type == UI::TYPE_EMBED) | |||
| if (fUI.type == UI::TYPE_EMBED) | |||
| { | |||
| const char* msg = nullptr; | |||
| const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId); | |||
| switch (fUi.rdfDescriptor->Type) | |||
| switch (fUI.rdfDescriptor->Type) | |||
| { | |||
| case LV2_UI_GTK2: | |||
| case LV2_UI_GTK3: | |||
| @@ -1176,7 +1191,7 @@ public: | |||
| case LV2_UI_COCOA: | |||
| # ifdef CARLA_OS_MAC | |||
| fUi.window = CarlaPluginUI::newCocoa(this, frontendWinId); | |||
| fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId); | |||
| # else | |||
| msg = "UI is for MacOS only"; | |||
| # endif | |||
| @@ -1184,7 +1199,7 @@ public: | |||
| case LV2_UI_WINDOWS: | |||
| # ifdef CARLA_OS_WIN | |||
| fUi.window = CarlaPluginUI::newWindows(this, frontendWinId); | |||
| fUI.window = CarlaPluginUI::newWindows(this, frontendWinId); | |||
| # else | |||
| msg = "UI is for Windows only"; | |||
| # endif | |||
| @@ -1192,7 +1207,7 @@ public: | |||
| case LV2_UI_X11: | |||
| # ifdef HAVE_X11 | |||
| fUi.window = CarlaPluginUI::newX11(this, frontendWinId); | |||
| fUI.window = CarlaPluginUI::newX11(this, frontendWinId); | |||
| # else | |||
| msg = "UI is only for systems with X11"; | |||
| # endif | |||
| @@ -1203,37 +1218,37 @@ public: | |||
| break; | |||
| } | |||
| if (fUi.window == nullptr && fExt.uishow == nullptr) | |||
| if (fUI.window == nullptr && fExt.uishow == nullptr) | |||
| { | |||
| return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, msg); | |||
| // unused | |||
| (void)frontendWinId; | |||
| } | |||
| if (fUi.window != nullptr) | |||
| if (fUI.window != nullptr) | |||
| { | |||
| fUi.window->setTitle(fLv2Options.windowTitle); | |||
| fFeatures[kFeatureIdUiParent]->data = fUi.window->getPtr(); | |||
| fUI.window->setTitle(fLv2Options.windowTitle); | |||
| fFeatures[kFeatureIdUiParent]->data = fUI.window->getPtr(); | |||
| } | |||
| } | |||
| #endif | |||
| fUi.widget = nullptr; | |||
| fUi.handle = fUi.descriptor->instantiate(fUi.descriptor, fRdfDescriptor->URI, fUi.rdfDescriptor->Bundle, | |||
| carla_lv2_ui_write_function, this, &fUi.widget, fFeatures); | |||
| fUI.widget = nullptr; | |||
| fUI.handle = fUI.descriptor->instantiate(fUI.descriptor, fRdfDescriptor->URI, fUI.rdfDescriptor->Bundle, | |||
| carla_lv2_ui_write_function, this, &fUI.widget, fFeatures); | |||
| } | |||
| CARLA_SAFE_ASSERT(fUi.handle != nullptr); | |||
| CARLA_SAFE_ASSERT(fUi.type != UI::TYPE_EXTERNAL || fUi.widget != nullptr); | |||
| CARLA_SAFE_ASSERT(fUI.handle != nullptr); | |||
| CARLA_SAFE_ASSERT(fUI.type != UI::TYPE_EXTERNAL || fUI.widget != nullptr); | |||
| if (fUi.handle == nullptr || (fUi.type == UI::TYPE_EXTERNAL && fUi.widget == nullptr)) | |||
| if (fUI.handle == nullptr || (fUI.type == UI::TYPE_EXTERNAL && fUI.widget == nullptr)) | |||
| { | |||
| fUi.widget = nullptr; | |||
| fUI.widget = nullptr; | |||
| if (fUi.handle != nullptr) | |||
| if (fUI.handle != nullptr) | |||
| { | |||
| fUi.descriptor->cleanup(fUi.handle); | |||
| fUi.handle = nullptr; | |||
| fUI.descriptor->cleanup(fUI.handle); | |||
| fUI.handle = nullptr; | |||
| } | |||
| return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, "Plugin refused to open its own UI"); | |||
| @@ -1242,15 +1257,15 @@ public: | |||
| updateUi(); | |||
| #ifndef LV2_UIS_ONLY_BRIDGES | |||
| if (fUi.type == UI::TYPE_EMBED) | |||
| if (fUI.type == UI::TYPE_EMBED) | |||
| { | |||
| if (fUi.window != nullptr) | |||
| if (fUI.window != nullptr) | |||
| { | |||
| fUi.window->show(); | |||
| fUI.window->show(); | |||
| } | |||
| else if (fExt.uishow != nullptr) | |||
| { | |||
| fExt.uishow->show(fUi.handle); | |||
| fExt.uishow->show(fUI.handle); | |||
| # ifndef BUILD_BRIDGE | |||
| pData->tryTransient(); | |||
| # endif | |||
| @@ -1259,7 +1274,7 @@ public: | |||
| else | |||
| #endif | |||
| { | |||
| LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUi.widget); | |||
| LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUI.widget); | |||
| #ifndef BUILD_BRIDGE | |||
| pData->tryTransient(); | |||
| #endif | |||
| @@ -1268,25 +1283,25 @@ public: | |||
| else | |||
| { | |||
| #ifndef LV2_UIS_ONLY_BRIDGES | |||
| if (fUi.type == UI::TYPE_EMBED) | |||
| if (fUI.type == UI::TYPE_EMBED) | |||
| { | |||
| if (fUi.window != nullptr) | |||
| fUi.window->hide(); | |||
| if (fUI.window != nullptr) | |||
| fUI.window->hide(); | |||
| else if (fExt.uishow != nullptr) | |||
| fExt.uishow->hide(fUi.handle); | |||
| fExt.uishow->hide(fUI.handle); | |||
| } | |||
| else | |||
| #endif | |||
| { | |||
| CARLA_SAFE_ASSERT(fUi.widget != nullptr); | |||
| CARLA_SAFE_ASSERT(fUI.widget != nullptr); | |||
| if (fUi.widget != nullptr) | |||
| LV2_EXTERNAL_UI_HIDE((LV2_External_UI_Widget*)fUi.widget); | |||
| if (fUI.widget != nullptr) | |||
| LV2_EXTERNAL_UI_HIDE((LV2_External_UI_Widget*)fUI.widget); | |||
| } | |||
| fUi.descriptor->cleanup(fUi.handle); | |||
| fUi.handle = nullptr; | |||
| fUi.widget = nullptr; | |||
| fUI.descriptor->cleanup(fUI.handle); | |||
| fUI.handle = nullptr; | |||
| fUI.widget = nullptr; | |||
| } | |||
| } | |||
| @@ -1301,7 +1316,7 @@ public: | |||
| uint32_t portIndex; | |||
| const LV2_Atom* atom; | |||
| const bool hasPortEvent(fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->port_event != nullptr); | |||
| const bool hasPortEvent(fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr); | |||
| for (; tmpRingBuffer.get(atom, portIndex);) | |||
| { | |||
| @@ -1310,7 +1325,7 @@ public: | |||
| CARLA_SAFE_ASSERT_CONTINUE(fExt.worker != nullptr && fExt.worker->work != nullptr); | |||
| fExt.worker->work(fHandle, carla_lv2_worker_respond, this, atom->size, LV2_ATOM_BODY_CONST(atom)); | |||
| } | |||
| else if (fUi.type == UI::TYPE_OSC) | |||
| else if (fUI.type == UI::TYPE_OSC) | |||
| { | |||
| if (pData->osc.data.target != nullptr) | |||
| { | |||
| @@ -1321,7 +1336,7 @@ public: | |||
| else | |||
| { | |||
| if (hasPortEvent) | |||
| fUi.descriptor->port_event(fUi.handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||
| fUI.descriptor->port_event(fUI.handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||
| } | |||
| } | |||
| } | |||
| @@ -1353,16 +1368,16 @@ public: | |||
| carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); | |||
| } | |||
| if (fUi.handle != nullptr && fUi.descriptor != nullptr) | |||
| if (fUI.handle != nullptr && fUI.descriptor != nullptr) | |||
| { | |||
| if (fUi.type == UI::TYPE_EXTERNAL && fUi.widget != nullptr) | |||
| LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)fUi.widget); | |||
| if (fUI.type == UI::TYPE_EXTERNAL && fUI.widget != nullptr) | |||
| LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)fUI.widget); | |||
| #ifndef LV2_UIS_ONLY_BRIDGES | |||
| else if (fUi.type == UI::TYPE_EMBED && fUi.window != nullptr) | |||
| fUi.window->idle(); | |||
| else if (fUI.type == UI::TYPE_EMBED && fUI.window != nullptr) | |||
| fUI.window->idle(); | |||
| // note: UI might have been closed by ext-ui or window idle | |||
| if (fUi.handle != nullptr && fExt.uiidle != nullptr && fExt.uiidle->idle(fUi.handle) != 0) | |||
| if (fUI.handle != nullptr && fExt.uiidle != nullptr && fExt.uiidle->idle(fUI.handle) != 0) | |||
| { | |||
| showCustomUI(false); | |||
| pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); | |||
| @@ -2129,10 +2144,10 @@ public: | |||
| pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false); | |||
| } | |||
| if (fExt.worker != nullptr || (fUi.type != UI::TYPE_NULL && fEventsIn.count > 0 && (fEventsIn.data[0].type & CARLA_EVENT_DATA_ATOM) != 0)) | |||
| if (fExt.worker != nullptr || (fUI.type != UI::TYPE_NULL && fEventsIn.count > 0 && (fEventsIn.data[0].type & CARLA_EVENT_DATA_ATOM) != 0)) | |||
| fAtomBufferIn.createBuffer(eventBufferSize); | |||
| if (fExt.worker != nullptr || (fUi.type != UI::TYPE_NULL && fEventsOut.count > 0 && (fEventsOut.data[0].type & CARLA_EVENT_DATA_ATOM) != 0)) | |||
| if (fExt.worker != nullptr || (fUI.type != UI::TYPE_NULL && fEventsOut.count > 0 && (fEventsOut.data[0].type & CARLA_EVENT_DATA_ATOM) != 0)) | |||
| fAtomBufferOut.createBuffer(eventBufferSize); | |||
| if (fEventsIn.ctrl != nullptr && fEventsIn.ctrl->port == nullptr) | |||
| @@ -2152,11 +2167,11 @@ public: | |||
| if (isRealtimeSafe()) | |||
| pData->hints |= PLUGIN_IS_RTSAFE; | |||
| if (fUi.type != UI::TYPE_NULL) | |||
| if (fUI.type != UI::TYPE_NULL) | |||
| { | |||
| pData->hints |= PLUGIN_HAS_CUSTOM_UI; | |||
| if (fUi.type == UI::TYPE_EMBED) | |||
| if (fUI.type == UI::TYPE_EMBED) | |||
| pData->hints |= PLUGIN_NEEDS_SINGLE_THREAD; | |||
| } | |||
| @@ -3710,30 +3725,30 @@ public: | |||
| void uiParameterChange(const uint32_t index, const float value) noexcept override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,); | |||
| if (fUi.type == UI::TYPE_OSC) | |||
| if (fUI.type == UI::TYPE_OSC) | |||
| { | |||
| if (pData->osc.data.target != nullptr) | |||
| osc_send_control(pData->osc.data, pData->param.data[index].rindex, value); | |||
| } | |||
| else | |||
| { | |||
| if (fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->port_event != nullptr) | |||
| if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->param.data[index].rindex >= 0,); | |||
| fUi.descriptor->port_event(fUi.handle, static_cast<uint32_t>(pData->param.data[index].rindex), sizeof(float), 0, &value); | |||
| fUI.descriptor->port_event(fUI.handle, static_cast<uint32_t>(pData->param.data[index].rindex), sizeof(float), 0, &value); | |||
| } | |||
| } | |||
| } | |||
| void uiMidiProgramChange(const uint32_t index) noexcept override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,); | |||
| if (fUi.type == UI::TYPE_OSC) | |||
| if (fUI.type == UI::TYPE_OSC) | |||
| { | |||
| if (pData->osc.data.target != nullptr) | |||
| osc_send_midi_program(pData->osc.data, pData->midiprog.data[index].bank, pData->midiprog.data[index].program); | |||
| @@ -3741,18 +3756,18 @@ public: | |||
| else | |||
| { | |||
| if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program != nullptr) | |||
| fExt.uiprograms->select_program(fUi.handle, pData->midiprog.data[index].bank, pData->midiprog.data[index].program); | |||
| fExt.uiprograms->select_program(fUI.handle, pData->midiprog.data[index].bank, pData->midiprog.data[index].program); | |||
| } | |||
| } | |||
| void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||
| CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); | |||
| CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,); | |||
| if (fUi.type == UI::TYPE_OSC) | |||
| if (fUI.type == UI::TYPE_OSC) | |||
| { | |||
| if (pData->osc.data.target != nullptr) | |||
| { | |||
| @@ -3765,7 +3780,7 @@ public: | |||
| } | |||
| else | |||
| { | |||
| if (fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr) | |||
| if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr) | |||
| { | |||
| LV2_Atom_MidiEvent midiEv; | |||
| midiEv.event.time.frames = 0; | |||
| @@ -3775,18 +3790,18 @@ public: | |||
| midiEv.data[1] = note; | |||
| midiEv.data[2] = velo; | |||
| fUi.descriptor->port_event(fUi.handle, fEventsIn.ctrl->rindex, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv); | |||
| fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv); | |||
| } | |||
| } | |||
| } | |||
| void uiNoteOff(const uint8_t channel, const uint8_t note) noexcept override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL,); | |||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||
| CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); | |||
| if (fUi.type == UI::TYPE_OSC) | |||
| if (fUI.type == UI::TYPE_OSC) | |||
| { | |||
| if (pData->osc.data.target != nullptr) | |||
| { | |||
| @@ -3798,7 +3813,7 @@ public: | |||
| } | |||
| else | |||
| { | |||
| if (fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr) | |||
| if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr) | |||
| { | |||
| LV2_Atom_MidiEvent midiEv; | |||
| midiEv.event.time.frames = 0; | |||
| @@ -3808,7 +3823,7 @@ public: | |||
| midiEv.data[1] = note; | |||
| midiEv.data[2] = 0; | |||
| fUi.descriptor->port_event(fUi.handle, fEventsIn.ctrl->rindex, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv); | |||
| fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv); | |||
| } | |||
| } | |||
| } | |||
| @@ -3848,16 +3863,16 @@ public: | |||
| CARLA_SAFE_ASSERT_RETURN(uiId < fRdfDescriptor->UICount, false); | |||
| #ifndef LV2_UIS_ONLY_INPROCESS | |||
| const LV2_RDF_UI* const rdfUi(&fRdfDescriptor->UIs[uiId]); | |||
| const LV2_RDF_UI* const rdfUI(&fRdfDescriptor->UIs[uiId]); | |||
| if (std::strstr(rdfUi->URI, "http://calf.sourceforge.net/plugins/gui/") != nullptr) | |||
| if (std::strstr(rdfUI->URI, "http://calf.sourceforge.net/plugins/gui/") != nullptr) | |||
| return false; | |||
| for (uint32_t i=0; i < rdfUi->FeatureCount; ++i) | |||
| for (uint32_t i=0; i < rdfUI->FeatureCount; ++i) | |||
| { | |||
| if (std::strcmp(rdfUi->Features[i].URI, LV2_INSTANCE_ACCESS_URI) == 0) | |||
| if (std::strcmp(rdfUI->Features[i].URI, LV2_INSTANCE_ACCESS_URI) == 0) | |||
| return false; | |||
| if (std::strcmp(rdfUi->Features[i].URI, LV2_DATA_ACCESS_URI) == 0) | |||
| if (std::strcmp(rdfUI->Features[i].URI, LV2_DATA_ACCESS_URI) == 0) | |||
| return false; | |||
| } | |||
| @@ -3869,13 +3884,13 @@ public: | |||
| bool isUiResizable() const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.rdfDescriptor != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr, false); | |||
| for (uint32_t i=0; i < fUi.rdfDescriptor->FeatureCount; ++i) | |||
| for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i) | |||
| { | |||
| if (std::strcmp(fUi.rdfDescriptor->Features[i].URI, LV2_UI__fixedSize) == 0) | |||
| if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__fixedSize) == 0) | |||
| return false; | |||
| if (std::strcmp(fUi.rdfDescriptor->Features[i].URI, LV2_UI__noUserResize) == 0) | |||
| if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__noUserResize) == 0) | |||
| return false; | |||
| } | |||
| @@ -3892,29 +3907,29 @@ public: | |||
| switch (type) | |||
| { | |||
| case LV2_UI_GTK2: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-gtk2"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk2"; | |||
| break; | |||
| case LV2_UI_GTK3: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-gtk3"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk3"; | |||
| break; | |||
| case LV2_UI_QT4: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-qt4"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt4"; | |||
| break; | |||
| case LV2_UI_QT5: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-qt5"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt5"; | |||
| break; | |||
| case LV2_UI_COCOA: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-cocoa"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-cocoa"; | |||
| break; | |||
| case LV2_UI_WINDOWS: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-windows"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-windows"; | |||
| break; | |||
| case LV2_UI_X11: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-x11"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-x11"; | |||
| break; | |||
| case LV2_UI_EXTERNAL: | |||
| case LV2_UI_OLD_EXTERNAL: | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-lv2-external"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-external"; | |||
| break; | |||
| default: | |||
| return nullptr; | |||
| @@ -3994,25 +4009,25 @@ public: | |||
| void updateUi() | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.handle != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.descriptor != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.handle != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,); | |||
| carla_debug("Lv2Plugin::updateUi()"); | |||
| // update midi program | |||
| if (fExt.uiprograms != nullptr && pData->midiprog.count > 0 && pData->midiprog.current >= 0) | |||
| { | |||
| const MidiProgramData& curData(pData->midiprog.getCurrent()); | |||
| fExt.uiprograms->select_program(fUi.handle, curData.bank, curData.program); | |||
| fExt.uiprograms->select_program(fUI.handle, curData.bank, curData.program); | |||
| } | |||
| // update control ports | |||
| if (fUi.descriptor->port_event != nullptr) | |||
| if (fUI.descriptor->port_event != nullptr) | |||
| { | |||
| float value; | |||
| for (uint32_t i=0; i < pData->param.count; ++i) | |||
| { | |||
| value = getParameterValue(i); | |||
| fUi.descriptor->port_event(fUi.handle, static_cast<uint32_t>(pData->param.data[i].rindex), sizeof(float), CARLA_URI_MAP_ID_NULL, &value); | |||
| fUI.descriptor->port_event(fUI.handle, static_cast<uint32_t>(pData->param.data[i].rindex), sizeof(float), CARLA_URI_MAP_ID_NULL, &value); | |||
| } | |||
| } | |||
| } | |||
| @@ -4035,7 +4050,7 @@ public: | |||
| fCustomURIDs.append(carla_strdup(uri)); | |||
| if (fUi.type == UI::TYPE_OSC && pData->osc.data.target != nullptr) | |||
| if (fUI.type == UI::TYPE_OSC && pData->osc.data.target != nullptr) | |||
| osc_send_lv2_urid_map(pData->osc.data, urid, uri); | |||
| return urid; | |||
| @@ -4241,30 +4256,30 @@ public: | |||
| void handleExternalUIClosed() | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type == UI::TYPE_EXTERNAL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EXTERNAL,); | |||
| carla_debug("Lv2Plugin::handleExternalUIClosed()"); | |||
| if (fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->cleanup != nullptr) | |||
| fUi.descriptor->cleanup(fUi.handle); | |||
| if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->cleanup != nullptr) | |||
| fUI.descriptor->cleanup(fUI.handle); | |||
| fUi.handle = nullptr; | |||
| fUi.widget = nullptr; | |||
| fUI.handle = nullptr; | |||
| fUI.widget = nullptr; | |||
| pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); | |||
| } | |||
| void handlePluginUIClosed() override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type == UI::TYPE_EMBED,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.window != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,); | |||
| carla_debug("Lv2Plugin::handlePluginUIClosed()"); | |||
| fUi.window->hide(); | |||
| fUI.window->hide(); | |||
| if (fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->cleanup != nullptr) | |||
| fUi.descriptor->cleanup(fUi.handle); | |||
| if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->cleanup != nullptr) | |||
| fUI.descriptor->cleanup(fUI.handle); | |||
| fUi.handle = nullptr; | |||
| fUi.widget = nullptr; | |||
| fUI.handle = nullptr; | |||
| fUI.widget = nullptr; | |||
| pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); | |||
| } | |||
| @@ -4286,12 +4301,12 @@ public: | |||
| int handleUIResize(const int width, const int height) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.window != nullptr, 1); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr, 1); | |||
| CARLA_SAFE_ASSERT_RETURN(width > 0, 1); | |||
| CARLA_SAFE_ASSERT_RETURN(height > 0, 1); | |||
| carla_debug("Lv2Plugin::handleUIResize(%i, %i)", width, height); | |||
| fUi.window->setSize(static_cast<uint>(width), static_cast<uint>(height), true); | |||
| fUI.window->setSize(static_cast<uint>(width), static_cast<uint>(height), true); | |||
| return 0; | |||
| } | |||
| @@ -4934,7 +4949,7 @@ public: | |||
| } | |||
| } | |||
| fUi.rdfDescriptor = &fRdfDescriptor->UIs[iFinal]; | |||
| fUI.rdfDescriptor = &fRdfDescriptor->UIs[iFinal]; | |||
| // --------------------------------------------------------------- | |||
| // check supported ui features | |||
| @@ -4942,32 +4957,32 @@ public: | |||
| bool canContinue = true; | |||
| bool canDelete = true; | |||
| for (uint32_t i=0; i < fUi.rdfDescriptor->FeatureCount; ++i) | |||
| for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i) | |||
| { | |||
| if (! is_lv2_ui_feature_supported(fUi.rdfDescriptor->Features[i].URI)) | |||
| if (! is_lv2_ui_feature_supported(fUI.rdfDescriptor->Features[i].URI)) | |||
| { | |||
| carla_stderr("Plugin UI requires a feature that is not supported:\n%s", fUi.rdfDescriptor->Features[i].URI); | |||
| carla_stderr("Plugin UI requires a feature that is not supported:\n%s", fUI.rdfDescriptor->Features[i].URI); | |||
| if (LV2_IS_FEATURE_REQUIRED(fUi.rdfDescriptor->Features[i].Type)) | |||
| if (LV2_IS_FEATURE_REQUIRED(fUI.rdfDescriptor->Features[i].Type)) | |||
| { | |||
| canContinue = false; | |||
| break; | |||
| } | |||
| } | |||
| if (std::strcmp(fUi.rdfDescriptor->Features[i].URI, LV2_UI__makeResident) == 0) | |||
| if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__makeResident) == 0) | |||
| canDelete = false; | |||
| } | |||
| if (! canContinue) | |||
| { | |||
| fUi.rdfDescriptor = nullptr; | |||
| fUI.rdfDescriptor = nullptr; | |||
| return; | |||
| } | |||
| // --------------------------------------------------------------- | |||
| // initialize ui according to type | |||
| const LV2_Property uiType(fUi.rdfDescriptor->Type); | |||
| const LV2_Property uiType(fUI.rdfDescriptor->Type); | |||
| if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3 || iFinal == eCocoa || iFinal == eWindows || iFinal == eX11 || iFinal == eExt) | |||
| { | |||
| @@ -4977,8 +4992,8 @@ public: | |||
| if (const char* const bridgeBinary = getUiBridgeBinary(uiType)) | |||
| { | |||
| carla_stdout("Will use OSC-Bridge UI, binary: \"%s\"", bridgeBinary); | |||
| fUi.type = UI::TYPE_OSC; | |||
| pData->osc.thread.setOscData(bridgeBinary, fDescriptor->URI, fUi.rdfDescriptor->URI); | |||
| fUI.type = UI::TYPE_OSC; | |||
| pData->osc.thread.setOscData(bridgeBinary, fDescriptor->URI, fUI.rdfDescriptor->URI); | |||
| delete[] bridgeBinary; | |||
| return; | |||
| } | |||
| @@ -4986,24 +5001,24 @@ public: | |||
| if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3) | |||
| { | |||
| carla_stderr2("Failed to find UI bridge binary, cannot use UI"); | |||
| fUi.rdfDescriptor = nullptr; | |||
| fUI.rdfDescriptor = nullptr; | |||
| return; | |||
| } | |||
| } | |||
| #ifdef LV2_UIS_ONLY_BRIDGES | |||
| carla_stderr2("Failed to get an UI working, canBridge:%s", bool2str(isUiBridgeable(static_cast<uint32_t>(iFinal)))); | |||
| fUi.rdfDescriptor = nullptr; | |||
| fUI.rdfDescriptor = nullptr; | |||
| return; | |||
| #endif | |||
| // --------------------------------------------------------------- | |||
| // open UI DLL | |||
| if (! pData->uiLibOpen(fUi.rdfDescriptor->Binary, canDelete)) | |||
| if (! pData->uiLibOpen(fUI.rdfDescriptor->Binary, canDelete)) | |||
| { | |||
| carla_stderr2("Could not load UI library, error was:\n%s", pData->libError(fUi.rdfDescriptor->Binary)); | |||
| fUi.rdfDescriptor = nullptr; | |||
| carla_stderr2("Could not load UI library, error was:\n%s", pData->libError(fUI.rdfDescriptor->Binary)); | |||
| fUI.rdfDescriptor = nullptr; | |||
| return; | |||
| } | |||
| @@ -5016,7 +5031,7 @@ public: | |||
| { | |||
| carla_stderr2("Could not find the LV2UI Descriptor in the UI library"); | |||
| pData->uiLibClose(); | |||
| fUi.rdfDescriptor = nullptr; | |||
| fUI.rdfDescriptor = nullptr; | |||
| return; | |||
| } | |||
| @@ -5024,17 +5039,17 @@ public: | |||
| // get UI descriptor that matches UI URI | |||
| uint32_t i = 0; | |||
| while ((fUi.descriptor = uiDescFn(i++))) | |||
| while ((fUI.descriptor = uiDescFn(i++))) | |||
| { | |||
| if (std::strcmp(fUi.descriptor->URI, fUi.rdfDescriptor->URI) == 0) | |||
| if (std::strcmp(fUI.descriptor->URI, fUI.rdfDescriptor->URI) == 0) | |||
| break; | |||
| } | |||
| if (fUi.descriptor == nullptr) | |||
| if (fUI.descriptor == nullptr) | |||
| { | |||
| carla_stderr2("Could not find the requested GUI in the plugin UI library"); | |||
| pData->uiLibClose(); | |||
| fUi.rdfDescriptor = nullptr; | |||
| fUI.rdfDescriptor = nullptr; | |||
| return; | |||
| } | |||
| @@ -5045,30 +5060,30 @@ public: | |||
| { | |||
| case LV2_UI_QT4: | |||
| carla_stdout("Will use LV2 Qt4 UI, NOT!"); | |||
| fUi.type = UI::TYPE_EMBED; | |||
| fUI.type = UI::TYPE_EMBED; | |||
| break; | |||
| case LV2_UI_QT5: | |||
| carla_stdout("Will use LV2 Qt5 UI, NOT!"); | |||
| fUi.type = UI::TYPE_EMBED; | |||
| fUI.type = UI::TYPE_EMBED; | |||
| break; | |||
| case LV2_UI_GTK2: | |||
| carla_stdout("Will use LV2 Gtk2 UI, NOT!"); | |||
| fUi.type = UI::TYPE_EMBED; | |||
| fUI.type = UI::TYPE_EMBED; | |||
| break; | |||
| case LV2_UI_GTK3: | |||
| carla_stdout("Will use LV2 Gtk3 UI, NOT!"); | |||
| fUi.type = UI::TYPE_EMBED; | |||
| fUI.type = UI::TYPE_EMBED; | |||
| break; | |||
| #ifdef CARLA_OS_MAC | |||
| case LV2_UI_COCOA: | |||
| carla_stdout("Will use LV2 Cocoa UI"); | |||
| fUi.type = UI::TYPE_EMBED; | |||
| fUI.type = UI::TYPE_EMBED; | |||
| break; | |||
| #endif | |||
| #ifdef CARLA_OS_WIN | |||
| case LV2_UI_WINDOWS: | |||
| carla_stdout("Will use LV2 Windows UI"); | |||
| fUi.type = UI::TYPE_EMBED; | |||
| fUI.type = UI::TYPE_EMBED; | |||
| break; | |||
| #endif | |||
| case LV2_UI_X11: | |||
| @@ -5077,20 +5092,20 @@ public: | |||
| #else | |||
| carla_stdout("Will use LV2 X11 UI, NOT!"); | |||
| #endif | |||
| fUi.type = UI::TYPE_EMBED; | |||
| fUI.type = UI::TYPE_EMBED; | |||
| break; | |||
| case LV2_UI_EXTERNAL: | |||
| case LV2_UI_OLD_EXTERNAL: | |||
| carla_stdout("Will use LV2 External UI"); | |||
| fUi.type = UI::TYPE_EXTERNAL; | |||
| fUI.type = UI::TYPE_EXTERNAL; | |||
| break; | |||
| } | |||
| if (fUi.type == UI::TYPE_NULL) | |||
| if (fUI.type == UI::TYPE_NULL) | |||
| { | |||
| pData->uiLibClose(); | |||
| fUi.descriptor = nullptr; | |||
| fUi.rdfDescriptor = nullptr; | |||
| fUI.descriptor = nullptr; | |||
| fUI.rdfDescriptor = nullptr; | |||
| return; | |||
| } | |||
| @@ -5170,12 +5185,12 @@ public: | |||
| // --------------------------------------------------------------- | |||
| // initialize ui extensions | |||
| if (fUi.descriptor->extension_data == nullptr) | |||
| if (fUI.descriptor->extension_data == nullptr) | |||
| return; | |||
| fExt.uiidle = (const LV2UI_Idle_Interface*)fUi.descriptor->extension_data(LV2_UI__idleInterface); | |||
| fExt.uishow = (const LV2UI_Show_Interface*)fUi.descriptor->extension_data(LV2_UI__showInterface); | |||
| fExt.uiprograms = (const LV2_Programs_UI_Interface*)fUi.descriptor->extension_data(LV2_PROGRAMS__UIInterface); | |||
| fExt.uiidle = (const LV2UI_Idle_Interface*)fUI.descriptor->extension_data(LV2_UI__idleInterface); | |||
| fExt.uishow = (const LV2UI_Show_Interface*)fUI.descriptor->extension_data(LV2_UI__showInterface); | |||
| fExt.uiprograms = (const LV2_Programs_UI_Interface*)fUI.descriptor->extension_data(LV2_PROGRAMS__UIInterface); | |||
| // check if invalid | |||
| if (fExt.uiidle != nullptr && fExt.uiidle->idle == nullptr) | |||
| @@ -5274,6 +5289,8 @@ private: | |||
| uiidle(nullptr), | |||
| uishow(nullptr), | |||
| uiprograms(nullptr) {} | |||
| CARLA_DECLARE_NON_COPY_STRUCT(Extensions); | |||
| } fExt; | |||
| struct UI { | |||
| @@ -5308,7 +5325,9 @@ private: | |||
| CARLA_ASSERT(rdfDescriptor == nullptr); | |||
| CARLA_ASSERT(window == nullptr); | |||
| } | |||
| } fUi; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(UI); | |||
| } fUI; | |||
| // ------------------------------------------------------------------- | |||
| // Event Feature | |||
| @@ -138,12 +138,17 @@ public: | |||
| : CarlaPlugin(engine, id), | |||
| fHandle(nullptr), | |||
| fHandle2(nullptr), | |||
| fHost(), | |||
| fDescriptor(nullptr), | |||
| fIsProcessing(false), | |||
| fIsUiVisible(false), | |||
| fAudioInBuffers(nullptr), | |||
| fAudioOutBuffers(nullptr), | |||
| fMidiEventCount(0) | |||
| fMidiEventCount(0), | |||
| fMidiIn(), | |||
| fMidiOut(), | |||
| fTimeInfo(), | |||
| leakDetector_NativePlugin() | |||
| { | |||
| carla_debug("NativePlugin::NativePlugin(%p, %i)", engine, id); | |||
| @@ -58,10 +58,19 @@ public: | |||
| fUnique1(1), | |||
| fEffect(nullptr), | |||
| fMidiEventCount(0), | |||
| fTimeInfo(), | |||
| fNeedIdle(false), | |||
| fLastChunk(nullptr), | |||
| fIsProcessing(false), | |||
| fUnique2(2) | |||
| #ifdef PTW32_DLLPORT | |||
| fProcThread({nullptr, 0}), | |||
| #else | |||
| fProcThread(0), | |||
| #endif | |||
| fEvents(), | |||
| fUI(), | |||
| fUnique2(2), | |||
| leakDetector_VstPlugin() | |||
| { | |||
| carla_debug("VstPlugin::VstPlugin(%p, %i)", engine, id); | |||
| @@ -94,7 +103,7 @@ public: | |||
| { | |||
| showCustomUI(false); | |||
| if (fUi.type == UI::UI_OSC) | |||
| if (fUI.type == UI::UI_OSC) | |||
| pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | |||
| } | |||
| @@ -305,11 +314,11 @@ public: | |||
| { | |||
| CarlaPlugin::setName(newName); | |||
| if (fUi.window != nullptr) | |||
| if (fUI.window != nullptr) | |||
| { | |||
| CarlaString guiTitle(pData->name); | |||
| guiTitle += " (GUI)"; | |||
| fUi.window->setTitle(guiTitle.buffer()); | |||
| fUI.window->setTitle(guiTitle.buffer()); | |||
| } | |||
| } | |||
| @@ -391,7 +400,7 @@ public: | |||
| void showCustomUI(const bool yesNo) override | |||
| { | |||
| if (fUi.type == UI::UI_OSC) | |||
| if (fUI.type == UI::UI_OSC) | |||
| { | |||
| if (yesNo) | |||
| { | |||
| @@ -414,7 +423,7 @@ public: | |||
| return; | |||
| } | |||
| if (fUi.isVisible == yesNo) | |||
| if (fUI.isVisible == yesNo) | |||
| return; | |||
| if (yesNo) | |||
| @@ -426,47 +435,47 @@ public: | |||
| void* vstPtr = nullptr; | |||
| ERect* vstRect = nullptr; | |||
| if (fUi.window == nullptr && fUi.type == UI::UI_EMBED) | |||
| if (fUI.window == nullptr && fUI.type == UI::UI_EMBED) | |||
| { | |||
| const char* msg = nullptr; | |||
| const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId); | |||
| #if defined(CARLA_OS_LINUX) | |||
| # ifdef HAVE_X11 | |||
| fUi.window = CarlaPluginUI::newX11(this, frontendWinId); | |||
| fUI.window = CarlaPluginUI::newX11(this, frontendWinId); | |||
| # else | |||
| msg = "UI is only for systems with X11"; | |||
| # endif | |||
| #elif defined(CARLA_OS_MAC) | |||
| # ifdef __LP64__ | |||
| fUi.window = CarlaPluginUI::newCocoa(this, frontendWinId); | |||
| fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId); | |||
| # endif | |||
| #elif defined(CARLA_OS_WIN) | |||
| fUi.window = CarlaPluginUI::newWindows(this, frontendWinId); | |||
| fUI.window = CarlaPluginUI::newWindows(this, frontendWinId); | |||
| #else | |||
| msg = "Unknown UI type"; | |||
| #endif | |||
| if (fUi.window == nullptr) | |||
| if (fUI.window == nullptr) | |||
| return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, msg); | |||
| fUi.window->setTitle(uiTitle.buffer()); | |||
| fUI.window->setTitle(uiTitle.buffer()); | |||
| } | |||
| if (fUi.type == UI::UI_EMBED) | |||
| vstPtr = fUi.window->getPtr(); | |||
| if (fUI.type == UI::UI_EMBED) | |||
| vstPtr = fUI.window->getPtr(); | |||
| else | |||
| vstPtr = const_cast<char*>(uiTitle.buffer()); | |||
| dispatcher(effEditGetRect, 0, 0, &vstRect, 0.0f); | |||
| #ifdef HAVE_X11 | |||
| value = (intptr_t)fUi.window->getDisplay(); | |||
| value = (intptr_t)fUI.window->getDisplay(); | |||
| #endif | |||
| if (dispatcher(effEditOpen, 0, value, vstPtr, 0.0f) != 0) | |||
| { | |||
| if (fUi.type == UI::UI_EMBED) | |||
| if (fUI.type == UI::UI_EMBED) | |||
| { | |||
| if (vstRect == nullptr || vstRect->right - vstRect->left < 2) | |||
| dispatcher(effEditGetRect, 0, 0, &vstRect, 0.0f); | |||
| @@ -479,10 +488,10 @@ public: | |||
| CARLA_SAFE_ASSERT_INT2(width > 1 && height > 1, width, height); | |||
| if (width > 1 && height > 1) | |||
| fUi.window->setSize(static_cast<uint>(width), static_cast<uint>(height), false); | |||
| fUI.window->setSize(static_cast<uint>(width), static_cast<uint>(height), false); | |||
| } | |||
| fUi.window->show(); | |||
| fUI.window->show(); | |||
| } | |||
| else | |||
| { | |||
| @@ -490,14 +499,14 @@ public: | |||
| pData->transientTryCounter = 1; | |||
| } | |||
| fUi.isVisible = true; | |||
| fUI.isVisible = true; | |||
| } | |||
| else | |||
| { | |||
| if (fUi.type == UI::UI_EMBED) | |||
| if (fUI.type == UI::UI_EMBED) | |||
| { | |||
| delete fUi.window; | |||
| fUi.window = nullptr; | |||
| delete fUI.window; | |||
| fUI.window = nullptr; | |||
| } | |||
| return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, "Plugin refused to open its own UI"); | |||
| @@ -505,12 +514,12 @@ public: | |||
| } | |||
| else | |||
| { | |||
| fUi.isVisible = false; | |||
| fUI.isVisible = false; | |||
| if (fUi.type == UI::UI_EMBED) | |||
| if (fUI.type == UI::UI_EMBED) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.window != nullptr,); | |||
| fUi.window->hide(); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,); | |||
| fUI.window->hide(); | |||
| } | |||
| else | |||
| { | |||
| @@ -526,11 +535,11 @@ public: | |||
| if (fNeedIdle) | |||
| dispatcher(effIdle, 0, 0, nullptr, 0.0f); | |||
| if (fUi.window != nullptr) | |||
| if (fUI.window != nullptr) | |||
| { | |||
| fUi.window->idle(); | |||
| fUI.window->idle(); | |||
| if (fUi.isVisible) | |||
| if (fUI.isVisible) | |||
| dispatcher(effEditIdle, 0, 0, nullptr, 0.0f); | |||
| } | |||
| @@ -839,7 +848,7 @@ public: | |||
| { | |||
| pData->hints |= PLUGIN_HAS_CUSTOM_UI; | |||
| if (fUi.type == UI::UI_EMBED) | |||
| if (fUI.type == UI::UI_EMBED) | |||
| pData->hints |= PLUGIN_NEEDS_SINGLE_THREAD; | |||
| } | |||
| @@ -1697,7 +1706,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,); | |||
| if (fUi.type != UI::UI_OSC) | |||
| if (fUI.type != UI::UI_OSC) | |||
| return; | |||
| if (pData->osc.data.target == nullptr) | |||
| return; | |||
| @@ -1709,7 +1718,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < pData->prog.count,); | |||
| if (fUi.type != UI::UI_OSC) | |||
| if (fUI.type != UI::UI_OSC) | |||
| return; | |||
| if (pData->osc.data.target == nullptr) | |||
| return; | |||
| @@ -1723,7 +1732,7 @@ public: | |||
| CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); | |||
| CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,); | |||
| if (fUi.type != UI::UI_OSC) | |||
| if (fUI.type != UI::UI_OSC) | |||
| return; | |||
| if (pData->osc.data.target == nullptr) | |||
| return; | |||
| @@ -1742,7 +1751,7 @@ public: | |||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||
| CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); | |||
| if (fUi.type != UI::UI_OSC) | |||
| if (fUI.type != UI::UI_OSC) | |||
| return; | |||
| if (pData->osc.data.target == nullptr) | |||
| return; | |||
| @@ -1761,8 +1770,8 @@ public: | |||
| protected: | |||
| void handlePluginUIClosed() override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.type == UI::UI_EMBED || fUi.type == UI::UI_EXTERNAL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUi.window != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::UI_EMBED || fUI.type == UI::UI_EXTERNAL,); | |||
| CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,); | |||
| carla_debug("VstPlugin::handlePluginUIClosed()"); | |||
| showCustomUI(false); | |||
| @@ -1813,7 +1822,7 @@ protected: | |||
| pData->postponeRtEvent(kPluginPostRtEventParameterChange, index, 0, fixedValue); | |||
| } | |||
| // Called from UI | |||
| else if (fUi.isVisible) | |||
| else if (fUI.isVisible) | |||
| { | |||
| CarlaPlugin::setParameterValue(uindex, fixedValue, false, true, true); | |||
| } | |||
| @@ -1961,10 +1970,10 @@ protected: | |||
| #endif | |||
| case audioMasterSizeWindow: | |||
| CARLA_SAFE_ASSERT_BREAK(fUi.window != nullptr); | |||
| CARLA_SAFE_ASSERT_BREAK(fUI.window != nullptr); | |||
| CARLA_SAFE_ASSERT_BREAK(index > 0); | |||
| CARLA_SAFE_ASSERT_BREAK(value > 0); | |||
| fUi.window->setSize(static_cast<uint>(index), static_cast<uint>(value), true); | |||
| fUI.window->setSize(static_cast<uint>(index), static_cast<uint>(value), true); | |||
| ret = 1; | |||
| break; | |||
| @@ -2041,7 +2050,7 @@ protected: | |||
| case audioMasterVendorSpecific: | |||
| if (index == 0xedcd && value == 0 && ptr != nullptr && std::strcmp((const char*)ptr, "EditorClosed") == 0) | |||
| { | |||
| CARLA_SAFE_ASSERT_BREAK(fUi.type == UI::UI_EXTERNAL); | |||
| CARLA_SAFE_ASSERT_BREAK(fUI.type == UI::UI_EXTERNAL); | |||
| handlePluginUIClosed(); | |||
| break; | |||
| } | |||
| @@ -2068,7 +2077,7 @@ protected: | |||
| case audioMasterUpdateDisplay: | |||
| // Idle UI if visible | |||
| if (fUi.isVisible) | |||
| if (fUI.isVisible) | |||
| dispatcher(effEditIdle, 0, 0, nullptr, 0.0f); | |||
| // Update current program | |||
| @@ -2249,7 +2258,7 @@ public: | |||
| if (strBuf[0] != '\0') | |||
| pData->name = pData->engine->getUniquePluginName(strBuf); | |||
| else if (const char* const shortname = std::strrchr(filename, OS_SEP)) | |||
| else if (const char* const shortname = std::strrchr(filename, CARLA_OS_SEP)) | |||
| pData->name = pData->engine->getUniquePluginName(shortname+1); | |||
| else | |||
| pData->name = pData->engine->getUniquePluginName("unknown"); | |||
| @@ -2289,26 +2298,26 @@ public: | |||
| if (fEffect->flags & effFlagsHasEditor) | |||
| { | |||
| fUi.type = UI::UI_EMBED; | |||
| fUI.type = UI::UI_EMBED; | |||
| if ((fEffect->flags & effFlagsProgramChunks) == 0 && pData->engine->getOptions().preferUiBridges) | |||
| { | |||
| CarlaString bridgeBinary(pData->engine->getOptions().binaryDir); | |||
| #if defined(CARLA_OS_LINUX) | |||
| bridgeBinary += OS_SEP_STR "carla-bridge-vst-x11"; | |||
| bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-vst-x11"; | |||
| #endif | |||
| if (bridgeBinary.isNotEmpty() && File(bridgeBinary.buffer()).existsAsFile()) | |||
| { | |||
| pData->osc.thread.setOscData(bridgeBinary, nullptr); | |||
| fUi.type = UI::UI_OSC; | |||
| fUI.type = UI::UI_OSC; | |||
| } | |||
| } | |||
| } | |||
| else if (vstPluginCanDo(fEffect, "ExternalUI")) | |||
| { | |||
| fUi.type = UI::UI_EXTERNAL; | |||
| fUI.type = UI::UI_EXTERNAL; | |||
| } | |||
| // --------------------------------------------------------------- | |||
| @@ -2361,6 +2370,8 @@ private: | |||
| { | |||
| carla_fill<VstEvent*>(data, nullptr, kPluginMaxMidiEvents*2); | |||
| } | |||
| CARLA_DECLARE_NON_COPY_STRUCT(FixedVstEvents); | |||
| } fEvents; | |||
| struct UI { | |||
| @@ -2389,9 +2400,11 @@ private: | |||
| window = nullptr; | |||
| } | |||
| } | |||
| } fUi; | |||
| int fUnique2; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(UI); | |||
| } fUI; | |||
| int fUnique2; | |||
| static VstPlugin* sLastVstPlugin; | |||
| @@ -171,7 +171,11 @@ class CarlaBridgePlugin | |||
| public: | |||
| CarlaBridgePlugin(const bool useBridge, const char* const clientName, const char* const audioPoolBaseName, const char* const rtBaseName, const char* const nonRtBaseName) | |||
| : fEngine(nullptr), | |||
| fOscServerThread(nullptr) | |||
| fProjFilename(), | |||
| fOscControlData(), | |||
| fOscServerPath(), | |||
| fOscServerThread(nullptr), | |||
| leakDetector_CarlaBridgePlugin() | |||
| { | |||
| CARLA_ASSERT(clientName != nullptr && clientName[0] != '\0'); | |||
| carla_debug("CarlaBridgePlugin::CarlaBridgePlugin(%s, \"%s\", %s, %s, %s)", bool2str(useBridge), clientName, audioPoolBaseName, rtBaseName, nonRtBaseName); | |||
| @@ -360,6 +364,8 @@ private: | |||
| { | |||
| carla_stderr("CarlaBridgePlugin::osc_error_handler(%i, \"%s\", \"%s\")", num, msg, path); | |||
| } | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgePlugin) | |||
| }; | |||
| // ------------------------------------------------------------------------- | |||
| @@ -944,8 +944,8 @@ static void do_lv2_check(const char* const bundle, const bool init) | |||
| CarlaString sBundle("file://"); | |||
| sBundle += bundle; | |||
| if (! sBundle.endsWith(OS_SEP)) | |||
| sBundle += OS_SEP_STR; | |||
| if (! sBundle.endsWith(CARLA_OS_SEP)) | |||
| sBundle += CARLA_OS_SEP_STR; | |||
| // Load bundle | |||
| lv2World.load_bundle(sBundle); | |||
| @@ -1508,7 +1508,7 @@ static void do_fluidsynth_check(const char* const filename, const bool init) | |||
| CarlaString name; | |||
| if (const char* const shortname = std::strrchr(filename, OS_SEP)) | |||
| if (const char* const shortname = std::strrchr(filename, CARLA_OS_SEP)) | |||
| name = shortname+1; | |||
| else | |||
| name = filename; | |||
| @@ -238,7 +238,7 @@ private: \ | |||
| # endif | |||
| #endif | |||
| /* Define OS_SEP */ | |||
| /* Define CARLA_OS_SEP */ | |||
| #ifdef CARLA_OS_WIN | |||
| # define CARLA_OS_SEP '\\' | |||
| # define CARLA_OS_SEP_STR "\\" | |||
| @@ -482,6 +482,8 @@ struct JackBridge { | |||
| lib = nullptr; | |||
| } | |||
| } | |||
| CARLA_DECLARE_NON_COPY_STRUCT(JackBridge); | |||
| }; | |||
| static const JackBridge bridge; | |||
| @@ -17,6 +17,8 @@ | |||
| #ifndef LILV_LILVMM_HPP | |||
| #define LILV_LILVMM_HPP | |||
| #include "CarlaDefines.h" | |||
| #include "lilv/lilv.h" | |||
| #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) | |||
| @@ -97,6 +99,12 @@ struct Node { | |||
| LILV_WRAP0_CONST(bool, node, is_bool); | |||
| LILV_WRAP0_CONST(bool, node, as_bool); | |||
| Node& operator=(const Node& copy) { | |||
| lilv_node_free(me); | |||
| me = lilv_node_duplicate(copy.me); | |||
| return *this; | |||
| } | |||
| LilvNode* me; | |||
| }; | |||
| @@ -265,15 +273,13 @@ struct Instance { | |||
| inline Instance(LilvInstance* instance) : me(instance) {} | |||
| LILV_DEPRECATED | |||
| inline Instance(Plugin plugin, double sample_rate) { | |||
| me = lilv_plugin_instantiate(plugin, sample_rate, nullptr); | |||
| } | |||
| inline Instance(Plugin plugin, double sample_rate) | |||
| : me(lilv_plugin_instantiate(plugin, sample_rate, nullptr)) {} | |||
| LILV_DEPRECATED inline Instance(Plugin plugin, | |||
| double sample_rate, | |||
| LV2_Feature* const* features) { | |||
| me = lilv_plugin_instantiate(plugin, sample_rate, features); | |||
| } | |||
| LV2_Feature* const* features) | |||
| : me(lilv_plugin_instantiate(plugin, sample_rate, features)) {} | |||
| static inline Instance* create(Plugin plugin, | |||
| double sample_rate, | |||
| @@ -310,8 +316,8 @@ struct Instance { | |||
| }; | |||
| struct World { | |||
| inline World() : me(lilv_world_new()) {} | |||
| inline ~World() { lilv_world_free(me); } | |||
| inline World() : me(lilv_world_new()) {} | |||
| inline virtual ~World() { lilv_world_free(me); } | |||
| inline LilvNode* new_uri(const char* uri) const { | |||
| return lilv_new_uri(me, uri); | |||
| @@ -343,6 +349,8 @@ struct World { | |||
| LILV_WRAP1(int, world, load_resource, const LilvNode*, resource); | |||
| LilvWorld* me; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(World) | |||
| }; | |||
| } /* namespace Lilv */ | |||
| @@ -18,36 +18,38 @@ | |||
| #include "CarlaDefines.h" | |||
| // Simple plugins | |||
| extern void carla_register_native_plugin_bypass(); | |||
| extern void carla_register_native_plugin_lfo(); | |||
| extern void carla_register_native_plugin_midigain(); | |||
| extern void carla_register_native_plugin_midisplit(); | |||
| extern void carla_register_native_plugin_midithrough(); | |||
| extern void carla_register_native_plugin_miditranspose(); | |||
| extern void carla_register_native_plugin_nekofilter(); | |||
| extern void carla_register_native_plugin_bypass(void); | |||
| extern void carla_register_native_plugin_lfo(void); | |||
| extern void carla_register_native_plugin_midigain(void); | |||
| extern void carla_register_native_plugin_midisplit(void); | |||
| extern void carla_register_native_plugin_midithrough(void); | |||
| extern void carla_register_native_plugin_miditranspose(void); | |||
| extern void carla_register_native_plugin_nekofilter(void); | |||
| // Audio File | |||
| extern void carla_register_native_plugin_audiofile(); | |||
| extern void carla_register_native_plugin_audiofile(void); | |||
| // MIDI File | |||
| extern void carla_register_native_plugin_midifile(); | |||
| extern void carla_register_native_plugin_midifile(void); | |||
| #ifndef CARLA_OS_WIN | |||
| // Carla | |||
| extern void carla_register_native_plugin_carla(); | |||
| extern void carla_register_native_plugin_carla(void); | |||
| // External-UI plugins | |||
| extern void carla_register_native_plugin_bigmeter(); | |||
| extern void carla_register_native_plugin_notes(); | |||
| extern void carla_register_native_plugin_bigmeter(void); | |||
| extern void carla_register_native_plugin_notes(void); | |||
| #endif | |||
| #ifdef WANT_ZYNADDSUBFX | |||
| // ZynAddSubFX | |||
| extern void carla_register_native_plugin_zynaddsubfx_fx(); | |||
| extern void carla_register_native_plugin_zynaddsubfx_synth(); | |||
| extern void carla_register_native_plugin_zynaddsubfx_fx(void); | |||
| extern void carla_register_native_plugin_zynaddsubfx_synth(void); | |||
| #endif | |||
| void carla_register_all_plugins() | |||
| void carla_register_all_plugins(void); | |||
| void carla_register_all_plugins(void) | |||
| { | |||
| // Simple plugins | |||
| carla_register_native_plugin_bypass(); | |||
| @@ -34,9 +34,8 @@ public: | |||
| : NativePluginAndUiClass(host, "/bigmeter-ui"), | |||
| fColor(1), | |||
| fOutLeft(0.0f), | |||
| fOutRight(0.0f) | |||
| { | |||
| } | |||
| fOutRight(0.0f), | |||
| leakDetector_BigMeterPlugin() {} | |||
| protected: | |||
| // ------------------------------------------------------------------- | |||
| @@ -188,6 +187,9 @@ static const NativePluginDescriptor bigmeterDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_bigmeter(); | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_bigmeter() | |||
| { | |||
| @@ -92,7 +92,9 @@ static const NativePluginDescriptor bypassDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_bypass() | |||
| void carla_register_native_plugin_bypass(void); | |||
| void carla_register_native_plugin_bypass(void) | |||
| { | |||
| carla_register_native_plugin(&bypassDesc); | |||
| } | |||
| @@ -78,7 +78,7 @@ static uint32_t lfo_get_parameter_count(NativePluginHandle handle) | |||
| (void)handle; | |||
| } | |||
| const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_t index) | |||
| static const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_t index) | |||
| { | |||
| if (index > PARAM_COUNT) | |||
| return NULL; | |||
| @@ -315,7 +315,9 @@ static const NativePluginDescriptor lfoDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_lfo() | |||
| void carla_register_native_plugin_lfo(void); | |||
| void carla_register_native_plugin_lfo(void) | |||
| { | |||
| carla_register_native_plugin(&lfoDesc); | |||
| } | |||
| @@ -52,7 +52,10 @@ class MidiPattern | |||
| { | |||
| public: | |||
| MidiPattern(AbstractMidiPlayer* const player) | |||
| : kPlayer(player) | |||
| : kPlayer(player), | |||
| fMutex(), | |||
| fData(), | |||
| leakDetector_MidiPattern() | |||
| //fStartTime(0), | |||
| //fDuration(0) | |||
| { | |||
| @@ -230,6 +233,8 @@ private: | |||
| const CarlaMutexLocker sl(fMutex); | |||
| fData.append(event); | |||
| } | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiPattern) | |||
| }; | |||
| #endif // MIDI_BASE_HPP_INCLUDED | |||
| @@ -29,7 +29,8 @@ public: | |||
| MidiFilePlugin(const NativeHostDescriptor* const host) | |||
| : NativePluginClass(host), | |||
| fMidiOut(this), | |||
| fWasPlayingBefore(false) {} | |||
| fWasPlayingBefore(false), | |||
| leakDetector_MidiFilePlugin() {} | |||
| protected: | |||
| // ------------------------------------------------------------------- | |||
| @@ -185,8 +186,9 @@ private: | |||
| continue; | |||
| const double time(midiMessage.getTimeStamp()*sampleRate); | |||
| CARLA_SAFE_ASSERT_CONTINUE(time >= 0.0); | |||
| fMidiOut.addRaw(time, midiMessage.getRawData(), static_cast<uint8_t>(dataSize)); | |||
| fMidiOut.addRaw(static_cast<uint64_t>(time), midiMessage.getRawData(), static_cast<uint8_t>(dataSize)); | |||
| } | |||
| } | |||
| } | |||
| @@ -216,6 +218,9 @@ static const NativePluginDescriptor midifileDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_midifile(); | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_midifile() | |||
| { | |||
| @@ -71,7 +71,7 @@ static uint32_t midigain_get_parameter_count(NativePluginHandle handle) | |||
| (void)handle; | |||
| } | |||
| const NativeParameter* midigain_get_parameter_info(NativePluginHandle handle, uint32_t index) | |||
| static const NativeParameter* midigain_get_parameter_info(NativePluginHandle handle, uint32_t index) | |||
| { | |||
| if (index > PARAM_COUNT) | |||
| return NULL; | |||
| @@ -263,7 +263,9 @@ static const NativePluginDescriptor midigainDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_midigain() | |||
| void carla_register_native_plugin_midigain(void); | |||
| void carla_register_native_plugin_midigain(void) | |||
| { | |||
| carla_register_native_plugin(&midigainDesc); | |||
| } | |||
| @@ -251,10 +251,13 @@ static const NativePluginDescriptor midisequencerDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_midisequencer(); | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_midisequencer() | |||
| { | |||
| carla_register_native_plugin(&midiSequencerDesc); | |||
| carla_register_native_plugin(&midisequencerDesc); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -133,7 +133,9 @@ static const NativePluginDescriptor midisplitDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_midisplit() | |||
| void carla_register_native_plugin_midisplit(void); | |||
| void carla_register_native_plugin_midisplit(void) | |||
| { | |||
| carla_register_native_plugin(&midisplitDesc); | |||
| } | |||
| @@ -114,7 +114,9 @@ static const NativePluginDescriptor midithroughDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_midithrough() | |||
| void carla_register_native_plugin_midithrough(void); | |||
| void carla_register_native_plugin_midithrough(void) | |||
| { | |||
| carla_register_native_plugin(&midithroughDesc); | |||
| } | |||
| @@ -56,7 +56,7 @@ static uint32_t miditranspose_get_parameter_count(NativePluginHandle handle) | |||
| (void)handle; | |||
| } | |||
| const NativeParameter* miditranspose_get_parameter_info(NativePluginHandle handle, uint32_t index) | |||
| static const NativeParameter* miditranspose_get_parameter_info(NativePluginHandle handle, uint32_t index) | |||
| { | |||
| if (index != 0) | |||
| return NULL; | |||
| @@ -192,7 +192,9 @@ static const NativePluginDescriptor miditransposeDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_miditranspose() | |||
| void carla_register_native_plugin_miditranspose(void); | |||
| void carla_register_native_plugin_miditranspose(void) | |||
| { | |||
| carla_register_native_plugin(&miditransposeDesc); | |||
| } | |||
| @@ -88,7 +88,9 @@ static const NativePluginDescriptor nekofilterDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_nekofilter() | |||
| void carla_register_native_plugin_nekofilter(void); | |||
| void carla_register_native_plugin_nekofilter(void) | |||
| { | |||
| carla_register_native_plugin(&nekofilterDesc); | |||
| } | |||
| @@ -30,9 +30,8 @@ class NotesPlugin : public NativePluginAndUiClass | |||
| public: | |||
| NotesPlugin(const NativeHostDescriptor* const host) | |||
| : NativePluginAndUiClass(host, "/notes-ui"), | |||
| fCurPage(1) | |||
| { | |||
| } | |||
| fCurPage(1), | |||
| leakDetector_NotesPlugin() {} | |||
| protected: | |||
| // ------------------------------------------------------------------- | |||
| @@ -119,6 +118,9 @@ static const NativePluginDescriptor notesDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_notes(); | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_notes() | |||
| { | |||
| @@ -1443,6 +1443,9 @@ static const NativePluginDescriptor fxReverbDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_zynaddsubfx_fx(); | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_zynaddsubfx_fx() | |||
| { | |||
| @@ -842,6 +842,9 @@ static const NativePluginDescriptor zynaddsubfxDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_zynaddsubfx_synth(); | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_zynaddsubfx_synth() | |||
| { | |||
| @@ -38,6 +38,13 @@ using CarlaBackend::CarlaPlugin; | |||
| struct PluginListManager { | |||
| PluginListManager() | |||
| #ifdef CARLA_NATIVE_PLUGIN_DSSI | |||
| : dssiDescs(), | |||
| #endif | |||
| #ifdef CARLA_NATIVE_PLUGIN_LV2 | |||
| : lv2Descs(), | |||
| #endif | |||
| descs() | |||
| { | |||
| for (size_t i=0, count = CarlaPlugin::getNativePluginCount(); i < count; ++i) | |||
| { | |||
| @@ -1088,6 +1088,8 @@ private: | |||
| } | |||
| } | |||
| } | |||
| CARLA_DECLARE_NON_COPY_STRUCT(Ports); | |||
| } fPorts; | |||
| // ------------------------------------------------------------------- | |||
| @@ -22,10 +22,12 @@ | |||
| #ifdef CARLA_OS_WIN | |||
| struct shm_t { HANDLE shm; HANDLE map; }; | |||
| # define shm_t_INIT {nullptr, nullptr} | |||
| #else | |||
| # include <fcntl.h> | |||
| # include <sys/mman.h> | |||
| struct shm_t { int fd; const char* filename; }; | |||
| # define shm_t_INIT {-1, nullptr} | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| @@ -29,15 +29,16 @@ class Lv2AtomRingBuffer : public CarlaRingBuffer<HeapBuffer> | |||
| { | |||
| public: | |||
| Lv2AtomRingBuffer() noexcept | |||
| : CarlaRingBuffer<HeapBuffer>(), | |||
| fNeedsDataDelete(true) | |||
| { | |||
| carla_zeroStruct(fHeapBuffer); | |||
| } | |||
| : fMutex(), | |||
| fHeapBuffer(HeapBuffer_INIT), | |||
| fNeedsDataDelete(true), | |||
| fRetAtom{{0,0}, {0}} {} | |||
| Lv2AtomRingBuffer(Lv2AtomRingBuffer& ringBuf, uint8_t buf[]) noexcept | |||
| : CarlaRingBuffer<HeapBuffer>(), | |||
| fNeedsDataDelete(false) | |||
| : fMutex(), | |||
| fHeapBuffer(HeapBuffer_INIT), | |||
| fNeedsDataDelete(false), | |||
| fRetAtom{{0,0}, {0}} | |||
| { | |||
| fHeapBuffer.buf = buf; | |||
| fHeapBuffer.size = ringBuf.fHeapBuffer.size; | |||
| @@ -204,7 +205,7 @@ private: | |||
| friend class Lv2AtomQueue; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_PREVENT_VIRTUAL_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(Lv2AtomRingBuffer) | |||
| }; | |||