@@ -89,7 +89,7 @@ public: | |||
mainWindowList.createWindowIfNoneAreOpen(); | |||
#if JUCE_MAC | |||
#if JUCE_MAC | |||
// NB: the native recent menus doesn't work at the moment - must reenable this when fixed | |||
//MenuBarModel::setMacMainMenu (menuModel, nullptr, "Open Recent"); | |||
MenuBarModel::setMacMainMenu (menuModel, nullptr); | |||
@@ -41,16 +41,16 @@ public: | |||
~AudioUnitPluginFormat(); | |||
//============================================================================== | |||
String getName() const { return "AudioUnit"; } | |||
void findAllTypesForFile (OwnedArray <PluginDescription>&, const String& fileOrIdentifier); | |||
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); | |||
bool fileMightContainThisPluginType (const String& fileOrIdentifier); | |||
String getNameOfPluginFromIdentifier (const String& fileOrIdentifier); | |||
bool pluginNeedsRescanning (const PluginDescription&); | |||
String getName() const override { return "AudioUnit"; } | |||
void findAllTypesForFile (OwnedArray <PluginDescription>&, const String& fileOrIdentifier) override; | |||
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc) override; | |||
bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; | |||
String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; | |||
bool pluginNeedsRescanning (const PluginDescription&) override; | |||
StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive); | |||
bool doesPluginStillExist (const PluginDescription&); | |||
FileSearchPath getDefaultLocationsToSearch(); | |||
bool canScanForPlugins() const { return true; } | |||
bool doesPluginStillExist (const PluginDescription&) override; | |||
FileSearchPath getDefaultLocationsToSearch() override; | |||
bool canScanForPlugins() const override { return true; } | |||
private: | |||
//============================================================================== | |||
@@ -345,7 +345,7 @@ public: | |||
//============================================================================== | |||
// AudioPluginInstance methods: | |||
void fillInPluginDescription (PluginDescription& desc) const | |||
void fillInPluginDescription (PluginDescription& desc) const override | |||
{ | |||
desc.name = pluginName; | |||
desc.descriptiveName = pluginName; | |||
@@ -363,15 +363,15 @@ public: | |||
desc.isInstrument = (componentDesc.componentType == kAudioUnitType_MusicDevice); | |||
} | |||
void* getPlatformSpecificData() { return audioUnit; } | |||
const String getName() const { return pluginName; } | |||
void* getPlatformSpecificData() override { return audioUnit; } | |||
const String getName() const override { return pluginName; } | |||
bool silenceInProducesSilenceOut() const | |||
bool silenceInProducesSilenceOut() const override | |||
{ | |||
return getTailLengthSeconds() <= 0; | |||
} | |||
double getTailLengthSeconds() const | |||
double getTailLengthSeconds() const override | |||
{ | |||
Float64 tail = 0; | |||
UInt32 tailSize = sizeof (tail); | |||
@@ -383,13 +383,13 @@ public: | |||
return tail; | |||
} | |||
bool acceptsMidi() const { return wantsMidiMessages; } | |||
bool producesMidi() const { return producesMidiMessages; } | |||
bool acceptsMidi() const override { return wantsMidiMessages; } | |||
bool producesMidi() const override { return producesMidiMessages; } | |||
//============================================================================== | |||
// AudioProcessor methods: | |||
void prepareToPlay (double newSampleRate, int estimatedSamplesPerBlock) | |||
void prepareToPlay (double newSampleRate, int estimatedSamplesPerBlock) override | |||
{ | |||
if (audioUnit != nullptr) | |||
{ | |||
@@ -472,7 +472,7 @@ public: | |||
} | |||
} | |||
void releaseResources() | |||
void releaseResources() override | |||
{ | |||
if (prepared) | |||
{ | |||
@@ -494,7 +494,7 @@ public: | |||
for (int i = 0; i < numOutputBusses; ++i) AudioUnitReset (audioUnit, kAudioUnitScope_Output, i); | |||
} | |||
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) | |||
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) override | |||
{ | |||
const int numSamples = buffer.getNumSamples(); | |||
@@ -560,11 +560,11 @@ public: | |||
} | |||
//============================================================================== | |||
bool hasEditor() const { return true; } | |||
AudioProcessorEditor* createEditor(); | |||
bool hasEditor() const override { return true; } | |||
AudioProcessorEditor* createEditor() override; | |||
//============================================================================== | |||
const String getInputChannelName (int index) const | |||
const String getInputChannelName (int index) const override | |||
{ | |||
if (isPositiveAndBelow (index, getNumInputChannels())) | |||
return "Input " + String (index + 1); | |||
@@ -572,7 +572,7 @@ public: | |||
return String::empty; | |||
} | |||
const String getOutputChannelName (int index) const | |||
const String getOutputChannelName (int index) const override | |||
{ | |||
if (isPositiveAndBelow (index, getNumOutputChannels())) | |||
return "Output " + String (index + 1); | |||
@@ -580,13 +580,13 @@ public: | |||
return String::empty; | |||
} | |||
bool isInputChannelStereoPair (int index) const { return isPositiveAndBelow (index, getNumInputChannels()); } | |||
bool isOutputChannelStereoPair (int index) const { return isPositiveAndBelow (index, getNumOutputChannels()); } | |||
bool isInputChannelStereoPair (int index) const override { return isPositiveAndBelow (index, getNumInputChannels()); } | |||
bool isOutputChannelStereoPair (int index) const override { return isPositiveAndBelow (index, getNumOutputChannels()); } | |||
//============================================================================== | |||
int getNumParameters() { return parameters.size(); } | |||
int getNumParameters() override { return parameters.size(); } | |||
float getParameter (int index) | |||
float getParameter (int index) override | |||
{ | |||
const ScopedLock sl (lock); | |||
@@ -608,7 +608,7 @@ public: | |||
return value; | |||
} | |||
void setParameter (int index, float newValue) | |||
void setParameter (int index, float newValue) override | |||
{ | |||
const ScopedLock sl (lock); | |||
@@ -646,7 +646,7 @@ public: | |||
sendParameterChangeEvent (i); | |||
} | |||
const String getParameterName (int index) | |||
const String getParameterName (int index) override | |||
{ | |||
if (const ParamInfo* p = parameters[index]) | |||
return p->name; | |||
@@ -654,9 +654,9 @@ public: | |||
return String::empty; | |||
} | |||
const String getParameterText (int index) { return String (getParameter (index)); } | |||
const String getParameterText (int index) override { return String (getParameter (index)); } | |||
bool isParameterAutomatable (int index) const | |||
bool isParameterAutomatable (int index) const override | |||
{ | |||
if (const ParamInfo* p = parameters[index]) | |||
return p->automatable; | |||
@@ -665,7 +665,7 @@ public: | |||
} | |||
//============================================================================== | |||
int getNumPrograms() | |||
int getNumPrograms() override | |||
{ | |||
CFArrayRef presets; | |||
UInt32 sz = sizeof (CFArrayRef); | |||
@@ -681,7 +681,7 @@ public: | |||
return num; | |||
} | |||
int getCurrentProgram() | |||
int getCurrentProgram() override | |||
{ | |||
AUPreset current; | |||
current.presetNumber = 0; | |||
@@ -693,7 +693,7 @@ public: | |||
return current.presetNumber; | |||
} | |||
void setCurrentProgram (int newIndex) | |||
void setCurrentProgram (int newIndex) override | |||
{ | |||
AUPreset current; | |||
current.presetNumber = newIndex; | |||
@@ -705,7 +705,7 @@ public: | |||
sendAllParametersChangedEvents(); | |||
} | |||
const String getProgramName (int index) | |||
const String getProgramName (int index) override | |||
{ | |||
String s; | |||
CFArrayRef presets; | |||
@@ -732,18 +732,18 @@ public: | |||
return s; | |||
} | |||
void changeProgramName (int index, const String& newName) | |||
void changeProgramName (int index, const String& newName) override | |||
{ | |||
jassertfalse; // xxx not implemented! | |||
} | |||
//============================================================================== | |||
void getStateInformation (MemoryBlock& destData) | |||
void getStateInformation (MemoryBlock& destData) override | |||
{ | |||
getCurrentProgramStateInformation (destData); | |||
} | |||
void getCurrentProgramStateInformation (MemoryBlock& destData) | |||
void getCurrentProgramStateInformation (MemoryBlock& destData) override | |||
{ | |||
CFPropertyListRef propertyList = 0; | |||
UInt32 sz = sizeof (CFPropertyListRef); | |||
@@ -770,12 +770,12 @@ public: | |||
} | |||
} | |||
void setStateInformation (const void* data, int sizeInBytes) | |||
void setStateInformation (const void* data, int sizeInBytes) override | |||
{ | |||
setCurrentProgramStateInformation (data, sizeInBytes); | |||
} | |||
void setCurrentProgramStateInformation (const void* data, int sizeInBytes) | |||
void setCurrentProgramStateInformation (const void* data, int sizeInBytes) override | |||
{ | |||
CFReadStreamRef stream = CFReadStreamCreateWithBytesNoCopy (kCFAllocatorDefault, | |||
(const UInt8*) data, | |||
@@ -803,7 +803,7 @@ public: | |||
} | |||
} | |||
void refreshParameterList() | |||
void refreshParameterList() override | |||
{ | |||
parameters.clear(); | |||
@@ -1425,9 +1425,9 @@ private: | |||
class AudioUnitPluginWindowCarbon : public AudioProcessorEditor | |||
{ | |||
public: | |||
AudioUnitPluginWindowCarbon (AudioUnitPluginInstance& plugin_) | |||
: AudioProcessorEditor (&plugin_), | |||
plugin (plugin_), | |||
AudioUnitPluginWindowCarbon (AudioUnitPluginInstance& p) | |||
: AudioProcessorEditor (&p), | |||
plugin (p), | |||
audioComponent (nullptr), | |||
viewComponent (nullptr) | |||
{ | |||
@@ -248,13 +248,13 @@ namespace | |||
{ | |||
static bool xErrorTriggered = false; | |||
int temporaryErrorHandler (Display*, XErrorEvent*) | |||
static int temporaryErrorHandler (Display*, XErrorEvent*) | |||
{ | |||
xErrorTriggered = true; | |||
return 0; | |||
} | |||
EventProcPtr getPropertyFromXWindow (Window handle, Atom atom) | |||
static EventProcPtr getPropertyFromXWindow (Window handle, Atom atom) | |||
{ | |||
XErrorHandler oldErrorHandler = XSetErrorHandler (temporaryErrorHandler); | |||
xErrorTriggered = false; | |||
@@ -292,7 +292,7 @@ namespace | |||
return 0; | |||
} | |||
void translateJuceToXButtonModifiers (const MouseEvent& e, XEvent& ev) noexcept | |||
static void translateJuceToXButtonModifiers (const MouseEvent& e, XEvent& ev) noexcept | |||
{ | |||
if (e.mods.isLeftButtonDown()) | |||
{ | |||
@@ -311,21 +311,21 @@ namespace | |||
} | |||
} | |||
void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) noexcept | |||
static void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) noexcept | |||
{ | |||
if (e.mods.isLeftButtonDown()) ev.xmotion.state |= Button1Mask; | |||
else if (e.mods.isRightButtonDown()) ev.xmotion.state |= Button3Mask; | |||
else if (e.mods.isMiddleButtonDown()) ev.xmotion.state |= Button2Mask; | |||
} | |||
void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) noexcept | |||
static void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) noexcept | |||
{ | |||
if (e.mods.isLeftButtonDown()) ev.xcrossing.state |= Button1Mask; | |||
else if (e.mods.isRightButtonDown()) ev.xcrossing.state |= Button3Mask; | |||
else if (e.mods.isMiddleButtonDown()) ev.xcrossing.state |= Button2Mask; | |||
} | |||
void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) noexcept | |||
static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) noexcept | |||
{ | |||
if (increment < 0) | |||
{ | |||
@@ -2033,7 +2033,7 @@ public: | |||
ev.xexpose.width = clip.getWidth(); | |||
ev.xexpose.height = clip.getHeight(); | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
} | |||
#endif | |||
} | |||
@@ -2080,20 +2080,11 @@ public: | |||
toFront (true); | |||
XEvent ev = { 0 }; | |||
ev.xbutton.display = display; | |||
XEvent ev; | |||
prepareXEvent (ev, e); | |||
ev.xbutton.type = ButtonPress; | |||
ev.xbutton.window = pluginWindow; | |||
ev.xbutton.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xbutton.time = CurrentTime; | |||
ev.xbutton.x = e.x; | |||
ev.xbutton.y = e.y; | |||
ev.xbutton.x_root = e.getScreenX(); | |||
ev.xbutton.y_root = e.getScreenY(); | |||
translateJuceToXButtonModifiers (e, ev); | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
#elif JUCE_WINDOWS | |||
toFront (true); | |||
@@ -2392,42 +2383,46 @@ private: | |||
#if JUCE_LINUX | |||
//============================================================================== | |||
// overload mouse/keyboard events to forward them to the plugin's inner window.. | |||
void sendEventToChild (XEvent* event) | |||
void sendEventToChild (XEvent& event) | |||
{ | |||
if (pluginProc != 0) | |||
{ | |||
// if the plugin publishes an event procedure, pass the event directly.. | |||
pluginProc (event); | |||
pluginProc (&event); | |||
} | |||
else if (pluginWindow != 0) | |||
{ | |||
// if the plugin has a window, then send the event to the window so that | |||
// its message thread will pick it up.. | |||
XSendEvent (display, pluginWindow, False, 0L, event); | |||
XSendEvent (display, pluginWindow, False, NoEventMask, &event); | |||
XFlush (display); | |||
} | |||
} | |||
void prepareXEvent (XEvent& ev, const MouseEvent& e) const noexcept | |||
{ | |||
zerostruct (ev); | |||
ev.xcrossing.display = display; | |||
ev.xcrossing.window = pluginWindow; | |||
ev.xcrossing.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xcrossing.time = CurrentTime; | |||
ev.xcrossing.x = e.x; | |||
ev.xcrossing.y = e.y; | |||
ev.xcrossing.x_root = e.getScreenX(); | |||
ev.xcrossing.y_root = e.getScreenY(); | |||
} | |||
void mouseEnter (const MouseEvent& e) override | |||
{ | |||
if (pluginWindow != 0) | |||
{ | |||
XEvent ev = { 0 }; | |||
ev.xcrossing.display = display; | |||
XEvent ev; | |||
prepareXEvent (ev, e); | |||
ev.xcrossing.type = EnterNotify; | |||
ev.xcrossing.window = pluginWindow; | |||
ev.xcrossing.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xcrossing.time = CurrentTime; | |||
ev.xcrossing.x = e.x; | |||
ev.xcrossing.y = e.y; | |||
ev.xcrossing.x_root = e.getScreenX(); | |||
ev.xcrossing.y_root = e.getScreenY(); | |||
ev.xcrossing.mode = NotifyNormal; // NotifyGrab, NotifyUngrab | |||
ev.xcrossing.detail = NotifyAncestor; // NotifyVirtual, NotifyInferior, NotifyNonlinear,NotifyNonlinearVirtual | |||
ev.xcrossing.mode = NotifyNormal; | |||
ev.xcrossing.detail = NotifyAncestor; | |||
translateJuceToXCrossingModifiers (e, ev); | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
} | |||
} | |||
@@ -2435,23 +2430,14 @@ private: | |||
{ | |||
if (pluginWindow != 0) | |||
{ | |||
XEvent ev = { 0 }; | |||
ev.xcrossing.display = display; | |||
XEvent ev; | |||
prepareXEvent (ev, e); | |||
ev.xcrossing.type = LeaveNotify; | |||
ev.xcrossing.window = pluginWindow; | |||
ev.xcrossing.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xcrossing.time = CurrentTime; | |||
ev.xcrossing.x = e.x; | |||
ev.xcrossing.y = e.y; | |||
ev.xcrossing.x_root = e.getScreenX(); | |||
ev.xcrossing.y_root = e.getScreenY(); | |||
ev.xcrossing.mode = NotifyNormal; // NotifyGrab, NotifyUngrab | |||
ev.xcrossing.detail = NotifyAncestor; // NotifyVirtual, NotifyInferior, NotifyNonlinear,NotifyNonlinearVirtual | |||
ev.xcrossing.focus = hasKeyboardFocus (true); // TODO - yes ? | |||
ev.xcrossing.mode = NotifyNormal; | |||
ev.xcrossing.detail = NotifyAncestor; | |||
ev.xcrossing.focus = hasKeyboardFocus (true); | |||
translateJuceToXCrossingModifiers (e, ev); | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
} | |||
} | |||
@@ -2459,19 +2445,11 @@ private: | |||
{ | |||
if (pluginWindow != 0) | |||
{ | |||
XEvent ev = { 0 }; | |||
ev.xmotion.display = display; | |||
XEvent ev; | |||
prepareXEvent (ev, e); | |||
ev.xmotion.type = MotionNotify; | |||
ev.xmotion.window = pluginWindow; | |||
ev.xmotion.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xmotion.time = CurrentTime; | |||
ev.xmotion.is_hint = NotifyNormal; | |||
ev.xmotion.x = e.x; | |||
ev.xmotion.y = e.y; | |||
ev.xmotion.x_root = e.getScreenX(); | |||
ev.xmotion.y_root = e.getScreenY(); | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
} | |||
} | |||
@@ -2479,20 +2457,12 @@ private: | |||
{ | |||
if (pluginWindow != 0) | |||
{ | |||
XEvent ev = { 0 }; | |||
ev.xmotion.display = display; | |||
XEvent ev; | |||
prepareXEvent (ev, e); | |||
ev.xmotion.type = MotionNotify; | |||
ev.xmotion.window = pluginWindow; | |||
ev.xmotion.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xmotion.time = CurrentTime; | |||
ev.xmotion.x = e.x ; | |||
ev.xmotion.y = e.y; | |||
ev.xmotion.x_root = e.getScreenX(); | |||
ev.xmotion.y_root = e.getScreenY(); | |||
ev.xmotion.is_hint = NotifyNormal; | |||
translateJuceToXMotionModifiers (e, ev); | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
} | |||
} | |||
@@ -2500,19 +2470,11 @@ private: | |||
{ | |||
if (pluginWindow != 0) | |||
{ | |||
XEvent ev = { 0 }; | |||
ev.xbutton.display = display; | |||
XEvent ev; | |||
prepareXEvent (ev, e); | |||
ev.xbutton.type = ButtonRelease; | |||
ev.xbutton.window = pluginWindow; | |||
ev.xbutton.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xbutton.time = CurrentTime; | |||
ev.xbutton.x = e.x; | |||
ev.xbutton.y = e.y; | |||
ev.xbutton.x_root = e.getScreenX(); | |||
ev.xbutton.y_root = e.getScreenY(); | |||
translateJuceToXButtonModifiers (e, ev); | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
} | |||
} | |||
@@ -2520,24 +2482,14 @@ private: | |||
{ | |||
if (pluginWindow != 0) | |||
{ | |||
XEvent ev = { 0 }; | |||
ev.xbutton.display = display; | |||
XEvent ev; | |||
prepareXEvent (ev, e); | |||
ev.xbutton.type = ButtonPress; | |||
ev.xbutton.window = pluginWindow; | |||
ev.xbutton.root = RootWindow (display, DefaultScreen (display)); | |||
ev.xbutton.time = CurrentTime; | |||
ev.xbutton.x = e.x; | |||
ev.xbutton.y = e.y; | |||
ev.xbutton.x_root = e.getScreenX(); | |||
ev.xbutton.y_root = e.getScreenY(); | |||
translateJuceToXMouseWheelModifiers (e, wheel.deltaY, ev); | |||
sendEventToChild (&ev); | |||
// TODO - put a usleep here ? | |||
sendEventToChild (ev); | |||
ev.xbutton.type = ButtonRelease; | |||
sendEventToChild (&ev); | |||
sendEventToChild (ev); | |||
} | |||
} | |||
#endif | |||