| @@ -15,9 +15,6 @@ LINK_FLAGS += $(DGL_LIBS) | |||||
| ifneq ($(MACOS_OLD),true) | ifneq ($(MACOS_OLD),true) | ||||
| # needed by sofd right now, fix later | # needed by sofd right now, fix later | ||||
| BUILD_CXX_FLAGS += -Wno-type-limits -fpermissive | BUILD_CXX_FLAGS += -Wno-type-limits -fpermissive | ||||
| # needed by stb_image | |||||
| BUILD_CXX_FLAGS += -Wno-misleading-indentation -Wno-shift-negative-value | |||||
| endif | endif | ||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| @@ -20,7 +20,9 @@ | |||||
| #include "Color.hpp" | #include "Color.hpp" | ||||
| #include "Widget.hpp" | #include "Widget.hpp" | ||||
| #define NANOVG_DEJAVU_SANS_TTF "__dpf_dejavusans_ttf__" | |||||
| #ifndef DGL_NO_SHARED_RESOURCES | |||||
| # define NANOVG_DEJAVU_SANS_TTF "__dpf_dejavusans_ttf__" | |||||
| #endif | |||||
| struct NVGcontext; | struct NVGcontext; | ||||
| struct NVGpaint; | struct NVGpaint; | ||||
| @@ -844,10 +846,12 @@ public: | |||||
| */ | */ | ||||
| int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow& rows, int maxRows); | int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow& rows, int maxRows); | ||||
| #ifndef DGL_NO_SHARED_RESOURCES | |||||
| /** | /** | ||||
| Load DPF's internal shared resources for this NanoVG class. | Load DPF's internal shared resources for this NanoVG class. | ||||
| */ | */ | ||||
| virtual void loadSharedResources(); | virtual void loadSharedResources(); | ||||
| #endif | |||||
| private: | private: | ||||
| NVGcontext* const fContext; | NVGcontext* const fContext; | ||||
| @@ -19,6 +19,10 @@ | |||||
| #include "Geometry.hpp" | #include "Geometry.hpp" | ||||
| START_NAMESPACE_DISTRHO | |||||
| class UIExporter; | |||||
| END_NAMESPACE_DISTRHO | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -30,6 +34,7 @@ class StandaloneWindow; | |||||
| class Window | class Window | ||||
| { | { | ||||
| public: | public: | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| /** | /** | ||||
| File browser options. | File browser options. | ||||
| */ | */ | ||||
| @@ -66,6 +71,7 @@ public: | |||||
| height(0), | height(0), | ||||
| buttons() {} | buttons() {} | ||||
| }; | }; | ||||
| #endif // DGL_FILE_BROWSER_DISABLED | |||||
| explicit Window(Application& app); | explicit Window(Application& app); | ||||
| explicit Window(Application& app, Window& parent); | explicit Window(Application& app, Window& parent); | ||||
| @@ -80,7 +86,9 @@ public: | |||||
| void focus(); | void focus(); | ||||
| void repaint() noexcept; | void repaint() noexcept; | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| bool openFileBrowser(const FileBrowserOptions& options); | bool openFileBrowser(const FileBrowserOptions& options); | ||||
| #endif | |||||
| bool isVisible() const noexcept; | bool isVisible() const noexcept; | ||||
| void setVisible(bool yesNo); | void setVisible(bool yesNo); | ||||
| @@ -111,7 +119,9 @@ protected: | |||||
| virtual void onReshape(uint width, uint height); | virtual void onReshape(uint width, uint height); | ||||
| virtual void onClose(); | virtual void onClose(); | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| virtual void fileBrowserSelected(const char* filename); | virtual void fileBrowserSelected(const char* filename); | ||||
| #endif | |||||
| private: | private: | ||||
| struct PrivateData; | struct PrivateData; | ||||
| @@ -119,11 +129,15 @@ private: | |||||
| friend class Application; | friend class Application; | ||||
| friend class Widget; | friend class Widget; | ||||
| friend class StandaloneWindow; | friend class StandaloneWindow; | ||||
| friend class DISTRHO_NAMESPACE::UIExporter; | |||||
| virtual void _addWidget(Widget* const widget); | virtual void _addWidget(Widget* const widget); | ||||
| virtual void _removeWidget(Widget* const widget); | virtual void _removeWidget(Widget* const widget); | ||||
| void _idle(); | void _idle(); | ||||
| bool handlePluginKeyboard(const bool press, const uint key); | |||||
| bool handlePluginSpecial(const bool press, const Key key); | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window) | ||||
| }; | }; | ||||
| @@ -545,7 +545,7 @@ const T& Circle<T>::getX() const noexcept | |||||
| template<typename T> | template<typename T> | ||||
| const T& Circle<T>::getY() const noexcept | const T& Circle<T>::getY() const noexcept | ||||
| { | { | ||||
| return fPos.fX; | |||||
| return fPos.fY; | |||||
| } | } | ||||
| template<typename T> | template<typename T> | ||||
| @@ -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,9 +15,12 @@ | |||||
| */ | */ | ||||
| #include "../NanoVG.hpp" | #include "../NanoVG.hpp" | ||||
| #include "Resources.hpp" | |||||
| #include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
| #ifndef DGL_NO_SHARED_RESOURCES | |||||
| # include "Resources.hpp" | |||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| @@ -895,6 +898,7 @@ int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWi | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| #ifndef DGL_NO_SHARED_RESOURCES | |||||
| void NanoVG::loadSharedResources() | void NanoVG::loadSharedResources() | ||||
| { | { | ||||
| if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0) | if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0) | ||||
| @@ -904,6 +908,7 @@ void NanoVG::loadSharedResources() | |||||
| nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0); | nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0); | ||||
| } | } | ||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -972,8 +977,18 @@ END_NAMESPACE_DGL | |||||
| #undef final | #undef final | ||||
| #if defined(__GNUC__) && (__GNUC__ >= 6) | |||||
| # pragma GCC diagnostic push | |||||
| # pragma GCC diagnostic ignored "-Wmisleading-indentation" | |||||
| # pragma GCC diagnostic ignored "-Wshift-negative-value" | |||||
| #endif | |||||
| extern "C" { | extern "C" { | ||||
| #include "nanovg/nanovg.c" | #include "nanovg/nanovg.c" | ||||
| } | } | ||||
| #if defined(__GNUC__) && (__GNUC__ >= 6) | |||||
| # pragma GCC diagnostic pop | |||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -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 | ||||
| @@ -25,6 +25,11 @@ | |||||
| #include "pugl/pugl.h" | #include "pugl/pugl.h" | ||||
| #if defined(__GNUC__) && (__GNUC__ >= 7) | |||||
| # pragma GCC diagnostic push | |||||
| # pragma GCC diagnostic ignored "-Wimplicit-fallthrough" | |||||
| #endif | |||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| # include "pugl/pugl_win.cpp" | # include "pugl/pugl_win.cpp" | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| @@ -37,6 +42,10 @@ extern "C" { | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if defined(__GNUC__) && (__GNUC__ >= 7) | |||||
| # pragma GCC diagnostic pop | |||||
| #endif | |||||
| #include "ApplicationPrivateData.hpp" | #include "ApplicationPrivateData.hpp" | ||||
| #include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
| #include "../StandaloneWindow.hpp" | #include "../StandaloneWindow.hpp" | ||||
| @@ -78,11 +87,13 @@ struct Window::PrivateData { | |||||
| fWidgets(), | fWidgets(), | ||||
| fModal(), | fModal(), | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| hwnd(0) | |||||
| hwnd(nullptr), | |||||
| hwndParent(nullptr) | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| fNeedsIdle(true), | fNeedsIdle(true), | ||||
| mView(nullptr), | mView(nullptr), | ||||
| mWindow(nullptr) | |||||
| mWindow(nullptr), | |||||
| mParentWindow(nullptr) | |||||
| #else | #else | ||||
| xDisplay(nullptr), | xDisplay(nullptr), | ||||
| xWindow(0) | xWindow(0) | ||||
| @@ -106,11 +117,13 @@ struct Window::PrivateData { | |||||
| fWidgets(), | fWidgets(), | ||||
| fModal(parent.pData), | fModal(parent.pData), | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| hwnd(0) | |||||
| hwnd(nullptr), | |||||
| hwndParent(nullptr) | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| fNeedsIdle(false), | fNeedsIdle(false), | ||||
| mView(nullptr), | mView(nullptr), | ||||
| mWindow(nullptr) | |||||
| mWindow(nullptr), | |||||
| mParentWindow(nullptr) | |||||
| #else | #else | ||||
| xDisplay(nullptr), | xDisplay(nullptr), | ||||
| xWindow(0) | xWindow(0) | ||||
| @@ -120,11 +133,13 @@ struct Window::PrivateData { | |||||
| init(); | init(); | ||||
| const PuglInternals* const parentImpl(parent.pData->fView->impl); | const PuglInternals* const parentImpl(parent.pData->fView->impl); | ||||
| // NOTE: almost a 1:1 copy of setTransientWinId() | |||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| // TODO | |||||
| hwndParent = parentImpl->hwnd; | |||||
| SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)hwndParent); | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| // TODO | |||||
| //[parentImpl->window orderWindow:NSWindowBelow relativeTo:[[mView window] windowNumber]]; | |||||
| mParentWindow = parentImpl->window; | |||||
| #else | #else | ||||
| XSetTransientForHint(xDisplay, xWindow, parentImpl->win); | XSetTransientForHint(xDisplay, xWindow, parentImpl->win); | ||||
| #endif | #endif | ||||
| @@ -144,11 +159,13 @@ struct Window::PrivateData { | |||||
| fWidgets(), | fWidgets(), | ||||
| fModal(), | fModal(), | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| hwnd(0) | |||||
| hwnd(nullptr), | |||||
| hwndParent(nullptr) | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| fNeedsIdle(parentId == 0), | fNeedsIdle(parentId == 0), | ||||
| mView(nullptr), | mView(nullptr), | ||||
| mWindow(nullptr) | |||||
| mWindow(nullptr), | |||||
| mParentWindow(nullptr) | |||||
| #else | #else | ||||
| xDisplay(nullptr), | xDisplay(nullptr), | ||||
| xWindow(0) | xWindow(0) | ||||
| @@ -196,7 +213,9 @@ struct Window::PrivateData { | |||||
| puglSetSpecialFunc(fView, onSpecialCallback); | puglSetSpecialFunc(fView, onSpecialCallback); | ||||
| puglSetReshapeFunc(fView, onReshapeCallback); | puglSetReshapeFunc(fView, onReshapeCallback); | ||||
| puglSetCloseFunc(fView, onCloseCallback); | puglSetCloseFunc(fView, onCloseCallback); | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | ||||
| #endif | |||||
| puglCreateWindow(fView, nullptr); | puglCreateWindow(fView, nullptr); | ||||
| @@ -330,22 +349,6 @@ struct Window::PrivateData { | |||||
| fModal.enabled = true; | fModal.enabled = true; | ||||
| fModal.parent->fModal.childFocus = this; | fModal.parent->fModal.childFocus = this; | ||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| // Center this window | |||||
| PuglInternals* const parentImpl = fModal.parent->fView->impl; | |||||
| RECT curRect; | |||||
| RECT parentRect; | |||||
| GetWindowRect(hwnd, &curRect); | |||||
| GetWindowRect(parentImpl->hwnd, &parentRect); | |||||
| int x = parentRect.left+(parentRect.right-curRect.right)/2; | |||||
| int y = parentRect.top +(parentRect.bottom-curRect.bottom)/2; | |||||
| SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); | |||||
| UpdateWindow(hwnd); | |||||
| #endif | |||||
| fModal.parent->setVisible(true); | fModal.parent->setVisible(true); | ||||
| setVisible(true); | setVisible(true); | ||||
| @@ -390,11 +393,7 @@ struct Window::PrivateData { | |||||
| SetFocus(hwnd); | SetFocus(hwnd); | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| if (mWindow != nullptr) | if (mWindow != nullptr) | ||||
| { | |||||
| // TODO | |||||
| //[NSApp activateIgnoringOtherApps:YES]; | |||||
| //[mWindow makeKeyAndOrderFront:mWindow]; | |||||
| } | |||||
| [mWindow makeKeyWindow]; | |||||
| #else | #else | ||||
| XRaiseWindow(xDisplay, xWindow); | XRaiseWindow(xDisplay, xWindow); | ||||
| XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime); | XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime); | ||||
| @@ -426,25 +425,65 @@ struct Window::PrivateData { | |||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| if (yesNo) | if (yesNo) | ||||
| ShowWindow(hwnd, fFirstInit ? SW_SHOWNORMAL : SW_RESTORE); | |||||
| { | |||||
| if (fFirstInit) | |||||
| { | |||||
| RECT rectChild, rectParent; | |||||
| if (hwndParent != nullptr && | |||||
| GetWindowRect(hwnd, &rectChild) && | |||||
| GetWindowRect(hwndParent, &rectParent)) | |||||
| { | |||||
| SetWindowPos(hwnd, hwndParent, | |||||
| rectParent.left + (rectChild.right-rectChild.left)/2, | |||||
| rectParent.top + (rectChild.bottom-rectChild.top)/2, | |||||
| 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE); | |||||
| } | |||||
| else | |||||
| { | |||||
| ShowWindow(hwnd, SW_SHOWNORMAL); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| ShowWindow(hwnd, SW_RESTORE); | |||||
| } | |||||
| } | |||||
| else | else | ||||
| { | |||||
| ShowWindow(hwnd, SW_HIDE); | ShowWindow(hwnd, SW_HIDE); | ||||
| } | |||||
| UpdateWindow(hwnd); | UpdateWindow(hwnd); | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| if (yesNo) | if (yesNo) | ||||
| { | { | ||||
| if (mWindow != nullptr) | if (mWindow != nullptr) | ||||
| { | |||||
| if (mParentWindow != nullptr) | |||||
| [mParentWindow addChildWindow:mWindow | |||||
| ordered:NSWindowAbove]; | |||||
| [mWindow setIsVisible:YES]; | [mWindow setIsVisible:YES]; | ||||
| } | |||||
| else | else | ||||
| { | |||||
| [mView setHidden:NO]; | [mView setHidden:NO]; | ||||
| } | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| if (mWindow != nullptr) | if (mWindow != nullptr) | ||||
| { | |||||
| if (mParentWindow != nullptr) | |||||
| [mParentWindow removeChildWindow:mWindow]; | |||||
| [mWindow setIsVisible:NO]; | [mWindow setIsVisible:NO]; | ||||
| } | |||||
| else | else | ||||
| { | |||||
| [mView setHidden:YES]; | [mView setHidden:YES]; | ||||
| } | |||||
| } | } | ||||
| #else | #else | ||||
| if (yesNo) | if (yesNo) | ||||
| @@ -613,10 +652,17 @@ struct Window::PrivateData { | |||||
| void setTransientWinId(const uintptr_t winId) | void setTransientWinId(const uintptr_t winId) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(winId != 0,); | |||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| // TODO | |||||
| hwndParent = (HWND)winId; | |||||
| SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)winId); | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| // TODO | |||||
| NSWindow* const parentWindow = [NSApp windowWithWindowNumber:winId]; | |||||
| DISTRHO_SAFE_ASSERT_RETURN(parentWindow != nullptr,); | |||||
| [parentWindow addChildWindow:mWindow | |||||
| ordered:NSWindowAbove]; | |||||
| #else | #else | ||||
| XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); | XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); | ||||
| #endif | #endif | ||||
| @@ -845,6 +891,90 @@ struct Window::PrivateData { | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| bool handlePluginKeyboard(const bool press, const uint key) | |||||
| { | |||||
| DBGp("PUGL: handlePluginKeyboard : %i %i\n", press, key); | |||||
| if (fModal.childFocus != nullptr) | |||||
| { | |||||
| fModal.childFocus->focus(); | |||||
| return true; | |||||
| } | |||||
| Widget::KeyboardEvent ev; | |||||
| ev.press = press; | |||||
| ev.key = key; | |||||
| ev.mod = static_cast<Modifier>(fView->mods); | |||||
| ev.time = 0; | |||||
| if ((ev.mod & kModifierShift) != 0 && ev.key >= 'a' && ev.key <= 'z') | |||||
| ev.key -= 'a' - 'A'; // a-z -> A-Z | |||||
| FOR_EACH_WIDGET_INV(rit) | |||||
| { | |||||
| Widget* const widget(*rit); | |||||
| if (widget->isVisible() && widget->onKeyboard(ev)) | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| bool handlePluginSpecial(const bool press, const Key key) | |||||
| { | |||||
| DBGp("PUGL: handlePluginSpecial : %i %i\n", press, key); | |||||
| if (fModal.childFocus != nullptr) | |||||
| { | |||||
| fModal.childFocus->focus(); | |||||
| return true; | |||||
| } | |||||
| int mods = 0x0; | |||||
| switch (key) | |||||
| { | |||||
| case kKeyShift: | |||||
| mods |= kModifierShift; | |||||
| break; | |||||
| case kKeyControl: | |||||
| mods |= kModifierControl; | |||||
| break; | |||||
| case kKeyAlt: | |||||
| mods |= kModifierAlt; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| if (mods != 0x0) | |||||
| { | |||||
| if (press) | |||||
| fView->mods |= mods; | |||||
| else | |||||
| fView->mods &= ~(mods); | |||||
| } | |||||
| Widget::SpecialEvent ev; | |||||
| ev.press = press; | |||||
| ev.key = key; | |||||
| ev.mod = static_cast<Modifier>(fView->mods); | |||||
| ev.time = 0; | |||||
| FOR_EACH_WIDGET_INV(rit) | |||||
| { | |||||
| Widget* const widget(*rit); | |||||
| if (widget->isVisible() && widget->onSpecial(ev)) | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| Application& fApp; | Application& fApp; | ||||
| Window* fSelf; | Window* fSelf; | ||||
| PuglView* fView; | PuglView* fView; | ||||
| @@ -883,11 +1013,13 @@ struct Window::PrivateData { | |||||
| } fModal; | } fModal; | ||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| HWND hwnd; | |||||
| HWND hwnd; | |||||
| HWND hwndParent; | |||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| bool fNeedsIdle; | bool fNeedsIdle; | ||||
| PuglOpenGLView* mView; | PuglOpenGLView* mView; | ||||
| id mWindow; | id mWindow; | ||||
| id mParentWindow; | |||||
| #else | #else | ||||
| Display* xDisplay; | Display* xDisplay; | ||||
| ::Window xWindow; | ::Window xWindow; | ||||
| @@ -938,10 +1070,12 @@ struct Window::PrivateData { | |||||
| handlePtr->onPuglClose(); | handlePtr->onPuglClose(); | ||||
| } | } | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| static void fileBrowserSelectedCallback(PuglView* view, const char* filename) | static void fileBrowserSelectedCallback(PuglView* view, const char* filename) | ||||
| { | { | ||||
| handlePtr->fSelf->fileBrowserSelected(filename); | handlePtr->fSelf->fileBrowserSelected(filename); | ||||
| } | } | ||||
| #endif | |||||
| #undef handlePtr | #undef handlePtr | ||||
| @@ -1001,9 +1135,10 @@ void Window::repaint() noexcept | |||||
| // (void)name; | // (void)name; | ||||
| // } | // } | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| bool Window::openFileBrowser(const FileBrowserOptions& options) | bool Window::openFileBrowser(const FileBrowserOptions& options) | ||||
| { | { | ||||
| #ifdef SOFD_HAVE_X11 | |||||
| # ifdef SOFD_HAVE_X11 | |||||
| using DISTRHO_NAMESPACE::String; | using DISTRHO_NAMESPACE::String; | ||||
| // -------------------------------------------------------------------------- | // -------------------------------------------------------------------------- | ||||
| @@ -1061,11 +1196,12 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) | |||||
| // show | // show | ||||
| return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0); | return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0); | ||||
| #else | |||||
| # else | |||||
| // not implemented | // not implemented | ||||
| return false; | return false; | ||||
| #endif | |||||
| # endif | |||||
| } | } | ||||
| #endif | |||||
| bool Window::isVisible() const noexcept | bool Window::isVisible() const noexcept | ||||
| { | { | ||||
| @@ -1196,9 +1332,21 @@ void Window::onClose() | |||||
| { | { | ||||
| } | } | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| void Window::fileBrowserSelected(const char*) | void Window::fileBrowserSelected(const char*) | ||||
| { | { | ||||
| } | } | ||||
| #endif | |||||
| bool Window::handlePluginKeyboard(const bool press, const uint key) | |||||
| { | |||||
| return pData->handlePluginKeyboard(press, key); | |||||
| } | |||||
| bool Window::handlePluginSpecial(const bool press, const Key key) | |||||
| { | |||||
| return pData->handlePluginSpecial(press, key); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -24,6 +24,9 @@ | |||||
| #include "pugl_internal.h" | #include "pugl_internal.h" | ||||
| #define PuglWindow PuglWindow ## DGL_NAMESPACE | |||||
| #define PuglOpenGLView PuglOpenGLView ## DGL_NAMESPACE | |||||
| @interface PuglWindow : NSWindow | @interface PuglWindow : NSWindow | ||||
| { | { | ||||
| @public | @public | ||||
| @@ -438,13 +441,11 @@ void | |||||
| puglLeaveContext(PuglView* view, bool flush) | puglLeaveContext(PuglView* view, bool flush) | ||||
| { | { | ||||
| #ifdef PUGL_HAVE_GL | #ifdef PUGL_HAVE_GL | ||||
| if (view->ctx_type == PUGL_GL) { | |||||
| if (flush) { | |||||
| if (view->impl->glview->doubleBuffered) { | |||||
| [[view->impl->glview openGLContext] flushBuffer]; | |||||
| } else { | |||||
| glFlush(); | |||||
| } | |||||
| if (view->ctx_type == PUGL_GL && flush) { | |||||
| if (view->impl->glview->doubleBuffered) { | |||||
| [[view->impl->glview openGLContext] flushBuffer]; | |||||
| } else { | |||||
| glFlush(); | |||||
| } | } | ||||
| //[NSOpenGLContext clearCurrentContext]; | //[NSOpenGLContext clearCurrentContext]; | ||||
| } | } | ||||
| @@ -572,4 +573,7 @@ void* | |||||
| puglGetContext(PuglView* view) | puglGetContext(PuglView* view) | ||||
| { | { | ||||
| return NULL; | return NULL; | ||||
| // unused | |||||
| (void)view; | |||||
| } | } | ||||
| @@ -41,9 +41,11 @@ | |||||
| #include "pugl/pugl_internal.h" | #include "pugl/pugl_internal.h" | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| #define SOFD_HAVE_X11 | #define SOFD_HAVE_X11 | ||||
| #include "../sofd/libsofd.h" | #include "../sofd/libsofd.h" | ||||
| #include "../sofd/libsofd.c" | #include "../sofd/libsofd.c" | ||||
| #endif | |||||
| struct PuglInternalsImpl { | struct PuglInternalsImpl { | ||||
| Display* display; | Display* display; | ||||
| @@ -339,7 +341,9 @@ puglDestroy(PuglView* view) | |||||
| return; | return; | ||||
| } | } | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| x_fib_close(view->impl->display); | x_fib_close(view->impl->display); | ||||
| #endif | |||||
| destroyContext(view); | destroyContext(view); | ||||
| XDestroyWindow(view->impl->display, view->impl->win); | XDestroyWindow(view->impl->display, view->impl->win); | ||||
| @@ -441,7 +445,7 @@ dispatchKey(PuglView* view, XEvent* event, bool press) | |||||
| view->redisplay = false; | view->redisplay = false; | ||||
| return; | return; | ||||
| } | } | ||||
| if (n == 0) { | |||||
| if (n == 0 && sym == 0) { | |||||
| goto send_event; | goto send_event; | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -477,6 +481,7 @@ puglProcessEvents(PuglView* view) | |||||
| while (XPending(view->impl->display) > 0) { | while (XPending(view->impl->display) > 0) { | ||||
| XNextEvent(view->impl->display, &event); | XNextEvent(view->impl->display, &event); | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| if (x_fib_handle_events(view->impl->display, &event)) { | if (x_fib_handle_events(view->impl->display, &event)) { | ||||
| const int status = x_fib_status(); | const int status = x_fib_status(); | ||||
| @@ -495,6 +500,7 @@ puglProcessEvents(PuglView* view) | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| #endif | |||||
| if (event.xany.window != view->impl->win && | if (event.xany.window != view->impl->win && | ||||
| (view->parent == 0 || event.xany.window != (Window)view->parent)) { | (view->parent == 0 || event.xany.window != (Window)view->parent)) { | ||||
| @@ -2126,6 +2126,7 @@ int x_fib_handle_events (Display *dpy, XEvent *event) { | |||||
| if (!strcmp (XGetAtomName (dpy, event->xclient.message_type), "WM_PROTOCOLS")) { | if (!strcmp (XGetAtomName (dpy, event->xclient.message_type), "WM_PROTOCOLS")) { | ||||
| _status = -1; | _status = -1; | ||||
| } | } | ||||
| break; | |||||
| case ConfigureNotify: | case ConfigureNotify: | ||||
| if ( | if ( | ||||
| (event->xconfigure.width > 1 && event->xconfigure.height > 1) | (event->xconfigure.width > 1 && event->xconfigure.height > 1) | ||||
| @@ -2319,6 +2320,7 @@ int x_fib_cfg_buttons (int k, int v) { | |||||
| _btn_filter.flags |= 2; | _btn_filter.flags |= 2; | ||||
| _fib_filter_fn = 0; | _fib_filter_fn = 0; | ||||
| } | } | ||||
| break; | |||||
| default: | default: | ||||
| return -2; | return -2; | ||||
| } | } | ||||
| @@ -25,10 +25,10 @@ | |||||
| typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget; | typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget; | ||||
| #elif DISTRHO_UI_USE_NANOVG | #elif DISTRHO_UI_USE_NANOVG | ||||
| # include "../dgl/NanoVG.hpp" | # include "../dgl/NanoVG.hpp" | ||||
| typedef DGL::NanoWidget UIWidget; | |||||
| typedef DGL_NAMESPACE::NanoWidget UIWidget; | |||||
| #else | #else | ||||
| # include "../dgl/Widget.hpp" | # include "../dgl/Widget.hpp" | ||||
| typedef DGL::Widget UIWidget; | |||||
| typedef DGL_NAMESPACE::Widget UIWidget; | |||||
| #endif | #endif | ||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| @@ -175,11 +175,13 @@ protected: | |||||
| */ | */ | ||||
| virtual void uiIdle() {} | virtual void uiIdle() {} | ||||
| #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 | |||||
| /** | /** | ||||
| OpenGL window reshape function, called when parent window is resized. | OpenGL window reshape function, called when parent window is resized. | ||||
| @@ -212,7 +214,7 @@ private: | |||||
| void setAbsoluteX(int) const noexcept {} | void setAbsoluteX(int) const noexcept {} | ||||
| void setAbsoluteY(int) const noexcept {} | void setAbsoluteY(int) const noexcept {} | ||||
| void setAbsolutePos(int, int) const noexcept {} | void setAbsolutePos(int, int) const noexcept {} | ||||
| void setAbsolutePos(const DGL::Point<int>&) const noexcept {} | |||||
| void setAbsolutePos(const DGL_NAMESPACE::Point<int>&) const noexcept {} | |||||
| #endif | #endif | ||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI) | ||||
| @@ -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 | ||||
| @@ -33,7 +33,7 @@ | |||||
| # include <stdint.h> | # include <stdint.h> | ||||
| #endif | #endif | ||||
| #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! (defined(DISTRHO_PROPER_CPP11_SUPPORT) && defined(__clang__)) | |||||
| #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||||
| namespace std { | namespace std { | ||||
| inline float fmin(float __x, float __y) | inline float fmin(float __x, float __y) | ||||
| { return __builtin_fminf(__x, __y); } | { return __builtin_fminf(__x, __y); } | ||||
| @@ -106,7 +106,7 @@ std::vector<uint8_t> d_getChunkFromBase64String(const char* const base64string) | |||||
| if (c == ' ' || c == '\n') | if (c == ' ' || c == '\n') | ||||
| continue; | continue; | ||||
| DISTRHO_SAFE_ASSERT_CONTINUE(CarlaBase64Helpers::isBase64Char(c)); | |||||
| DISTRHO_SAFE_ASSERT_CONTINUE(DistrhoBase64Helpers::isBase64Char(c)); | |||||
| charArray4[i++] = static_cast<uint>(c); | charArray4[i++] = static_cast<uint>(c); | ||||
| @@ -317,7 +317,7 @@ protected: | |||||
| fPlugin.deactivate(); | fPlugin.deactivate(); | ||||
| } | } | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override | void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override | ||||
| { | { | ||||
| MidiEvent realMidiEvents[midiEventCount]; | MidiEvent realMidiEvents[midiEventCount]; | ||||
| @@ -503,7 +503,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| void run(const float** const inputs, float** const outputs, const uint32_t frames, | void run(const float** const inputs, float** const outputs, const uint32_t frames, | ||||
| const MidiEvent* const midiEvents, const uint32_t midiEventCount) | const MidiEvent* const midiEvents, const uint32_t midiEventCount) | ||||
| { | { | ||||
| @@ -332,7 +332,7 @@ protected: | |||||
| if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf)) | if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf)) | ||||
| { | { | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| uint32_t midiEventCount = 0; | uint32_t midiEventCount = 0; | ||||
| MidiEvent midiEvents[eventCount]; | MidiEvent midiEvents[eventCount]; | ||||
| #endif | #endif | ||||
| @@ -383,7 +383,7 @@ protected: | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| MidiEvent& midiEvent(midiEvents[midiEventCount++]); | MidiEvent& midiEvent(midiEvents[midiEventCount++]); | ||||
| midiEvent.frame = jevent.time; | midiEvent.frame = jevent.time; | ||||
| @@ -396,11 +396,11 @@ protected: | |||||
| #endif | #endif | ||||
| } | } | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount); | fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount); | ||||
| #endif | #endif | ||||
| } | } | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| else | else | ||||
| { | { | ||||
| fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0); | fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0); | ||||
| @@ -23,6 +23,7 @@ | |||||
| #include "lv2/instance-access.h" | #include "lv2/instance-access.h" | ||||
| #include "lv2/midi.h" | #include "lv2/midi.h" | ||||
| #include "lv2/options.h" | #include "lv2/options.h" | ||||
| #include "lv2/parameters.h" | |||||
| #include "lv2/state.h" | #include "lv2/state.h" | ||||
| #include "lv2/time.h" | #include "lv2/time.h" | ||||
| #include "lv2/urid.h" | #include "lv2/urid.h" | ||||
| @@ -30,6 +31,10 @@ | |||||
| #include "lv2/lv2_kxstudio_properties.h" | #include "lv2/lv2_kxstudio_properties.h" | ||||
| #include "lv2/lv2_programs.h" | #include "lv2/lv2_programs.h" | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| # include "libmodauth.h" | |||||
| #endif | |||||
| #ifdef noexcept | #ifdef noexcept | ||||
| # undef noexcept | # undef noexcept | ||||
| #endif | #endif | ||||
| @@ -58,6 +63,9 @@ class PluginLv2 | |||||
| public: | public: | ||||
| PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal) | PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal) | ||||
| : fUsingNominal(usingNominal), | : fUsingNominal(usingNominal), | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| fRunCount(0), | |||||
| #endif | |||||
| fPortControls(nullptr), | fPortControls(nullptr), | ||||
| fLastControlValues(nullptr), | fLastControlValues(nullptr), | ||||
| fSampleRate(sampleRate), | fSampleRate(sampleRate), | ||||
| @@ -379,7 +387,7 @@ public: | |||||
| if (fLastPositionData.barBeat >= 0.0f) | if (fLastPositionData.barBeat >= 0.0f) | ||||
| { | { | ||||
| const double rest = std::fmod(fLastPositionData.barBeat, 1.0f); | const double rest = std::fmod(fLastPositionData.barBeat, 1.0f); | ||||
| fTimePosition.bbt.beat = fLastPositionData.barBeat-rest+1.0; | |||||
| fTimePosition.bbt.beat = std::round(fLastPositionData.barBeat-rest+1.0); | |||||
| fTimePosition.bbt.tick = rest*fTimePosition.bbt.ticksPerBeat+0.5; | fTimePosition.bbt.tick = rest*fTimePosition.bbt.ticksPerBeat+0.5; | ||||
| } | } | ||||
| } | } | ||||
| @@ -525,12 +533,21 @@ public: | |||||
| // Run plugin | // Run plugin | ||||
| if (sampleCount != 0) | if (sampleCount != 0) | ||||
| { | { | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| fRunCount = mod_license_run_begin(fRunCount, sampleCount); | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount, fMidiEvents, midiEventCount); | fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount, fMidiEvents, midiEventCount); | ||||
| #else | #else | ||||
| fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); | fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); | ||||
| #endif | #endif | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | |||||
| mod_license_run_noise(fRunCount, fPortAudioOuts[i], sampleCount, i); | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_TIMEPOS | #if DISTRHO_PLUGIN_WANT_TIMEPOS | ||||
| // update timePos for next callback | // update timePos for next callback | ||||
| if (d_isNotZero(fLastPositionData.speed)) | if (d_isNotZero(fLastPositionData.speed)) | ||||
| @@ -563,7 +580,7 @@ public: | |||||
| (double)fLastPositionData.beatsPerBar); | (double)fLastPositionData.beatsPerBar); | ||||
| const double rest = std::fmod(fLastPositionData.barBeat, 1.0f); | const double rest = std::fmod(fLastPositionData.barBeat, 1.0f); | ||||
| fTimePosition.bbt.beat = fLastPositionData.barBeat-rest+1.0; | |||||
| fTimePosition.bbt.beat = std::round(fLastPositionData.barBeat-rest+1.0); | |||||
| fTimePosition.bbt.tick = rest*fTimePosition.bbt.ticksPerBeat+0.5; | fTimePosition.bbt.tick = rest*fTimePosition.bbt.ticksPerBeat+0.5; | ||||
| if (fLastPositionData.bar >= 0) | if (fLastPositionData.bar >= 0) | ||||
| @@ -669,7 +686,7 @@ public: | |||||
| { | { | ||||
| if (options[i].type == fURIDs.atomInt) | if (options[i].type == fURIDs.atomInt) | ||||
| { | { | ||||
| const int bufferSize(*(const int*)options[i].value); | |||||
| const int32_t bufferSize(*(const int32_t*)options[i].value); | |||||
| fPlugin.setBufferSize(bufferSize); | fPlugin.setBufferSize(bufferSize); | ||||
| } | } | ||||
| else | else | ||||
| @@ -681,7 +698,7 @@ public: | |||||
| { | { | ||||
| if (options[i].type == fURIDs.atomInt) | if (options[i].type == fURIDs.atomInt) | ||||
| { | { | ||||
| const int bufferSize(*(const int*)options[i].value); | |||||
| const int32_t bufferSize(*(const int32_t*)options[i].value); | |||||
| fPlugin.setBufferSize(bufferSize); | fPlugin.setBufferSize(bufferSize); | ||||
| } | } | ||||
| else | else | ||||
| @@ -689,11 +706,11 @@ public: | |||||
| d_stderr("Host changed maxBlockLength but with wrong value type"); | d_stderr("Host changed maxBlockLength but with wrong value type"); | ||||
| } | } | ||||
| } | } | ||||
| else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate)) | |||||
| else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_PARAMETERS__sampleRate)) | |||||
| { | { | ||||
| if (options[i].type == fURIDs.atomDouble) | |||||
| if (options[i].type == fURIDs.atomFloat) | |||||
| { | { | ||||
| const double sampleRate(*(const double*)options[i].value); | |||||
| const float sampleRate(*(const float*)options[i].value); | |||||
| fSampleRate = sampleRate; | fSampleRate = sampleRate; | ||||
| fPlugin.setSampleRate(sampleRate); | fPlugin.setSampleRate(sampleRate); | ||||
| } | } | ||||
| @@ -847,6 +864,10 @@ private: | |||||
| PluginExporter fPlugin; | PluginExporter fPlugin; | ||||
| const bool fUsingNominal; // if false use maxBlockLength | const bool fUsingNominal; // if false use maxBlockLength | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| uint32_t fRunCount; | |||||
| #endif | |||||
| // LV2 ports | // LV2 ports | ||||
| #if DISTRHO_PLUGIN_NUM_INPUTS > 0 | #if DISTRHO_PLUGIN_NUM_INPUTS > 0 | ||||
| const float* fPortAudioIns[DISTRHO_PLUGIN_NUM_INPUTS]; | const float* fPortAudioIns[DISTRHO_PLUGIN_NUM_INPUTS]; | ||||
| @@ -1035,6 +1056,10 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons | |||||
| } | } | ||||
| #endif | #endif | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| mod_check_license(features, DISTRHO_PLUGIN_URI); | |||||
| #endif | |||||
| d_lastBufferSize = 0; | d_lastBufferSize = 0; | ||||
| bool usingNominal = false; | bool usingNominal = false; | ||||
| @@ -1194,7 +1219,11 @@ static const void* lv2_extension_data(const char* uri) | |||||
| return &directaccess; | return &directaccess; | ||||
| #endif | #endif | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| return mod_license_interface(uri); | |||||
| #else | |||||
| return nullptr; | return nullptr; | ||||
| #endif | |||||
| } | } | ||||
| #undef instancePtr | #undef instancePtr | ||||
| @@ -34,6 +34,10 @@ | |||||
| #include "lv2/lv2_kxstudio_properties.h" | #include "lv2/lv2_kxstudio_properties.h" | ||||
| #include "lv2/lv2_programs.h" | #include "lv2/lv2_programs.h" | ||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| # include "mod-license.h" | |||||
| #endif | |||||
| #include <fstream> | #include <fstream> | ||||
| #include <iostream> | #include <iostream> | ||||
| @@ -197,6 +201,7 @@ void lv2_generate_ttl(const char* const basename) | |||||
| #ifdef DISTRHO_PLUGIN_BRAND | #ifdef DISTRHO_PLUGIN_BRAND | ||||
| pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n"; | pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n"; | ||||
| #endif | #endif | ||||
| pluginString += "@prefix opts: <" LV2_OPTIONS_PREFIX "> .\n"; | |||||
| pluginString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | pluginString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | ||||
| pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n"; | pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n"; | ||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| @@ -224,6 +229,9 @@ void lv2_generate_ttl(const char* const basename) | |||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | #if DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
| pluginString += ",\n <" LV2_PROGRAMS__Interface "> "; | pluginString += ",\n <" LV2_PROGRAMS__Interface "> "; | ||||
| #endif | |||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| pluginString += ",\n <" MOD_LICENSE__interface "> "; | |||||
| #endif | #endif | ||||
| pluginString += ";\n\n"; | pluginString += ";\n\n"; | ||||
| @@ -241,9 +249,18 @@ void lv2_generate_ttl(const char* const basename) | |||||
| pluginString += ",\n <" LV2_URID__map "> "; | pluginString += ",\n <" LV2_URID__map "> "; | ||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| pluginString += ",\n <" LV2_WORKER__schedule "> "; | pluginString += ",\n <" LV2_WORKER__schedule "> "; | ||||
| #endif | |||||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||||
| pluginString += ",\n <" MOD_LICENSE__feature "> "; | |||||
| #endif | #endif | ||||
| pluginString += ";\n\n"; | pluginString += ";\n\n"; | ||||
| // supportedOptions | |||||
| pluginString += " opts:supportedOption <" LV2_BUF_SIZE__nominalBlockLength "> ,\n"; | |||||
| pluginString += " <" LV2_BUF_SIZE__maxBlockLength "> ,\n"; | |||||
| pluginString += " <" LV2_PARAMETERS__sampleRate "> ;\n"; | |||||
| pluginString += "\n"; | |||||
| // UI | // UI | ||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| pluginString += " ui:ui <" DISTRHO_UI_URI "> ;\n"; | pluginString += " ui:ui <" DISTRHO_UI_URI "> ;\n"; | ||||
| @@ -573,8 +590,9 @@ void lv2_generate_ttl(const char* const basename) | |||||
| std::fstream uiFile(uiTTL, std::ios::out); | std::fstream uiFile(uiTTL, std::ios::out); | ||||
| String uiString; | String uiString; | ||||
| uiString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||||
| uiString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; | |||||
| uiString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||||
| uiString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; | |||||
| uiString += "@prefix opts: <" LV2_OPTIONS_PREFIX "> .\n"; | |||||
| uiString += "\n"; | uiString += "\n"; | ||||
| uiString += "<" DISTRHO_UI_URI ">\n"; | uiString += "<" DISTRHO_UI_URI ">\n"; | ||||
| @@ -593,7 +611,9 @@ void lv2_generate_ttl(const char* const basename) | |||||
| uiString += "\n"; | uiString += "\n"; | ||||
| # endif | # endif | ||||
| uiString += " lv2:requiredFeature <" LV2_OPTIONS__options "> ,\n"; | uiString += " lv2:requiredFeature <" LV2_OPTIONS__options "> ,\n"; | ||||
| uiString += " <" LV2_URID__map "> .\n"; | |||||
| uiString += " <" LV2_URID__map "> ;\n"; | |||||
| uiString += " opts:supportedOption <" LV2_PARAMETERS__sampleRate "> .\n"; | |||||
| uiFile << uiString << std::endl; | uiFile << uiString << std::endl; | ||||
| uiFile.close(); | uiFile.close(); | ||||
| @@ -693,7 +713,7 @@ void lv2_generate_ttl(const char* const basename) | |||||
| else | else | ||||
| presetString += " pset:value " + String(plugin.getParameterValue(j)) + " ;\n"; | presetString += " pset:value " + String(plugin.getParameterValue(j)) + " ;\n"; | ||||
| if (j+1 == numParameters || (j+2 == numParameters && plugin.isParameterOutput(j+1))) | |||||
| if (j+1 == numParameters || plugin.isParameterOutput(j+1)) | |||||
| presetString += " ] .\n\n"; | presetString += " ] .\n\n"; | ||||
| else | else | ||||
| presetString += " ] ,\n"; | presetString += " ] ,\n"; | ||||
| @@ -52,6 +52,8 @@ | |||||
| #define effGetProgramNameIndexed 29 | #define effGetProgramNameIndexed 29 | ||||
| #define effGetPlugCategory 35 | #define effGetPlugCategory 35 | ||||
| #define effIdle 53 | #define effIdle 53 | ||||
| #define effEditKeyDown 59 | |||||
| #define effEditKeyUp 60 | |||||
| #define kPlugCategEffect 1 | #define kPlugCategEffect 1 | ||||
| #define kPlugCategSynth 2 | #define kPlugCategSynth 2 | ||||
| #define kVstVersion 2400 | #define kVstVersion 2400 | ||||
| @@ -80,6 +82,12 @@ void snprintf_param(char* const dst, const float value, const size_t size) | |||||
| dst[size-1] = '\0'; | dst[size-1] = '\0'; | ||||
| } | } | ||||
| void snprintf_iparam(char* const dst, const int32_t value, const size_t size) | |||||
| { | |||||
| std::snprintf(dst, size-1, "%d", value); | |||||
| dst[size-1] = '\0'; | |||||
| } | |||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -122,8 +130,20 @@ public: | |||||
| fEffect(effect), | fEffect(effect), | ||||
| fUiHelper(uiHelper), | fUiHelper(uiHelper), | ||||
| fPlugin(plugin), | fPlugin(plugin), | ||||
| fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, plugin->getInstancePointer()) | |||||
| fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, plugin->getInstancePointer()), | |||||
| fShouldCaptureVstKeys(false) | |||||
| { | { | ||||
| // FIXME only needed for windows? | |||||
| //#ifdef DISTRHO_OS_WINDOWS | |||||
| char strBuf[0xff+1]; | |||||
| std::memset(strBuf, 0, sizeof(char)*(0xff+1)); | |||||
| hostCallback(audioMasterGetProductString, 0, 0, strBuf); | |||||
| d_stdout("Plugin UI running in '%s'", strBuf); | |||||
| // TODO make a white-list of needed hosts | |||||
| if (/*std::strcmp(strBuf, "") == 0*/ true) | |||||
| fShouldCaptureVstKeys = true; | |||||
| //#endif | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -167,6 +187,60 @@ public: | |||||
| } | } | ||||
| # endif | # endif | ||||
| int handlePluginKeyEvent(const bool down, int32_t index, const intptr_t value) | |||||
| { | |||||
| # if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| if (! fShouldCaptureVstKeys) | |||||
| return 0; | |||||
| d_stdout("handlePluginKeyEvent %i %i %li\n", down, index, (long int)value); | |||||
| int special = 0; | |||||
| switch (value) | |||||
| { | |||||
| // convert some specials to normal keys | |||||
| case 1: index = kCharBackspace; break; | |||||
| case 6: index = kCharEscape; break; | |||||
| case 7: index = ' '; break; | |||||
| case 22: index = kCharDelete; break; | |||||
| // handle rest of special keys | |||||
| case 40: special = kKeyF1; break; | |||||
| case 41: special = kKeyF2; break; | |||||
| case 42: special = kKeyF3; break; | |||||
| case 43: special = kKeyF4; break; | |||||
| case 44: special = kKeyF5; break; | |||||
| case 45: special = kKeyF6; break; | |||||
| case 46: special = kKeyF7; break; | |||||
| case 47: special = kKeyF8; break; | |||||
| case 48: special = kKeyF9; break; | |||||
| case 49: special = kKeyF10; break; | |||||
| case 50: special = kKeyF11; break; | |||||
| case 51: special = kKeyF12; break; | |||||
| case 11: special = kKeyLeft; break; | |||||
| case 12: special = kKeyUp; break; | |||||
| case 13: special = kKeyRight; break; | |||||
| case 14: special = kKeyDown; break; | |||||
| case 15: special = kKeyPageUp; break; | |||||
| case 16: special = kKeyPageDown; break; | |||||
| case 10: special = kKeyHome; break; | |||||
| case 9: special = kKeyEnd; break; | |||||
| case 21: special = kKeyInsert; break; | |||||
| case 54: special = kKeyShift; break; | |||||
| case 55: special = kKeyControl; break; | |||||
| case 56: special = kKeyAlt; break; | |||||
| } | |||||
| if (special != 0) | |||||
| return fUI.handlePluginSpecial(down, static_cast<Key>(special)); | |||||
| if (index >= 0) | |||||
| return fUI.handlePluginKeyboard(down, static_cast<uint>(index)); | |||||
| # endif | |||||
| return 0; | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| protected: | protected: | ||||
| @@ -231,6 +305,7 @@ private: | |||||
| // Plugin UI | // Plugin UI | ||||
| UIExporter fUI; | UIExporter fUI; | ||||
| bool fShouldCaptureVstKeys; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Callbacks | // Callbacks | ||||
| @@ -352,7 +427,7 @@ public: | |||||
| case effSetProgramName: | case effSetProgramName: | ||||
| if (char* const programName = (char*)ptr) | if (char* const programName = (char*)ptr) | ||||
| { | { | ||||
| DISTRHO::strncpy(fProgramName, programName, 32); | |||||
| DISTRHO_NAMESPACE::strncpy(fProgramName, programName, 32); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -360,7 +435,7 @@ public: | |||||
| case effGetProgramName: | case effGetProgramName: | ||||
| if (char* const programName = (char*)ptr) | if (char* const programName = (char*)ptr) | ||||
| { | { | ||||
| DISTRHO::strncpy(programName, fProgramName, 24); | |||||
| DISTRHO_NAMESPACE::strncpy(programName, fProgramName, 24); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -368,7 +443,7 @@ public: | |||||
| case effGetProgramNameIndexed: | case effGetProgramNameIndexed: | ||||
| if (char* const programName = (char*)ptr) | if (char* const programName = (char*)ptr) | ||||
| { | { | ||||
| DISTRHO::strncpy(programName, fProgramName, 24); | |||||
| DISTRHO_NAMESPACE::strncpy(programName, fProgramName, 24); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -376,7 +451,26 @@ public: | |||||
| case effGetParamDisplay: | case effGetParamDisplay: | ||||
| if (ptr != nullptr && index < static_cast<int32_t>(fPlugin.getParameterCount())) | if (ptr != nullptr && index < static_cast<int32_t>(fPlugin.getParameterCount())) | ||||
| { | { | ||||
| DISTRHO::snprintf_param((char*)ptr, fPlugin.getParameterValue(index), 24); | |||||
| const uint32_t hints = fPlugin.getParameterHints(index); | |||||
| float value = fPlugin.getParameterValue(index); | |||||
| if (hints & kParameterIsBoolean) | |||||
| { | |||||
| const ParameterRanges& ranges(fPlugin.getParameterRanges(index)); | |||||
| const float midRange = ranges.min + (ranges.max - ranges.min) / 2.0f; | |||||
| value = value > midRange ? ranges.max : ranges.min; | |||||
| } | |||||
| if (hints & kParameterIsInteger) | |||||
| { | |||||
| DISTRHO_NAMESPACE::snprintf_iparam((char*)ptr, (int32_t)std::round(value), 24); | |||||
| } | |||||
| else | |||||
| { | |||||
| DISTRHO_NAMESPACE::snprintf_param((char*)ptr, value, 24); | |||||
| } | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -499,6 +593,16 @@ public: | |||||
| if (fVstUI != nullptr) | if (fVstUI != nullptr) | ||||
| fVstUI->idle(); | fVstUI->idle(); | ||||
| break; | break; | ||||
| case effEditKeyDown: | |||||
| if (fVstUI != nullptr) | |||||
| return fVstUI->handlePluginKeyEvent(true, index, value); | |||||
| break; | |||||
| case effEditKeyUp: | |||||
| if (fVstUI != nullptr) | |||||
| return fVstUI->handlePluginKeyEvent(false, index, value); | |||||
| break; | |||||
| #endif // DISTRHO_PLUGIN_HAS_UI | #endif // DISTRHO_PLUGIN_HAS_UI | ||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| @@ -967,7 +1071,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||||
| case effGetParamLabel: | case effGetParamLabel: | ||||
| if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount())) | if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount())) | ||||
| { | { | ||||
| DISTRHO::strncpy((char*)ptr, plugin.getParameterUnit(index), 8); | |||||
| DISTRHO_NAMESPACE::strncpy((char*)ptr, plugin.getParameterUnit(index), 8); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -975,11 +1079,47 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||||
| case effGetParamName: | case effGetParamName: | ||||
| if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount())) | if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount())) | ||||
| { | { | ||||
| DISTRHO::strncpy((char*)ptr, plugin.getParameterName(index), 16); | |||||
| DISTRHO_NAMESPACE::strncpy((char*)ptr, plugin.getParameterName(index), 16); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| case effGetParameterProperties: | |||||
| if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount())) | |||||
| { | |||||
| if (VstParameterProperties* const properties = (VstParameterProperties*)ptr) | |||||
| { | |||||
| memset(properties, 0, sizeof(VstParameterProperties)); | |||||
| const uint32_t hints = plugin.getParameterHints(index); | |||||
| if (hints & kParameterIsOutput) | |||||
| return 1; | |||||
| if (hints & kParameterIsBoolean) | |||||
| { | |||||
| properties->flags |= kVstParameterIsSwitch; | |||||
| } | |||||
| if (hints & kParameterIsInteger) | |||||
| { | |||||
| properties->flags |= kVstParameterUsesIntegerMinMax; | |||||
| const ParameterRanges& ranges(plugin.getParameterRanges(index)); | |||||
| properties->minInteger = static_cast<int32_t>(ranges.min); | |||||
| properties->maxInteger = static_cast<int32_t>(ranges.max); | |||||
| } | |||||
| if (hints & kParameterIsLogarithmic) | |||||
| { | |||||
| properties->flags |= kVstParameterCanRamp; | |||||
| } | |||||
| return 1; | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| case effGetPlugCategory: | case effGetPlugCategory: | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | #if DISTRHO_PLUGIN_IS_SYNTH | ||||
| return kPlugCategSynth; | return kPlugCategSynth; | ||||
| @@ -990,7 +1130,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||||
| case effGetEffectName: | case effGetEffectName: | ||||
| if (char* const cptr = (char*)ptr) | if (char* const cptr = (char*)ptr) | ||||
| { | { | ||||
| DISTRHO::strncpy(cptr, plugin.getName(), 32); | |||||
| DISTRHO_NAMESPACE::strncpy(cptr, plugin.getName(), 32); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -998,7 +1138,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||||
| case effGetVendorString: | case effGetVendorString: | ||||
| if (char* const cptr = (char*)ptr) | if (char* const cptr = (char*)ptr) | ||||
| { | { | ||||
| DISTRHO::strncpy(cptr, plugin.getMaker(), 32); | |||||
| DISTRHO_NAMESPACE::strncpy(cptr, plugin.getMaker(), 32); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -1006,7 +1146,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||||
| case effGetProductString: | case effGetProductString: | ||||
| if (char* const cptr = (char*)ptr) | if (char* const cptr = (char*)ptr) | ||||
| { | { | ||||
| DISTRHO::strncpy(cptr, plugin.getLabel(), 32); | |||||
| DISTRHO_NAMESPACE::strncpy(cptr, plugin.getLabel(), 32); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -125,9 +125,11 @@ void UI::sampleRateChanged(double) {} | |||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * UI Callbacks (optional) */ | * UI Callbacks (optional) */ | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| void UI::uiFileBrowserSelected(const char*) | void UI::uiFileBrowserSelected(const char*) | ||||
| { | { | ||||
| } | } | ||||
| #endif | |||||
| void UI::uiReshape(uint width, uint height) | void UI::uiReshape(uint width, uint height) | ||||
| { | { | ||||
| @@ -22,9 +22,9 @@ | |||||
| #ifdef HAVE_DGL | #ifdef HAVE_DGL | ||||
| # include "../../dgl/Application.hpp" | # include "../../dgl/Application.hpp" | ||||
| # include "../../dgl/Window.hpp" | # include "../../dgl/Window.hpp" | ||||
| using DGL::Application; | |||||
| using DGL::IdleCallback; | |||||
| using DGL::Window; | |||||
| using DGL_NAMESPACE::Application; | |||||
| using DGL_NAMESPACE::IdleCallback; | |||||
| using DGL_NAMESPACE::Window; | |||||
| #endif | #endif | ||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| @@ -186,6 +186,7 @@ protected: | |||||
| fIsReady = true; | fIsReady = true; | ||||
| } | } | ||||
| #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 | ||||
| { | { | ||||
| @@ -193,6 +194,7 @@ protected: | |||||
| fUI->uiFileBrowserSelected(filename); | fUI->uiFileBrowserSelected(filename); | ||||
| } | } | ||||
| #endif | |||||
| private: | private: | ||||
| UI* const fUI; | UI* const fUI; | ||||
| @@ -416,6 +418,16 @@ public: | |||||
| return ! glApp.isQuiting(); | return ! glApp.isQuiting(); | ||||
| } | } | ||||
| bool handlePluginKeyboard(const bool press, const uint key) | |||||
| { | |||||
| return glWindow.handlePluginKeyboard(press, key); | |||||
| } | |||||
| bool handlePluginSpecial(const bool press, const Key key) | |||||
| { | |||||
| return glWindow.handlePluginKeyboard(press, key); | |||||
| } | |||||
| #else | #else | ||||
| void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | ||||
| void setWindowTransientWinId(const uintptr_t winId) {} | void setWindowTransientWinId(const uintptr_t winId) {} | ||||
| @@ -23,6 +23,7 @@ | |||||
| #include "lv2/data-access.h" | #include "lv2/data-access.h" | ||||
| #include "lv2/instance-access.h" | #include "lv2/instance-access.h" | ||||
| #include "lv2/options.h" | #include "lv2/options.h" | ||||
| #include "lv2/parameters.h" | |||||
| #include "lv2/ui.h" | #include "lv2/ui.h" | ||||
| #include "lv2/urid.h" | #include "lv2/urid.h" | ||||
| #include "lv2/lv2_kxstudio_properties.h" | #include "lv2/lv2_kxstudio_properties.h" | ||||
| @@ -175,17 +176,17 @@ public: | |||||
| { | { | ||||
| for (int i=0; options[i].key != 0; ++i) | for (int i=0; options[i].key != 0; ++i) | ||||
| { | { | ||||
| if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate)) | |||||
| if (options[i].key == fUridMap->map(fUridMap->handle, LV2_PARAMETERS__sampleRate)) | |||||
| { | { | ||||
| if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double)) | |||||
| if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Float)) | |||||
| { | { | ||||
| const double sampleRate(*(const double*)options[i].value); | |||||
| const float sampleRate(*(const float*)options[i].value); | |||||
| fUI.setSampleRate(sampleRate); | fUI.setSampleRate(sampleRate); | ||||
| continue; | continue; | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| d_stderr("Host changed sampleRate but with wrong value type"); | |||||
| d_stderr("Host changed UI sample-rate but with wrong value type"); | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| @@ -402,23 +403,23 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||||
| if (options != nullptr) | if (options != nullptr) | ||||
| { | { | ||||
| const LV2_URID uridSampleRate(uridMap->map(uridMap->handle, LV2_CORE__sampleRate)); | |||||
| const LV2_URID uridSampleRate(uridMap->map(uridMap->handle, LV2_PARAMETERS__sampleRate)); | |||||
| for (int i=0; options[i].key != 0; ++i) | for (int i=0; options[i].key != 0; ++i) | ||||
| { | { | ||||
| if (options[i].key == uridSampleRate) | if (options[i].key == uridSampleRate) | ||||
| { | { | ||||
| if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Double)) | |||||
| d_lastUiSampleRate = *(const double*)options[i].value; | |||||
| if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Float)) | |||||
| d_lastUiSampleRate = *(const float*)options[i].value; | |||||
| else | else | ||||
| d_stderr("Host provides sampleRate but has wrong value type"); | |||||
| d_stderr("Host provides UI sample-rate but has wrong value type"); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (d_lastUiSampleRate == 0.0) | |||||
| if (d_lastUiSampleRate < 1.0) | |||||
| { | { | ||||
| d_stdout("WARNING: this host does not send sample-rate information for LV2 UIs, using 44100 as fallback (this could be wrong)"); | d_stdout("WARNING: this host does not send sample-rate information for LV2 UIs, using 44100 as fallback (this could be wrong)"); | ||||
| d_lastUiSampleRate = 44100.0; | d_lastUiSampleRate = 44100.0; | ||||
| @@ -11,11 +11,6 @@ fi | |||||
| PWD=`pwd` | PWD=`pwd` | ||||
| if [ ! -d /System/Library ]; then | |||||
| echo "This doesn't seem to be OSX, please stop!" | |||||
| exit 0 | |||||
| fi | |||||
| rm -rf *.vst/ | rm -rf *.vst/ | ||||
| PLUGINS=`ls | grep vst.dylib` | PLUGINS=`ls | grep vst.dylib` | ||||
| @@ -27,7 +22,6 @@ for i in $PLUGINS; do | |||||
| rm -f $FILE.vst/Contents/MacOS/deleteme | rm -f $FILE.vst/Contents/MacOS/deleteme | ||||
| sed -i -e "s/X-PROJECTNAME-X/$FILE/" $FILE.vst/Contents/Info.plist | sed -i -e "s/X-PROJECTNAME-X/$FILE/" $FILE.vst/Contents/Info.plist | ||||
| rm -f $FILE.vst/Contents/Info.plist-e | rm -f $FILE.vst/Contents/Info.plist-e | ||||
| SetFile -a B $FILE.vst | |||||
| done | done | ||||
| cd .. | cd .. | ||||
| @@ -16,7 +16,10 @@ | |||||
| # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| import os, numpy, sys | import os, numpy, sys | ||||
| import Image | |||||
| try: | |||||
| import Image | |||||
| except: | |||||
| from PIL import Image | |||||
| # ----------------------------------------------------- | # ----------------------------------------------------- | ||||