Signed-off-by: falkTX <falktx@gmail.com>vstgui
| @@ -16,6 +16,7 @@ ifeq ($(HAVE_DGL),true) | |||||
| endif | endif | ||||
| examples: dgl | examples: dgl | ||||
| $(MAKE) all -C examples/ExternalUI | |||||
| $(MAKE) all -C examples/Info | $(MAKE) all -C examples/Info | ||||
| $(MAKE) all -C examples/Latency | $(MAKE) all -C examples/Latency | ||||
| $(MAKE) all -C examples/Meters | $(MAKE) all -C examples/Meters | ||||
| @@ -23,6 +24,13 @@ examples: dgl | |||||
| $(MAKE) all -C examples/Parameters | $(MAKE) all -C examples/Parameters | ||||
| $(MAKE) all -C examples/States | $(MAKE) all -C examples/States | ||||
| # ExternalUI launcher | |||||
| install -d bin/d_extui-dssi | |||||
| install -d bin/d_extui.lv2 | |||||
| install -m 755 examples/ExternalUI/ExternalLauncher.sh bin/d_extui.sh | |||||
| install -m 755 examples/ExternalUI/ExternalLauncher.sh bin/d_extui-dssi/d_extui.sh | |||||
| install -m 755 examples/ExternalUI/ExternalLauncher.sh bin/d_extui.lv2/d_extui.sh | |||||
| ifneq ($(CROSS_COMPILING),true) | ifneq ($(CROSS_COMPILING),true) | ||||
| gen: examples utils/lv2_ttl_generator | gen: examples utils/lv2_ttl_generator | ||||
| @$(CURDIR)/utils/generate-ttl.sh | @$(CURDIR)/utils/generate-ttl.sh | ||||
| @@ -40,6 +48,7 @@ endif | |||||
| clean: | clean: | ||||
| $(MAKE) clean -C dgl | $(MAKE) clean -C dgl | ||||
| $(MAKE) clean -C examples/ExternalUI | |||||
| $(MAKE) clean -C examples/Info | $(MAKE) clean -C examples/Info | ||||
| $(MAKE) clean -C examples/Latency | $(MAKE) clean -C examples/Latency | ||||
| $(MAKE) clean -C examples/Meters | $(MAKE) clean -C examples/Meters | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -20,7 +20,8 @@ | |||||
| #include "extra/LeakDetector.hpp" | #include "extra/LeakDetector.hpp" | ||||
| #include "src/DistrhoPluginChecks.h" | #include "src/DistrhoPluginChecks.h" | ||||
| #ifndef HAVE_DGL | |||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| # include "../dgl/Base.hpp" | |||||
| # include "extra/ExternalWindow.hpp" | # include "extra/ExternalWindow.hpp" | ||||
| typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget; | typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget; | ||||
| #elif DISTRHO_UI_USE_NANOVG | #elif DISTRHO_UI_USE_NANOVG | ||||
| @@ -67,7 +68,7 @@ public: | |||||
| */ | */ | ||||
| bool isUserResizable() const noexcept; | bool isUserResizable() const noexcept; | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| /** | /** | ||||
| Set geometry constraints for the UI when resized by the user, and optionally scale UI automatically. | Set geometry constraints for the UI when resized by the user, and optionally scale UI automatically. | ||||
| @see Window::setGeometryConstraints(uint,uint,bool) | @see Window::setGeometryConstraints(uint,uint,bool) | ||||
| @@ -181,7 +182,7 @@ protected: | |||||
| */ | */ | ||||
| virtual void sampleRateChanged(double newSampleRate); | virtual void sampleRateChanged(double newSampleRate); | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| /* -------------------------------------------------------------------------------------------------------- | /* -------------------------------------------------------------------------------------------------------- | ||||
| * UI Callbacks (optional) */ | * UI Callbacks (optional) */ | ||||
| @@ -191,13 +192,13 @@ protected: | |||||
| */ | */ | ||||
| virtual void uiIdle() {} | virtual void uiIdle() {} | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| # ifndef DGL_FILE_BROWSER_DISABLED | |||||
| /** | /** | ||||
| File browser selected function. | File browser selected function. | ||||
| @see Window::fileBrowserSelected(const char*) | @see Window::fileBrowserSelected(const char*) | ||||
| */ | */ | ||||
| virtual void uiFileBrowserSelected(const char* filename); | virtual void uiFileBrowserSelected(const char* filename); | ||||
| #endif | |||||
| # endif | |||||
| /** | /** | ||||
| OpenGL window reshape function, called when parent window is resized. | OpenGL window reshape function, called when parent window is resized. | ||||
| @@ -225,7 +226,7 @@ private: | |||||
| friend class UIExporter; | friend class UIExporter; | ||||
| friend class UIExporterWindow; | friend class UIExporterWindow; | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| // these should not be used | // these should not be used | ||||
| void setAbsoluteX(int) const noexcept {} | void setAbsoluteX(int) const noexcept {} | ||||
| void setAbsoluteY(int) const noexcept {} | void setAbsoluteY(int) const noexcept {} | ||||
| @@ -40,6 +40,8 @@ public: | |||||
| : width(w), | : width(w), | ||||
| height(h), | height(h), | ||||
| title(t), | title(t), | ||||
| transientWinId(0), | |||||
| visible(false), | |||||
| pid(0) {} | pid(0) {} | ||||
| virtual ~ExternalWindow() | virtual ~ExternalWindow() | ||||
| @@ -62,9 +64,14 @@ public: | |||||
| return title; | return title; | ||||
| } | } | ||||
| void setTitle(const char* const t) noexcept | |||||
| uintptr_t getTransientWinId() const noexcept | |||||
| { | { | ||||
| title = t; | |||||
| return transientWinId; | |||||
| } | |||||
| bool isVisible() const noexcept | |||||
| { | |||||
| return visible; | |||||
| } | } | ||||
| bool isRunning() noexcept | bool isRunning() noexcept | ||||
| @@ -84,6 +91,27 @@ public: | |||||
| return true; | return true; | ||||
| } | } | ||||
| virtual void setSize(uint w, uint h) | |||||
| { | |||||
| width = w; | |||||
| height = h; | |||||
| } | |||||
| virtual void setTitle(const char* const t) | |||||
| { | |||||
| title = t; | |||||
| } | |||||
| virtual void setTransientWinId(const uintptr_t winId) | |||||
| { | |||||
| transientWinId = winId; | |||||
| } | |||||
| virtual void setVisible(const bool yesNo) | |||||
| { | |||||
| visible = yesNo; | |||||
| } | |||||
| protected: | protected: | ||||
| bool startExternalProcess(const char* args[]) | bool startExternalProcess(const char* args[]) | ||||
| { | { | ||||
| @@ -107,14 +135,6 @@ protected: | |||||
| } | } | ||||
| } | } | ||||
| private: | |||||
| uint width; | |||||
| uint height; | |||||
| String title; | |||||
| pid_t pid; | |||||
| friend class UIExporter; | |||||
| void terminateAndWaitForProcess() | void terminateAndWaitForProcess() | ||||
| { | { | ||||
| if (pid <= 0) | if (pid <= 0) | ||||
| @@ -162,6 +182,16 @@ private: | |||||
| } | } | ||||
| } | } | ||||
| private: | |||||
| uint width; | |||||
| uint height; | |||||
| String title; | |||||
| uintptr_t transientWinId; | |||||
| bool visible; | |||||
| pid_t pid; | |||||
| friend class UIExporter; | |||||
| DISTRHO_DECLARE_NON_COPY_CLASS(ExternalWindow) | DISTRHO_DECLARE_NON_COPY_CLASS(ExternalWindow) | ||||
| }; | }; | ||||
| @@ -16,11 +16,6 @@ | |||||
| #include "DistrhoPluginInternal.hpp" | #include "DistrhoPluginInternal.hpp" | ||||
| #if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| # undef DISTRHO_PLUGIN_HAS_UI | |||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| # include "DistrhoUIInternal.hpp" | # include "DistrhoUIInternal.hpp" | ||||
| #else | #else | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -15,8 +15,7 @@ | |||||
| */ | */ | ||||
| #include "DistrhoUIInternal.hpp" | #include "DistrhoUIInternal.hpp" | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| # include "src/WidgetPrivateData.hpp" | # include "src/WidgetPrivateData.hpp" | ||||
| #endif | #endif | ||||
| @@ -27,16 +26,21 @@ START_NAMESPACE_DISTRHO | |||||
| double d_lastUiSampleRate = 0.0; | double d_lastUiSampleRate = 0.0; | ||||
| void* d_lastUiDspPtr = nullptr; | void* d_lastUiDspPtr = nullptr; | ||||
| #ifdef HAVE_DGL | |||||
| Window* d_lastUiWindow = nullptr; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| uintptr_t g_nextWindowId = 0; | uintptr_t g_nextWindowId = 0; | ||||
| const char* g_nextBundlePath = nullptr; | const char* g_nextBundlePath = nullptr; | ||||
| #else | |||||
| Window* d_lastUiWindow = nullptr; | |||||
| #endif | |||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * UI */ | * UI */ | ||||
| #ifdef HAVE_DGL | |||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| UI::UI(uint width, uint height, bool userResizable) | |||||
| : UIWidget(width, height), | |||||
| pData(new PrivateData(userResizable)) {} | |||||
| #else | |||||
| UI::UI(uint width, uint height, bool userResizable) | UI::UI(uint width, uint height, bool userResizable) | ||||
| : UIWidget(*d_lastUiWindow), | : UIWidget(*d_lastUiWindow), | ||||
| pData(new PrivateData(userResizable)) | pData(new PrivateData(userResizable)) | ||||
| @@ -46,10 +50,6 @@ UI::UI(uint width, uint height, bool userResizable) | |||||
| if (width > 0 && height > 0) | if (width > 0 && height > 0) | ||||
| setSize(width, height); | setSize(width, height); | ||||
| } | } | ||||
| #else | |||||
| UI::UI(uint width, uint height, bool userResizable) | |||||
| : UIWidget(width, height), | |||||
| pData(new PrivateData(userResizable)) {} | |||||
| #endif | #endif | ||||
| UI::~UI() | UI::~UI() | ||||
| @@ -62,7 +62,7 @@ bool UI::isUserResizable() const noexcept | |||||
| return pData->userResizable; | return pData->userResizable; | ||||
| } | } | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale) | void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(minWidth > 0,); | DISTRHO_SAFE_ASSERT_RETURN(minWidth > 0,); | ||||
| @@ -73,7 +73,6 @@ void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRa | |||||
| pData->minHeight = minHeight; | pData->minHeight = minHeight; | ||||
| getParentWindow().setGeometryConstraints(minWidth, minHeight, keepAspectRatio); | getParentWindow().setGeometryConstraints(minWidth, minHeight, keepAspectRatio); | ||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -141,15 +140,15 @@ uintptr_t UI::getNextWindowId() noexcept | |||||
| void UI::sampleRateChanged(double) {} | void UI::sampleRateChanged(double) {} | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * UI Callbacks (optional) */ | * UI Callbacks (optional) */ | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| # ifndef DGL_FILE_BROWSER_DISABLED | |||||
| void UI::uiFileBrowserSelected(const char*) | void UI::uiFileBrowserSelected(const char*) | ||||
| { | { | ||||
| } | } | ||||
| #endif | |||||
| # endif | |||||
| void UI::uiReshape(uint width, uint height) | void UI::uiReshape(uint width, uint height) | ||||
| { | { | ||||
| @@ -173,7 +172,7 @@ void UI::onResize(const ResizeEvent& ev) | |||||
| pData->setSizeCallback(ev.size.getWidth(), ev.size.getHeight()); | pData->setSizeCallback(ev.size.getWidth(), ev.size.getHeight()); | ||||
| } | } | ||||
| #endif | |||||
| #endif // !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| // ----------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------- | ||||
| @@ -112,6 +112,7 @@ public: | |||||
| void exec() | void exec() | ||||
| { | { | ||||
| d_stdout("exec 1"); | |||||
| for (;;) | for (;;) | ||||
| { | { | ||||
| fOscData.idle(); | fOscData.idle(); | ||||
| @@ -121,6 +122,7 @@ public: | |||||
| d_msleep(30); | d_msleep(30); | ||||
| } | } | ||||
| d_stdout("exec 3"); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -19,7 +19,10 @@ | |||||
| #include "../DistrhoUI.hpp" | #include "../DistrhoUI.hpp" | ||||
| #ifdef HAVE_DGL | |||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| # include "../extra/Sleep.hpp" | |||||
| using DGL_NAMESPACE::IdleCallback; | |||||
| #else | |||||
| # include "../../dgl/Application.hpp" | # include "../../dgl/Application.hpp" | ||||
| # include "../../dgl/Window.hpp" | # include "../../dgl/Window.hpp" | ||||
| using DGL_NAMESPACE::Application; | using DGL_NAMESPACE::Application; | ||||
| @@ -34,7 +37,7 @@ START_NAMESPACE_DISTRHO | |||||
| extern double d_lastUiSampleRate; | extern double d_lastUiSampleRate; | ||||
| extern void* d_lastUiDspPtr; | extern void* d_lastUiDspPtr; | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| extern Window* d_lastUiWindow; | extern Window* d_lastUiWindow; | ||||
| #endif | #endif | ||||
| extern uintptr_t g_nextWindowId; | extern uintptr_t g_nextWindowId; | ||||
| @@ -146,7 +149,20 @@ struct UI::PrivateData { | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Plugin Window, needed to take care of resize properly | // Plugin Window, needed to take care of resize properly | ||||
| #ifdef HAVE_DGL | |||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| static inline | |||||
| UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const char* const bundlePath) | |||||
| { | |||||
| d_lastUiDspPtr = dspPtr; | |||||
| g_nextWindowId = winId; | |||||
| g_nextBundlePath = bundlePath; | |||||
| UI* const ret = createUI(); | |||||
| d_lastUiDspPtr = nullptr; | |||||
| g_nextWindowId = 0; | |||||
| g_nextBundlePath = nullptr; | |||||
| return ret; | |||||
| } | |||||
| #else // DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| static inline | static inline | ||||
| UI* createUiWrapper(void* const dspPtr, Window* const window) | UI* createUiWrapper(void* const dspPtr, Window* const window) | ||||
| { | { | ||||
| @@ -212,7 +228,7 @@ protected: | |||||
| fIsReady = true; | fIsReady = true; | ||||
| } | } | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| # ifndef DGL_FILE_BROWSER_DISABLED | |||||
| // custom file-browser selected | // custom file-browser selected | ||||
| void fileBrowserSelected(const char* filename) override | void fileBrowserSelected(const char* filename) override | ||||
| { | { | ||||
| @@ -220,26 +236,13 @@ protected: | |||||
| fUI->uiFileBrowserSelected(filename); | fUI->uiFileBrowserSelected(filename); | ||||
| } | } | ||||
| #endif | |||||
| # endif | |||||
| private: | private: | ||||
| UI* const fUI; | UI* const fUI; | ||||
| bool fIsReady; | bool fIsReady; | ||||
| }; | }; | ||||
| #else | |||||
| static inline | |||||
| UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const char* const bundlePath) | |||||
| { | |||||
| d_lastUiDspPtr = dspPtr; | |||||
| g_nextWindowId = winId; | |||||
| g_nextBundlePath = bundlePath; | |||||
| UI* const ret = createUI(); | |||||
| d_lastUiDspPtr = nullptr; | |||||
| g_nextWindowId = 0; | |||||
| g_nextBundlePath = nullptr; | |||||
| return ret; | |||||
| } | |||||
| #endif | |||||
| #endif // DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // UI exporter class | // UI exporter class | ||||
| @@ -256,13 +259,13 @@ public: | |||||
| const setSizeFunc setSizeCall, | const setSizeFunc setSizeCall, | ||||
| void* const dspPtr = nullptr, | void* const dspPtr = nullptr, | ||||
| const char* const bundlePath = nullptr) | const char* const bundlePath = nullptr) | ||||
| #ifdef HAVE_DGL | |||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| : fUI(createUiWrapper(dspPtr, winId, bundlePath)), | |||||
| #else | |||||
| : glApp(), | : glApp(), | ||||
| glWindow(glApp, winId, dspPtr), | glWindow(glApp, winId, dspPtr), | ||||
| fChangingSize(false), | fChangingSize(false), | ||||
| fUI(glWindow.getUI()), | fUI(glWindow.getUI()), | ||||
| #else | |||||
| : fUI(createUiWrapper(dspPtr, winId, bundlePath)), | |||||
| #endif | #endif | ||||
| fData((fUI != nullptr) ? fUI->pData : nullptr) | fData((fUI != nullptr) ? fUI->pData : nullptr) | ||||
| { | { | ||||
| @@ -276,54 +279,65 @@ public: | |||||
| fData->sendNoteCallbackFunc = sendNoteCall; | fData->sendNoteCallbackFunc = sendNoteCall; | ||||
| fData->setSizeCallbackFunc = setSizeCall; | fData->setSizeCallbackFunc = setSizeCall; | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| // unused | // unused | ||||
| return; (void)bundlePath; | return; (void)bundlePath; | ||||
| #endif | #endif | ||||
| } | } | ||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| ~UIExporter() | |||||
| { | |||||
| delete fUI; | |||||
| } | |||||
| #endif | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| uint getWidth() const noexcept | uint getWidth() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.getWidth(); | |||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1); | ||||
| return fUI->getWidth(); | return fUI->getWidth(); | ||||
| #endif | |||||
| } | } | ||||
| uint getHeight() const noexcept | uint getHeight() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.getHeight(); | |||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1); | ||||
| return fUI->getHeight(); | return fUI->getHeight(); | ||||
| #endif | |||||
| } | } | ||||
| bool isVisible() const noexcept | bool isVisible() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.isVisible(); | |||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | ||||
| return fUI->isRunning(); | return fUI->isRunning(); | ||||
| #endif | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | |||||
| intptr_t getWindowId() const noexcept | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| #else | |||||
| uint getWidth() const noexcept | |||||
| { | |||||
| return glWindow.getWidth(); | |||||
| } | |||||
| uint getHeight() const noexcept | |||||
| { | |||||
| return glWindow.getHeight(); | |||||
| } | |||||
| bool isVisible() const noexcept | |||||
| { | |||||
| return glWindow.isVisible(); | |||||
| } | |||||
| intptr_t getWindowId() const noexcept | intptr_t getWindowId() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.getWindowId(); | return glWindow.getWindowId(); | ||||
| #else | |||||
| return 0; | |||||
| #endif | |||||
| } | } | ||||
| #endif | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -365,7 +379,39 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| #ifdef HAVE_DGL | |||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| void exec(IdleCallback* const cb) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||||
| fUI->setVisible(true); | |||||
| cb->idleCallback(); | |||||
| while (fUI->isRunning()) | |||||
| { | |||||
| d_msleep(10); | |||||
| cb->idleCallback(); | |||||
| } | |||||
| } | |||||
| void exec_idle() | |||||
| { | |||||
| } | |||||
| bool idle() | |||||
| { | |||||
| return true; | |||||
| } | |||||
| void quit() | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||||
| fUI->setVisible(false); | |||||
| fUI->terminateAndWaitForProcess(); | |||||
| } | |||||
| #else | |||||
| void exec(IdleCallback* const cb) | void exec(IdleCallback* const cb) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | ||||
| @@ -381,48 +427,64 @@ public: | |||||
| if (glWindow.isReady()) | if (glWindow.isReady()) | ||||
| fUI->uiIdle(); | fUI->uiIdle(); | ||||
| } | } | ||||
| #endif | |||||
| bool idle() | bool idle() | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | ||||
| #ifdef HAVE_DGL | |||||
| glApp.idle(); | glApp.idle(); | ||||
| if (glWindow.isReady()) | if (glWindow.isReady()) | ||||
| fUI->uiIdle(); | fUI->uiIdle(); | ||||
| return ! glApp.isQuiting(); | return ! glApp.isQuiting(); | ||||
| #else | |||||
| return fUI->isRunning(); | |||||
| #endif | |||||
| } | } | ||||
| void quit() | void quit() | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| glWindow.close(); | glWindow.close(); | ||||
| glApp.quit(); | glApp.quit(); | ||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||||
| fUI->terminateAndWaitForProcess(); | |||||
| #endif | |||||
| } | } | ||||
| #endif | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| void setWindowTitle(const char* const uiTitle) | void setWindowTitle(const char* const uiTitle) | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| glWindow.setTitle(uiTitle); | |||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | ||||
| fUI->setTitle(uiTitle); | fUI->setTitle(uiTitle); | ||||
| #endif | |||||
| } | } | ||||
| #ifdef HAVE_DGL | |||||
| void setWindowSize(const uint width, const uint height, const bool = false) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||||
| fUI->setSize(width, height); | |||||
| } | |||||
| void setWindowTransientWinId(const uintptr_t winId) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||||
| fUI->setTransientWinId(winId); | |||||
| } | |||||
| bool setWindowVisible(const bool yesNo) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | |||||
| fUI->setVisible(yesNo); | |||||
| return fUI->isRunning(); | |||||
| } | |||||
| #else | |||||
| void setWindowTitle(const char* const uiTitle) | |||||
| { | |||||
| glWindow.setTitle(uiTitle); | |||||
| } | |||||
| void setWindowSize(const uint width, const uint height, const bool updateUI = false) | void setWindowSize(const uint width, const uint height, const bool updateUI = false) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | ||||
| @@ -459,10 +521,6 @@ public: | |||||
| { | { | ||||
| return glWindow.handlePluginSpecial(press, key); | return glWindow.handlePluginSpecial(press, key); | ||||
| } | } | ||||
| #else | |||||
| void setWindowSize(const uint, const uint, const bool = false) {} | |||||
| void setWindowTransientWinId(const uintptr_t) {} | |||||
| bool setWindowVisible(const bool) { return true; } | |||||
| #endif | #endif | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -483,7 +541,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| #ifdef HAVE_DGL | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // DGL Application and Window for this widget | // DGL Application and Window for this widget | ||||
| @@ -0,0 +1,36 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * 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. | |||||
| */ | |||||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||||
| #define DISTRHO_PLUGIN_NAME "ExternalUI" | |||||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/ExternalUI" | |||||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||||
| #define DISTRHO_PLUGIN_HAS_EMBED_UI 0 | |||||
| #define DISTRHO_PLUGIN_HAS_EXTERNAL_UI 1 | |||||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||||
| #define DISTRHO_PLUGIN_NUM_INPUTS 1 | |||||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 1 | |||||
| enum Parameters { | |||||
| kParameterLevel = 0, | |||||
| kParameterCount | |||||
| }; | |||||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||||
| @@ -0,0 +1,188 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * 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 "DistrhoPlugin.hpp" | |||||
| START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------------------------------------------- | |||||
| /** | |||||
| Plugin to show how to get some basic information sent to the UI. | |||||
| */ | |||||
| class ExternalExamplePlugin : public Plugin | |||||
| { | |||||
| public: | |||||
| ExternalExamplePlugin() | |||||
| : Plugin(kParameterCount, 0, 0), | |||||
| fValue(0.0f) | |||||
| { | |||||
| } | |||||
| protected: | |||||
| /* -------------------------------------------------------------------------------------------------------- | |||||
| * Information */ | |||||
| /** | |||||
| Get the plugin label. | |||||
| This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. | |||||
| */ | |||||
| const char* getLabel() const override | |||||
| { | |||||
| return "ExternalUI"; | |||||
| } | |||||
| /** | |||||
| Get an extensive comment/description about the plugin. | |||||
| */ | |||||
| const char* getDescription() const override | |||||
| { | |||||
| return "Plugin to show how to use an external / remote UI."; | |||||
| } | |||||
| /** | |||||
| Get the plugin author/maker. | |||||
| */ | |||||
| const char* getMaker() const override | |||||
| { | |||||
| return "DISTRHO"; | |||||
| } | |||||
| /** | |||||
| Get the plugin homepage. | |||||
| */ | |||||
| const char* getHomePage() const override | |||||
| { | |||||
| return "https://github.com/DISTRHO/DPF"; | |||||
| } | |||||
| /** | |||||
| Get the plugin license name (a single line of text). | |||||
| For commercial plugins this should return some short copyright information. | |||||
| */ | |||||
| const char* getLicense() const override | |||||
| { | |||||
| return "ISC"; | |||||
| } | |||||
| /** | |||||
| Get the plugin version, in hexadecimal. | |||||
| */ | |||||
| uint32_t getVersion() const override | |||||
| { | |||||
| return d_version(1, 0, 0); | |||||
| } | |||||
| /** | |||||
| Get the plugin unique Id. | |||||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||||
| */ | |||||
| int64_t getUniqueId() const override | |||||
| { | |||||
| return d_cconst('d', 'E', 'x', 't'); | |||||
| } | |||||
| /* -------------------------------------------------------------------------------------------------------- | |||||
| * Init */ | |||||
| /** | |||||
| Initialize the parameter @a index. | |||||
| This function will be called once, shortly after the plugin is created. | |||||
| */ | |||||
| void initParameter(uint32_t index, Parameter& parameter) override | |||||
| { | |||||
| if (index != 0) | |||||
| return; | |||||
| parameter.hints = kParameterIsAutomable|kParameterIsInteger; | |||||
| parameter.ranges.def = 0.0f; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 100.0f; | |||||
| parameter.name = "Value"; | |||||
| parameter.symbol = "value"; | |||||
| } | |||||
| /* -------------------------------------------------------------------------------------------------------- | |||||
| * Internal data */ | |||||
| /** | |||||
| Get the current value of a parameter. | |||||
| The host may call this function from any context, including realtime processing. | |||||
| */ | |||||
| float getParameterValue(uint32_t index) const override | |||||
| { | |||||
| if (index != 0) | |||||
| return 0.0f; | |||||
| return fValue; | |||||
| } | |||||
| /** | |||||
| Change a parameter value. | |||||
| The host may call this function from any context, including realtime processing. | |||||
| When a parameter is marked as automable, you must ensure no non-realtime operations are performed. | |||||
| @note This function will only be called for parameter inputs. | |||||
| */ | |||||
| void setParameterValue(uint32_t index, float value) override | |||||
| { | |||||
| if (index != 0) | |||||
| return; | |||||
| fValue = value; | |||||
| } | |||||
| /* -------------------------------------------------------------------------------------------------------- | |||||
| * Audio/MIDI Processing */ | |||||
| /** | |||||
| Run/process function for plugins without MIDI input. | |||||
| @note Some parameters might be null if there are no audio inputs or outputs. | |||||
| */ | |||||
| void run(const float** inputs, float** outputs, uint32_t frames) override | |||||
| { | |||||
| /** | |||||
| This plugin does nothing, it just demonstrates information usage. | |||||
| So here we directly copy inputs over outputs, leaving the audio untouched. | |||||
| We need to be careful in case the host re-uses the same buffer for both ins and outs. | |||||
| */ | |||||
| if (outputs[0] != inputs[0]) | |||||
| std::memcpy(outputs[0], inputs[0], sizeof(float)*frames); | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------- | |||||
| private: | |||||
| // Parameters | |||||
| float fValue; | |||||
| /** | |||||
| Set our plugin class as non-copyable and add a leak detector just in case. | |||||
| */ | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExternalExamplePlugin) | |||||
| }; | |||||
| /* ------------------------------------------------------------------------------------------------------------ | |||||
| * Plugin entry point, called by DPF to create a new plugin instance. */ | |||||
| Plugin* createPlugin() | |||||
| { | |||||
| return new ExternalExamplePlugin(); | |||||
| } | |||||
| // ----------------------------------------------------------------------------------------------------------- | |||||
| END_NAMESPACE_DISTRHO | |||||
| @@ -0,0 +1,187 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * 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 "DistrhoUI.hpp" | |||||
| // Extra includes for current path and fifo stuff | |||||
| #include <dlfcn.h> | |||||
| #include <fcntl.h> | |||||
| #include <sys/stat.h> | |||||
| #include <sys/types.h> | |||||
| START_NAMESPACE_DISTRHO | |||||
| // TODO: generate a random, not-yet-existing, filename | |||||
| const char* const kFifoFilename = "/tmp/dpf-fifo-test"; | |||||
| // Helper to get current path of this plugin | |||||
| static const char* getCurrentPluginFilename() | |||||
| { | |||||
| Dl_info exeInfo; | |||||
| void* localSymbol = (void*)kFifoFilename; | |||||
| dladdr(localSymbol, &exeInfo); | |||||
| return exeInfo.dli_fname; | |||||
| } | |||||
| // Helper to check if a file exists | |||||
| static bool fileExists(const char* const filename) | |||||
| { | |||||
| return access(filename, F_OK) != -1; | |||||
| } | |||||
| // Helper function to keep trying to write until it succeeds or really errors out | |||||
| static ssize_t | |||||
| writeRetry(int fd, const void* src, size_t size) | |||||
| { | |||||
| ssize_t error; | |||||
| do { | |||||
| error = write(fd, src, size); | |||||
| } while (error == -1 && (errno == EINTR || errno == EPIPE)); | |||||
| return error; | |||||
| } | |||||
| // ----------------------------------------------------------------------------------------------------------- | |||||
| class ExternalExampleUI : public UI | |||||
| { | |||||
| public: | |||||
| ExternalExampleUI() | |||||
| : UI(405, 256, true), | |||||
| fFifo(-1), | |||||
| fValue(0.0f), | |||||
| fExternalScript(getNextBundlePath()) | |||||
| { | |||||
| if (fExternalScript.isEmpty()) | |||||
| { | |||||
| fExternalScript = getCurrentPluginFilename(); | |||||
| fExternalScript.truncate(fExternalScript.rfind('/')); | |||||
| } | |||||
| fExternalScript += "/d_extui.sh"; | |||||
| d_stdout("External script = %s", fExternalScript.buffer()); | |||||
| } | |||||
| protected: | |||||
| /* -------------------------------------------------------------------------------------------------------- | |||||
| * DSP/Plugin Callbacks */ | |||||
| /** | |||||
| A parameter has changed on the plugin side. | |||||
| This is called by the host to inform the UI about parameter changes. | |||||
| */ | |||||
| void parameterChanged(uint32_t index, float value) override | |||||
| { | |||||
| if (index != 0) | |||||
| return; | |||||
| fValue = value; | |||||
| if (fFifo == -1) | |||||
| return; | |||||
| // NOTE: This is a terrible way to pass values, also locale might get in the way... | |||||
| char valueStr[24]; | |||||
| std::memset(valueStr, 0, sizeof(valueStr)); | |||||
| std::snprintf(valueStr, 23, "%i\n", static_cast<int>(value + 0.5f)); | |||||
| DISTRHO_SAFE_ASSERT(writeRetry(fFifo, valueStr, 24) == sizeof(valueStr)); | |||||
| } | |||||
| /* -------------------------------------------------------------------------------------------------------- | |||||
| * External Window overrides */ | |||||
| /** | |||||
| Manage external process and IPC when UI is requested to be visible. | |||||
| */ | |||||
| void setVisible(const bool yesNo) override | |||||
| { | |||||
| if (yesNo) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fileExists(fExternalScript),); | |||||
| mkfifo(kFifoFilename, 0666); | |||||
| sync(); | |||||
| char winIdStr[24]; | |||||
| std::memset(winIdStr, 0, sizeof(winIdStr)); | |||||
| std::snprintf(winIdStr, 23, "%lu", getTransientWinId()); | |||||
| const char* args[] = { | |||||
| fExternalScript.buffer(), | |||||
| kFifoFilename, | |||||
| "--progressbar", "External UI example", | |||||
| "--title", getTitle(), | |||||
| nullptr, | |||||
| }; | |||||
| DISTRHO_SAFE_ASSERT_RETURN(startExternalProcess(args),); | |||||
| // NOTE: this can lockup the current thread if the other side does not read the file! | |||||
| fFifo = open(kFifoFilename, O_WRONLY); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fFifo != -1,); | |||||
| parameterChanged(0, fValue); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (fFifo != -1) | |||||
| { | |||||
| if (isRunning()) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT(writeRetry(fFifo, "quit\n", 5) == 5); | |||||
| fsync(fFifo); | |||||
| } | |||||
| close(fFifo); | |||||
| fFifo = -1; | |||||
| } | |||||
| unlink(kFifoFilename); | |||||
| terminateAndWaitForProcess(); | |||||
| } | |||||
| UI::setVisible(yesNo); | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------- | |||||
| private: | |||||
| // IPC Stuff | |||||
| int fFifo; | |||||
| // Current value, cached for when UI becomes visible | |||||
| float fValue; | |||||
| // Path to external ui script | |||||
| String fExternalScript; | |||||
| /** | |||||
| Set our UI class as non-copyable and add a leak detector just in case. | |||||
| */ | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExternalExampleUI) | |||||
| }; | |||||
| /* ------------------------------------------------------------------------------------------------------------ | |||||
| * UI entry point, called by DPF to create a new UI instance. */ | |||||
| UI* createUI() | |||||
| { | |||||
| return new ExternalExampleUI(); | |||||
| } | |||||
| // ----------------------------------------------------------------------------------------------------------- | |||||
| END_NAMESPACE_DISTRHO | |||||
| @@ -0,0 +1,40 @@ | |||||
| #!/bin/bash | |||||
| # Read FIFO argument from CLI | |||||
| FIFO=${1} | |||||
| shift | |||||
| if [ ! -e "${FIFO}" ]; then | |||||
| echo "Fifo file ${FIFO} does not exist, cannot run" | |||||
| exit 1 | |||||
| fi | |||||
| # Start kdialog with all other arguments and get dbus reference | |||||
| dbusRef=$(kdialog "$@" 100) | |||||
| if [ $? -ne 0 ] || [ -z "${dbusRef}" ]; then | |||||
| echo "Failed to start kdialog" | |||||
| exit 1 | |||||
| fi | |||||
| # Setup cancellation point for this script | |||||
| quitfn() { | |||||
| qdbus ${dbusRef} close 2>/dev/null | |||||
| } | |||||
| trap quitfn SIGINT | |||||
| trap quitfn SIGTERM | |||||
| # Read Fifo for new values or a quit message | |||||
| while read line <"${FIFO}"; do | |||||
| if echo "${line}" | grep -q "quit"; then | |||||
| break | |||||
| fi | |||||
| if ! qdbus ${dbusRef} Set "" value "${line}"; then | |||||
| break | |||||
| fi | |||||
| done | |||||
| # Cleanup | |||||
| rm -f "${FIFO}" | |||||
| quitfn | |||||
| @@ -0,0 +1,40 @@ | |||||
| #!/usr/bin/make -f | |||||
| # Makefile for DISTRHO Plugins # | |||||
| # ---------------------------- # | |||||
| # Created by falkTX | |||||
| # | |||||
| # -------------------------------------------------------------- | |||||
| # Project name, used for binaries | |||||
| NAME = d_extui | |||||
| # -------------------------------------------------------------- | |||||
| # Files to build | |||||
| FILES_DSP = \ | |||||
| ExternalExamplePlugin.cpp | |||||
| FILES_UI = \ | |||||
| ExternalExampleUI.cpp | |||||
| # -------------------------------------------------------------- | |||||
| # Do some magic | |||||
| include ../../Makefile.plugins.mk | |||||
| LINK_FLAGS += -ldl | |||||
| # -------------------------------------------------------------- | |||||
| # Enable all possible plugin types | |||||
| ifeq ($(HAVE_JACK),true) | |||||
| TARGETS += jack | |||||
| endif | |||||
| TARGETS += dssi | |||||
| TARGETS += lv2_sep | |||||
| all: $(TARGETS) | |||||
| # -------------------------------------------------------------- | |||||
| @@ -0,0 +1,11 @@ | |||||
| # External UI example | |||||
| This example will show how to use an external / remote UI together with DPF.<br/> | |||||
| The Plugin has a shell script that calls kdialog and uses qdbus for sending values to it.<br/> | |||||
| It is a very ugly way to show a remote UI (using a shell script!), but it is only to prove the point.<br/> | |||||
| Note that everything regarding external UIs is still a bit experimental in DPF.<br/> | |||||
| There is Unix-specific code in there.<br/> | |||||
| If this is something you are interested on using and contributing to, please let us know.<br/> | |||||