| @@ -33,6 +33,88 @@ | |||||
| // compiled on its own). | // compiled on its own). | ||||
| #if JUCE_INCLUDED_FILE && JUCE_OPENGL | #if JUCE_INCLUDED_FILE && JUCE_OPENGL | ||||
| END_JUCE_NAMESPACE | |||||
| //============================================================================== | |||||
| @interface ThreadSafeNSOpenGLView : NSOpenGLView | |||||
| { | |||||
| CriticalSection* contextLock; | |||||
| bool needsUpdate; | |||||
| } | |||||
| - (id) initWithFrame: (NSRect) frameRect pixelFormat: (NSOpenGLPixelFormat*) format; | |||||
| - (bool) makeActive; | |||||
| - (void) makeInactive; | |||||
| - (void) reshape; | |||||
| @end | |||||
| @implementation ThreadSafeNSOpenGLView | |||||
| - (id) initWithFrame: (NSRect) frameRect | |||||
| pixelFormat: (NSOpenGLPixelFormat*) format | |||||
| { | |||||
| contextLock = new CriticalSection(); | |||||
| self = [super initWithFrame: frameRect pixelFormat: format]; | |||||
| if (self != nil) | |||||
| [[NSNotificationCenter defaultCenter] addObserver: self | |||||
| selector: @selector (_surfaceNeedsUpdate:) | |||||
| name: NSViewGlobalFrameDidChangeNotification | |||||
| object: self]; | |||||
| return self; | |||||
| } | |||||
| - (void) dealloc | |||||
| { | |||||
| [[NSNotificationCenter defaultCenter] removeObserver: self]; | |||||
| delete contextLock; | |||||
| [super dealloc]; | |||||
| } | |||||
| - (bool) makeActive | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| if ([self openGLContext] == 0) | |||||
| return false; | |||||
| [[self openGLContext] makeCurrentContext]; | |||||
| if (needsUpdate) | |||||
| { | |||||
| [super update]; | |||||
| needsUpdate = false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| - (void) makeInactive | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| [NSOpenGLContext clearCurrentContext]; | |||||
| } | |||||
| - (void) _surfaceNeedsUpdate: (NSNotification*) notification | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| needsUpdate = true; | |||||
| } | |||||
| - (void) update | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| needsUpdate = true; | |||||
| } | |||||
| - (void) reshape | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| needsUpdate = true; | |||||
| } | |||||
| @end | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| class WindowedGLContext : public OpenGLContext | class WindowedGLContext : public OpenGLContext | ||||
| @@ -50,6 +132,7 @@ public: | |||||
| int n = 0; | int n = 0; | ||||
| attribs[n++] = NSOpenGLPFADoubleBuffer; | attribs[n++] = NSOpenGLPFADoubleBuffer; | ||||
| attribs[n++] = NSOpenGLPFAAccelerated; | attribs[n++] = NSOpenGLPFAAccelerated; | ||||
| attribs[n++] = NSOpenGLPFAMPSafe; // NSOpenGLPFAAccelerated, NSOpenGLPFAMultiScreen, NSOpenGLPFASingleRenderer | |||||
| attribs[n++] = NSOpenGLPFAColorSize; | attribs[n++] = NSOpenGLPFAColorSize; | ||||
| attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits, | attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits, | ||||
| pixelFormat.greenBits, | pixelFormat.greenBits, | ||||
| @@ -67,7 +150,6 @@ public: | |||||
| pixelFormat.accumulationBufferAlphaBits); | pixelFormat.accumulationBufferAlphaBits); | ||||
| // xxx not sure how to do fullSceneAntiAliasingNumSamples.. | // xxx not sure how to do fullSceneAntiAliasingNumSamples.. | ||||
| attribs[n++] = NSOpenGLPFASampleBuffers; | attribs[n++] = NSOpenGLPFASampleBuffers; | ||||
| attribs[n++] = (NSOpenGLPixelFormatAttribute) 1; | attribs[n++] = (NSOpenGLPixelFormatAttribute) 1; | ||||
| attribs[n++] = NSOpenGLPFAClosestPolicy; | attribs[n++] = NSOpenGLPFAClosestPolicy; | ||||
| @@ -77,21 +159,13 @@ public: | |||||
| NSOpenGLPixelFormat* format | NSOpenGLPixelFormat* format | ||||
| = [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs]; | = [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs]; | ||||
| NSOpenGLView* view | |||||
| = [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) | |||||
| pixelFormat: format]; | |||||
| if (sharedContext != 0) | |||||
| { | |||||
| renderContext = [[NSOpenGLContext alloc] initWithFormat: format | |||||
| shareContext: sharedContext]; | |||||
| [view setOpenGLContext: renderContext]; | |||||
| [renderContext setView: view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| renderContext = [view openGLContext]; | |||||
| } | |||||
| view = [[ThreadSafeNSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) | |||||
| pixelFormat: format]; | |||||
| renderContext = [[[NSOpenGLContext alloc] initWithFormat: format | |||||
| shareContext: sharedContext] autorelease]; | |||||
| [view setOpenGLContext: renderContext]; | |||||
| [renderContext setView: view]; | |||||
| [format release]; | [format release]; | ||||
| @@ -108,15 +182,13 @@ public: | |||||
| bool makeActive() const throw() | bool makeActive() const throw() | ||||
| { | { | ||||
| jassert (renderContext != 0); | jassert (renderContext != 0); | ||||
| [renderContext makeCurrentContext]; | |||||
| return renderContext != 0; | |||||
| [view makeActive]; | |||||
| return isActive(); | |||||
| } | } | ||||
| bool makeInactive() const throw() | bool makeInactive() const throw() | ||||
| { | { | ||||
| if (! isActive()) | |||||
| [NSOpenGLContext clearCurrentContext]; | |||||
| [view makeInactive]; | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -134,7 +206,6 @@ public: | |||||
| void swapBuffers() | void swapBuffers() | ||||
| { | { | ||||
| glFlush(); | |||||
| [renderContext flushBuffer]; | [renderContext flushBuffer]; | ||||
| } | } | ||||
| @@ -173,6 +244,7 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| NSOpenGLContext* renderContext; | NSOpenGLContext* renderContext; | ||||
| ThreadSafeNSOpenGLView* view; | |||||
| private: | private: | ||||
| OpenGLPixelFormat pixelFormat; | OpenGLPixelFormat pixelFormat; | ||||
| @@ -2033,9 +2033,18 @@ private: | |||||
| return 0; | return 0; | ||||
| case WM_QUIT: | case WM_QUIT: | ||||
| JUCEApplication::quit(); | |||||
| if (JUCEApplication::getInstance() != 0) | |||||
| JUCEApplication::getInstance()->systemRequestedQuit(); | |||||
| return 0; | return 0; | ||||
| case WM_QUERYENDSESSION: | |||||
| if (JUCEApplication::getInstance() != 0) | |||||
| { | |||||
| JUCEApplication::getInstance()->systemRequestedQuit(); | |||||
| return MessageManager::getInstance()->hasStopMessageBeenSent(); | |||||
| } | |||||
| return TRUE; | |||||
| //============================================================================== | //============================================================================== | ||||
| case WM_TRAYNOTIFY: | case WM_TRAYNOTIFY: | ||||
| if (component->isCurrentlyBlockedByAnotherModalComponent()) | if (component->isCurrentlyBlockedByAnotherModalComponent()) | ||||
| @@ -69,12 +69,26 @@ | |||||
| #include "public.sdk/source/vst2.x/aeffeditor.h" | #include "public.sdk/source/vst2.x/aeffeditor.h" | ||||
| #include "public.sdk/source/vst2.x/audioeffectx.cpp" | #include "public.sdk/source/vst2.x/audioeffectx.cpp" | ||||
| #include "public.sdk/source/vst2.x/audioeffect.cpp" | #include "public.sdk/source/vst2.x/audioeffect.cpp" | ||||
| #if JUCE_LINUX | |||||
| #define __cdecl | |||||
| #endif | |||||
| #if ! VST_2_4_EXTENSIONS | |||||
| #error // You're probably trying to include the wrong VSTSDK version - make sure your include path matches the JUCE_USE_VSTSDK_2_4 flag | |||||
| #endif | |||||
| #else | #else | ||||
| // VSTSDK V2.3 includes.. | // VSTSDK V2.3 includes.. | ||||
| #include "source/common/audioeffectx.h" | #include "source/common/audioeffectx.h" | ||||
| #include "source/common/AEffEditor.hpp" | #include "source/common/AEffEditor.hpp" | ||||
| #include "source/common/audioeffectx.cpp" | #include "source/common/audioeffectx.cpp" | ||||
| #include "source/common/AudioEffect.cpp" | #include "source/common/AudioEffect.cpp" | ||||
| #if (! VST_2_3_EXTENSIONS) || VST_2_4_EXTENSIONS | |||||
| #error // You're probably trying to include the wrong VSTSDK version - make sure your include path matches the JUCE_USE_VSTSDK_2_4 flag | |||||
| #endif | |||||
| typedef long VstInt32; | typedef long VstInt32; | ||||
| typedef long VstIntPtr; | typedef long VstIntPtr; | ||||
| enum Vst2StringConstants | enum Vst2StringConstants | ||||
| @@ -966,7 +980,13 @@ public: | |||||
| bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput, | bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput, | ||||
| VstSpeakerArrangement* pluginOutput) | VstSpeakerArrangement* pluginOutput) | ||||
| { | { | ||||
| // if this method isn't implemented, nuendo4 + cubase4 crash when you've got multiple channels.. | |||||
| if (numInChans != pluginInput->numChannels | |||||
| || numOutChans != pluginOutput->numChannels) | |||||
| { | |||||
| setNumInputs (pluginInput->numChannels); | |||||
| setNumOutputs (pluginOutput->numChannels); | |||||
| ioChanged(); | |||||
| } | |||||
| numInChans = pluginInput->numChannels; | numInChans = pluginInput->numChannels; | ||||
| numOutChans = pluginOutput->numChannels; | numOutChans = pluginOutput->numChannels; | ||||
| @@ -8029,8 +8029,12 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) | |||||
| destBuffer = (void*) (((char*) destBuffer) + bytesAvailable); | destBuffer = (void*) (((char*) destBuffer) + bytesAvailable); | ||||
| } | } | ||||
| const int64 oldLastReadPos = lastReadPos; | |||||
| ensureBuffered(); | ensureBuffered(); | ||||
| if (oldLastReadPos == lastReadPos) | |||||
| break; // if ensureBuffered() failed to read any more data, bail out | |||||
| if (isExhausted()) | if (isExhausted()) | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -9749,6 +9753,11 @@ void LocalisedStrings::loadFromText (const String& fileContents) throw() | |||||
| } | } | ||||
| } | } | ||||
| void LocalisedStrings::setIgnoresCase (const bool shouldIgnoreCase) throw() | |||||
| { | |||||
| translations.setIgnoresCase (shouldIgnoreCase); | |||||
| } | |||||
| static CriticalSection currentMappingsLock; | static CriticalSection currentMappingsLock; | ||||
| static LocalisedStrings* currentMappings = 0; | static LocalisedStrings* currentMappings = 0; | ||||
| @@ -12592,6 +12601,11 @@ void StringPairArray::remove (const int index) throw() | |||||
| values.remove (index); | values.remove (index); | ||||
| } | } | ||||
| void StringPairArray::setIgnoresCase (const bool shouldIgnoreCase) throw() | |||||
| { | |||||
| ignoreCase = shouldIgnoreCase; | |||||
| } | |||||
| void StringPairArray::minimiseStorageOverheads() throw() | void StringPairArray::minimiseStorageOverheads() throw() | ||||
| { | { | ||||
| keys.minimiseStorageOverheads(); | keys.minimiseStorageOverheads(); | ||||
| @@ -22363,7 +22377,7 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne | |||||
| const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName); | const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName); | ||||
| if (currentSetup.inputDeviceName != newInputDeviceName | if (currentSetup.inputDeviceName != newInputDeviceName | ||||
| || currentSetup.inputDeviceName != newOutputDeviceName | |||||
| || currentSetup.outputDeviceName != newOutputDeviceName | |||||
| || currentAudioDevice == 0) | || currentAudioDevice == 0) | ||||
| { | { | ||||
| deleteCurrentDevice(); | deleteCurrentDevice(); | ||||
| @@ -22813,12 +22827,18 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName) | |||||
| { | { | ||||
| if (defaultMidiOutputName != deviceName) | if (defaultMidiOutputName != deviceName) | ||||
| { | { | ||||
| if (currentCallback != 0 && currentAudioDevice != 0) | |||||
| currentCallback->audioDeviceStopped(); | |||||
| deleteAndZero (defaultMidiOutput); | deleteAndZero (defaultMidiOutput); | ||||
| defaultMidiOutputName = deviceName; | defaultMidiOutputName = deviceName; | ||||
| if (deviceName.isNotEmpty()) | if (deviceName.isNotEmpty()) | ||||
| defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName)); | defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName)); | ||||
| if (currentCallback != 0 && currentAudioDevice != 0) | |||||
| currentCallback->audioDeviceAboutToStart (currentAudioDevice); | |||||
| updateXml(); | updateXml(); | ||||
| sendChangeMessage (this); | sendChangeMessage (this); | ||||
| } | } | ||||
| @@ -71675,6 +71695,11 @@ void AlertWindow::lookAndFeelChanged() | |||||
| setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | ||||
| } | } | ||||
| int AlertWindow::getDesktopWindowStyleFlags() const | |||||
| { | |||||
| return getLookAndFeel().getAlertBoxWindowFlags(); | |||||
| } | |||||
| struct AlertWindowInfo | struct AlertWindowInfo | ||||
| { | { | ||||
| String title, message, button1, button2, button3; | String title, message, button1, button2, button3; | ||||
| @@ -76036,7 +76061,7 @@ void Graphics::strokePath (const Path& path, | |||||
| const PathStrokeType& strokeType, | const PathStrokeType& strokeType, | ||||
| const AffineTransform& transform) const throw() | const AffineTransform& transform) const throw() | ||||
| { | { | ||||
| if (! state->colour.isTransparent()) | |||||
| if ((! state->colour.isTransparent()) || state->brush != 0) | |||||
| { | { | ||||
| Path stroke; | Path stroke; | ||||
| strokeType.createStrokedPath (stroke, path, transform); | strokeType.createStrokedPath (stroke, path, transform); | ||||
| @@ -244183,9 +244208,18 @@ private: | |||||
| return 0; | return 0; | ||||
| case WM_QUIT: | case WM_QUIT: | ||||
| JUCEApplication::quit(); | |||||
| if (JUCEApplication::getInstance() != 0) | |||||
| JUCEApplication::getInstance()->systemRequestedQuit(); | |||||
| return 0; | return 0; | ||||
| case WM_QUERYENDSESSION: | |||||
| if (JUCEApplication::getInstance() != 0) | |||||
| { | |||||
| JUCEApplication::getInstance()->systemRequestedQuit(); | |||||
| return MessageManager::getInstance()->hasStopMessageBeenSent(); | |||||
| } | |||||
| return TRUE; | |||||
| case WM_TRAYNOTIFY: | case WM_TRAYNOTIFY: | ||||
| if (component->isCurrentlyBlockedByAnotherModalComponent()) | if (component->isCurrentlyBlockedByAnotherModalComponent()) | ||||
| { | { | ||||
| @@ -267842,6 +267876,88 @@ void AppleRemoteDevice::handleCallbackInternal() | |||||
| // compiled on its own). | // compiled on its own). | ||||
| #if JUCE_INCLUDED_FILE && JUCE_OPENGL | #if JUCE_INCLUDED_FILE && JUCE_OPENGL | ||||
| END_JUCE_NAMESPACE | |||||
| @interface ThreadSafeNSOpenGLView : NSOpenGLView | |||||
| { | |||||
| CriticalSection* contextLock; | |||||
| bool needsUpdate; | |||||
| } | |||||
| - (id) initWithFrame: (NSRect) frameRect pixelFormat: (NSOpenGLPixelFormat*) format; | |||||
| - (bool) makeActive; | |||||
| - (void) makeInactive; | |||||
| - (void) reshape; | |||||
| @end | |||||
| @implementation ThreadSafeNSOpenGLView | |||||
| - (id) initWithFrame: (NSRect) frameRect | |||||
| pixelFormat: (NSOpenGLPixelFormat*) format | |||||
| { | |||||
| contextLock = new CriticalSection(); | |||||
| self = [super initWithFrame: frameRect pixelFormat: format]; | |||||
| if (self != nil) | |||||
| [[NSNotificationCenter defaultCenter] addObserver: self | |||||
| selector: @selector (_surfaceNeedsUpdate:) | |||||
| name: NSViewGlobalFrameDidChangeNotification | |||||
| object: self]; | |||||
| return self; | |||||
| } | |||||
| - (void) dealloc | |||||
| { | |||||
| [[NSNotificationCenter defaultCenter] removeObserver: self]; | |||||
| delete contextLock; | |||||
| [super dealloc]; | |||||
| } | |||||
| - (bool) makeActive | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| if ([self openGLContext] == 0) | |||||
| return false; | |||||
| [[self openGLContext] makeCurrentContext]; | |||||
| if (needsUpdate) | |||||
| { | |||||
| [super update]; | |||||
| needsUpdate = false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| - (void) makeInactive | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| [NSOpenGLContext clearCurrentContext]; | |||||
| } | |||||
| - (void) _surfaceNeedsUpdate: (NSNotification*) notification | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| needsUpdate = true; | |||||
| } | |||||
| - (void) update | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| needsUpdate = true; | |||||
| } | |||||
| - (void) reshape | |||||
| { | |||||
| const ScopedLock sl (*contextLock); | |||||
| needsUpdate = true; | |||||
| } | |||||
| @end | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| class WindowedGLContext : public OpenGLContext | class WindowedGLContext : public OpenGLContext | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -267857,6 +267973,7 @@ public: | |||||
| int n = 0; | int n = 0; | ||||
| attribs[n++] = NSOpenGLPFADoubleBuffer; | attribs[n++] = NSOpenGLPFADoubleBuffer; | ||||
| attribs[n++] = NSOpenGLPFAAccelerated; | attribs[n++] = NSOpenGLPFAAccelerated; | ||||
| attribs[n++] = NSOpenGLPFAMPSafe; // NSOpenGLPFAAccelerated, NSOpenGLPFAMultiScreen, NSOpenGLPFASingleRenderer | |||||
| attribs[n++] = NSOpenGLPFAColorSize; | attribs[n++] = NSOpenGLPFAColorSize; | ||||
| attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits, | attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits, | ||||
| pixelFormat.greenBits, | pixelFormat.greenBits, | ||||
| @@ -267874,7 +267991,6 @@ public: | |||||
| pixelFormat.accumulationBufferAlphaBits); | pixelFormat.accumulationBufferAlphaBits); | ||||
| // xxx not sure how to do fullSceneAntiAliasingNumSamples.. | // xxx not sure how to do fullSceneAntiAliasingNumSamples.. | ||||
| attribs[n++] = NSOpenGLPFASampleBuffers; | attribs[n++] = NSOpenGLPFASampleBuffers; | ||||
| attribs[n++] = (NSOpenGLPixelFormatAttribute) 1; | attribs[n++] = (NSOpenGLPixelFormatAttribute) 1; | ||||
| attribs[n++] = NSOpenGLPFAClosestPolicy; | attribs[n++] = NSOpenGLPFAClosestPolicy; | ||||
| @@ -267884,21 +268000,13 @@ public: | |||||
| NSOpenGLPixelFormat* format | NSOpenGLPixelFormat* format | ||||
| = [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs]; | = [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs]; | ||||
| NSOpenGLView* view | |||||
| = [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) | |||||
| pixelFormat: format]; | |||||
| view = [[ThreadSafeNSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) | |||||
| pixelFormat: format]; | |||||
| if (sharedContext != 0) | |||||
| { | |||||
| renderContext = [[NSOpenGLContext alloc] initWithFormat: format | |||||
| shareContext: sharedContext]; | |||||
| [view setOpenGLContext: renderContext]; | |||||
| [renderContext setView: view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| renderContext = [view openGLContext]; | |||||
| } | |||||
| renderContext = [[[NSOpenGLContext alloc] initWithFormat: format | |||||
| shareContext: sharedContext] autorelease]; | |||||
| [view setOpenGLContext: renderContext]; | |||||
| [renderContext setView: view]; | |||||
| [format release]; | [format release]; | ||||
| @@ -267915,15 +268023,13 @@ public: | |||||
| bool makeActive() const throw() | bool makeActive() const throw() | ||||
| { | { | ||||
| jassert (renderContext != 0); | jassert (renderContext != 0); | ||||
| [renderContext makeCurrentContext]; | |||||
| return renderContext != 0; | |||||
| [view makeActive]; | |||||
| return isActive(); | |||||
| } | } | ||||
| bool makeInactive() const throw() | bool makeInactive() const throw() | ||||
| { | { | ||||
| if (! isActive()) | |||||
| [NSOpenGLContext clearCurrentContext]; | |||||
| [view makeInactive]; | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -267941,7 +268047,6 @@ public: | |||||
| void swapBuffers() | void swapBuffers() | ||||
| { | { | ||||
| glFlush(); | |||||
| [renderContext flushBuffer]; | [renderContext flushBuffer]; | ||||
| } | } | ||||
| @@ -267979,6 +268084,7 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| NSOpenGLContext* renderContext; | NSOpenGLContext* renderContext; | ||||
| ThreadSafeNSOpenGLView* view; | |||||
| private: | private: | ||||
| OpenGLPixelFormat pixelFormat; | OpenGLPixelFormat pixelFormat; | ||||
| @@ -2783,6 +2783,7 @@ protected: | |||||
| numAllocated (0), | numAllocated (0), | ||||
| granularity (granularity_) | granularity (granularity_) | ||||
| { | { | ||||
| jassert (granularity > 0); | |||||
| } | } | ||||
| /** Destructor. */ | /** Destructor. */ | ||||
| @@ -8102,6 +8103,10 @@ public: | |||||
| */ | */ | ||||
| void remove (const int index) throw(); | void remove (const int index) throw(); | ||||
| /** Indicates whether to use a case-insensitive search when looking up a key string. | |||||
| */ | |||||
| void setIgnoresCase (const bool shouldIgnoreCase) throw(); | |||||
| /** Reduces the amount of storage being used by the array. | /** Reduces the amount of storage being used by the array. | ||||
| Arrays typically allocate slightly more storage than they need, and after | Arrays typically allocate slightly more storage than they need, and after | ||||
| @@ -11214,23 +11219,26 @@ public: | |||||
| { | { | ||||
| jassert (numValuesToRemove >= 0); | jassert (numValuesToRemove >= 0); | ||||
| if (numValuesToRemove != 0 | |||||
| if (numValuesToRemove >= 0 | |||||
| && firstValue < values.getLast()) | && firstValue < values.getLast()) | ||||
| { | { | ||||
| const bool onAtStart = contains (firstValue - 1); | const bool onAtStart = contains (firstValue - 1); | ||||
| Type lastValue = firstValue + numValuesToRemove; | |||||
| if (lastValue < firstValue) // possible if the signed arithmetic wraps around | |||||
| lastValue = values.getLast(); | |||||
| const Type lastValue = firstValue + jmin (numValuesToRemove, values.getLast() - firstValue); | |||||
| const bool onAtEnd = contains (lastValue); | const bool onAtEnd = contains (lastValue); | ||||
| for (int i = values.size(); --i >= 0;) | for (int i = values.size(); --i >= 0;) | ||||
| { | { | ||||
| if (values.getUnchecked(i) >= firstValue | |||||
| && values.getUnchecked(i) <= lastValue) | |||||
| if (values.getUnchecked(i) <= lastValue) | |||||
| { | { | ||||
| values.remove (i); | |||||
| while (values.getUnchecked(i) >= firstValue) | |||||
| { | |||||
| values.remove (i); | |||||
| if (--i < 0) | |||||
| break; | |||||
| } | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| @@ -13693,6 +13701,11 @@ public: | |||||
| */ | */ | ||||
| const StringArray getCountryCodes() const throw() { return countryCodes; } | const StringArray getCountryCodes() const throw() { return countryCodes; } | ||||
| /** Indicates whether to use a case-insensitive search when looking up a string. | |||||
| This defaults to true. | |||||
| */ | |||||
| void setIgnoresCase (const bool shouldIgnoreCase) throw(); | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| @@ -50713,6 +50726,8 @@ protected: | |||||
| void lookAndFeelChanged(); | void lookAndFeelChanged(); | ||||
| /** @internal */ | /** @internal */ | ||||
| void userTriedToCloseWindow(); | void userTriedToCloseWindow(); | ||||
| /** @internal */ | |||||
| int getDesktopWindowStyleFlags() const; | |||||
| private: | private: | ||||
| String text; | String text; | ||||
| @@ -379,7 +379,7 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne | |||||
| const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName); | const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName); | ||||
| if (currentSetup.inputDeviceName != newInputDeviceName | if (currentSetup.inputDeviceName != newInputDeviceName | ||||
| || currentSetup.inputDeviceName != newOutputDeviceName | |||||
| || currentSetup.outputDeviceName != newOutputDeviceName | |||||
| || currentAudioDevice == 0) | || currentAudioDevice == 0) | ||||
| { | { | ||||
| deleteCurrentDevice(); | deleteCurrentDevice(); | ||||
| @@ -832,12 +832,18 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName) | |||||
| { | { | ||||
| if (defaultMidiOutputName != deviceName) | if (defaultMidiOutputName != deviceName) | ||||
| { | { | ||||
| if (currentCallback != 0 && currentAudioDevice != 0) | |||||
| currentCallback->audioDeviceStopped(); | |||||
| deleteAndZero (defaultMidiOutput); | deleteAndZero (defaultMidiOutput); | ||||
| defaultMidiOutputName = deviceName; | defaultMidiOutputName = deviceName; | ||||
| if (deviceName.isNotEmpty()) | if (deviceName.isNotEmpty()) | ||||
| defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName)); | defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName)); | ||||
| if (currentCallback != 0 && currentAudioDevice != 0) | |||||
| currentCallback->audioDeviceAboutToStart (currentAudioDevice); | |||||
| updateXml(); | updateXml(); | ||||
| sendChangeMessage (this); | sendChangeMessage (this); | ||||
| } | } | ||||
| @@ -591,6 +591,11 @@ void AlertWindow::lookAndFeelChanged() | |||||
| setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | ||||
| } | } | ||||
| int AlertWindow::getDesktopWindowStyleFlags() const | |||||
| { | |||||
| return getLookAndFeel().getAlertBoxWindowFlags(); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| struct AlertWindowInfo | struct AlertWindowInfo | ||||
| { | { | ||||
| @@ -339,6 +339,8 @@ protected: | |||||
| void lookAndFeelChanged(); | void lookAndFeelChanged(); | ||||
| /** @internal */ | /** @internal */ | ||||
| void userTriedToCloseWindow(); | void userTriedToCloseWindow(); | ||||
| /** @internal */ | |||||
| int getDesktopWindowStyleFlags() const; | |||||
| private: | private: | ||||
| String text; | String text; | ||||
| @@ -429,7 +429,7 @@ void Graphics::strokePath (const Path& path, | |||||
| const PathStrokeType& strokeType, | const PathStrokeType& strokeType, | ||||
| const AffineTransform& transform) const throw() | const AffineTransform& transform) const throw() | ||||
| { | { | ||||
| if (! state->colour.isTransparent()) | |||||
| if ((! state->colour.isTransparent()) || state->brush != 0) | |||||
| { | { | ||||
| Path stroke; | Path stroke; | ||||
| strokeType.createStrokedPath (stroke, path, transform); | strokeType.createStrokedPath (stroke, path, transform); | ||||
| @@ -65,6 +65,7 @@ protected: | |||||
| numAllocated (0), | numAllocated (0), | ||||
| granularity (granularity_) | granularity (granularity_) | ||||
| { | { | ||||
| jassert (granularity > 0); | |||||
| } | } | ||||
| /** Destructor. */ | /** Destructor. */ | ||||
| @@ -225,23 +225,26 @@ public: | |||||
| { | { | ||||
| jassert (numValuesToRemove >= 0); | jassert (numValuesToRemove >= 0); | ||||
| if (numValuesToRemove != 0 | |||||
| if (numValuesToRemove >= 0 | |||||
| && firstValue < values.getLast()) | && firstValue < values.getLast()) | ||||
| { | { | ||||
| const bool onAtStart = contains (firstValue - 1); | const bool onAtStart = contains (firstValue - 1); | ||||
| Type lastValue = firstValue + numValuesToRemove; | |||||
| if (lastValue < firstValue) // possible if the signed arithmetic wraps around | |||||
| lastValue = values.getLast(); | |||||
| const Type lastValue = firstValue + jmin (numValuesToRemove, values.getLast() - firstValue); | |||||
| const bool onAtEnd = contains (lastValue); | const bool onAtEnd = contains (lastValue); | ||||
| for (int i = values.size(); --i >= 0;) | for (int i = values.size(); --i >= 0;) | ||||
| { | { | ||||
| if (values.getUnchecked(i) >= firstValue | |||||
| && values.getUnchecked(i) <= lastValue) | |||||
| if (values.getUnchecked(i) <= lastValue) | |||||
| { | { | ||||
| values.remove (i); | |||||
| while (values.getUnchecked(i) >= firstValue) | |||||
| { | |||||
| values.remove (i); | |||||
| if (--i < 0) | |||||
| break; | |||||
| } | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| @@ -153,8 +153,12 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) | |||||
| destBuffer = (void*) (((char*) destBuffer) + bytesAvailable); | destBuffer = (void*) (((char*) destBuffer) + bytesAvailable); | ||||
| } | } | ||||
| const int64 oldLastReadPos = lastReadPos; | |||||
| ensureBuffered(); | ensureBuffered(); | ||||
| if (oldLastReadPos == lastReadPos) | |||||
| break; // if ensureBuffered() failed to read any more data, bail out | |||||
| if (isExhausted()) | if (isExhausted()) | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -124,6 +124,11 @@ void LocalisedStrings::loadFromText (const String& fileContents) throw() | |||||
| } | } | ||||
| } | } | ||||
| void LocalisedStrings::setIgnoresCase (const bool shouldIgnoreCase) throw() | |||||
| { | |||||
| translations.setIgnoresCase (shouldIgnoreCase); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| static CriticalSection currentMappingsLock; | static CriticalSection currentMappingsLock; | ||||
| static LocalisedStrings* currentMappings = 0; | static LocalisedStrings* currentMappings = 0; | ||||
| @@ -181,6 +181,13 @@ public: | |||||
| */ | */ | ||||
| const StringArray getCountryCodes() const throw() { return countryCodes; } | const StringArray getCountryCodes() const throw() { return countryCodes; } | ||||
| //============================================================================== | |||||
| /** Indicates whether to use a case-insensitive search when looking up a string. | |||||
| This defaults to true. | |||||
| */ | |||||
| void setIgnoresCase (const bool shouldIgnoreCase) throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -130,6 +130,11 @@ void StringPairArray::remove (const int index) throw() | |||||
| values.remove (index); | values.remove (index); | ||||
| } | } | ||||
| void StringPairArray::setIgnoresCase (const bool shouldIgnoreCase) throw() | |||||
| { | |||||
| ignoreCase = shouldIgnoreCase; | |||||
| } | |||||
| void StringPairArray::minimiseStorageOverheads() throw() | void StringPairArray::minimiseStorageOverheads() throw() | ||||
| { | { | ||||
| keys.minimiseStorageOverheads(); | keys.minimiseStorageOverheads(); | ||||
| @@ -138,6 +138,11 @@ public: | |||||
| */ | */ | ||||
| void remove (const int index) throw(); | void remove (const int index) throw(); | ||||
| //============================================================================== | |||||
| /** Indicates whether to use a case-insensitive search when looking up a key string. | |||||
| */ | |||||
| void setIgnoresCase (const bool shouldIgnoreCase) throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Reduces the amount of storage being used by the array. | /** Reduces the amount of storage being used by the array. | ||||