diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 229cee7f0..6bbc7fabf 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -1160,12 +1160,18 @@ public: break; } - if (fUi.window == 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; + } - fUi.window->setTitle(fUi.title); - - fFeatures[kFeatureIdUiParent]->data = fUi.window->getPtr(); + if (fUi.window != nullptr) + { + fUi.window->setTitle(fUi.title); + fFeatures[kFeatureIdUiParent]->data = fUi.window->getPtr(); + } } #endif @@ -1195,7 +1201,10 @@ public: #ifndef LV2_UIS_ONLY_BRIDGES if (fUi.type == UI::TYPE_EMBED) { - fUi.window->show(); + if (fUi.window != nullptr) + fUi.window->show(); + else if (fExt.uishow != nullptr) + fExt.uishow->show(fUi.handle); } else #endif @@ -1209,10 +1218,10 @@ public: #ifndef LV2_UIS_ONLY_BRIDGES if (fUi.type == UI::TYPE_EMBED) { - CARLA_SAFE_ASSERT(fUi.window != nullptr); - if (fUi.window != nullptr) fUi.window->hide(); + else if (fExt.uishow != nullptr) + fExt.uishow->hide(fUi.handle); } else #endif @@ -3762,6 +3771,8 @@ public: for (uint32_t i=0; i < fRdfDescriptor->ExtensionCount; ++i) { + CARLA_SAFE_ASSERT_CONTINUE(fRdfDescriptor->Extensions[i] != nullptr); + if (std::strcmp(fRdfDescriptor->Extensions[i], LV2_OPTIONS__interface) == 0) pData->hints |= PLUGIN_HAS_EXTENSION_OPTIONS; else if (std::strcmp(fRdfDescriptor->Extensions[i], LV2_PROGRAMS__Interface) == 0) @@ -3811,22 +3822,6 @@ public: CARLA_SAFE_ASSERT_RETURN(fUi.descriptor != nullptr,); carla_debug("Lv2Plugin::updateUi()"); - fExt.uiidle = nullptr; - fExt.uiprograms = nullptr; - - if (fUi.descriptor->extension_data != nullptr) - { - fExt.uiidle = (const LV2UI_Idle_Interface*)fUi.descriptor->extension_data(LV2_UI__idleInterface); - 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) - fExt.uiidle = nullptr; - - if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program == nullptr) - fExt.uiprograms = nullptr; - } - // update midi program if (fExt.uiprograms != nullptr && pData->midiprog.count > 0 && pData->midiprog.current >= 0) { @@ -4620,7 +4615,7 @@ public: void initUi() { // --------------------------------------------------------------- - // find more appropriate ui + // find the most appropriate ui int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, eExt, iCocoa, iWindows, iX11, iExt, iFinal; eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = eExt = iCocoa = iWindows = iX11 = iExt = iFinal = -1; @@ -4657,32 +4652,21 @@ public: if (isUiBridgeable(i)) eGtk3 = ii; break; -#if defined(CARLA_OS_HAIKU) -#elif defined(CARLA_OS_MAC) case LV2_UI_COCOA: if (isUiBridgeable(i) && preferUiBridges) eCocoa = ii; -# ifndef LV2_UIS_ONLY_BRIDGES iCocoa = ii; -# endif break; -#elif defined(CARLA_OS_WIN) case LV2_UI_WINDOWS: if (isUiBridgeable(i) && preferUiBridges) eWindows = ii; -# ifndef LV2_UIS_ONLY_BRIDGES iWindows = ii; -# endif break; -#else case LV2_UI_X11: if (isUiBridgeable(i) && preferUiBridges) eX11 = ii; -# ifndef LV2_UIS_ONLY_BRIDGES iX11 = ii; -# endif break; -#endif case LV2_UI_EXTERNAL: case LV2_UI_OLD_EXTERNAL: if (isUiBridgeable(i)) @@ -4702,29 +4686,64 @@ public: iFinal = eGtk2; else if (eGtk3 >= 0) iFinal = eGtk3; +#ifdef CARLA_OS_MAC else if (eCocoa >= 0) iFinal = eCocoa; +#endif +#ifdef CARLA_OS_WIN else if (eWindows >= 0) iFinal = eWindows; +#endif +#ifdef HAVE_X11 else if (eX11 >= 0) iFinal = eX11; +#endif //else if (eExt >= 0) // TODO // iFinal = eExt; #ifndef LV2_UIS_ONLY_BRIDGES +# ifdef CARLA_OS_MAC else if (iCocoa >= 0) iFinal = iCocoa; +# endif +# ifdef CARLA_OS_WIN else if (iWindows >= 0) iFinal = iWindows; +# endif +# ifdef HAVE_X11 else if (iX11 >= 0) iFinal = iX11; +# endif #endif else if (iExt >= 0) iFinal = iExt; if (iFinal < 0) { - carla_stderr("Failed to find an appropriate LV2 UI for this plugin"); - return; + // no suitable UI found, see if there's one which supports ui:showInterface + bool hasShowInterface = false; + + for (uint32_t i=0; i < fRdfDescriptor->UICount && ! hasShowInterface; ++i) + { + LV2_RDF_UI* const ui(&fRdfDescriptor->UIs[i]); + + for (uint32_t j=0; j < ui->ExtensionCount; ++j) + { + CARLA_SAFE_ASSERT_CONTINUE(ui->Extensions[j] != nullptr); + + if (std::strcmp(ui->Extensions[j], LV2_UI__showInterface) != 0) + continue; + + iFinal = static_cast(i); + hasShowInterface = true; + break; + } + } + + if (! hasShowInterface) + { + carla_stderr("Failed to find an appropriate LV2 UI for this plugin"); + return; + } } fUi.rdfDescriptor = &fRdfDescriptor->UIs[iFinal]; @@ -4772,6 +4791,13 @@ public: delete[] bridgeBinary; return; } + + if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3) + { + carla_stderr2("Failed to find UI bridge binary, cannot use UI"); + fUi.rdfDescriptor = nullptr; + return; + } } #ifdef LV2_UIS_ONLY_BRIDGES @@ -4828,33 +4854,40 @@ public: { case LV2_UI_QT4: carla_stdout("Will use LV2 Qt4 UI, NOT!"); + fUi.type = UI::TYPE_EMBED; break; case LV2_UI_QT5: carla_stdout("Will use LV2 Qt5 UI, NOT!"); + fUi.type = UI::TYPE_EMBED; break; case LV2_UI_GTK2: carla_stdout("Will use LV2 Gtk2 UI, NOT!"); + fUi.type = UI::TYPE_EMBED; break; case LV2_UI_GTK3: carla_stdout("Will use LV2 Gtk3 UI, NOT!"); + fUi.type = UI::TYPE_EMBED; break; -#if defined(CARLA_OS_HAIKU) -#elif defined(CARLA_OS_MAC) +#ifdef CARLA_OS_MAC case LV2_UI_COCOA: carla_stdout("Will use LV2 Cocoa UI"); fUi.type = UI::TYPE_EMBED; break; -#elif defined(CARLA_OS_WIN) +#endif +#ifdef CARLA_OS_WIN case LV2_UI_WINDOWS: carla_stdout("Will use LV2 Windows UI"); fUi.type = UI::TYPE_EMBED; break; -#else +#endif case LV2_UI_X11: +#ifdef HAVE_X11 carla_stdout("Will use LV2 X11 UI"); +#else + carla_stdout("Will use LV2 X11 UI, NOT!"); +#endif fUi.type = UI::TYPE_EMBED; break; -#endif case LV2_UI_EXTERNAL: case LV2_UI_OLD_EXTERNAL: carla_stdout("Will use LV2 External UI"); @@ -4938,6 +4971,26 @@ public: fFeatures[kFeatureIdExternalUiOld]->URI = LV2_EXTERNAL_UI_DEPRECATED_URI; fFeatures[kFeatureIdExternalUiOld]->data = uiExternalHostFt; + + // --------------------------------------------------------------- + // initialize ui extensions + + 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); + + // check if invalid + if (fExt.uiidle != nullptr && fExt.uiidle->idle == nullptr) + fExt.uiidle = nullptr; + + if (fExt.uishow != nullptr && (fExt.uishow->show == nullptr || fExt.uishow->hide == nullptr)) + fExt.uishow = nullptr; + + if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program == nullptr) + fExt.uiprograms = nullptr; } // ------------------------------------------------------------------- @@ -5010,6 +5063,7 @@ private: const LV2_Worker_Interface* worker; const LV2_Programs_Interface* programs; const LV2UI_Idle_Interface* uiidle; + const LV2UI_Show_Interface* uishow; const LV2_Programs_UI_Interface* uiprograms; Extensions() @@ -5018,6 +5072,7 @@ private: worker(nullptr), programs(nullptr), uiidle(nullptr), + uishow(nullptr), uiprograms(nullptr) {} } fExt; diff --git a/source/modules/dgl/Makefile b/source/modules/dgl/Makefile index 5e0109efa..3f06efccc 100644 --- a/source/modules/dgl/Makefile +++ b/source/modules/dgl/Makefile @@ -14,7 +14,6 @@ LINK_FLAGS += $(DGL_LIBS) OBJS = \ src/App.cpp.o \ - src/Base.cpp.o \ src/Image.cpp.o \ src/ImageAboutWindow.cpp.o \ src/ImageButton.cpp.o \ @@ -26,7 +25,6 @@ OBJS = \ OBJS_posix32 = \ src/App.cpp.posix32.o \ - src/Base.cpp.posix32.o \ src/Image.cpp.posix32.o \ src/ImageAboutWindow.cpp.posix32.o \ src/ImageButton.cpp.posix32.o \ @@ -38,7 +36,6 @@ OBJS_posix32 = \ OBJS_posix64 = \ src/App.cpp.posix64.o \ - src/Base.cpp.posix64.o \ src/Image.cpp.posix64.o \ src/ImageAboutWindow.cpp.posix64.o \ src/ImageButton.cpp.posix64.o \ @@ -50,7 +47,6 @@ OBJS_posix64 = \ OBJS_win32 = \ src/App.cpp.win32.o \ - src/Base.cpp.win32.o \ src/Image.cpp.win32.o \ src/ImageAboutWindow.cpp.win32.o \ src/ImageButton.cpp.win32.o \ @@ -62,7 +58,6 @@ OBJS_win32 = \ OBJS_win64 = \ src/App.cpp.win64.o \ - src/Base.cpp.win64.o \ src/Image.cpp.win64.o \ src/ImageAboutWindow.cpp.win64.o \ src/ImageButton.cpp.win64.o \ diff --git a/source/modules/dgl/src/Base.cpp b/source/modules/dgl/src/Base.cpp deleted file mode 100644 index 58c44c4d0..000000000 --- a/source/modules/dgl/src/Base.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2014 Filipe Coelho - * - * Permission to use, copy, modify, and/or distribute this software for any purpose with - * or without fee is hereby granted, provided that the above copyright notice and this - * permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "../Base.hpp" - -#ifdef DGL_OS_WINDOWS -# include -#else -# include -#endif - -START_NAMESPACE_DGL - -// ----------------------------------------------------------------------- - -void sleep(unsigned int secs) -{ -#ifdef DGL_OS_WINDOWS - ::Sleep(secs * 1000); -#else - ::sleep(secs); -#endif -} - -void msleep(unsigned int msecs) -{ -#ifdef DGL_OS_WINDOWS - ::Sleep(msecs); -#else - ::usleep(msecs * 1000); -#endif -} - -// ----------------------------------------------------------------------- - -END_NAMESPACE_DGL diff --git a/source/utils/CarlaLv2Utils.hpp b/source/utils/CarlaLv2Utils.hpp index 0012ca820..97a25e1dd 100644 --- a/source/utils/CarlaLv2Utils.hpp +++ b/source/utils/CarlaLv2Utils.hpp @@ -905,63 +905,70 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit) if (unitUnitNodes.size() > 0) { - if (const char* const unitUnit = unitUnitNodes.get_first().as_uri()) + Lilv::Node unitUnitNode(unitUnitNodes.get_first()); + + if (unitUnitNode.is_uri()) { - rdfPort->Unit.Hints |= LV2_PORT_UNIT_UNIT; - - if (std::strcmp(unitUnit, LV2_UNITS__bar) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_BAR; - else if (std::strcmp(unitUnit, LV2_UNITS__beat) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_BEAT; - else if (std::strcmp(unitUnit, LV2_UNITS__bpm) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_BPM; - else if (std::strcmp(unitUnit, LV2_UNITS__cent) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_CENT; - else if (std::strcmp(unitUnit, LV2_UNITS__cm) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_CM; - else if (std::strcmp(unitUnit, LV2_UNITS__coef) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_COEF; - else if (std::strcmp(unitUnit, LV2_UNITS__db) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_DB; - else if (std::strcmp(unitUnit, LV2_UNITS__degree) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_DEGREE; - else if (std::strcmp(unitUnit, LV2_UNITS__frame) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_FRAME; - else if (std::strcmp(unitUnit, LV2_UNITS__hz) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_HZ; - else if (std::strcmp(unitUnit, LV2_UNITS__inch) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_INCH; - else if (std::strcmp(unitUnit, LV2_UNITS__khz) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_KHZ; - else if (std::strcmp(unitUnit, LV2_UNITS__km) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_KM; - else if (std::strcmp(unitUnit, LV2_UNITS__m) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_M; - else if (std::strcmp(unitUnit, LV2_UNITS__mhz) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_MHZ; - else if (std::strcmp(unitUnit, LV2_UNITS__midiNote) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_MIDINOTE; - else if (std::strcmp(unitUnit, LV2_UNITS__mile) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_MILE; - else if (std::strcmp(unitUnit, LV2_UNITS__min) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_MIN; - else if (std::strcmp(unitUnit, LV2_UNITS__mm) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_MM; - else if (std::strcmp(unitUnit, LV2_UNITS__ms) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_MS; - else if (std::strcmp(unitUnit, LV2_UNITS__oct) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_OCT; - else if (std::strcmp(unitUnit, LV2_UNITS__pc) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_PC; - else if (std::strcmp(unitUnit, LV2_UNITS__s) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_S; - else if (std::strcmp(unitUnit, LV2_UNITS__semitone12TET) == 0) - rdfPort->Unit.Unit = LV2_PORT_UNIT_SEMITONE; - else - carla_stderr("lv2_rdf_new(\"%s\") - got unknown unit unit '%s'", uri, unitUnit); + if (const char* const unitUnit = unitUnitNode.as_uri()) + { + rdfPort->Unit.Hints |= LV2_PORT_UNIT_UNIT; + + if (std::strcmp(unitUnit, LV2_UNITS__bar) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_BAR; + else if (std::strcmp(unitUnit, LV2_UNITS__beat) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_BEAT; + else if (std::strcmp(unitUnit, LV2_UNITS__bpm) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_BPM; + else if (std::strcmp(unitUnit, LV2_UNITS__cent) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_CENT; + else if (std::strcmp(unitUnit, LV2_UNITS__cm) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_CM; + else if (std::strcmp(unitUnit, LV2_UNITS__coef) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_COEF; + else if (std::strcmp(unitUnit, LV2_UNITS__db) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_DB; + else if (std::strcmp(unitUnit, LV2_UNITS__degree) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_DEGREE; + else if (std::strcmp(unitUnit, LV2_UNITS__frame) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_FRAME; + else if (std::strcmp(unitUnit, LV2_UNITS__hz) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_HZ; + else if (std::strcmp(unitUnit, LV2_UNITS__inch) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_INCH; + else if (std::strcmp(unitUnit, LV2_UNITS__khz) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_KHZ; + else if (std::strcmp(unitUnit, LV2_UNITS__km) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_KM; + else if (std::strcmp(unitUnit, LV2_UNITS__m) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_M; + else if (std::strcmp(unitUnit, LV2_UNITS__mhz) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_MHZ; + else if (std::strcmp(unitUnit, LV2_UNITS__midiNote) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_MIDINOTE; + else if (std::strcmp(unitUnit, LV2_UNITS__mile) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_MILE; + else if (std::strcmp(unitUnit, LV2_UNITS__min) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_MIN; + else if (std::strcmp(unitUnit, LV2_UNITS__mm) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_MM; + else if (std::strcmp(unitUnit, LV2_UNITS__ms) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_MS; + else if (std::strcmp(unitUnit, LV2_UNITS__oct) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_OCT; + else if (std::strcmp(unitUnit, LV2_UNITS__pc) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_PC; + else if (std::strcmp(unitUnit, LV2_UNITS__s) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_S; + else if (std::strcmp(unitUnit, LV2_UNITS__semitone12TET) == 0) + rdfPort->Unit.Unit = LV2_PORT_UNIT_SEMITONE; + else + carla_stderr("lv2_rdf_new(\"%s\") - got unknown unit unit '%s'", uri, unitUnit); + } } } + // FIXME + Lilv::Nodes unitNameNodes(lilvPort.get_value(lv2World.unit_name)); if (unitNameNodes.size() > 0) @@ -1264,7 +1271,7 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit) { CARLA_SAFE_ASSERT_BREAK(h2 < rdfUI->ExtensionCount); - Lilv::Node lilvExtensionDataNode(lilvExtensionDataNodes.get(it)); + Lilv::Node lilvExtensionDataNode(lilvExtensionDataNodes.get(it2)); LV2_URI* const rdfExtension(&rdfUI->Extensions[h2++]); if (lilvExtensionDataNode.is_uri())