| @@ -15,9 +15,6 @@ LINK_FLAGS += $(DGL_LIBS) | |||
| ifneq ($(MACOS_OLD),true) | |||
| # needed by sofd right now, fix later | |||
| BUILD_CXX_FLAGS += -Wno-type-limits -fpermissive | |||
| # needed by stb_image | |||
| BUILD_CXX_FLAGS += -Wno-misleading-indentation -Wno-shift-negative-value | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| @@ -20,7 +20,9 @@ | |||
| #include "Color.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 NVGpaint; | |||
| @@ -844,10 +846,12 @@ public: | |||
| */ | |||
| 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. | |||
| */ | |||
| virtual void loadSharedResources(); | |||
| #endif | |||
| private: | |||
| NVGcontext* const fContext; | |||
| @@ -19,6 +19,10 @@ | |||
| #include "Geometry.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| class UIExporter; | |||
| END_NAMESPACE_DISTRHO | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| @@ -30,6 +34,7 @@ class StandaloneWindow; | |||
| class Window | |||
| { | |||
| public: | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| /** | |||
| File browser options. | |||
| */ | |||
| @@ -66,6 +71,7 @@ public: | |||
| height(0), | |||
| buttons() {} | |||
| }; | |||
| #endif // DGL_FILE_BROWSER_DISABLED | |||
| explicit Window(Application& app); | |||
| explicit Window(Application& app, Window& parent); | |||
| @@ -80,7 +86,9 @@ public: | |||
| void focus(); | |||
| void repaint() noexcept; | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| bool openFileBrowser(const FileBrowserOptions& options); | |||
| #endif | |||
| bool isVisible() const noexcept; | |||
| void setVisible(bool yesNo); | |||
| @@ -111,7 +119,9 @@ protected: | |||
| virtual void onReshape(uint width, uint height); | |||
| virtual void onClose(); | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| virtual void fileBrowserSelected(const char* filename); | |||
| #endif | |||
| private: | |||
| struct PrivateData; | |||
| @@ -119,11 +129,15 @@ private: | |||
| friend class Application; | |||
| friend class Widget; | |||
| friend class StandaloneWindow; | |||
| friend class DISTRHO_NAMESPACE::UIExporter; | |||
| virtual void _addWidget(Widget* const widget); | |||
| virtual void _removeWidget(Widget* const widget); | |||
| 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) | |||
| }; | |||
| @@ -545,7 +545,7 @@ const T& Circle<T>::getX() const noexcept | |||
| template<typename T> | |||
| const T& Circle<T>::getY() const noexcept | |||
| { | |||
| return fPos.fX; | |||
| return fPos.fY; | |||
| } | |||
| template<typename T> | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -15,9 +15,12 @@ | |||
| */ | |||
| #include "../NanoVG.hpp" | |||
| #include "Resources.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| #ifndef DGL_NO_SHARED_RESOURCES | |||
| # include "Resources.hpp" | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| @@ -895,6 +898,7 @@ int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWi | |||
| return 0; | |||
| } | |||
| #ifndef DGL_NO_SHARED_RESOURCES | |||
| void NanoVG::loadSharedResources() | |||
| { | |||
| 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); | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| @@ -972,8 +977,18 @@ END_NAMESPACE_DGL | |||
| #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" { | |||
| #include "nanovg/nanovg.c" | |||
| } | |||
| #if defined(__GNUC__) && (__GNUC__ >= 6) | |||
| # pragma GCC diagnostic pop | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -25,6 +25,11 @@ | |||
| #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) | |||
| # include "pugl/pugl_win.cpp" | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| @@ -37,6 +42,10 @@ extern "C" { | |||
| } | |||
| #endif | |||
| #if defined(__GNUC__) && (__GNUC__ >= 7) | |||
| # pragma GCC diagnostic pop | |||
| #endif | |||
| #include "ApplicationPrivateData.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| #include "../StandaloneWindow.hpp" | |||
| @@ -78,11 +87,13 @@ struct Window::PrivateData { | |||
| fWidgets(), | |||
| fModal(), | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| hwnd(0) | |||
| hwnd(nullptr), | |||
| hwndParent(nullptr) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| fNeedsIdle(true), | |||
| mView(nullptr), | |||
| mWindow(nullptr) | |||
| mWindow(nullptr), | |||
| mParentWindow(nullptr) | |||
| #else | |||
| xDisplay(nullptr), | |||
| xWindow(0) | |||
| @@ -106,11 +117,13 @@ struct Window::PrivateData { | |||
| fWidgets(), | |||
| fModal(parent.pData), | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| hwnd(0) | |||
| hwnd(nullptr), | |||
| hwndParent(nullptr) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| fNeedsIdle(false), | |||
| mView(nullptr), | |||
| mWindow(nullptr) | |||
| mWindow(nullptr), | |||
| mParentWindow(nullptr) | |||
| #else | |||
| xDisplay(nullptr), | |||
| xWindow(0) | |||
| @@ -120,11 +133,13 @@ struct Window::PrivateData { | |||
| init(); | |||
| const PuglInternals* const parentImpl(parent.pData->fView->impl); | |||
| // NOTE: almost a 1:1 copy of setTransientWinId() | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| // TODO | |||
| hwndParent = parentImpl->hwnd; | |||
| SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)hwndParent); | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| // TODO | |||
| //[parentImpl->window orderWindow:NSWindowBelow relativeTo:[[mView window] windowNumber]]; | |||
| mParentWindow = parentImpl->window; | |||
| #else | |||
| XSetTransientForHint(xDisplay, xWindow, parentImpl->win); | |||
| #endif | |||
| @@ -144,11 +159,13 @@ struct Window::PrivateData { | |||
| fWidgets(), | |||
| fModal(), | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| hwnd(0) | |||
| hwnd(nullptr), | |||
| hwndParent(nullptr) | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| fNeedsIdle(parentId == 0), | |||
| mView(nullptr), | |||
| mWindow(nullptr) | |||
| mWindow(nullptr), | |||
| mParentWindow(nullptr) | |||
| #else | |||
| xDisplay(nullptr), | |||
| xWindow(0) | |||
| @@ -196,7 +213,9 @@ struct Window::PrivateData { | |||
| puglSetSpecialFunc(fView, onSpecialCallback); | |||
| puglSetReshapeFunc(fView, onReshapeCallback); | |||
| puglSetCloseFunc(fView, onCloseCallback); | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | |||
| #endif | |||
| puglCreateWindow(fView, nullptr); | |||
| @@ -330,22 +349,6 @@ struct Window::PrivateData { | |||
| fModal.enabled = true; | |||
| 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); | |||
| setVisible(true); | |||
| @@ -390,11 +393,7 @@ struct Window::PrivateData { | |||
| SetFocus(hwnd); | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| if (mWindow != nullptr) | |||
| { | |||
| // TODO | |||
| //[NSApp activateIgnoringOtherApps:YES]; | |||
| //[mWindow makeKeyAndOrderFront:mWindow]; | |||
| } | |||
| [mWindow makeKeyWindow]; | |||
| #else | |||
| XRaiseWindow(xDisplay, xWindow); | |||
| XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime); | |||
| @@ -426,25 +425,65 @@ struct Window::PrivateData { | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| 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 | |||
| { | |||
| ShowWindow(hwnd, SW_HIDE); | |||
| } | |||
| UpdateWindow(hwnd); | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| if (yesNo) | |||
| { | |||
| if (mWindow != nullptr) | |||
| { | |||
| if (mParentWindow != nullptr) | |||
| [mParentWindow addChildWindow:mWindow | |||
| ordered:NSWindowAbove]; | |||
| [mWindow setIsVisible:YES]; | |||
| } | |||
| else | |||
| { | |||
| [mView setHidden:NO]; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (mWindow != nullptr) | |||
| { | |||
| if (mParentWindow != nullptr) | |||
| [mParentWindow removeChildWindow:mWindow]; | |||
| [mWindow setIsVisible:NO]; | |||
| } | |||
| else | |||
| { | |||
| [mView setHidden:YES]; | |||
| } | |||
| } | |||
| #else | |||
| if (yesNo) | |||
| @@ -613,10 +652,17 @@ struct Window::PrivateData { | |||
| void setTransientWinId(const uintptr_t winId) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(winId != 0,); | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| // TODO | |||
| hwndParent = (HWND)winId; | |||
| SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)winId); | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| // TODO | |||
| NSWindow* const parentWindow = [NSApp windowWithWindowNumber:winId]; | |||
| DISTRHO_SAFE_ASSERT_RETURN(parentWindow != nullptr,); | |||
| [parentWindow addChildWindow:mWindow | |||
| ordered:NSWindowAbove]; | |||
| #else | |||
| XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); | |||
| #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; | |||
| Window* fSelf; | |||
| PuglView* fView; | |||
| @@ -883,11 +1013,13 @@ struct Window::PrivateData { | |||
| } fModal; | |||
| #if defined(DISTRHO_OS_WINDOWS) | |||
| HWND hwnd; | |||
| HWND hwnd; | |||
| HWND hwndParent; | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| bool fNeedsIdle; | |||
| PuglOpenGLView* mView; | |||
| id mWindow; | |||
| id mParentWindow; | |||
| #else | |||
| Display* xDisplay; | |||
| ::Window xWindow; | |||
| @@ -938,10 +1070,12 @@ struct Window::PrivateData { | |||
| handlePtr->onPuglClose(); | |||
| } | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| static void fileBrowserSelectedCallback(PuglView* view, const char* filename) | |||
| { | |||
| handlePtr->fSelf->fileBrowserSelected(filename); | |||
| } | |||
| #endif | |||
| #undef handlePtr | |||
| @@ -1001,9 +1135,10 @@ void Window::repaint() noexcept | |||
| // (void)name; | |||
| // } | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| bool Window::openFileBrowser(const FileBrowserOptions& options) | |||
| { | |||
| #ifdef SOFD_HAVE_X11 | |||
| # ifdef SOFD_HAVE_X11 | |||
| using DISTRHO_NAMESPACE::String; | |||
| // -------------------------------------------------------------------------- | |||
| @@ -1061,11 +1196,12 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) | |||
| // show | |||
| return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0); | |||
| #else | |||
| # else | |||
| // not implemented | |||
| return false; | |||
| #endif | |||
| # endif | |||
| } | |||
| #endif | |||
| bool Window::isVisible() const noexcept | |||
| { | |||
| @@ -1196,9 +1332,21 @@ void Window::onClose() | |||
| { | |||
| } | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| 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" | |||
| #define PuglWindow PuglWindow ## DGL_NAMESPACE | |||
| #define PuglOpenGLView PuglOpenGLView ## DGL_NAMESPACE | |||
| @interface PuglWindow : NSWindow | |||
| { | |||
| @public | |||
| @@ -438,13 +441,11 @@ void | |||
| puglLeaveContext(PuglView* view, bool flush) | |||
| { | |||
| #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]; | |||
| } | |||
| @@ -572,4 +573,7 @@ void* | |||
| puglGetContext(PuglView* view) | |||
| { | |||
| return NULL; | |||
| // unused | |||
| (void)view; | |||
| } | |||
| @@ -41,9 +41,11 @@ | |||
| #include "pugl/pugl_internal.h" | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| #define SOFD_HAVE_X11 | |||
| #include "../sofd/libsofd.h" | |||
| #include "../sofd/libsofd.c" | |||
| #endif | |||
| struct PuglInternalsImpl { | |||
| Display* display; | |||
| @@ -339,7 +341,9 @@ puglDestroy(PuglView* view) | |||
| return; | |||
| } | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| x_fib_close(view->impl->display); | |||
| #endif | |||
| destroyContext(view); | |||
| XDestroyWindow(view->impl->display, view->impl->win); | |||
| @@ -441,7 +445,7 @@ dispatchKey(PuglView* view, XEvent* event, bool press) | |||
| view->redisplay = false; | |||
| return; | |||
| } | |||
| if (n == 0) { | |||
| if (n == 0 && sym == 0) { | |||
| goto send_event; | |||
| return; | |||
| } | |||
| @@ -477,6 +481,7 @@ puglProcessEvents(PuglView* view) | |||
| while (XPending(view->impl->display) > 0) { | |||
| XNextEvent(view->impl->display, &event); | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| if (x_fib_handle_events(view->impl->display, &event)) { | |||
| const int status = x_fib_status(); | |||
| @@ -495,6 +500,7 @@ puglProcessEvents(PuglView* view) | |||
| } | |||
| break; | |||
| } | |||
| #endif | |||
| if (event.xany.window != view->impl->win && | |||
| (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")) { | |||
| _status = -1; | |||
| } | |||
| break; | |||
| case ConfigureNotify: | |||
| if ( | |||
| (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; | |||
| _fib_filter_fn = 0; | |||
| } | |||
| break; | |||
| default: | |||
| return -2; | |||
| } | |||
| @@ -25,10 +25,10 @@ | |||
| typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget; | |||
| #elif DISTRHO_UI_USE_NANOVG | |||
| # include "../dgl/NanoVG.hpp" | |||
| typedef DGL::NanoWidget UIWidget; | |||
| typedef DGL_NAMESPACE::NanoWidget UIWidget; | |||
| #else | |||
| # include "../dgl/Widget.hpp" | |||
| typedef DGL::Widget UIWidget; | |||
| typedef DGL_NAMESPACE::Widget UIWidget; | |||
| #endif | |||
| START_NAMESPACE_DISTRHO | |||
| @@ -175,11 +175,13 @@ protected: | |||
| */ | |||
| virtual void uiIdle() {} | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| /** | |||
| File browser selected function. | |||
| @see Window::fileBrowserSelected(const char*) | |||
| */ | |||
| virtual void uiFileBrowserSelected(const char* filename); | |||
| #endif | |||
| /** | |||
| OpenGL window reshape function, called when parent window is resized. | |||
| @@ -212,7 +214,7 @@ private: | |||
| void setAbsoluteX(int) const noexcept {} | |||
| void setAbsoluteY(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 | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI) | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -33,7 +33,7 @@ | |||
| # include <stdint.h> | |||
| #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 { | |||
| inline float fmin(float __x, float __y) | |||
| { return __builtin_fminf(__x, __y); } | |||
| @@ -106,7 +106,7 @@ std::vector<uint8_t> d_getChunkFromBase64String(const char* const base64string) | |||
| if (c == ' ' || c == '\n') | |||
| continue; | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(CarlaBase64Helpers::isBase64Char(c)); | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(DistrhoBase64Helpers::isBase64Char(c)); | |||
| charArray4[i++] = static_cast<uint>(c); | |||
| @@ -317,7 +317,7 @@ protected: | |||
| 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 | |||
| { | |||
| 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, | |||
| 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 DISTRHO_PLUGIN_IS_SYNTH | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| uint32_t midiEventCount = 0; | |||
| MidiEvent midiEvents[eventCount]; | |||
| #endif | |||
| @@ -383,7 +383,7 @@ protected: | |||
| } | |||
| #endif | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| MidiEvent& midiEvent(midiEvents[midiEventCount++]); | |||
| midiEvent.frame = jevent.time; | |||
| @@ -396,11 +396,11 @@ protected: | |||
| #endif | |||
| } | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| fPlugin.run(audioIns, audioOuts, nframes, midiEvents, midiEventCount); | |||
| #endif | |||
| } | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| else | |||
| { | |||
| fPlugin.run(audioIns, audioOuts, nframes, nullptr, 0); | |||
| @@ -23,6 +23,7 @@ | |||
| #include "lv2/instance-access.h" | |||
| #include "lv2/midi.h" | |||
| #include "lv2/options.h" | |||
| #include "lv2/parameters.h" | |||
| #include "lv2/state.h" | |||
| #include "lv2/time.h" | |||
| #include "lv2/urid.h" | |||
| @@ -30,6 +31,10 @@ | |||
| #include "lv2/lv2_kxstudio_properties.h" | |||
| #include "lv2/lv2_programs.h" | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| # include "libmodauth.h" | |||
| #endif | |||
| #ifdef noexcept | |||
| # undef noexcept | |||
| #endif | |||
| @@ -58,6 +63,9 @@ class PluginLv2 | |||
| public: | |||
| PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal) | |||
| : fUsingNominal(usingNominal), | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| fRunCount(0), | |||
| #endif | |||
| fPortControls(nullptr), | |||
| fLastControlValues(nullptr), | |||
| fSampleRate(sampleRate), | |||
| @@ -379,7 +387,7 @@ public: | |||
| if (fLastPositionData.barBeat >= 0.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; | |||
| } | |||
| } | |||
| @@ -525,12 +533,21 @@ public: | |||
| // Run plugin | |||
| if (sampleCount != 0) | |||
| { | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| fRunCount = mod_license_run_begin(fRunCount, sampleCount); | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount, fMidiEvents, midiEventCount); | |||
| #else | |||
| fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); | |||
| #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 | |||
| // update timePos for next callback | |||
| if (d_isNotZero(fLastPositionData.speed)) | |||
| @@ -563,7 +580,7 @@ public: | |||
| (double)fLastPositionData.beatsPerBar); | |||
| 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; | |||
| if (fLastPositionData.bar >= 0) | |||
| @@ -669,7 +686,7 @@ public: | |||
| { | |||
| 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); | |||
| } | |||
| else | |||
| @@ -681,7 +698,7 @@ public: | |||
| { | |||
| 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); | |||
| } | |||
| else | |||
| @@ -689,11 +706,11 @@ public: | |||
| 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; | |||
| fPlugin.setSampleRate(sampleRate); | |||
| } | |||
| @@ -847,6 +864,10 @@ private: | |||
| PluginExporter fPlugin; | |||
| const bool fUsingNominal; // if false use maxBlockLength | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| uint32_t fRunCount; | |||
| #endif | |||
| // LV2 ports | |||
| #if DISTRHO_PLUGIN_NUM_INPUTS > 0 | |||
| const float* fPortAudioIns[DISTRHO_PLUGIN_NUM_INPUTS]; | |||
| @@ -1035,6 +1056,10 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons | |||
| } | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| mod_check_license(features, DISTRHO_PLUGIN_URI); | |||
| #endif | |||
| d_lastBufferSize = 0; | |||
| bool usingNominal = false; | |||
| @@ -1194,7 +1219,11 @@ static const void* lv2_extension_data(const char* uri) | |||
| return &directaccess; | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| return mod_license_interface(uri); | |||
| #else | |||
| return nullptr; | |||
| #endif | |||
| } | |||
| #undef instancePtr | |||
| @@ -34,6 +34,10 @@ | |||
| #include "lv2/lv2_kxstudio_properties.h" | |||
| #include "lv2/lv2_programs.h" | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| # include "mod-license.h" | |||
| #endif | |||
| #include <fstream> | |||
| #include <iostream> | |||
| @@ -197,6 +201,7 @@ void lv2_generate_ttl(const char* const basename) | |||
| #ifdef DISTRHO_PLUGIN_BRAND | |||
| pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n"; | |||
| #endif | |||
| pluginString += "@prefix opts: <" LV2_OPTIONS_PREFIX "> .\n"; | |||
| pluginString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | |||
| pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n"; | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| @@ -224,6 +229,9 @@ void lv2_generate_ttl(const char* const basename) | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| pluginString += ",\n <" LV2_PROGRAMS__Interface "> "; | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| pluginString += ",\n <" MOD_LICENSE__interface "> "; | |||
| #endif | |||
| pluginString += ";\n\n"; | |||
| @@ -241,9 +249,18 @@ void lv2_generate_ttl(const char* const basename) | |||
| pluginString += ",\n <" LV2_URID__map "> "; | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| pluginString += ",\n <" LV2_WORKER__schedule "> "; | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD | |||
| pluginString += ",\n <" MOD_LICENSE__feature "> "; | |||
| #endif | |||
| 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 | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| 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); | |||
| 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 += "<" DISTRHO_UI_URI ">\n"; | |||
| @@ -593,7 +611,9 @@ void lv2_generate_ttl(const char* const basename) | |||
| uiString += "\n"; | |||
| # endif | |||
| 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.close(); | |||
| @@ -693,7 +713,7 @@ void lv2_generate_ttl(const char* const basename) | |||
| else | |||
| 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"; | |||
| else | |||
| presetString += " ] ,\n"; | |||
| @@ -52,6 +52,8 @@ | |||
| #define effGetProgramNameIndexed 29 | |||
| #define effGetPlugCategory 35 | |||
| #define effIdle 53 | |||
| #define effEditKeyDown 59 | |||
| #define effEditKeyUp 60 | |||
| #define kPlugCategEffect 1 | |||
| #define kPlugCategSynth 2 | |||
| #define kVstVersion 2400 | |||
| @@ -80,6 +82,12 @@ void snprintf_param(char* const dst, const float value, const size_t size) | |||
| 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 | |||
| // ----------------------------------------------------------------------- | |||
| @@ -122,8 +130,20 @@ public: | |||
| fEffect(effect), | |||
| fUiHelper(uiHelper), | |||
| 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 | |||
| 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: | |||
| @@ -231,6 +305,7 @@ private: | |||
| // Plugin UI | |||
| UIExporter fUI; | |||
| bool fShouldCaptureVstKeys; | |||
| // ------------------------------------------------------------------- | |||
| // Callbacks | |||
| @@ -352,7 +427,7 @@ public: | |||
| case effSetProgramName: | |||
| if (char* const programName = (char*)ptr) | |||
| { | |||
| DISTRHO::strncpy(fProgramName, programName, 32); | |||
| DISTRHO_NAMESPACE::strncpy(fProgramName, programName, 32); | |||
| return 1; | |||
| } | |||
| break; | |||
| @@ -360,7 +435,7 @@ public: | |||
| case effGetProgramName: | |||
| if (char* const programName = (char*)ptr) | |||
| { | |||
| DISTRHO::strncpy(programName, fProgramName, 24); | |||
| DISTRHO_NAMESPACE::strncpy(programName, fProgramName, 24); | |||
| return 1; | |||
| } | |||
| break; | |||
| @@ -368,7 +443,7 @@ public: | |||
| case effGetProgramNameIndexed: | |||
| if (char* const programName = (char*)ptr) | |||
| { | |||
| DISTRHO::strncpy(programName, fProgramName, 24); | |||
| DISTRHO_NAMESPACE::strncpy(programName, fProgramName, 24); | |||
| return 1; | |||
| } | |||
| break; | |||
| @@ -376,7 +451,26 @@ public: | |||
| case effGetParamDisplay: | |||
| 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; | |||
| } | |||
| break; | |||
| @@ -499,6 +593,16 @@ public: | |||
| if (fVstUI != nullptr) | |||
| fVstUI->idle(); | |||
| 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 | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| @@ -967,7 +1071,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| case effGetParamLabel: | |||
| 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 0; | |||
| @@ -975,11 +1079,47 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| case effGetParamName: | |||
| 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 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: | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| return kPlugCategSynth; | |||
| @@ -990,7 +1130,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| case effGetEffectName: | |||
| if (char* const cptr = (char*)ptr) | |||
| { | |||
| DISTRHO::strncpy(cptr, plugin.getName(), 32); | |||
| DISTRHO_NAMESPACE::strncpy(cptr, plugin.getName(), 32); | |||
| return 1; | |||
| } | |||
| return 0; | |||
| @@ -998,7 +1138,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| case effGetVendorString: | |||
| if (char* const cptr = (char*)ptr) | |||
| { | |||
| DISTRHO::strncpy(cptr, plugin.getMaker(), 32); | |||
| DISTRHO_NAMESPACE::strncpy(cptr, plugin.getMaker(), 32); | |||
| return 1; | |||
| } | |||
| return 0; | |||
| @@ -1006,7 +1146,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| case effGetProductString: | |||
| if (char* const cptr = (char*)ptr) | |||
| { | |||
| DISTRHO::strncpy(cptr, plugin.getLabel(), 32); | |||
| DISTRHO_NAMESPACE::strncpy(cptr, plugin.getLabel(), 32); | |||
| return 1; | |||
| } | |||
| return 0; | |||
| @@ -125,9 +125,11 @@ void UI::sampleRateChanged(double) {} | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * UI Callbacks (optional) */ | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| void UI::uiFileBrowserSelected(const char*) | |||
| { | |||
| } | |||
| #endif | |||
| void UI::uiReshape(uint width, uint height) | |||
| { | |||
| @@ -22,9 +22,9 @@ | |||
| #ifdef HAVE_DGL | |||
| # include "../../dgl/Application.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 | |||
| START_NAMESPACE_DISTRHO | |||
| @@ -186,6 +186,7 @@ protected: | |||
| fIsReady = true; | |||
| } | |||
| #ifndef DGL_FILE_BROWSER_DISABLED | |||
| // custom file-browser selected | |||
| void fileBrowserSelected(const char* filename) override | |||
| { | |||
| @@ -193,6 +194,7 @@ protected: | |||
| fUI->uiFileBrowserSelected(filename); | |||
| } | |||
| #endif | |||
| private: | |||
| UI* const fUI; | |||
| @@ -416,6 +418,16 @@ public: | |||
| 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 | |||
| void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | |||
| void setWindowTransientWinId(const uintptr_t winId) {} | |||
| @@ -23,6 +23,7 @@ | |||
| #include "lv2/data-access.h" | |||
| #include "lv2/instance-access.h" | |||
| #include "lv2/options.h" | |||
| #include "lv2/parameters.h" | |||
| #include "lv2/ui.h" | |||
| #include "lv2/urid.h" | |||
| #include "lv2/lv2_kxstudio_properties.h" | |||
| @@ -175,17 +176,17 @@ public: | |||
| { | |||
| 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); | |||
| continue; | |||
| } | |||
| else | |||
| { | |||
| d_stderr("Host changed sampleRate but with wrong value type"); | |||
| d_stderr("Host changed UI sample-rate but with wrong value type"); | |||
| continue; | |||
| } | |||
| } | |||
| @@ -402,23 +403,23 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, | |||
| 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) | |||
| { | |||
| 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 | |||
| d_stderr("Host provides sampleRate but has wrong value type"); | |||
| d_stderr("Host provides UI sample-rate but has wrong value type"); | |||
| 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_lastUiSampleRate = 44100.0; | |||
| @@ -11,11 +11,6 @@ fi | |||
| PWD=`pwd` | |||
| if [ ! -d /System/Library ]; then | |||
| echo "This doesn't seem to be OSX, please stop!" | |||
| exit 0 | |||
| fi | |||
| rm -rf *.vst/ | |||
| PLUGINS=`ls | grep vst.dylib` | |||
| @@ -27,7 +22,6 @@ for i in $PLUGINS; do | |||
| rm -f $FILE.vst/Contents/MacOS/deleteme | |||
| sed -i -e "s/X-PROJECTNAME-X/$FILE/" $FILE.vst/Contents/Info.plist | |||
| rm -f $FILE.vst/Contents/Info.plist-e | |||
| SetFile -a B $FILE.vst | |||
| done | |||
| cd .. | |||
| @@ -16,7 +16,10 @@ | |||
| # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| import os, numpy, sys | |||
| import Image | |||
| try: | |||
| import Image | |||
| except: | |||
| from PIL import Image | |||
| # ----------------------------------------------------- | |||