diff --git a/dgl/Application.hpp b/dgl/Application.hpp index c028b53c..fac5fccc 100644 --- a/dgl/Application.hpp +++ b/dgl/Application.hpp @@ -83,10 +83,21 @@ BUILD_CONFIG_SENTINEL(fail_to_link_is_mismatch_dgl_no_shared_resources_off) class DISTRHO_API Application { public: + /** + Type of application to setup, either "classic" or "modern". + + What this means depends on the OS. + */ + enum Type { + kTypeAuto, + kTypeClassic, + kTypeModern, + }; + /** Constructor for standalone or plugin application. */ - Application(bool isStandalone = true); + Application(bool isStandalone = true, Type type = kTypeAuto); /** Constructor for a standalone application. @@ -141,6 +152,12 @@ public: */ double getTime() const; + /** + Return the application type, either kTypeClassic or kTypeModern. + This function never return kTypeAuto. + */ + Type getType() const noexcept; + /** Add a callback function to be triggered on every idle cycle. You can add more than one, and remove them at anytime with removeIdleCallback(). diff --git a/dgl/src/Application.cpp b/dgl/src/Application.cpp index 09f57e1e..705b10fb 100644 --- a/dgl/src/Application.cpp +++ b/dgl/src/Application.cpp @@ -98,8 +98,8 @@ static void app_idle(void* const app) } #endif -Application::Application(const bool isStandalone) - : pData(new PrivateData(isStandalone)) +Application::Application(const bool isStandalone, const Type type) + : pData(new PrivateData(isStandalone, type)) { // build config sentinels #ifdef DPF_DEBUG @@ -126,7 +126,7 @@ Application::Application(const bool isStandalone) } Application::Application(int argc, char* argv[]) - : pData(new PrivateData(true)) + : pData(new PrivateData(true, kTypeAuto)) { #if defined(HAVE_X11) && defined(DISTRHO_OS_LINUX) && defined(DGL_USE_WEB_VIEW) if (argc >= 2 && std::strcmp(argv[1], "dpf-ld-linux-webview") == 0) @@ -213,6 +213,11 @@ double Application::getTime() const return pData->getTime(); } +Application::Type Application::getType() const noexcept +{ + return pData->isModern ? kTypeModern : kTypeClassic; +} + void Application::addIdleCallback(IdleCallback* const callback) { DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) diff --git a/dgl/src/ApplicationPrivateData.cpp b/dgl/src/ApplicationPrivateData.cpp index 0e353a7e..ca0d27f9 100644 --- a/dgl/src/ApplicationPrivateData.cpp +++ b/dgl/src/ApplicationPrivateData.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2024 Filipe Coelho + * Copyright (C) 2012-2025 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 @@ -53,13 +53,14 @@ const char* Application::getClassName() const noexcept // -------------------------------------------------------------------------------------------------------------------- -Application::PrivateData::PrivateData(const bool standalone) +Application::PrivateData::PrivateData(const bool standalone, const Type type) : world(puglNewWorld(standalone ? PUGL_PROGRAM : PUGL_MODULE, - standalone ? PUGL_WORLD_THREADS : 0x0)), + (standalone ? PUGL_WORLD_THREADS : 0))), + isModern(false), isStandalone(standalone), + isStarting(true), isQuitting(false), isQuittingInNextCycle(false), - isStarting(true), needsRepaint(false), visibleWindows(0), mainThreadHandle(getCurrentThreadHandle()), @@ -68,16 +69,11 @@ Application::PrivateData::PrivateData(const bool standalone) { DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); - #ifdef DGL_USING_SDL - SDL_Init(SDL_INIT_EVENTS|SDL_INIT_TIMER|SDL_INIT_VIDEO); - #else - puglSetWorldHandle(world, this); #ifdef __EMSCRIPTEN__ puglSetWorldString(world, PUGL_CLASS_NAME, "canvas"); #else puglSetWorldString(world, PUGL_CLASS_NAME, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); #endif - #endif } Application::PrivateData::~PrivateData() @@ -88,12 +84,8 @@ Application::PrivateData::~PrivateData() windows.clear(); idleCallbacks.clear(); - #ifdef DGL_USING_SDL - SDL_Quit(); - #else if (world != nullptr) puglFreeWorld(world); - #endif } // -------------------------------------------------------------------------------------------------------------------- diff --git a/dgl/src/ApplicationPrivateData.hpp b/dgl/src/ApplicationPrivateData.hpp index 59afaae3..b5ef6621 100644 --- a/dgl/src/ApplicationPrivateData.hpp +++ b/dgl/src/ApplicationPrivateData.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2021 Filipe Coelho + * Copyright (C) 2012-2025 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 @@ -51,18 +51,21 @@ struct Application::PrivateData { /** Pugl world instance. */ PuglWorld* const world; + /** Whether the applicating uses modern backend, otherwise classic. */ + const bool isModern; + /** Whether the application is running as standalone, otherwise it is part of a plugin. */ const bool isStandalone; + /** Whether the applicating is starting up, that is, no windows have been made visible yet. Defaults to true. */ + bool isStarting; + /** Whether the applicating is about to quit, or already stopped. Defaults to false. */ bool isQuitting; /** Helper for safely close everything from main thread. */ bool isQuittingInNextCycle; - /** Whether the applicating is starting up, that is, no windows have been made visible yet. Defaults to true. */ - bool isStarting; - /** When true force all windows to be repainted on next idle. */ bool needsRepaint; @@ -80,7 +83,7 @@ struct Application::PrivateData { std::list idleCallbacks; /** Constructor and destructor */ - explicit PrivateData(bool standalone); + explicit PrivateData(bool standalone, Type type); ~PrivateData(); /** Flag one window as shown, which increments @a visibleWindows. diff --git a/distrho/src/DistrhoPluginCLAP.cpp b/distrho/src/DistrhoPluginCLAP.cpp index 4ee36287..dd6859cf 100644 --- a/distrho/src/DistrhoPluginCLAP.cpp +++ b/distrho/src/DistrhoPluginCLAP.cpp @@ -286,7 +286,7 @@ public: #else UIExporter tmpUI(nullptr, 0, fPlugin.getSampleRate(), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, d_nextBundlePath, - fPlugin.getInstancePointer(), scaleFactor); + fPlugin.getInstancePointer(), scaleFactor, DGL_NAMESPACE::Application::kTypeClassic); *width = tmpUI.getWidth(); *height = tmpUI.getHeight(); scaleFactor = tmpUI.getScaleFactor(); @@ -584,7 +584,8 @@ private: nullptr, // TODO fileRequestCallback, d_nextBundlePath, fPlugin.getInstancePointer(), - fScaleFactor); + fScaleFactor, + DGL_NAMESPACE::Application::kTypeClassic); #if DISTRHO_PLUGIN_WANT_PROGRAMS fUI->programLoaded(fCurrentProgram); diff --git a/distrho/src/DistrhoPluginVST2.cpp b/distrho/src/DistrhoPluginVST2.cpp index a45f927b..00a02613 100644 --- a/distrho/src/DistrhoPluginVST2.cpp +++ b/distrho/src/DistrhoPluginVST2.cpp @@ -175,7 +175,8 @@ public: nullptr, // TODO file request d_nextBundlePath, plugin->getInstancePointer(), - scaleFactor), + scaleFactor, + DGL_NAMESPACE::Application::kTypeClassic), fKeyboardModifiers(0) #if DISTRHO_PLUGIN_WANT_MIDI_INPUT , fNotesRingBuffer() @@ -600,7 +601,7 @@ public: #else UIExporter tmpUI(nullptr, 0, fPlugin.getSampleRate(), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, d_nextBundlePath, - fPlugin.getInstancePointer(), scaleFactor); + fPlugin.getInstancePointer(), scaleFactor, DGL_NAMESPACE::Application::kTypeClassic); fVstRect.right = tmpUI.getWidth(); fVstRect.bottom = tmpUI.getHeight(); scaleFactor = tmpUI.getScaleFactor(); diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp index ea3f56a2..f7b578e6 100644 --- a/distrho/src/DistrhoUIInternal.hpp +++ b/distrho/src/DistrhoUIInternal.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2024 Filipe Coelho + * Copyright (C) 2012-2025 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 @@ -21,18 +21,18 @@ START_NAMESPACE_DISTRHO -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // UI exporter class class UIExporter { - // ------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- // UI Widget and its private data UI* ui; UI::PrivateData* uiData; - // ------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- public: UIExporter(void* const callbacksPtr, @@ -47,11 +47,12 @@ public: const char* const bundlePath = nullptr, void* const dspPtr = nullptr, const double scaleFactor = 0.0, + const DGL_NAMESPACE::Application::Type appType = DGL_NAMESPACE::Application::kTypeAuto, const uint32_t bgColor = 0, const uint32_t fgColor = 0xffffffff, const char* const appClassName = nullptr) : ui(nullptr), - uiData(new UI::PrivateData(appClassName)) + uiData(new UI::PrivateData(appClassName, appType)) { uiData->sampleRate = sampleRate; uiData->bundlePath = bundlePath != nullptr ? strdup(bundlePath) : nullptr; diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp index d7b0af65..7f5e414c 100644 --- a/distrho/src/DistrhoUILV2.cpp +++ b/distrho/src/DistrhoUILV2.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2021 Filipe Coelho + * Copyright (C) 2012-2025 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 @@ -52,7 +52,7 @@ static constexpr const sendNoteFunc sendNoteCallback = nullptr; // unwanted in LV2, resize extension is deprecated and hosts can do it without extensions static constexpr const setSizeFunc setSizeCallback = nullptr; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- template static const LV2F* getLv2Feature(const LV2_Feature* const* features, const char* const uri) @@ -80,6 +80,7 @@ public: void* const dspPtr, const float sampleRate, const float scaleFactor, + const DGL_NAMESPACE::Application::Type appType, const uint32_t bgColor, const uint32_t fgColor, const char* const appClassName) @@ -101,7 +102,7 @@ public: sendNoteCallback, setSizeCallback, fileRequestCallback, - bundlePath, dspPtr, scaleFactor, bgColor, fgColor, appClassName) + bundlePath, dspPtr, scaleFactor, appType, bgColor, fgColor, appClassName) { if (widget != nullptr) *widget = (LV2UI_Widget)fUI.getNativeWindowHandle(); @@ -483,7 +484,7 @@ private: } }; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* const uri, @@ -499,6 +500,9 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, return nullptr; } + // TODO allow classic vs modern ui type + static constexpr const DGL_NAMESPACE::Application::Type appType = DGL_NAMESPACE::Application::kTypeClassic; + const LV2_Options_Option* options = nullptr; const LV2_URID_Map* uridMap = nullptr; void* parentId = nullptr; @@ -633,7 +637,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, return new UiLv2(bundlePath, winId, options, uridMap, features, controller, writeFunction, widget, instance, - sampleRate, scaleFactor, bgColor, fgColor, appClassName); + sampleRate, scaleFactor, appType, bgColor, fgColor, appClassName); } #define uiPtr ((UiLv2*)ui) @@ -648,7 +652,7 @@ static void lv2ui_port_event(LV2UI_Handle ui, uint32_t portIndex, uint32_t buffe uiPtr->lv2ui_port_event(portIndex, bufferSize, format, buffer); } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- static int lv2ui_idle(LV2UI_Handle ui) { @@ -665,7 +669,7 @@ static int lv2ui_hide(LV2UI_Handle ui) return uiPtr->lv2ui_hide(); } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- static uint32_t lv2_get_options(LV2UI_Handle ui, LV2_Options_Option* options) { @@ -677,7 +681,7 @@ static uint32_t lv2_set_options(LV2UI_Handle ui, const LV2_Options_Option* optio return uiPtr->lv2_set_options(options); } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- #if DISTRHO_PLUGIN_WANT_PROGRAMS static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t program) @@ -686,7 +690,7 @@ static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t progra } #endif -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- static const void* lv2ui_extension_data(const char* uri) { @@ -713,7 +717,7 @@ static const void* lv2ui_extension_data(const char* uri) #undef instancePtr -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- static const LV2UI_Descriptor sLv2UiDescriptor = { DISTRHO_UI_URI, @@ -723,7 +727,7 @@ static const LV2UI_Descriptor sLv2UiDescriptor = { lv2ui_extension_data }; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DISTRHO @@ -929,4 +933,4 @@ void modgui_cleanup(const LV2UI_Handle handle) } #endif -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- diff --git a/distrho/src/DistrhoUIPrivateData.hpp b/distrho/src/DistrhoUIPrivateData.hpp index 4a2e4494..108e76b6 100644 --- a/distrho/src/DistrhoUIPrivateData.hpp +++ b/distrho/src/DistrhoUIPrivateData.hpp @@ -67,14 +67,14 @@ START_NAMESPACE_DISTRHO int dpf_webview_start(int argc, char* argv[]); #endif -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // Plugin Application, will set class name based on plugin details class PluginApplication : public DGL_NAMESPACE::Application { public: - explicit PluginApplication(const char* className) - : DGL_NAMESPACE::Application(DISTRHO_UI_IS_STANDALONE) + explicit PluginApplication(const char* className, const Application::Type type) + : DGL_NAMESPACE::Application(DISTRHO_UI_IS_STANDALONE, type) { #if defined(__MOD_DEVICES__) || !defined(__EMSCRIPTEN__) if (className == nullptr) @@ -108,7 +108,7 @@ public: DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginApplication) }; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // Plugin Window, will pass some Window events to UI class PluginWindow : public DGL_NAMESPACE::Window @@ -243,7 +243,7 @@ protected: DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow) }; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // UI callbacks typedef void (*editParamFunc) (void* ptr, uint32_t rindex, bool started); @@ -253,7 +253,7 @@ typedef void (*sendNoteFunc) (void* ptr, uint8_t channel, uint8_t note, uint8 typedef void (*setSizeFunc) (void* ptr, uint width, uint height); typedef bool (*fileRequestFunc) (void* ptr, const char* key); -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // UI private data struct UI::PrivateData { @@ -292,8 +292,8 @@ struct UI::PrivateData { setSizeFunc setSizeCallbackFunc; fileRequestFunc fileRequestCallbackFunc; - PrivateData(const char* const appClassName) noexcept - : app(appClassName), + PrivateData(const char* const appClassName, const DGL_NAMESPACE::Application::Type appType) noexcept + : app(appClassName, appType), window(nullptr), #if DISTRHO_UI_USE_WEB_VIEW webview(nullptr), @@ -392,7 +392,7 @@ struct UI::PrivateData { #endif }; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // UI private data fileRequestCallback, which requires PluginWindow definitions inline bool UI::PrivateData::fileRequestCallback(const char* const key) @@ -419,7 +419,7 @@ inline bool UI::PrivateData::fileRequestCallback(const char* const key) return false; } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // PluginWindow onFileSelected that require UI::PrivateData definitions #if DISTRHO_UI_FILE_BROWSER @@ -457,7 +457,7 @@ inline void PluginWindow::onFileSelected(const char* const filename) } #endif -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DISTRHO diff --git a/distrho/src/DistrhoUIVST3.cpp b/distrho/src/DistrhoUIVST3.cpp index a326c4b3..744551c4 100644 --- a/distrho/src/DistrhoUIVST3.cpp +++ b/distrho/src/DistrhoUIVST3.cpp @@ -205,7 +205,8 @@ public: nullptr, // TODO file request d_nextBundlePath, instancePointer, - scaleFactor) + scaleFactor, + DGL_NAMESPACE::Application::kTypeClassic) { } @@ -1374,7 +1375,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { #else UIExporter tmpUI(nullptr, 0, view->sampleRate, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, d_nextBundlePath, - view->instancePointer, scaleFactor); + view->instancePointer, scaleFactor, DGL_NAMESPACE::Application::kTypeClassic); rect->right = tmpUI.getWidth(); rect->bottom = tmpUI.getHeight(); scaleFactor = tmpUI.getScaleFactor();