mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Linux: Added support for building and hosting VST3 plug-ins
This commit is contained in:
parent
74ca3b44c4
commit
de712ca02e
15 changed files with 416 additions and 121 deletions
|
|
@ -1847,8 +1847,8 @@ private:
|
||||||
if (handleManufacturerSpecificVST2Opcode (args.index, args.value, args.ptr, args.opt))
|
if (handleManufacturerSpecificVST2Opcode (args.index, args.value, args.ptr, args.opt))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (args.index == JUCE_MULTICHAR_CONSTANT ('P', 'r', 'e', 'S')
|
if (args.index == (int32) JUCE_MULTICHAR_CONSTANT ('P', 'r', 'e', 'S')
|
||||||
&& args.value == JUCE_MULTICHAR_CONSTANT ('A', 'e', 'C', 's'))
|
&& args.value == (int32) JUCE_MULTICHAR_CONSTANT ('A', 'e', 'C', 's'))
|
||||||
return handleSetContentScaleFactor (args.opt);
|
return handleSetContentScaleFactor (args.opt);
|
||||||
|
|
||||||
if (args.index == Vst2::effGetParamDisplay)
|
if (args.index == Vst2::effGetParamDisplay)
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@
|
||||||
#include "../../juce_core/system/juce_TargetPlatform.h"
|
#include "../../juce_core/system/juce_TargetPlatform.h"
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64)
|
#if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64 || LINUX || __linux__)
|
||||||
|
|
||||||
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS)
|
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
|
||||||
#undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
|
#undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
|
||||||
#define JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY 1
|
#define JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY 1
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -30,9 +30,11 @@
|
||||||
#include "../../juce_audio_processors/format_types/juce_VST3Headers.h"
|
#include "../../juce_audio_processors/format_types/juce_VST3Headers.h"
|
||||||
|
|
||||||
#undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
|
#undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
|
||||||
|
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
|
||||||
|
|
||||||
#include "../utility/juce_CheckSettingMacros.h"
|
#include "../utility/juce_CheckSettingMacros.h"
|
||||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||||
|
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||||
#include "../utility/juce_WindowsHooks.h"
|
#include "../utility/juce_WindowsHooks.h"
|
||||||
#include "../utility/juce_FakeMouseMoveGenerator.h"
|
#include "../utility/juce_FakeMouseMoveGenerator.h"
|
||||||
#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"
|
#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"
|
||||||
|
|
@ -55,6 +57,10 @@ namespace Vst2
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if JUCE_LINUX
|
||||||
|
std::vector<std::pair<int, std::function<void(int)>>> getFdReadCallbacks();
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -62,14 +68,14 @@ using namespace Steinberg;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#if JUCE_MAC
|
#if JUCE_MAC
|
||||||
extern void initialiseMacVST();
|
extern void initialiseMacVST();
|
||||||
|
|
||||||
#if ! JUCE_64BIT
|
#if ! JUCE_64BIT
|
||||||
extern void updateEditorCompBoundsVST (Component*);
|
extern void updateEditorCompBoundsVST (Component*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern JUCE_API void* attachComponentToWindowRefVST (Component*, void* parentWindowOrView, bool isNSView);
|
extern JUCE_API void* attachComponentToWindowRefVST (Component*, void* parentWindowOrView, bool isNSView);
|
||||||
extern JUCE_API void detachComponentFromWindowRefVST (Component*, void* nsWindow, bool isNSView);
|
extern JUCE_API void detachComponentFromWindowRefVST (Component*, void* nsWindow, bool isNSView);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
||||||
|
|
@ -426,7 +432,7 @@ public:
|
||||||
jassert (info.defaultNormalizedValue >= 0 && info.defaultNormalizedValue <= 1.0f);
|
jassert (info.defaultNormalizedValue >= 0 && info.defaultNormalizedValue <= 1.0f);
|
||||||
|
|
||||||
// Is this a meter?
|
// Is this a meter?
|
||||||
if (((param.getCategory() & 0xffff0000) >> 16) == 2)
|
if ((((unsigned int) param.getCategory() & 0xffff0000) >> 16) == 2)
|
||||||
info.flags = Vst::ParameterInfo::kIsReadOnly;
|
info.flags = Vst::ParameterInfo::kIsReadOnly;
|
||||||
else
|
else
|
||||||
info.flags = param.isAutomatable() ? Vst::ParameterInfo::kCanAutomate : 0;
|
info.flags = param.isAutomatable() ? Vst::ParameterInfo::kCanAutomate : 0;
|
||||||
|
|
@ -1011,6 +1017,9 @@ private:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
class JuceVST3Editor : public Vst::EditorView,
|
class JuceVST3Editor : public Vst::EditorView,
|
||||||
public Steinberg::IPlugViewContentScaleSupport,
|
public Steinberg::IPlugViewContentScaleSupport,
|
||||||
|
#if JUCE_LINUX
|
||||||
|
public Steinberg::Linux::IEventHandler,
|
||||||
|
#endif
|
||||||
private Timer
|
private Timer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -1037,6 +1046,17 @@ private:
|
||||||
|
|
||||||
REFCOUNT_METHODS (Vst::EditorView)
|
REFCOUNT_METHODS (Vst::EditorView)
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
#if JUCE_LINUX
|
||||||
|
void PLUGIN_API onFDIsSet (Steinberg::Linux::FileDescriptor fd) override
|
||||||
|
{
|
||||||
|
auto it = fdCallbackMap.find (fd);
|
||||||
|
|
||||||
|
if (it != fdCallbackMap.end())
|
||||||
|
it->second (fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
tresult PLUGIN_API isPlatformTypeSupported (FIDString type) override
|
tresult PLUGIN_API isPlatformTypeSupported (FIDString type) override
|
||||||
{
|
{
|
||||||
|
|
@ -1044,8 +1064,10 @@ private:
|
||||||
{
|
{
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS
|
||||||
if (strcmp (type, kPlatformTypeHWND) == 0)
|
if (strcmp (type, kPlatformTypeHWND) == 0)
|
||||||
#else
|
#elif JUCE_MAC
|
||||||
if (strcmp (type, kPlatformTypeNSView) == 0 || strcmp (type, kPlatformTypeHIView) == 0)
|
if (strcmp (type, kPlatformTypeNSView) == 0 || strcmp (type, kPlatformTypeHIView) == 0)
|
||||||
|
#elif JUCE_LINUX
|
||||||
|
if (strcmp (type, kPlatformTypeX11EmbedWindowID) == 0)
|
||||||
#endif
|
#endif
|
||||||
return kResultTrue;
|
return kResultTrue;
|
||||||
}
|
}
|
||||||
|
|
@ -1061,10 +1083,20 @@ private:
|
||||||
if (component == nullptr)
|
if (component == nullptr)
|
||||||
component.reset (new ContentWrapperComponent (*this, pluginInstance));
|
component.reset (new ContentWrapperComponent (*this, pluginInstance));
|
||||||
|
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS || JUCE_LINUX
|
||||||
component->addToDesktop (0, parent);
|
component->addToDesktop (0, parent);
|
||||||
component->setOpaque (true);
|
component->setOpaque (true);
|
||||||
component->setVisible (true);
|
component->setVisible (true);
|
||||||
|
#if JUCE_LINUX
|
||||||
|
if (auto* runLoop = getHostRunLoop())
|
||||||
|
{
|
||||||
|
for (auto& cb : getFdReadCallbacks())
|
||||||
|
{
|
||||||
|
fdCallbackMap[cb.first] = cb.second;
|
||||||
|
runLoop->registerEventHandler (this, cb.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
isNSView = (strcmp (type, kPlatformTypeNSView) == 0);
|
isNSView = (strcmp (type, kPlatformTypeNSView) == 0);
|
||||||
macHostWindow = juce::attachComponentToWindowRefVST (component.get(), parent, isNSView);
|
macHostWindow = juce::attachComponentToWindowRefVST (component.get(), parent, isNSView);
|
||||||
|
|
@ -1085,8 +1117,14 @@ private:
|
||||||
{
|
{
|
||||||
if (component != nullptr)
|
if (component != nullptr)
|
||||||
{
|
{
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS || JUCE_LINUX
|
||||||
component->removeFromDesktop();
|
component->removeFromDesktop();
|
||||||
|
#if JUCE_LINUX
|
||||||
|
fdCallbackMap.clear();
|
||||||
|
|
||||||
|
if (auto* runLoop = getHostRunLoop())
|
||||||
|
runLoop->unregisterEventHandler (this);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
if (macHostWindow != nullptr)
|
if (macHostWindow != nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -1465,6 +1503,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
ScopedJuceInitialiser_GUI libraryInitialiser;
|
||||||
|
|
||||||
ComSmartPtr<JuceVST3EditController> owner;
|
ComSmartPtr<JuceVST3EditController> owner;
|
||||||
AudioProcessor& pluginInstance;
|
AudioProcessor& pluginInstance;
|
||||||
|
|
||||||
|
|
@ -1497,7 +1537,22 @@ private:
|
||||||
|
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS
|
||||||
WindowsHooks hooks;
|
WindowsHooks hooks;
|
||||||
|
#elif JUCE_LINUX
|
||||||
|
std::unordered_map<int, std::function<void(int)>> fdCallbackMap;
|
||||||
|
|
||||||
|
::Display* display = XWindowSystem::getInstance()->getDisplay();
|
||||||
|
|
||||||
|
Steinberg::Linux::IRunLoop* getHostRunLoop()
|
||||||
|
{
|
||||||
|
Steinberg::Linux::IRunLoop* runLoop = nullptr;
|
||||||
|
|
||||||
|
if (plugFrame != nullptr)
|
||||||
|
plugFrame->queryInterface (Steinberg::Linux::IRunLoop::iid, (void**) &runLoop);
|
||||||
|
|
||||||
|
return runLoop;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
@ -1766,7 +1821,7 @@ public:
|
||||||
|
|
||||||
void setStateInformation (const void* data, int sizeAsInt)
|
void setStateInformation (const void* data, int sizeAsInt)
|
||||||
{
|
{
|
||||||
int64 size = sizeAsInt;
|
auto size = (uint64) sizeAsInt;
|
||||||
|
|
||||||
// Check if this data was written with a newer JUCE version
|
// Check if this data was written with a newer JUCE version
|
||||||
// and if it has the JUCE private data magic code at the end
|
// and if it has the JUCE private data magic code at the end
|
||||||
|
|
@ -1798,7 +1853,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size >= 0)
|
if (size > 0)
|
||||||
pluginInstance->setStateInformation (data, static_cast<int> (size));
|
pluginInstance->setStateInformation (data, static_cast<int> (size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2833,61 +2888,87 @@ bool shutdownModule()
|
||||||
#undef JUCE_EXPORTED_FUNCTION
|
#undef JUCE_EXPORTED_FUNCTION
|
||||||
|
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS
|
||||||
extern "C" __declspec (dllexport) bool InitDll() { return initModule(); }
|
extern "C" __declspec (dllexport) bool InitDll() { return initModule(); }
|
||||||
extern "C" __declspec (dllexport) bool ExitDll() { return shutdownModule(); }
|
extern "C" __declspec (dllexport) bool ExitDll() { return shutdownModule(); }
|
||||||
#define JUCE_EXPORTED_FUNCTION
|
#define JUCE_EXPORTED_FUNCTION
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define JUCE_EXPORTED_FUNCTION extern "C" __attribute__ ((visibility ("default")))
|
#define JUCE_EXPORTED_FUNCTION extern "C" __attribute__ ((visibility ("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
CFBundleRef globalBundleInstance = nullptr;
|
#if JUCE_LINUX
|
||||||
juce::uint32 numBundleRefs = 0;
|
void* moduleHandle = nullptr;
|
||||||
juce::Array<CFBundleRef> bundleRefs;
|
int moduleEntryCounter = 0;
|
||||||
|
|
||||||
enum { MaxPathLength = 2048 };
|
JUCE_EXPORTED_FUNCTION bool ModuleEntry (void* sharedLibraryHandle)
|
||||||
char modulePath[MaxPathLength] = { 0 };
|
{
|
||||||
void* moduleHandle = nullptr;
|
if (++moduleEntryCounter == 1)
|
||||||
|
{
|
||||||
|
moduleHandle = sharedLibraryHandle;
|
||||||
|
return initModule();
|
||||||
|
}
|
||||||
|
|
||||||
JUCE_EXPORTED_FUNCTION bool bundleEntry (CFBundleRef ref)
|
return true;
|
||||||
{
|
}
|
||||||
if (ref != nullptr)
|
|
||||||
{
|
|
||||||
++numBundleRefs;
|
|
||||||
CFRetain (ref);
|
|
||||||
|
|
||||||
bundleRefs.add (ref);
|
JUCE_EXPORTED_FUNCTION bool ModuleExit()
|
||||||
|
{
|
||||||
|
if (--moduleEntryCounter == 0)
|
||||||
|
{
|
||||||
|
moduleHandle = nullptr;
|
||||||
|
return shutdownModule();
|
||||||
|
}
|
||||||
|
|
||||||
if (moduleHandle == nullptr)
|
return true;
|
||||||
{
|
}
|
||||||
globalBundleInstance = ref;
|
#elif JUCE_MAC
|
||||||
moduleHandle = ref;
|
CFBundleRef globalBundleInstance = nullptr;
|
||||||
|
juce::uint32 numBundleRefs = 0;
|
||||||
|
juce::Array<CFBundleRef> bundleRefs;
|
||||||
|
|
||||||
CFURLRef tempURL = CFBundleCopyBundleURL (ref);
|
enum { MaxPathLength = 2048 };
|
||||||
CFURLGetFileSystemRepresentation (tempURL, true, (UInt8*) modulePath, MaxPathLength);
|
char modulePath[MaxPathLength] = { 0 };
|
||||||
CFRelease (tempURL);
|
void* moduleHandle = nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return initModule();
|
JUCE_EXPORTED_FUNCTION bool bundleEntry (CFBundleRef ref)
|
||||||
}
|
{
|
||||||
|
if (ref != nullptr)
|
||||||
|
{
|
||||||
|
++numBundleRefs;
|
||||||
|
CFRetain (ref);
|
||||||
|
|
||||||
JUCE_EXPORTED_FUNCTION bool bundleExit()
|
bundleRefs.add (ref);
|
||||||
{
|
|
||||||
if (shutdownModule())
|
|
||||||
{
|
|
||||||
if (--numBundleRefs == 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < bundleRefs.size(); ++i)
|
|
||||||
CFRelease (bundleRefs.getUnchecked (i));
|
|
||||||
|
|
||||||
bundleRefs.clear();
|
if (moduleHandle == nullptr)
|
||||||
}
|
{
|
||||||
|
globalBundleInstance = ref;
|
||||||
|
moduleHandle = ref;
|
||||||
|
|
||||||
return true;
|
CFURLRef tempURL = CFBundleCopyBundleURL (ref);
|
||||||
}
|
CFURLGetFileSystemRepresentation (tempURL, true, (UInt8*) modulePath, MaxPathLength);
|
||||||
|
CFRelease (tempURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return initModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JUCE_EXPORTED_FUNCTION bool bundleExit()
|
||||||
|
{
|
||||||
|
if (shutdownModule())
|
||||||
|
{
|
||||||
|
if (--numBundleRefs == 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < bundleRefs.size(); ++i)
|
||||||
|
CFRelease (bundleRefs.getUnchecked (i));
|
||||||
|
|
||||||
|
bundleRefs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
@ -3091,7 +3172,7 @@ private:
|
||||||
if (entry->isUnicode)
|
if (entry->isUnicode)
|
||||||
return kResultFalse;
|
return kResultFalse;
|
||||||
|
|
||||||
memcpy (info, &entry->info2, sizeof (PClassInfoType));
|
memcpy (info, (PClassInfoType*) &entry->info2, sizeof (PClassInfoType));
|
||||||
return kResultOk;
|
return kResultOk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
#define JucePlugin_Build_RTAS 0
|
#define JucePlugin_Build_RTAS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ! (defined (_MSC_VER) || defined (__APPLE_CPP__) || defined (__APPLE_CC__))
|
#if ! (defined (_MSC_VER) || defined (__APPLE_CPP__) || defined (__APPLE_CC__) || defined (LINUX) || defined (__linux__))
|
||||||
#undef JucePlugin_Build_VST3
|
#undef JucePlugin_Build_VST3
|
||||||
#define JucePlugin_Build_VST3 0
|
#define JucePlugin_Build_VST3 0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@
|
||||||
#include "../utility/juce_CheckSettingMacros.h"
|
#include "../utility/juce_CheckSettingMacros.h"
|
||||||
#include "juce_IncludeModuleHeaders.h"
|
#include "juce_IncludeModuleHeaders.h"
|
||||||
|
|
||||||
using namespace juce;
|
|
||||||
|
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -40,7 +38,7 @@ std::function<bool(AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioS
|
||||||
#define JUCE_VST3_CAN_REPLACE_VST2 1
|
#define JUCE_VST3_CAN_REPLACE_VST2 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64) && JUCE_VST3_CAN_REPLACE_VST2
|
#if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64 || LINUX || __linux__) && JUCE_VST3_CAN_REPLACE_VST2
|
||||||
#define VST3_REPLACEMENT_AVAILABLE 1
|
#define VST3_REPLACEMENT_AVAILABLE 1
|
||||||
|
|
||||||
// NB: Nasty old-fashioned code in here because it's copied from the Steinberg example code.
|
// NB: Nasty old-fashioned code in here because it's copied from the Steinberg example code.
|
||||||
|
|
@ -141,6 +139,8 @@ bool JUCE_API handleManufacturerSpecificVST2Opcode (int32 index, pointer_sized_i
|
||||||
|
|
||||||
} // namespace juce
|
} // namespace juce
|
||||||
|
|
||||||
|
using namespace juce;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||||
extern bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
|
extern bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ void AudioPluginFormatManager::addDefaultFormats()
|
||||||
jassert (dynamic_cast<VSTPluginFormat*> (format) == nullptr);
|
jassert (dynamic_cast<VSTPluginFormat*> (format) == nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS)
|
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
|
||||||
jassert (dynamic_cast<VST3PluginFormat*> (format) == nullptr);
|
jassert (dynamic_cast<VST3PluginFormat*> (format) == nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ void AudioPluginFormatManager::addDefaultFormats()
|
||||||
formats.add (new VSTPluginFormat());
|
formats.add (new VSTPluginFormat());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS)
|
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
|
||||||
formats.add (new VST3PluginFormat());
|
formats.add (new VST3PluginFormat());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,6 @@ static inline int strnicmp16 (const Steinberg::char16* s1, const Steinberg::char
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static inline int sprintf16 (Steinberg::char16* wcs, const Steinberg::char16* format, ...)
|
static inline int sprintf16 (Steinberg::char16* wcs, const Steinberg::char16* format, ...)
|
||||||
{
|
{
|
||||||
#warning DEPRECATED No Linux implementation
|
|
||||||
assert(false && "DEPRECATED No Linux implementation");
|
assert(false && "DEPRECATED No Linux implementation");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -311,7 +310,6 @@ static inline int vsnwprintf (Steinberg::char16* wcs, size_t maxlen,
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static inline Steinberg::char16* strrchr16 (const Steinberg::char16* str, Steinberg::char16 c)
|
static inline Steinberg::char16* strrchr16 (const Steinberg::char16* str, Steinberg::char16 c)
|
||||||
{
|
{
|
||||||
#warning DEPRECATED No Linux implementation
|
|
||||||
assert(false && "DEPRECATED No Linux implementation");
|
assert(false && "DEPRECATED No Linux implementation");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -1586,7 +1584,6 @@ char16 ConstString::toLower (char16 c)
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
#elif SMTG_OS_LINUX
|
#elif SMTG_OS_LINUX
|
||||||
#warning DEPRECATED No Linux implementation
|
|
||||||
assert(false && "DEPRECATED No Linux implementation");
|
assert(false && "DEPRECATED No Linux implementation");
|
||||||
return c;
|
return c;
|
||||||
#else
|
#else
|
||||||
|
|
@ -1615,7 +1612,6 @@ char16 ConstString::toUpper (char16 c)
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
#elif SMTG_OS_LINUX
|
#elif SMTG_OS_LINUX
|
||||||
#warning DEPRECATED No Linux implementation
|
|
||||||
assert(false && "DEPRECATED No Linux implementation");
|
assert(false && "DEPRECATED No Linux implementation");
|
||||||
return c;
|
return c;
|
||||||
#else
|
#else
|
||||||
|
|
@ -1913,8 +1909,7 @@ int32 ConstString::multiByteToWideString (char16* dest, const char8* source, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#warning DEPRECATED No Linux implementation
|
|
||||||
assert(false && "DEPRECATED No Linux implementation");
|
assert(false && "DEPRECATED No Linux implementation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1994,8 +1989,7 @@ int32 ConstString::wideStringToMultiByte (char8* dest, const char16* wideString,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#warning DEPRECATED No Linux implementation
|
|
||||||
assert(false && "DEPRECATED No Linux implementation");
|
assert(false && "DEPRECATED No Linux implementation");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,6 @@ bool FUID::generate ()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#warning implement me!
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,8 +85,10 @@ inline Steinberg::Vst::TChar* toString (const juce::String& source) noexcept
|
||||||
|
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS
|
||||||
static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeHWND;
|
static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeHWND;
|
||||||
#else
|
#elif JUCE_MAC
|
||||||
static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeNSView;
|
static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeNSView;
|
||||||
|
#elif JUCE_LINUX
|
||||||
|
static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeX11EmbedWindowID;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor",
|
||||||
"-Winconsistent-missing-destructor-override",
|
"-Winconsistent-missing-destructor-override",
|
||||||
"-Wcast-align",
|
"-Wcast-align",
|
||||||
"-Wignored-qualifiers",
|
"-Wignored-qualifiers",
|
||||||
"-Wmissing-field-initializers")
|
"-Wmissing-field-initializers",
|
||||||
|
"-Wformat=",
|
||||||
|
"-Wpedantic",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wclass-memaccess")
|
||||||
|
|
||||||
#undef DEVELOPMENT
|
#undef DEVELOPMENT
|
||||||
#define DEVELOPMENT 0 // This avoids a Clang warning in Steinberg code about unused values
|
#define DEVELOPMENT 0 // This avoids a Clang warning in Steinberg code about unused values
|
||||||
|
|
@ -93,12 +97,14 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor",
|
||||||
#include <base/source/fobject.cpp>
|
#include <base/source/fobject.cpp>
|
||||||
#include <base/source/fstreamer.cpp>
|
#include <base/source/fstreamer.cpp>
|
||||||
#include <base/source/fstring.cpp>
|
#include <base/source/fstring.cpp>
|
||||||
#if VST_VERSION >= 0x030608
|
|
||||||
#include <base/thread/source/flock.cpp>
|
#if VST_VERSION >= 0x030608
|
||||||
#include <pluginterfaces/base/coreiids.cpp>
|
#include <base/thread/source/flock.cpp>
|
||||||
#else
|
#include <pluginterfaces/base/coreiids.cpp>
|
||||||
#include <base/source/flock.cpp>
|
#else
|
||||||
#endif
|
#include <base/source/flock.cpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <base/source/updatehandler.cpp>
|
#include <base/source/updatehandler.cpp>
|
||||||
#include <pluginterfaces/base/conststringtable.cpp>
|
#include <pluginterfaces/base/conststringtable.cpp>
|
||||||
#include <pluginterfaces/base/funknown.cpp>
|
#include <pluginterfaces/base/funknown.cpp>
|
||||||
|
|
@ -118,9 +124,10 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor",
|
||||||
#include <public.sdk/source/vst/vstparameters.cpp>
|
#include <public.sdk/source/vst/vstparameters.cpp>
|
||||||
#include <public.sdk/source/vst/vstpresetfile.cpp>
|
#include <public.sdk/source/vst/vstpresetfile.cpp>
|
||||||
#include <public.sdk/source/vst/hosting/hostclasses.cpp>
|
#include <public.sdk/source/vst/hosting/hostclasses.cpp>
|
||||||
#if VST_VERSION >= 0x03060c // 3.6.12
|
|
||||||
#include <public.sdk/source/vst/hosting/pluginterfacesupport.cpp>
|
#if VST_VERSION >= 0x03060c // 3.6.12
|
||||||
#endif
|
#include <public.sdk/source/vst/hosting/pluginterfacesupport.cpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
namespace Steinberg
|
namespace Steinberg
|
||||||
|
|
@ -138,8 +145,12 @@ namespace Steinberg
|
||||||
DEF_CLASS_IID (IPlugView)
|
DEF_CLASS_IID (IPlugView)
|
||||||
DEF_CLASS_IID (IPlugFrame)
|
DEF_CLASS_IID (IPlugFrame)
|
||||||
DEF_CLASS_IID (IPlugViewContentScaleSupport)
|
DEF_CLASS_IID (IPlugViewContentScaleSupport)
|
||||||
|
|
||||||
|
#if JUCE_LINUX
|
||||||
|
DEF_CLASS_IID (Linux::IRunLoop)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif //JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
|
#endif // JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
|
||||||
|
|
||||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS)
|
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
|
||||||
|
|
||||||
#include "juce_VST3Headers.h"
|
#include "juce_VST3Headers.h"
|
||||||
#include "juce_VST3Common.h"
|
#include "juce_VST3Common.h"
|
||||||
|
|
@ -573,7 +573,7 @@ private:
|
||||||
|
|
||||||
tresult PLUGIN_API setBinary (AttrID id, const void* data, Steinberg::uint32 size) override
|
tresult PLUGIN_API setBinary (AttrID id, const void* data, Steinberg::uint32 size) override
|
||||||
{
|
{
|
||||||
jassert (size >= 0 && (data != nullptr || size == 0));
|
jassert (data != nullptr || size == 0);
|
||||||
addMessageToQueue (id, MemoryBlock (data, (size_t) size));
|
addMessageToQueue (id, MemoryBlock (data, (size_t) size));
|
||||||
return kResultTrue;
|
return kResultTrue;
|
||||||
}
|
}
|
||||||
|
|
@ -821,15 +821,18 @@ struct DLLHandle
|
||||||
{
|
{
|
||||||
typedef bool (PLUGIN_API *ExitModuleFn) ();
|
typedef bool (PLUGIN_API *ExitModuleFn) ();
|
||||||
|
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS || JUCE_LINUX
|
||||||
releaseFactory();
|
releaseFactory();
|
||||||
|
|
||||||
if (auto exitFn = (ExitModuleFn) getFunction ("ExitDll"))
|
#if JUCE_WINDOWS
|
||||||
|
if (auto exitFn = (ExitModuleFn) getFunction ("ExitDll"))
|
||||||
|
#else
|
||||||
|
if (auto exitFn = (ExitModuleFn) getFunction ("ModuleExit"))
|
||||||
|
#endif
|
||||||
exitFn();
|
exitFn();
|
||||||
|
|
||||||
library.close();
|
library.close();
|
||||||
|
#elif JUCE_MAC
|
||||||
#else
|
|
||||||
if (bundleRef != nullptr)
|
if (bundleRef != nullptr)
|
||||||
{
|
{
|
||||||
releaseFactory();
|
releaseFactory();
|
||||||
|
|
@ -846,11 +849,11 @@ struct DLLHandle
|
||||||
|
|
||||||
void open (const PluginDescription& description)
|
void open (const PluginDescription& description)
|
||||||
{
|
{
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS || JUCE_LINUX
|
||||||
jassert (description.fileOrIdentifier.isNotEmpty());
|
jassert (description.fileOrIdentifier.isNotEmpty());
|
||||||
jassert (File (description.fileOrIdentifier).existsAsFile());
|
jassert (File (description.fileOrIdentifier).existsAsFile());
|
||||||
library.open (description.fileOrIdentifier);
|
library.open (description.fileOrIdentifier);
|
||||||
#else
|
#elif JUCE_MAC
|
||||||
open (description.fileOrIdentifier);
|
open (description.fileOrIdentifier);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -878,9 +881,9 @@ struct DLLHandle
|
||||||
|
|
||||||
void* getFunction (const char* functionName)
|
void* getFunction (const char* functionName)
|
||||||
{
|
{
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS || JUCE_LINUX
|
||||||
return library.getFunction (functionName);
|
return library.getFunction (functionName);
|
||||||
#else
|
#elif JUCE_MAC
|
||||||
if (bundleRef == nullptr)
|
if (bundleRef == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
@ -924,8 +927,7 @@ private:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#elif JUCE_MAC
|
||||||
#else
|
|
||||||
CFBundleRef bundleRef;
|
CFBundleRef bundleRef;
|
||||||
|
|
||||||
bool open (const String& filePath)
|
bool open (const String& filePath)
|
||||||
|
|
@ -973,6 +975,55 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#elif JUCE_LINUX
|
||||||
|
DynamicLibrary library;
|
||||||
|
|
||||||
|
String getMachineName()
|
||||||
|
{
|
||||||
|
struct utsname unameData;
|
||||||
|
auto res = uname (&unameData);
|
||||||
|
|
||||||
|
if (res != 0)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return unameData.machine;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool open (const String& bundlePath)
|
||||||
|
{
|
||||||
|
File file (bundlePath);
|
||||||
|
|
||||||
|
if (! file.exists() || ! file.isDirectory())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto pluginName = file.getFileNameWithoutExtension();
|
||||||
|
|
||||||
|
file = file.getChildFile ("Contents")
|
||||||
|
.getChildFile (getMachineName() + "-linux")
|
||||||
|
.getChildFile (pluginName + ".so");
|
||||||
|
|
||||||
|
if (! file.exists())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (library.open (file.getFullPathName()))
|
||||||
|
{
|
||||||
|
typedef bool (PLUGIN_API *InitModuleProc) (void*);
|
||||||
|
|
||||||
|
if (auto* proc = (InitModuleProc) getFunction ("ModuleEntry"))
|
||||||
|
{
|
||||||
|
if (proc (library.getNativeHandle()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
library.close();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1091,7 +1142,7 @@ private:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
struct VST3PluginWindow : public AudioProcessorEditor,
|
struct VST3PluginWindow : public AudioProcessorEditor,
|
||||||
public ComponentMovementWatcher,
|
public ComponentMovementWatcher,
|
||||||
#if ! JUCE_MAC
|
#if JUCE_WINDOWS || JUCE_LINUX
|
||||||
public ComponentPeer::ScaleFactorListener,
|
public ComponentPeer::ScaleFactorListener,
|
||||||
#endif
|
#endif
|
||||||
public IPlugFrame
|
public IPlugFrame
|
||||||
|
|
@ -1121,6 +1172,10 @@ struct VST3PluginWindow : public AudioProcessorEditor,
|
||||||
scaleInterface->release();
|
scaleInterface->release();
|
||||||
|
|
||||||
removeScaleFactorListeners();
|
removeScaleFactorListeners();
|
||||||
|
|
||||||
|
#if JUCE_LINUX
|
||||||
|
embeddedComponent.removeClient();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
warnOnFailure (view->removed());
|
warnOnFailure (view->removed());
|
||||||
|
|
@ -1135,8 +1190,118 @@ struct VST3PluginWindow : public AudioProcessorEditor,
|
||||||
view = nullptr;
|
view = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
JUCE_DECLARE_VST3_COM_REF_METHODS
|
#if JUCE_LINUX
|
||||||
|
struct RunLoop final : public Steinberg::Linux::IRunLoop
|
||||||
|
{
|
||||||
|
~RunLoop()
|
||||||
|
{
|
||||||
|
for (const auto& h : eventHandlers)
|
||||||
|
LinuxEventLoop::unregisterFdCallback (h.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
tresult PLUGIN_API registerEventHandler (Linux::IEventHandler* handler,
|
||||||
|
Linux::FileDescriptor fd) override
|
||||||
|
{
|
||||||
|
if (handler == nullptr || eventHandlers.find (fd) != eventHandlers.end())
|
||||||
|
return kInvalidArgument;
|
||||||
|
|
||||||
|
LinuxEventLoop::registerFdCallback (fd, [handler] (int descriptor)
|
||||||
|
{
|
||||||
|
handler->onFDIsSet (descriptor);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
eventHandlers.emplace (fd, handler);
|
||||||
|
return kResultTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tresult PLUGIN_API unregisterEventHandler (Linux::IEventHandler* handler) override
|
||||||
|
{
|
||||||
|
if (handler == nullptr)
|
||||||
|
return kInvalidArgument;
|
||||||
|
|
||||||
|
for (auto it = eventHandlers.begin(), end = eventHandlers.end(); it != end; ++it)
|
||||||
|
{
|
||||||
|
if (it->second == handler)
|
||||||
|
{
|
||||||
|
LinuxEventLoop::unregisterFdCallback (it->first);
|
||||||
|
eventHandlers.erase (it);
|
||||||
|
return kResultTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kResultFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
tresult PLUGIN_API registerTimer (Linux::ITimerHandler* handler, Linux::TimerInterval milliseconds) override
|
||||||
|
{
|
||||||
|
if (handler == nullptr || milliseconds == 0)
|
||||||
|
return kInvalidArgument;
|
||||||
|
|
||||||
|
timerHandlers.push_back (std::make_unique<TimerCaller> (handler, (int) milliseconds));
|
||||||
|
return kResultTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tresult PLUGIN_API unregisterTimer (Linux::ITimerHandler* handler) override
|
||||||
|
{
|
||||||
|
if (handler == nullptr)
|
||||||
|
return kInvalidArgument;
|
||||||
|
|
||||||
|
for (auto it = timerHandlers.begin(), end = timerHandlers.end(); it != end; ++it)
|
||||||
|
{
|
||||||
|
if (it->get()->handler == handler)
|
||||||
|
{
|
||||||
|
timerHandlers.erase (it);
|
||||||
|
return kResultTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kNotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 PLUGIN_API addRef() override { return 1000; }
|
||||||
|
uint32 PLUGIN_API release() override { return 1000; }
|
||||||
|
tresult PLUGIN_API queryInterface (const TUID, void**) override { return kNoInterface; }
|
||||||
|
|
||||||
|
std::unordered_map<Linux::FileDescriptor, Linux::IEventHandler*> eventHandlers;
|
||||||
|
|
||||||
|
struct TimerCaller : public Timer
|
||||||
|
{
|
||||||
|
TimerCaller (Linux::ITimerHandler* h, int interval) : handler (h)
|
||||||
|
{
|
||||||
|
startTimer (interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timerCallback() override
|
||||||
|
{
|
||||||
|
handler->onTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
Linux::ITimerHandler* handler;
|
||||||
|
};
|
||||||
|
std::vector<std::unique_ptr<TimerCaller>> timerHandlers;
|
||||||
|
};
|
||||||
|
|
||||||
|
RunLoop runLoop;
|
||||||
|
|
||||||
|
Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) override
|
||||||
|
{
|
||||||
|
if (doUIDsMatch (iid, Steinberg::Linux::IRunLoop::iid))
|
||||||
|
{
|
||||||
|
*obj = &runLoop;
|
||||||
|
return kResultTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
jassertfalse;
|
||||||
|
*obj = nullptr;
|
||||||
|
|
||||||
|
return Steinberg::kNotImplemented;
|
||||||
|
}
|
||||||
|
#else
|
||||||
JUCE_DECLARE_VST3_COM_QUERY_METHODS
|
JUCE_DECLARE_VST3_COM_QUERY_METHODS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JUCE_DECLARE_VST3_COM_REF_METHODS
|
||||||
|
|
||||||
void paint (Graphics& g) override
|
void paint (Graphics& g) override
|
||||||
{
|
{
|
||||||
|
|
@ -1205,7 +1370,7 @@ struct VST3PluginWindow : public AudioProcessorEditor,
|
||||||
SetWindowPos (pluginHandle, 0,
|
SetWindowPos (pluginHandle, 0,
|
||||||
pos.x, pos.y, rect.getWidth(), rect.getHeight(),
|
pos.x, pos.y, rect.getWidth(), rect.getHeight(),
|
||||||
isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW);
|
isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW);
|
||||||
#elif JUCE_MAC
|
#else
|
||||||
embeddedComponent.setBounds (getLocalBounds());
|
embeddedComponent.setBounds (getLocalBounds());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1223,7 +1388,7 @@ struct VST3PluginWindow : public AudioProcessorEditor,
|
||||||
SetWindowPos (pluginHandle, 0,
|
SetWindowPos (pluginHandle, 0,
|
||||||
pos.x, pos.y, rect.getWidth(), rect.getHeight(),
|
pos.x, pos.y, rect.getWidth(), rect.getHeight(),
|
||||||
isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW);
|
isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW);
|
||||||
#elif JUCE_MAC
|
#else
|
||||||
embeddedComponent.setBounds (0, 0, (int) rect.getWidth(), (int) rect.getHeight());
|
embeddedComponent.setBounds (0, 0, (int) rect.getWidth(), (int) rect.getHeight());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -1233,6 +1398,8 @@ struct VST3PluginWindow : public AudioProcessorEditor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using ComponentMovementWatcher::componentMovedOrResized;
|
||||||
|
|
||||||
void componentVisibilityChanged() override
|
void componentVisibilityChanged() override
|
||||||
{
|
{
|
||||||
attachPluginWindow();
|
attachPluginWindow();
|
||||||
|
|
@ -1243,10 +1410,12 @@ struct VST3PluginWindow : public AudioProcessorEditor,
|
||||||
componentMovedOrResized (true, true);
|
componentMovedOrResized (true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ! JUCE_MAC
|
using ComponentMovementWatcher::componentVisibilityChanged;
|
||||||
|
|
||||||
|
#if JUCE_WINDOWS || JUCE_LINUX
|
||||||
void nativeScaleFactorChanged (double newScaleFactor) override
|
void nativeScaleFactorChanged (double newScaleFactor) override
|
||||||
{
|
{
|
||||||
if (pluginHandle == nullptr || approximatelyEqual ((float) newScaleFactor, nativeScaleFactor))
|
if (pluginHandle == 0 || approximatelyEqual ((float) newScaleFactor, nativeScaleFactor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nativeScaleFactor = (float) newScaleFactor;
|
nativeScaleFactor = (float) newScaleFactor;
|
||||||
|
|
@ -1291,7 +1460,11 @@ private:
|
||||||
|
|
||||||
void attachPluginWindow()
|
void attachPluginWindow()
|
||||||
{
|
{
|
||||||
if (pluginHandle == nullptr)
|
#if JUCE_MAC
|
||||||
|
if (pluginHandle == nil)
|
||||||
|
#else
|
||||||
|
if (pluginHandle == 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS
|
||||||
if (auto* topComp = getTopLevelComponent())
|
if (auto* topComp = getTopLevelComponent())
|
||||||
|
|
@ -1300,25 +1473,33 @@ private:
|
||||||
pluginHandle = (HandleFormat) peer->getNativeHandle();
|
pluginHandle = (HandleFormat) peer->getNativeHandle();
|
||||||
nativeScaleFactor = (float) peer->getPlatformScaleFactor();
|
nativeScaleFactor = (float) peer->getPlatformScaleFactor();
|
||||||
}
|
}
|
||||||
#elif JUCE_MAC
|
#else
|
||||||
embeddedComponent.setBounds (getLocalBounds());
|
embeddedComponent.setBounds (getLocalBounds());
|
||||||
addAndMakeVisible (embeddedComponent);
|
addAndMakeVisible (embeddedComponent);
|
||||||
pluginHandle = (NSView*) embeddedComponent.getView();
|
#if JUCE_MAC
|
||||||
|
pluginHandle = (HandleFormat) embeddedComponent.getView();
|
||||||
|
jassert (pluginHandle != nil);
|
||||||
|
#elif JUCE_LINUX
|
||||||
|
pluginHandle = (HandleFormat) embeddedComponent.getHostWindowID();
|
||||||
|
jassert (pluginHandle != 0);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pluginHandle != nullptr)
|
#if JUCE_MAC
|
||||||
warnOnFailure (view->attached (pluginHandle, defaultVST3WindowType));
|
if (pluginHandle != nil)
|
||||||
else
|
#else
|
||||||
jassertfalse;
|
if (pluginHandle != 0)
|
||||||
|
|
||||||
#if ! JUCE_MAC
|
|
||||||
if (auto* topPeer = getTopLevelComponent()->getPeer())
|
|
||||||
{
|
|
||||||
nativeScaleFactor = 1.0f; // force update
|
|
||||||
nativeScaleFactorChanged ((float) topPeer->getPlatformScaleFactor());
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
warnOnFailure (view->attached ((void*) pluginHandle, defaultVST3WindowType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ! JUCE_MAC
|
||||||
|
if (auto* topPeer = getTopLevelComponent()->getPeer())
|
||||||
|
{
|
||||||
|
nativeScaleFactor = 1.0f; // force update
|
||||||
|
nativeScaleFactorChanged ((float) topPeer->getPlatformScaleFactor());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ! JUCE_MAC
|
#if ! JUCE_MAC
|
||||||
|
|
@ -1350,6 +1531,9 @@ private:
|
||||||
#elif JUCE_MAC
|
#elif JUCE_MAC
|
||||||
AutoResizingNSViewComponentWithParent embeddedComponent;
|
AutoResizingNSViewComponentWithParent embeddedComponent;
|
||||||
using HandleFormat = NSView*;
|
using HandleFormat = NSView*;
|
||||||
|
#elif JUCE_LINUX
|
||||||
|
XEmbedComponent embeddedComponent { true, false };
|
||||||
|
using HandleFormat = Window;
|
||||||
#else
|
#else
|
||||||
Component embeddedComponent;
|
Component embeddedComponent;
|
||||||
using HandleFormat = void*;
|
using HandleFormat = void*;
|
||||||
|
|
@ -3141,7 +3325,7 @@ bool VST3PluginFormat::fileMightContainThisPluginType (const String& fileOrIdent
|
||||||
auto f = File::createFileWithoutCheckingPath (fileOrIdentifier);
|
auto f = File::createFileWithoutCheckingPath (fileOrIdentifier);
|
||||||
|
|
||||||
return f.hasFileExtension (".vst3")
|
return f.hasFileExtension (".vst3")
|
||||||
#if JUCE_MAC
|
#if JUCE_MAC || JUCE_LINUX
|
||||||
&& f.exists();
|
&& f.exists();
|
||||||
#else
|
#else
|
||||||
&& f.existsAsFile();
|
&& f.existsAsFile();
|
||||||
|
|
@ -3199,7 +3383,7 @@ FileSearchPath VST3PluginFormat::getDefaultLocationsToSearch()
|
||||||
#elif JUCE_MAC
|
#elif JUCE_MAC
|
||||||
return FileSearchPath ("/Library/Audio/Plug-Ins/VST3;~/Library/Audio/Plug-Ins/VST3");
|
return FileSearchPath ("/Library/Audio/Plug-Ins/VST3;~/Library/Audio/Plug-Ins/VST3");
|
||||||
#else
|
#else
|
||||||
return FileSearchPath();
|
return FileSearchPath ("/usr/lib/vst3/;/usr/local/lib/vst3/;~/.vst3/");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
#if (JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS)) || DOXYGEN
|
#if (JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)) || DOXYGEN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Implements a plugin format for VST3s.
|
Implements a plugin format for VST3s.
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,14 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JUCE_PLUGINHOST_VST && JUCE_LINUX
|
#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && JUCE_LINUX
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#undef KeyPress
|
#undef KeyPress
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ! JUCE_WINDOWS && ! JUCE_MAC
|
#if ! JUCE_WINDOWS && ! JUCE_MAC && ! JUCE_LINUX
|
||||||
#undef JUCE_PLUGINHOST_VST3
|
#undef JUCE_PLUGINHOST_VST3
|
||||||
#define JUCE_PLUGINHOST_VST3 0
|
#define JUCE_PLUGINHOST_VST3 0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,12 @@ public:
|
||||||
poll (&pfds.front(), static_cast<nfds_t> (pfds.size()), timeoutMs);
|
poll (&pfds.front(), static_cast<nfds_t> (pfds.size()), timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<int, std::function<void(int)>>> getFdReadCallbacks()
|
||||||
|
{
|
||||||
|
const ScopedLock sl (lock);
|
||||||
|
return fdReadCallbacks;
|
||||||
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
JUCE_DECLARE_SINGLETON (InternalRunLoop, false)
|
JUCE_DECLARE_SINGLETON (InternalRunLoop, false)
|
||||||
|
|
||||||
|
|
@ -318,3 +324,14 @@ void LinuxEventLoop::unregisterFdCallback (int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace juce
|
} // namespace juce
|
||||||
|
|
||||||
|
JUCE_API std::vector<std::pair<int, std::function<void(int)>>> getFdReadCallbacks()
|
||||||
|
{
|
||||||
|
using namespace juce;
|
||||||
|
|
||||||
|
if (auto* runLoop = InternalRunLoop::getInstanceWithoutCreating())
|
||||||
|
return runLoop->getFdReadCallbacks();
|
||||||
|
|
||||||
|
jassertfalse;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,9 @@ public:
|
||||||
*/
|
*/
|
||||||
unsigned long getHostWindowID();
|
unsigned long getHostWindowID();
|
||||||
|
|
||||||
|
/** Removes the client window from the host. */
|
||||||
|
void removeClient();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,8 @@ private:
|
||||||
|
|
||||||
X11Symbols::getInstance()->xReparentWindow (dpy, client, root, 0, 0);
|
X11Symbols::getInstance()->xReparentWindow (dpy, client, root, 0, 0);
|
||||||
client = 0;
|
client = 0;
|
||||||
|
|
||||||
|
X11Symbols::getInstance()->xSync (dpy, False);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -681,6 +683,7 @@ void XEmbedComponent::focusGained (FocusChangeType changeType) { pimpl->focu
|
||||||
void XEmbedComponent::focusLost (FocusChangeType changeType) { pimpl->focusLost (changeType); }
|
void XEmbedComponent::focusLost (FocusChangeType changeType) { pimpl->focusLost (changeType); }
|
||||||
void XEmbedComponent::broughtToFront() { pimpl->broughtToFront(); }
|
void XEmbedComponent::broughtToFront() { pimpl->broughtToFront(); }
|
||||||
unsigned long XEmbedComponent::getHostWindowID() { return pimpl->getHostWindowID(); }
|
unsigned long XEmbedComponent::getHostWindowID() { return pimpl->getHostWindowID(); }
|
||||||
|
void XEmbedComponent::removeClient() { pimpl->setClient (0, true); }
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
bool juce_handleXEmbedEvent (ComponentPeer* p, void* e)
|
bool juce_handleXEmbedEvent (ComponentPeer* p, void* e)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue