git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
2227
deps/juce/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
vendored
Normal file
2227
deps/juce/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
318
deps/juce/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm
vendored
Normal file
318
deps/juce/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
|
||||
#if JUCE_MAC
|
||||
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#if JucePlugin_Build_VST || JucePlugin_Build_VST3
|
||||
|
||||
#define JUCE_MAC_WINDOW_VISIBITY_BODGE 1
|
||||
|
||||
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
#include "../utility/juce_FakeMouseMoveGenerator.h"
|
||||
#include "../utility/juce_CarbonVisibility.h"
|
||||
|
||||
//==============================================================================
|
||||
namespace juce
|
||||
{
|
||||
|
||||
#if ! JUCE_64BIT
|
||||
JUCE_API void updateEditorCompBoundsVST (Component*);
|
||||
void updateEditorCompBoundsVST (Component* comp)
|
||||
{
|
||||
HIViewRef dummyView = (HIViewRef) (void*) (pointer_sized_int)
|
||||
comp->getProperties() ["dummyViewRef"].toString().getHexValue64();
|
||||
|
||||
HIRect r;
|
||||
HIViewGetFrame (dummyView, &r);
|
||||
HIViewRef root;
|
||||
HIViewFindByID (HIViewGetRoot (HIViewGetWindow (dummyView)), kHIViewWindowContentID, &root);
|
||||
HIViewConvertRect (&r, HIViewGetSuperview (dummyView), root);
|
||||
|
||||
Rect windowPos;
|
||||
GetWindowBounds (HIViewGetWindow (dummyView), kWindowContentRgn, &windowPos);
|
||||
|
||||
comp->setTopLeftPosition ((int) (windowPos.left + r.origin.x),
|
||||
(int) (windowPos.top + r.origin.y));
|
||||
}
|
||||
|
||||
static pascal OSStatus viewBoundsChangedEvent (EventHandlerCallRef, EventRef, void* user)
|
||||
{
|
||||
updateEditorCompBoundsVST ((Component*) user);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static bool shouldManuallyCloseHostWindow()
|
||||
{
|
||||
return getHostType().isCubase7orLater() || getHostType().isRenoise() || ((SystemStats::getOperatingSystemType() & 0xff) >= 12);
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
JUCE_API void initialiseMacVST();
|
||||
void initialiseMacVST()
|
||||
{
|
||||
#if ! JUCE_64BIT
|
||||
NSApplicationLoad();
|
||||
#endif
|
||||
}
|
||||
|
||||
JUCE_API void* attachComponentToWindowRefVST (Component* comp, void* parentWindowOrView, bool isNSView);
|
||||
void* attachComponentToWindowRefVST (Component* comp, void* parentWindowOrView, bool isNSView)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
#if ! JUCE_64BIT
|
||||
if (! isNSView)
|
||||
{
|
||||
NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: parentWindowOrView];
|
||||
|
||||
if (shouldManuallyCloseHostWindow())
|
||||
{
|
||||
[hostWindow setReleasedWhenClosed: NO];
|
||||
}
|
||||
else
|
||||
{
|
||||
[hostWindow retain];
|
||||
[hostWindow setReleasedWhenClosed: YES];
|
||||
}
|
||||
|
||||
[hostWindow setCanHide: YES];
|
||||
|
||||
HIViewRef parentView = 0;
|
||||
|
||||
WindowAttributes attributes;
|
||||
GetWindowAttributes ((WindowRef) parentWindowOrView, &attributes);
|
||||
|
||||
if ((attributes & kWindowCompositingAttribute) != 0)
|
||||
{
|
||||
HIViewRef root = HIViewGetRoot ((WindowRef) parentWindowOrView);
|
||||
HIViewFindByID (root, kHIViewWindowContentID, &parentView);
|
||||
|
||||
if (parentView == 0)
|
||||
parentView = root;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetRootControl ((WindowRef) parentWindowOrView, (ControlRef*) &parentView);
|
||||
|
||||
if (parentView == 0)
|
||||
CreateRootControl ((WindowRef) parentWindowOrView, (ControlRef*) &parentView);
|
||||
}
|
||||
|
||||
// It seems that the only way to successfully position our overlaid window is by putting a dummy
|
||||
// HIView into the host's carbon window, and then catching events to see when it gets repositioned
|
||||
HIViewRef dummyView = 0;
|
||||
HIImageViewCreate (0, &dummyView);
|
||||
HIRect r = { {0, 0}, { (float) comp->getWidth(), (float) comp->getHeight()} };
|
||||
HIViewSetFrame (dummyView, &r);
|
||||
HIViewAddSubview (parentView, dummyView);
|
||||
comp->getProperties().set ("dummyViewRef", String::toHexString ((pointer_sized_int) (void*) dummyView));
|
||||
|
||||
EventHandlerRef ref;
|
||||
const EventTypeSpec kControlBoundsChangedEvent = { kEventClassControl, kEventControlBoundsChanged };
|
||||
InstallEventHandler (GetControlEventTarget (dummyView), NewEventHandlerUPP (viewBoundsChangedEvent), 1, &kControlBoundsChangedEvent, (void*) comp, &ref);
|
||||
comp->getProperties().set ("boundsEventRef", String::toHexString ((pointer_sized_int) (void*) ref));
|
||||
|
||||
updateEditorCompBoundsVST (comp);
|
||||
|
||||
#if ! JucePlugin_EditorRequiresKeyboardFocus
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses);
|
||||
#else
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary);
|
||||
#endif
|
||||
|
||||
comp->setVisible (true);
|
||||
comp->toFront (false);
|
||||
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
[pluginWindow setExcludedFromWindowsMenu: YES];
|
||||
[pluginWindow setCanHide: YES];
|
||||
|
||||
[hostWindow addChildWindow: pluginWindow
|
||||
ordered: NSWindowAbove];
|
||||
[hostWindow orderFront: nil];
|
||||
[pluginWindow orderFront: nil];
|
||||
|
||||
attachWindowHidingHooks (comp, (WindowRef) parentWindowOrView, hostWindow);
|
||||
|
||||
return hostWindow;
|
||||
}
|
||||
#endif
|
||||
|
||||
ignoreUnused (isNSView);
|
||||
NSView* parentView = [(NSView*) parentWindowOrView retain];
|
||||
|
||||
#if JucePlugin_EditorRequiresKeyboardFocus
|
||||
comp->addToDesktop (0, parentView);
|
||||
#else
|
||||
comp->addToDesktop (ComponentPeer::windowIgnoresKeyPresses, parentView);
|
||||
#endif
|
||||
|
||||
// (this workaround is because Wavelab provides a zero-size parent view..)
|
||||
if ([parentView frame].size.height == 0)
|
||||
[((NSView*) comp->getWindowHandle()) setFrameOrigin: NSZeroPoint];
|
||||
|
||||
comp->setVisible (true);
|
||||
comp->toFront (false);
|
||||
|
||||
[[parentView window] setAcceptsMouseMovedEvents: YES];
|
||||
return parentView;
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_API void detachComponentFromWindowRefVST (Component* comp, void* window, bool isNSView);
|
||||
void detachComponentFromWindowRefVST (Component* comp, void* window, bool isNSView)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
#if ! JUCE_64BIT
|
||||
if (! isNSView)
|
||||
{
|
||||
EventHandlerRef ref = (EventHandlerRef) (void*) (pointer_sized_int)
|
||||
comp->getProperties() ["boundsEventRef"].toString().getHexValue64();
|
||||
RemoveEventHandler (ref);
|
||||
|
||||
removeWindowHidingHooks (comp);
|
||||
|
||||
CFUniquePtr<HIViewRef> dummyView ((HIViewRef) (void*) (pointer_sized_int)
|
||||
comp->getProperties() ["dummyViewRef"].toString().getHexValue64());
|
||||
|
||||
if (HIViewIsValid (dummyView.get()))
|
||||
dummyView = nullptr;
|
||||
|
||||
NSWindow* hostWindow = (NSWindow*) window;
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
|
||||
[pluginView retain];
|
||||
[hostWindow removeChildWindow: pluginWindow];
|
||||
[pluginWindow close];
|
||||
comp->removeFromDesktop();
|
||||
[pluginView release];
|
||||
|
||||
if (shouldManuallyCloseHostWindow())
|
||||
[hostWindow close];
|
||||
else
|
||||
[hostWindow release];
|
||||
|
||||
#if JUCE_MODAL_LOOPS_PERMITTED
|
||||
static bool needToRunMessageLoop = ! getHostType().isReaper();
|
||||
|
||||
// The event loop needs to be run between closing the window and deleting the plugin,
|
||||
// presumably to let the cocoa objects get tidied up. Leaving out this line causes crashes
|
||||
// in Live when you delete the plugin with its window open.
|
||||
// (Doing it this way rather than using a single longer timeout means that we can guarantee
|
||||
// how many messages will be dispatched, which seems to be vital in Reaper)
|
||||
if (needToRunMessageLoop)
|
||||
for (int i = 20; --i >= 0;)
|
||||
MessageManager::getInstance()->runDispatchLoopUntil (1);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ignoreUnused (isNSView);
|
||||
comp->removeFromDesktop();
|
||||
[(id) window release];
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_API void setNativeHostWindowSizeVST (void* window, Component* component, int newWidth, int newHeight, bool isNSView);
|
||||
void setNativeHostWindowSizeVST (void* window, Component* component, int newWidth, int newHeight, bool isNSView)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
#if ! JUCE_64BIT
|
||||
if (! isNSView)
|
||||
{
|
||||
if (HIViewRef dummyView = (HIViewRef) (void*) (pointer_sized_int)
|
||||
component->getProperties() ["dummyViewRef"].toString().getHexValue64())
|
||||
{
|
||||
HIRect frameRect;
|
||||
HIViewGetFrame (dummyView, &frameRect);
|
||||
frameRect.size.width = newWidth;
|
||||
frameRect.size.height = newHeight;
|
||||
HIViewSetFrame (dummyView, &frameRect);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ignoreUnused (isNSView);
|
||||
|
||||
if (NSView* hostView = (NSView*) window)
|
||||
{
|
||||
const int dx = newWidth - component->getWidth();
|
||||
const int dy = newHeight - component->getHeight();
|
||||
|
||||
NSRect r = [hostView frame];
|
||||
r.size.width += dx;
|
||||
r.size.height += dy;
|
||||
r.origin.y -= dy;
|
||||
[hostView setFrame: r];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_API void checkWindowVisibilityVST (void* window, Component* comp, bool isNSView);
|
||||
void checkWindowVisibilityVST (void* window, Component* comp, bool isNSView)
|
||||
{
|
||||
ignoreUnused (window, comp, isNSView);
|
||||
|
||||
#if ! JUCE_64BIT
|
||||
if (! isNSView)
|
||||
comp->setVisible ([((NSWindow*) window) isVisible]);
|
||||
#endif
|
||||
}
|
||||
|
||||
JUCE_API bool forwardCurrentKeyEventToHostVST (Component* comp, bool isNSView);
|
||||
bool forwardCurrentKeyEventToHostVST (Component* comp, bool isNSView)
|
||||
{
|
||||
#if ! JUCE_64BIT
|
||||
if (! isNSView)
|
||||
{
|
||||
NSWindow* win = [(NSView*) comp->getWindowHandle() window];
|
||||
[[win parentWindow] makeKeyWindow];
|
||||
repostCurrentNSEvent();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
ignoreUnused (comp, isNSView);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // (juce namespace)
|
||||
|
||||
#endif
|
||||
#endif
|
Reference in New Issue
Block a user