@@ -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 | |||
# ----------------------------------------------------- | |||