From 5ed75203246d5866b37be4c10cd369ea756d6480 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 16 Apr 2008 14:47:34 +0000 Subject: [PATCH] --- build/macosx/Juce.xcodeproj/project.pbxproj | 8 ++ build/macosx/juce.xcconfig | 10 +-- .../juce_mac_AudioCDBurner.cpp | 88 +++++++++++++++++++ .../juce_mac_Windowing.cpp | 2 + .../juce_win32_DirectSound.cpp | 71 +++++++++------ .../audio/devices/juce_AudioDeviceManager.cpp | 25 +++++- .../audio/devices/juce_AudioDeviceManager.h | 9 +- .../events/juce_InterprocessConnection.cpp | 17 ++++ .../events/juce_InterprocessConnection.h | 12 +++ .../gui/components/controls/juce_Slider.cpp | 9 +- .../gui/components/controls/juce_Slider.h | 10 ++- .../components/controls/juce_TextEditor.cpp | 22 ++++- .../special/juce_QuickTimeMovieComponent.cpp | 29 +++++- .../special/juce_QuickTimeMovieComponent.h | 4 + 14 files changed, 270 insertions(+), 46 deletions(-) create mode 100644 build/macosx/platform_specific_code/juce_mac_AudioCDBurner.cpp diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index b7be4dee6e..b61f4c2cd6 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 84022DFC0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */; }; + 84022DFD0DAE4CB9004CF59A /* juce_mac_HTTPStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */; }; 84052DE408D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */; }; 84052DE508D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */; }; 8406AA5A0C4BDF90003A0D6A /* juce_MidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */; }; @@ -691,6 +693,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_mac_AudioCDBurner.cpp; sourceTree = ""; }; + 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_mac_HTTPStream.h; sourceTree = ""; }; 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_ToneGeneratorAudioSource.cpp; sourceTree = ""; }; 84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_ToneGeneratorAudioSource.h; sourceTree = ""; }; 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_MidiOutput.cpp; sourceTree = ""; }; @@ -1538,10 +1542,12 @@ 84A4881C08A22E2400752A2B /* mac specific code */ = { isa = PBXGroup; children = ( + 84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */, 84A4881E08A22E2400752A2B /* juce_mac_CoreAudio.cpp */, 84A4881F08A22E2400752A2B /* juce_mac_CoreMidi.cpp */, 84A4882008A22E2400752A2B /* juce_mac_FileChooser.cpp */, 84A4882108A22E2400752A2B /* juce_mac_Files.cpp */, + 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */, 84A06BE209CADB06006A43BD /* juce_mac_NamedPipe.cpp */, 84A4882208A22E2400752A2B /* juce_mac_Fonts.cpp */, 84A4882308A22E2400752A2B /* juce_mac_Messaging.cpp */, @@ -2897,6 +2903,7 @@ 8495BB950D806BDA001D9C0B /* juce_FileInputSource.h in Headers */, 8495BB960D806BDA001D9C0B /* juce_InputSource.h in Headers */, 84581EEB0D9148C500AE1A4C /* juce_QuickTimeAudioFormat.h in Headers */, + 84022DFD0DAE4CB9004CF59A /* juce_mac_HTTPStream.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3312,6 +3319,7 @@ 8495BB8E0D8067B2001D9C0B /* juce_AudioThumbnailCache.cpp in Sources */, 8495BB940D806BDA001D9C0B /* juce_FileInputSource.cpp in Sources */, 84581EEA0D9148C500AE1A4C /* juce_QuickTimeAudioFormat.cpp in Sources */, + 84022DFC0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/build/macosx/juce.xcconfig b/build/macosx/juce.xcconfig index 75817d35f2..215fbb97d4 100644 --- a/build/macosx/juce.xcconfig +++ b/build/macosx/juce.xcconfig @@ -1,4 +1,4 @@ -ARCHS = ppc i386 +ARCHS = i386 // For 10.2 (and later) compatibility, use these values: //GCC_VERSION_ppc = 3.3 @@ -8,10 +8,10 @@ ARCHS = ppc i386 //SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.2.8.sdk // For 10.3 (and later) compatibility, use these instead: - MACOSX_DEPLOYMENT_TARGET = 10.4 - MACOSX_DEPLOYMENT_TARGET_ppc = 10.3 - SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk - SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk + MACOSX_DEPLOYMENT_TARGET = 10.5 +// MACOSX_DEPLOYMENT_TARGET_ppc = 10.3 + SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk +// SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk // For 10.4 (and later) compatibility, use these instead: // MACOSX_DEPLOYMENT_TARGET = 10.4 diff --git a/build/macosx/platform_specific_code/juce_mac_AudioCDBurner.cpp b/build/macosx/platform_specific_code/juce_mac_AudioCDBurner.cpp new file mode 100644 index 0000000000..fe928fdcf8 --- /dev/null +++ b/build/macosx/platform_specific_code/juce_mac_AudioCDBurner.cpp @@ -0,0 +1,88 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "../../../src/juce_core/basics/juce_StandardHeader.h" +#include + +BEGIN_JUCE_NAMESPACE + +#include "../../../src/juce_appframework/audio/audio_file_formats/juce_AudioCDBurner.h" + + +//============================================================================== +AudioCDBurner::AudioCDBurner (const int deviceIndex) + : internal (0) +{ +} + +AudioCDBurner::~AudioCDBurner() +{ +} + +AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex) +{ + return 0; +} + +const StringArray AudioCDBurner::findAvailableDevices() +{ + StringArray s; + + return s; +} + +bool AudioCDBurner::isDiskPresent() const +{ + return false; +} + +int AudioCDBurner::getNumAvailableAudioBlocks() const +{ + return 0; +} + +bool AudioCDBurner::addAudioTrack (AudioFormatReader& source, int numSamples) +{ + return false; +} + +bool AudioCDBurner::addAudioTrack (AudioSource& source, int numSamples) +{ + return false; +} + +const String AudioCDBurner::burn (BurnProgressListener* listener, + const bool ejectDiscAfterwards) +{ + return String::empty; +} + +END_JUCE_NAMESPACE \ No newline at end of file diff --git a/build/macosx/platform_specific_code/juce_mac_Windowing.cpp b/build/macosx/platform_specific_code/juce_mac_Windowing.cpp index 771f1723c3..aaaf70e1bc 100644 --- a/build/macosx/platform_specific_code/juce_mac_Windowing.cpp +++ b/build/macosx/platform_specific_code/juce_mac_Windowing.cpp @@ -1974,6 +1974,8 @@ public: isCompositingWindow = HIViewIsCompositingEnabled (viewRef); #endif + SetAutomaticControlDragTrackingEnabledForWindow (newWindow, true); + MouseCheckTimer::getInstance()->resetMouseMoveChecker(); } } diff --git a/build/win32/platform_specific_code/juce_win32_DirectSound.cpp b/build/win32/platform_specific_code/juce_win32_DirectSound.cpp index dec1590c91..6f624d20dd 100644 --- a/build/win32/platform_specific_code/juce_win32_DirectSound.cpp +++ b/build/win32/platform_specific_code/juce_win32_DirectSound.cpp @@ -1264,6 +1264,12 @@ private: if (threadShouldExit()) return; + // boost our priority while opening the devices to try to get better sync between them + const int oldThreadPri = GetThreadPriority (GetCurrentThread()); + const int oldProcPri = GetPriorityClass (GetCurrentProcess()); + SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + for (i = outChans.size(); --i >= 0;) { DSoundInternalOutChannel* const out = outChans.getUnchecked(i); @@ -1278,18 +1284,21 @@ private: in->open(); } - if (threadShouldExit()) - return; + if (! threadShouldExit()) + { + sleep (5); - sleep (5); + for (i = 0; i < numOutputBuffers; ++i) + if (outChans[i] != 0) + outChans[i]->synchronisePosition(); - for (i = 0; i < numOutputBuffers; ++i) - if (outChans[i] != 0) - outChans[i]->synchronisePosition(); + for (i = 0; i < numInputBuffers; ++i) + if (inChans[i] != 0) + inChans[i]->synchronisePosition(); + } - for (i = 0; i < numInputBuffers; ++i) - if (inChans[i] != 0) - inChans[i]->synchronisePosition(); + SetThreadPriority (GetCurrentThread(), oldThreadPri); + SetPriorityClass (GetCurrentProcess(), oldProcPri); } public: @@ -1707,6 +1716,12 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, String error; + // boost our priority while opening the devices to try to get better sync between them + const int oldThreadPri = GetThreadPriority (GetCurrentThread()); + const int oldProcPri = GetPriorityClass (GetCurrentProcess()); + SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + for (i = 0; i < numOutputBuffers; ++i) { if (outChans[i] != 0) @@ -1740,28 +1755,32 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, } } - if (error.isNotEmpty()) + if (error.isEmpty()) + { + totalSamplesOut = 0; + + for (i = 0; i < numOutputBuffers; ++i) + if (outChans[i] != 0) + outChans[i]->synchronisePosition(); + + for (i = 0; i < numInputBuffers; ++i) + if (inChans[i] != 0) + inChans[i]->synchronisePosition(); + + startThread (9); + sleep (10); + + notify(); + } + else { log (error); - return error; } - totalSamplesOut = 0; + SetThreadPriority (GetCurrentThread(), oldThreadPri); + SetPriorityClass (GetCurrentProcess(), oldProcPri); - startThread (9); - sleep (10); - - for (i = 0; i < numOutputBuffers; ++i) - if (outChans[i] != 0) - outChans[i]->synchronisePosition(); - - for (i = 0; i < numInputBuffers; ++i) - if (inChans[i] != 0) - inChans[i]->synchronisePosition(); - - notify(); - - return String::empty; + return error; } diff --git a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp index 0715b26d1c..9c819dd866 100644 --- a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp +++ b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp @@ -72,7 +72,8 @@ AudioDeviceManager::~AudioDeviceManager() const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, const int numOutputChannelsNeeded, const XmlElement* const e, - const bool selectDefaultDeviceOnFailure) + const bool selectDefaultDeviceOnFailure, + const String& preferredDefaultDeviceName) { if (listNeedsScanning) refreshDeviceList(); @@ -105,7 +106,8 @@ const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, setMidiInputEnabled (allMidiIns[i], enabledMidiIns.contains (allMidiIns[i])); if (error.isNotEmpty() && selectDefaultDeviceOnFailure) - error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0, false); + error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0, + false, preferredDefaultDeviceName); setDefaultMidiOutput (e->getStringAttribute (T("defaultMidiOutput"))); @@ -117,7 +119,24 @@ const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, String defaultDevice; - if (availableDeviceTypes [0] != 0) + if (preferredDefaultDeviceName.isNotEmpty()) + { + for (int i = 0; i < availableDeviceTypes.size(); ++i) + { + const StringArray devs (availableDeviceTypes.getUnchecked(i)->getDeviceNames()); + + for (int j = 0; j < devs.size(); ++j) + { + if (devs[j].matchesWildcard (preferredDefaultDeviceName, true)) + { + defaultDevice = devs[j]; + break; + } + } + } + } + + if (defaultDevice.isEmpty() && availableDeviceTypes [0] != 0) defaultDevice = availableDeviceTypes[0]->getDefaultDeviceName (numOutputChannelsNeeded == 0, numInputChannelsNeeded, numOutputChannelsNeeded); diff --git a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h index 0655083503..636645c490 100644 --- a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h +++ b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h @@ -109,12 +109,19 @@ public: fails to open, then a default device will be used instead. If false, then on failure, no device is opened. + @param preferredDefaultDeviceName if this is not empty, and there's a device with this + name, then that will be used as the default device + (assuming that there wasn't one specified in the XML). + The string can actually be a simple wildcard, containing "*" + and "?" characters + @returns an error message if anything went wrong, or an empty string if it worked ok. */ const String initialise (const int numInputChannelsNeeded, const int numOutputChannelsNeeded, const XmlElement* const savedState, - const bool selectDefaultDeviceOnFailure); + const bool selectDefaultDeviceOnFailure, + const String& preferredDefaultDeviceName = String::empty); /** Returns some XML representing the current state of the manager. diff --git a/src/juce_appframework/events/juce_InterprocessConnection.cpp b/src/juce_appframework/events/juce_InterprocessConnection.cpp index 5a96c711e3..7e9424c8a8 100644 --- a/src/juce_appframework/events/juce_InterprocessConnection.cpp +++ b/src/juce_appframework/events/juce_InterprocessConnection.cpp @@ -153,6 +153,23 @@ bool InterprocessConnection::isConnected() const && isThreadRunning(); } +const String InterprocessConnection::getConnectedHostName() const +{ + if (pipe != 0) + { + return "localhost"; + } + else if (socket != 0) + { + if (! socket->isLocal()) + return socket->getHostName(); + + return "localhost"; + } + + return String::empty; +} + //============================================================================== bool InterprocessConnection::sendMessage (const MemoryBlock& message) { diff --git a/src/juce_appframework/events/juce_InterprocessConnection.h b/src/juce_appframework/events/juce_InterprocessConnection.h index b346345d9c..814a24ffba 100644 --- a/src/juce_appframework/events/juce_InterprocessConnection.h +++ b/src/juce_appframework/events/juce_InterprocessConnection.h @@ -132,6 +132,18 @@ public: /** True if a socket or pipe is currently active. */ bool isConnected() const; + /** Returns the socket that this connection is using (or null if it uses a pipe). */ + StreamingSocket* getSocket() const throw() { return socket; } + + /** Returns the pipe that this connection is using (or null if it uses a socket). */ + NamedPipe* getPipe() const throw() { return pipe; } + + /** Returns the name of the machine at the other end of this connection. + + This will return an empty string if the other machine isn't known for + some reason. + */ + const String getConnectedHostName() const; //============================================================================== /** Tries to send a message to the other end of this connection. diff --git a/src/juce_appframework/gui/components/controls/juce_Slider.cpp b/src/juce_appframework/gui/components/controls/juce_Slider.cpp index 08b02f97a4..2346435ba3 100644 --- a/src/juce_appframework/gui/components/controls/juce_Slider.cpp +++ b/src/juce_appframework/gui/components/controls/juce_Slider.cpp @@ -122,6 +122,7 @@ Slider::Slider (const String& name) editableText (true), doubleClickToValue (false), isVelocityBased (false), + userKeyOverridesVelocity (true), rotaryStop (true), incDecButtonsSideBySide (false), sendChangeOnlyOnRelease (false), @@ -227,7 +228,8 @@ void Slider::setVelocityBasedMode (const bool velBased) throw() void Slider::setVelocityModeParameters (const double sensitivity, const int threshold, - const double offset) throw() + const double offset, + const bool userCanPressKeyToSwapMode) throw() { jassert (threshold >= 0); jassert (sensitivity > 0); @@ -236,6 +238,7 @@ void Slider::setVelocityModeParameters (const double sensitivity, velocityModeSensitivity = sensitivity; velocityModeOffset = offset; velocityModeThreshold = threshold; + userKeyOverridesVelocity = userCanPressKeyToSwapMode; } void Slider::setSkewFactor (const double factor) throw() @@ -1188,7 +1191,9 @@ void Slider::mouseDrag (const MouseEvent& e) return; } - if (isVelocityBased == (e.mods.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::commandModifier | ModifierKeys::altModifier)) + + if ((isVelocityBased == (userKeyOverridesVelocity ? false + : (e.mods.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::commandModifier | ModifierKeys::altModifier)))) || ((maximum - minimum) / sliderRegionSize < interval)) { const int mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.x : e.y; diff --git a/src/juce_appframework/gui/components/controls/juce_Slider.h b/src/juce_appframework/gui/components/controls/juce_Slider.h index ee0ab56d6f..fce29c762b 100644 --- a/src/juce_appframework/gui/components/controls/juce_Slider.h +++ b/src/juce_appframework/gui/components/controls/juce_Slider.h @@ -170,7 +170,8 @@ public: */ void setVelocityModeParameters (const double sensitivity = 1.0, const int threshold = 1.0, - const double offset = 0.0) throw(); + const double offset = 0.0, + const bool userCanPressKeyToSwapMode = true) throw(); //============================================================================== /** Sets up a skew factor to alter the way values are distributed. @@ -693,9 +694,10 @@ private: IncDecButtonMode incDecButtonMode; bool editableText : 1, doubleClickToValue : 1; - bool isVelocityBased : 1, rotaryStop : 1, incDecButtonsSideBySide : 1; - bool sendChangeOnlyOnRelease : 1, popupDisplayEnabled : 1; - bool menuEnabled : 1, menuShown : 1, mouseWasHidden : 1, incDecDragged : 1, scrollWheelEnabled : 1; + bool isVelocityBased : 1, userKeyOverridesVelocity : 1, rotaryStop : 1; + bool incDecButtonsSideBySide : 1, sendChangeOnlyOnRelease : 1, popupDisplayEnabled : 1; + bool menuEnabled : 1, menuShown : 1, mouseWasHidden : 1, incDecDragged : 1; + bool scrollWheelEnabled : 1; Font font; Label* valueBox; Button* incButton; diff --git a/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp b/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp index 326834f649..8eab3fca0e 100644 --- a/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp +++ b/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp @@ -448,6 +448,8 @@ public: } } + bool forceNewLine = false; + if (sectionIndex >= sections.size()) { moveToEndOfLastAtom(); @@ -478,6 +480,8 @@ public: // handle the case where the last atom in a section is actually part of the same // word as the first atom of the next section... float right = atomRight + lastAtom->width; + float lineHeight2 = lineHeight; + float maxDescent2 = maxDescent; for (int section = sectionIndex + 1; section < sections.size(); ++section) { @@ -493,8 +497,20 @@ public: right += nextAtom->width; - if (atom != 0 && SHOULD_WRAP (right, wordWrapWidth)) - return wrapCurrentAtom(); + lineHeight2 = jmax (lineHeight2, s->font.getHeight()); + maxDescent2 = jmax (maxDescent2, s->font.getDescent()); + + if (SHOULD_WRAP (right, wordWrapWidth)) + { + lineHeight = lineHeight2; + maxDescent = maxDescent2; + + forceNewLine = true; + break; + } + + if (s->getNumAtoms() > 1) + break; } } } @@ -516,7 +532,7 @@ public: atomRight = atomX + atom->width; ++atomIndex; - if (SHOULD_WRAP (atomRight, wordWrapWidth)) + if (SHOULD_WRAP (atomRight, wordWrapWidth) || forceNewLine) { if (atom->isWhitespace()) { diff --git a/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.cpp b/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.cpp index e905ead4a3..c2c9c664d7 100644 --- a/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.cpp +++ b/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.cpp @@ -85,6 +85,9 @@ BEGIN_JUCE_NAMESPACE bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); +static bool hasLoadedQT = false; +static bool isQTAvailable = false; + //============================================================================== struct QTMovieCompInternal @@ -148,6 +151,19 @@ QuickTimeMovieComponent::~QuickTimeMovieComponent() internal = 0; } +bool QuickTimeMovieComponent::isQuickTimeAvailable() throw() +{ + if (! hasLoadedQT) + { + hasLoadedQT = true; + + isQTAvailable = (InitializeQTML (0) == noErr) + && (EnterMovies() == noErr); + } + + return isQTAvailable; +} + //============================================================================== void QuickTimeMovieComponent::createControlIfNeeded() { @@ -364,8 +380,6 @@ void QuickTimeMovieComponent::paint (Graphics& g) #include "../../../events/juce_MessageManager.h" #include "../../graphics/geometry/juce_RectangleList.h" -static bool isQTAvailable = false; -static bool hasLoadedQT = false; static VoidArray activeQTWindows (2); struct MacClickEventData @@ -436,6 +450,17 @@ QuickTimeMovieComponent::~QuickTimeMovieComponent() } } +bool QuickTimeMovieComponent::isQuickTimeAvailable() throw() +{ + if (! hasLoadedQT) + { + hasLoadedQT = true; + isQTAvailable = EnterMovies() == noErr; + } + + return isQTAvailable; +} + bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream, const bool controllerVisible_) { diff --git a/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h b/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h index 699622e807..27e564d52c 100644 --- a/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h +++ b/src/juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h @@ -70,6 +70,10 @@ public: /** Destructor. */ ~QuickTimeMovieComponent(); + /** Returns true if QT is installed and working on this machine. + */ + static bool isQuickTimeAvailable() throw(); + //============================================================================== /** Tries to load a QuickTime movie into the player.