diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 709abca49b..d2013183e0 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -83,7 +83,6 @@ OBJECTS := \ $(OBJDIR)/juce_VSTPluginFormat_af341d6.o \ $(OBJDIR)/juce_AudioPluginFormat_5dc1eec2.o \ $(OBJDIR)/juce_AudioPluginFormatManager_c336c715.o \ - $(OBJDIR)/juce_AudioPluginInstance_96637ee0.o \ $(OBJDIR)/juce_KnownPluginList_cadece16.o \ $(OBJDIR)/juce_PluginDescription_d9c0f10b.o \ $(OBJDIR)/juce_PluginDirectoryScanner_c7652cec.o \ @@ -607,11 +606,6 @@ $(OBJDIR)/juce_AudioPluginFormatManager_c336c715.o: ../../src/audio/plugin_host/ @echo "Compiling juce_AudioPluginFormatManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_AudioPluginInstance_96637ee0.o: ../../src/audio/plugin_host/juce_AudioPluginInstance.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling juce_AudioPluginInstance.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_KnownPluginList_cadece16.o: ../../src/audio/plugin_host/juce_KnownPluginList.cpp -@mkdir -p $(OBJDIR) @echo "Compiling juce_KnownPluginList.cpp" diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj index 6ea3ec4117..45ee4f4c16 100644 --- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj @@ -52,7 +52,6 @@ D71FEEEA440682B04E024BB7 = { isa = PBXBuildFile; fileRef = 2EBF36FAAF019B6F811D1C84; }; B331EE2C23176373F2D52C1E = { isa = PBXBuildFile; fileRef = 1C8211DFB558D740EF4B173A; }; 79D8E372BA77018BDA956D92 = { isa = PBXBuildFile; fileRef = DA4820727D6DDC75561A262C; }; - 21005408DDA892A5B8B4F78D = { isa = PBXBuildFile; fileRef = C96D4FE222A8704A8F3BEDD8; }; 3688819F98EFF0AABDD79029 = { isa = PBXBuildFile; fileRef = 3110B983ACE956D6A24F8C8C; }; 84F9FCAE9DF003DC6FC3C941 = { isa = PBXBuildFile; fileRef = B6E20AE45813C0CA9B1014DD; }; E1046147432EB115A68D6C43 = { isa = PBXBuildFile; fileRef = AF47BC3796A74CC15A192E8B; }; @@ -483,7 +482,6 @@ 28534632DF76A1EA837BD0D7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../src/audio/plugin_host/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; DA4820727D6DDC75561A262C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormatManager.cpp"; path = "../../src/audio/plugin_host/juce_AudioPluginFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; A6415104D1E3E5CE7031C0C1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormatManager.h"; path = "../../src/audio/plugin_host/juce_AudioPluginFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; - C96D4FE222A8704A8F3BEDD8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginInstance.cpp"; path = "../../src/audio/plugin_host/juce_AudioPluginInstance.cpp"; sourceTree = "SOURCE_ROOT"; }; E5BA7B8913271E935A1DA487 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginInstance.h"; path = "../../src/audio/plugin_host/juce_AudioPluginInstance.h"; sourceTree = "SOURCE_ROOT"; }; 3110B983ACE956D6A24F8C8C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../src/audio/plugin_host/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; A3FE51C7DD706F536273AB0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KnownPluginList.h"; path = "../../src/audio/plugin_host/juce_KnownPluginList.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1024,6 +1022,7 @@ DCD09B6EF4A4A109DE01F152 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../src/native/windows/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; 7527A5E8F4F39581159D3E5B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../src/native/windows/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; 1DBF9DAAD0690CB2CA4E9960 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../src/native/windows/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + E9B203E963EB1AB566061AC1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../src/native/windows/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; BA561E64C6400CFB1DE013F6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../src/native/windows/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; 061B492EABD6B1C995D581A8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../src/native/windows/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; 519B519B76E2EEEAB49C62DF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Misc.cpp"; path = "../../src/native/windows/juce_win32_Misc.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1249,7 +1248,6 @@ 28534632DF76A1EA837BD0D7, DA4820727D6DDC75561A262C, A6415104D1E3E5CE7031C0C1, - C96D4FE222A8704A8F3BEDD8, E5BA7B8913271E935A1DA487, 3110B983ACE956D6A24F8C8C, A3FE51C7DD706F536273AB0E, @@ -1866,6 +1864,7 @@ DCD09B6EF4A4A109DE01F152, 7527A5E8F4F39581159D3E5B, 1DBF9DAAD0690CB2CA4E9960, + E9B203E963EB1AB566061AC1, BA561E64C6400CFB1DE013F6, 061B492EABD6B1C995D581A8, 519B519B76E2EEEAB49C62DF, @@ -2112,7 +2111,6 @@ D71FEEEA440682B04E024BB7, B331EE2C23176373F2D52C1E, 79D8E372BA77018BDA956D92, - 21005408DDA892A5B8B4F78D, 3688819F98EFF0AABDD79029, 84F9FCAE9DF003DC6FC3C941, E1046147432EB115A68D6C43, diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj index 295d21abb5..435a14cb44 100644 --- a/Builds/VisualStudio2005/Juce.vcproj +++ b/Builds/VisualStudio2005/Juce.vcproj @@ -305,7 +305,6 @@ - @@ -928,6 +927,7 @@ + diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj index 46255a9fe2..a3e43a7714 100644 --- a/Builds/VisualStudio2008/Juce.vcproj +++ b/Builds/VisualStudio2008/Juce.vcproj @@ -305,7 +305,6 @@ - @@ -928,6 +927,7 @@ + diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj index cb359798d0..e2b7f5a0f8 100644 --- a/Builds/VisualStudio2008_DLL/Juce.vcproj +++ b/Builds/VisualStudio2008_DLL/Juce.vcproj @@ -307,7 +307,6 @@ - @@ -930,6 +929,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj b/Builds/VisualStudio2010/Juce.vcxproj index 080c48240d..c059ce5395 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj +++ b/Builds/VisualStudio2010/Juce.vcxproj @@ -166,7 +166,6 @@ - @@ -792,6 +791,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj.filters b/Builds/VisualStudio2010/Juce.vcxproj.filters index c1ce23d49c..9f53b920f3 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj.filters +++ b/Builds/VisualStudio2010/Juce.vcxproj.filters @@ -355,9 +355,6 @@ Juce\Source\audio\plugin_host - - Juce\Source\audio\plugin_host - Juce\Source\audio\plugin_host @@ -2307,6 +2304,9 @@ Juce\Source\native\windows + + Juce\Source\native\windows + Juce\Source\native\windows diff --git a/Builds/iOS/Juce.xcodeproj/project.pbxproj b/Builds/iOS/Juce.xcodeproj/project.pbxproj index 12f6523459..2963342a75 100644 --- a/Builds/iOS/Juce.xcodeproj/project.pbxproj +++ b/Builds/iOS/Juce.xcodeproj/project.pbxproj @@ -52,7 +52,6 @@ D71FEEEA440682B04E024BB7 = { isa = PBXBuildFile; fileRef = 2EBF36FAAF019B6F811D1C84; }; B331EE2C23176373F2D52C1E = { isa = PBXBuildFile; fileRef = 1C8211DFB558D740EF4B173A; }; 79D8E372BA77018BDA956D92 = { isa = PBXBuildFile; fileRef = DA4820727D6DDC75561A262C; }; - 21005408DDA892A5B8B4F78D = { isa = PBXBuildFile; fileRef = C96D4FE222A8704A8F3BEDD8; }; 3688819F98EFF0AABDD79029 = { isa = PBXBuildFile; fileRef = 3110B983ACE956D6A24F8C8C; }; 84F9FCAE9DF003DC6FC3C941 = { isa = PBXBuildFile; fileRef = B6E20AE45813C0CA9B1014DD; }; E1046147432EB115A68D6C43 = { isa = PBXBuildFile; fileRef = AF47BC3796A74CC15A192E8B; }; @@ -483,7 +482,6 @@ 28534632DF76A1EA837BD0D7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../src/audio/plugin_host/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; DA4820727D6DDC75561A262C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormatManager.cpp"; path = "../../src/audio/plugin_host/juce_AudioPluginFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; A6415104D1E3E5CE7031C0C1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormatManager.h"; path = "../../src/audio/plugin_host/juce_AudioPluginFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; - C96D4FE222A8704A8F3BEDD8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginInstance.cpp"; path = "../../src/audio/plugin_host/juce_AudioPluginInstance.cpp"; sourceTree = "SOURCE_ROOT"; }; E5BA7B8913271E935A1DA487 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginInstance.h"; path = "../../src/audio/plugin_host/juce_AudioPluginInstance.h"; sourceTree = "SOURCE_ROOT"; }; 3110B983ACE956D6A24F8C8C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../src/audio/plugin_host/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; A3FE51C7DD706F536273AB0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KnownPluginList.h"; path = "../../src/audio/plugin_host/juce_KnownPluginList.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1024,6 +1022,7 @@ DCD09B6EF4A4A109DE01F152 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../src/native/windows/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; 7527A5E8F4F39581159D3E5B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../src/native/windows/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; 1DBF9DAAD0690CB2CA4E9960 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../src/native/windows/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + E9B203E963EB1AB566061AC1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../src/native/windows/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; BA561E64C6400CFB1DE013F6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../src/native/windows/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; 061B492EABD6B1C995D581A8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../src/native/windows/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; 519B519B76E2EEEAB49C62DF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Misc.cpp"; path = "../../src/native/windows/juce_win32_Misc.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1249,7 +1248,6 @@ 28534632DF76A1EA837BD0D7, DA4820727D6DDC75561A262C, A6415104D1E3E5CE7031C0C1, - C96D4FE222A8704A8F3BEDD8, E5BA7B8913271E935A1DA487, 3110B983ACE956D6A24F8C8C, A3FE51C7DD706F536273AB0E, @@ -1866,6 +1864,7 @@ DCD09B6EF4A4A109DE01F152, 7527A5E8F4F39581159D3E5B, 1DBF9DAAD0690CB2CA4E9960, + E9B203E963EB1AB566061AC1, BA561E64C6400CFB1DE013F6, 061B492EABD6B1C995D581A8, 519B519B76E2EEEAB49C62DF, @@ -2116,7 +2115,6 @@ D71FEEEA440682B04E024BB7, B331EE2C23176373F2D52C1E, 79D8E372BA77018BDA956D92, - 21005408DDA892A5B8B4F78D, 3688819F98EFF0AABDD79029, 84F9FCAE9DF003DC6FC3C941, E1046147432EB115A68D6C43, diff --git a/Juce.jucer b/Juce.jucer index ef0b8424f3..3510a50fa4 100644 --- a/Juce.jucer +++ b/Juce.jucer @@ -294,8 +294,6 @@ resource="0" file="src/audio/plugin_host/juce_AudioPluginFormatManager.cpp"/> - + // (needed to find out what platform we're using) + #undef Point #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #define JUCE_IPHONE 1 @@ -943,6 +953,7 @@ protected: #include #endif #else + #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) #import #import #if JUCE_BUILD_NATIVE @@ -961,6 +972,7 @@ protected: || ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) #include #endif + #undef Point #include #endif @@ -23659,11 +23671,13 @@ END_JUCE_NAMESPACE Alternatively, if you don't need any QuickTime services, just turn off the JUCE_QUICKTIME flag in juce_Config.h */ + #undef SIZE_MAX #include #include #include #include #include + #undef SIZE_MAX #if JUCE_MSVC #pragma warning (pop) @@ -31609,29 +31623,6 @@ END_JUCE_NAMESPACE /*** End of inlined file: juce_AudioPluginFormatManager.cpp ***/ -/*** Start of inlined file: juce_AudioPluginInstance.cpp ***/ -#define JUCE_PLUGIN_HOST 1 - -BEGIN_JUCE_NAMESPACE - -AudioPluginInstance::AudioPluginInstance() -{ -} - -AudioPluginInstance::~AudioPluginInstance() -{ -} - -void* AudioPluginInstance::getPlatformSpecificData() -{ - return nullptr; -} - -END_JUCE_NAMESPACE - -/*** End of inlined file: juce_AudioPluginInstance.cpp ***/ - - /*** Start of inlined file: juce_KnownPluginList.cpp ***/ BEGIN_JUCE_NAMESPACE @@ -32140,18 +32131,18 @@ bool PluginDescription::loadFromXml (const XmlElement& xml) { if (xml.hasTagName ("PLUGIN")) { - name = xml.getStringAttribute ("name"); - descriptiveName = xml.getStringAttribute ("name", name); - pluginFormatName = xml.getStringAttribute ("format"); - category = xml.getStringAttribute ("category"); - manufacturerName = xml.getStringAttribute ("manufacturer"); - version = xml.getStringAttribute ("version"); - fileOrIdentifier = xml.getStringAttribute ("file"); - uid = xml.getStringAttribute ("uid").getHexValue32(); - isInstrument = xml.getBoolAttribute ("isInstrument", false); - lastFileModTime = Time (xml.getStringAttribute ("fileTime").getHexValue64()); - numInputChannels = xml.getIntAttribute ("numInputs"); - numOutputChannels = xml.getIntAttribute ("numOutputs"); + name = xml.getStringAttribute ("name"); + descriptiveName = xml.getStringAttribute ("descriptiveName", name); + pluginFormatName = xml.getStringAttribute ("format"); + category = xml.getStringAttribute ("category"); + manufacturerName = xml.getStringAttribute ("manufacturer"); + version = xml.getStringAttribute ("version"); + fileOrIdentifier = xml.getStringAttribute ("file"); + uid = xml.getStringAttribute ("uid").getHexValue32(); + isInstrument = xml.getBoolAttribute ("isInstrument", false); + lastFileModTime = Time (xml.getStringAttribute ("fileTime").getHexValue64()); + numInputChannels = xml.getIntAttribute ("numInputs"); + numOutputChannels = xml.getIntAttribute ("numOutputs"); return true; } @@ -84923,7 +84914,7 @@ END_JUCE_NAMESPACE /*** End of inlined file: juce_FillType.cpp ***/ -/*** Start of inlined file: juce_Graphics.cpp ***/ +/*** Start of inlined file: juce_GraphicsContext.cpp ***/ BEGIN_JUCE_NAMESPACE namespace @@ -85601,7 +85592,7 @@ Graphics::ScopedSaveState::~ScopedSaveState() END_JUCE_NAMESPACE -/*** End of inlined file: juce_Graphics.cpp ***/ +/*** End of inlined file: juce_GraphicsContext.cpp ***/ /*** Start of inlined file: juce_Justification.cpp ***/ @@ -108440,14 +108431,14 @@ BEGIN_JUCE_NAMESPACE namespace FlacNamespace { -#if JUCE_INCLUDE_FLAC_CODE +#if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE) #if JUCE_MSVC - #pragma warning (disable: 4505 181 111) -#endif + #pragma warning (disable: 4505 181 111) + #endif #define FLAC__NO_DLL 1 - #if ! defined (SIZE_MAX) + #ifndef SIZE_MAX #define SIZE_MAX 0xffffffff #endif @@ -131691,7 +131682,7 @@ BEGIN_JUCE_NAMESPACE namespace OggVorbisNamespace { -#if JUCE_INCLUDE_OGGVORBIS_CODE +#if JUCE_INCLUDE_OGGVORBIS_CODE || ! defined (JUCE_INCLUDE_OGGVORBIS_CODE) /*** Start of inlined file: vorbisenc.h ***/ /** \file @@ -246536,12 +246527,11 @@ private: request = FtpOpenFile (connection, uc.lpszUrlPath, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_NEED_FILE, 0); else - openHTTPConnection (uc, sessionHandle, progressCallback, progressCallbackContext); + openHTTPConnection (uc, progressCallback, progressCallbackContext); } } - void openHTTPConnection (URL_COMPONENTS& uc, HINTERNET sessionHandle, - URL::OpenStreamProgressCallback* progressCallback, + void openHTTPConnection (URL_COMPONENTS& uc, URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) { const TCHAR* mimeTypes[] = { _T("*/*"), 0 }; @@ -246895,10 +246885,9 @@ void WindowsRegistry::registerFileAssociation (const String& fileExtension, #if ! JUCE_ONLY_BUILD_CORE_LIBRARY -/*** Start of inlined file: juce_win32_Messaging.cpp ***/ -// (This file gets included by juce_win32_NativeCode.cpp, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE +/*** Start of inlined file: juce_win32_HiddenMessageWindow.h ***/ +#ifndef __JUCE_WIN32_HIDDENMESSAGEWINDOW_JUCEHEADER__ +#define __JUCE_WIN32_HIDDENMESSAGEWINDOW_JUCEHEADER__ class HiddenMessageWindow { @@ -246957,6 +246946,58 @@ private: enum { improbableWindowNumber = 0xf965aa01 }; }; +class DeviceChangeDetector : private Timer +{ +public: + DeviceChangeDetector (const wchar_t* const name) + : messageWindow (name, (WNDPROC) deviceChangeEventCallback) + { + SetWindowLongPtr (messageWindow.getHWND(), GWLP_USERDATA, (LONG_PTR) this); + } + + virtual ~DeviceChangeDetector() {} + +protected: + virtual void systemDeviceChanged() = 0; + +private: + HiddenMessageWindow messageWindow; + + static LRESULT CALLBACK deviceChangeEventCallback (HWND h, const UINT message, + const WPARAM wParam, const LPARAM lParam) + { + if (message == WM_DEVICECHANGE + && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/ + || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/ + || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/)) + { + // We'll pause before sending a message, because on device removal, the OS hasn't always updated + // its device lists correctly at this point. This also helps avoid repeated callbacks. + ((DeviceChangeDetector*) GetWindowLongPtr (h, GWLP_USERDATA))->startTimer (500); + } + + return DefWindowProc (h, message, wParam, lParam); + } + + void timerCallback() + { + systemDeviceChanged(); + } +}; + +#endif // __JUCE_WIN32_HIDDENMESSAGEWINDOW_JUCEHEADER__ + +/*** End of inlined file: juce_win32_HiddenMessageWindow.h ***/ + + + +/*** Start of inlined file: juce_win32_Messaging.cpp ***/ +// (This file gets included by juce_win32_NativeCode.cpp, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE + +extern HWND juce_messageWindowHandle; + namespace WindowsMessageHelpers { const unsigned int specialId = WM_APP + 0x4400; @@ -247205,51 +247246,11 @@ void MessageManager::doPlatformSpecificShutdown() OleUninitialize(); } -class DeviceChangeDetector : private Timer // (Used by various audio classes) -{ -public: - DeviceChangeDetector (const wchar_t* const name) - : messageWindow (name, (WNDPROC) deviceChangeEventCallback) - { - SetWindowLongPtr (messageWindow.getHWND(), GWLP_USERDATA, (LONG_PTR) this); - } - - virtual ~DeviceChangeDetector() {} - -protected: - virtual void systemDeviceChanged() = 0; - -private: - HiddenMessageWindow messageWindow; - - static LRESULT CALLBACK deviceChangeEventCallback (HWND h, const UINT message, - const WPARAM wParam, const LPARAM lParam) - { - if (message == WM_DEVICECHANGE - && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/ - || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/ - || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/)) - { - // We'll pause before sending a message, because on device removal, the OS hasn't always updated - // its device lists correctly at this point. This also helps avoid repeated callbacks. - ((DeviceChangeDetector*) GetWindowLongPtr (h, GWLP_USERDATA))->startTimer (500); - } - - return DefWindowProc (h, message, wParam, lParam); - } - - void timerCallback() - { - systemDeviceChanged(); - } -}; - #endif /*** End of inlined file: juce_win32_Messaging.cpp ***/ - /*** Start of inlined file: juce_win32_Fonts.cpp ***/ // (This file gets included by juce_win32_NativeCode.cpp, rather than being // compiled on its own). @@ -259886,6 +259887,7 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() } #undef log +#undef logError #endif @@ -270846,22 +270848,15 @@ namespace } } -ScopedAutoReleasePool::ScopedAutoReleasePool() -{ - pool = [[NSAutoreleasePool alloc] init]; -} - -ScopedAutoReleasePool::~ScopedAutoReleasePool() -{ - [((NSAutoreleasePool*) pool) release]; -} - #endif // __JUCE_OSX_OBJCHELPERS_JUCEHEADER__ /*** End of inlined file: juce_osx_ObjCHelpers.h ***/ /*** Start of inlined file: juce_mac_ObjCSuffix.h ***/ +#ifndef __JUCE_MAC_OBJCSUFFIX_JUCEHEADER__ +#define __JUCE_MAC_OBJCSUFFIX_JUCEHEADER__ + /** This suffix is used for naming all Obj-C classes that are used inside juce. Because of the flat naming structure used by Obj-C, you can get horrible situations where @@ -270882,9 +270877,11 @@ ScopedAutoReleasePool::~ScopedAutoReleasePool() #ifndef DOXYGEN #define appendMacro1(a, b, c, d, e) a ## _ ## b ## _ ## c ## _ ## d ## _ ## e #define appendMacro2(a, b, c, d, e) appendMacro1(a, b, c, d, e) - #define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_BUILDNUMBER, JUCE_ObjCExtraSuffix) + #define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_BUILDNUMBER, JUCE_ObjCExtraSuffix) #endif +#endif // __JUCE_MAC_OBJCSUFFIX_JUCEHEADER__ + /*** End of inlined file: juce_mac_ObjCSuffix.h ***/ @@ -270970,6 +270967,16 @@ String String::convertToPrecomposedUnicode() const // compiled on its own). #if JUCE_INCLUDED_FILE +ScopedAutoReleasePool::ScopedAutoReleasePool() +{ + pool = [[NSAutoreleasePool alloc] init]; +} + +ScopedAutoReleasePool::~ScopedAutoReleasePool() +{ + [((NSAutoreleasePool*) pool) release]; +} + namespace SystemStatsHelpers { #if JUCE_INTEL @@ -273306,6 +273313,204 @@ private: #if JUCE_IOS +/*** Start of inlined file: juce_ios_MessageManager.mm ***/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE + +END_JUCE_NAMESPACE + +@interface JuceAppStartupDelegate : NSObject +{ +} + +- (void) applicationDidFinishLaunching: (UIApplication*) application; +- (void) applicationWillTerminate: (UIApplication*) application; + +@end + +@implementation JuceAppStartupDelegate + +- (void) applicationDidFinishLaunching: (UIApplication*) application +{ + initialiseJuce_GUI(); + + if (! JUCEApplication::createInstance()->initialiseApp (String::empty)) + exit (0); +} + +- (void) applicationWillTerminate: (UIApplication*) application +{ + JUCEApplication::appWillTerminateByForce(); +} + +@end + +BEGIN_JUCE_NAMESPACE + +int juce_iOSMain (int argc, const char* argv[]) +{ + return UIApplicationMain (argc, const_cast (argv), nil, @"JuceAppStartupDelegate"); +} + +struct CallbackMessagePayload +{ + MessageCallbackFunction* function; + void* parameter; + void* volatile result; + bool volatile hasBeenExecuted; +}; + +END_JUCE_NAMESPACE + +@interface JuceCustomMessageHandler : NSObject +{ +} + +- (void) performCallback: (id) info; + +@end + +@implementation JuceCustomMessageHandler + +- (void) performCallback: (id) info +{ + if ([info isKindOfClass: [NSData class]]) + { + JUCE_NAMESPACE::CallbackMessagePayload* pl = (JUCE_NAMESPACE::CallbackMessagePayload*) [((NSData*) info) bytes]; + + if (pl != nullptr) + { + pl->result = (*pl->function) (pl->parameter); + pl->hasBeenExecuted = true; + } + } + else + { + jassertfalse; // should never get here! + } +} + +@end + +BEGIN_JUCE_NAMESPACE + +void MessageManager::runDispatchLoop() +{ + jassert (isThisTheMessageThread()); // must only be called by the message thread + runDispatchLoopUntil (-1); +} + +void MessageManager::stopDispatchLoop() +{ + [[[UIApplication sharedApplication] delegate] applicationWillTerminate: [UIApplication sharedApplication]]; + exit (0); // iPhone apps get no mercy.. +} + +bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) +{ + JUCE_AUTORELEASEPOOL + jassert (isThisTheMessageThread()); // must only be called by the message thread + + uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor; + NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001]; + + while (! quitMessagePosted) + { + JUCE_AUTORELEASEPOOL + + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode + beforeDate: endDate]; + + if (millisecondsToRunFor >= 0 && Time::getMillisecondCounter() >= endTime) + break; + } + + return ! quitMessagePosted; +} + +struct MessageDispatchSystem +{ + MessageDispatchSystem() + : juceCustomMessageHandler (nil) + { + juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init]; + } + + ~MessageDispatchSystem() + { + [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler]; + [juceCustomMessageHandler release]; + } + + JuceCustomMessageHandler* juceCustomMessageHandler; + MessageQueue messageQueue; +}; + +static ScopedPointer dispatcher; + +void MessageManager::doPlatformSpecificInitialisation() +{ + if (dispatcher == nullptr) + dispatcher = new MessageDispatchSystem(); +} + +void MessageManager::doPlatformSpecificShutdown() +{ + dispatcher = nullptr; +} + +bool MessageManager::postMessageToSystemQueue (Message* message) +{ + if (dispatcher != nullptr) + dispatcher->messageQueue.post (message); + + return true; +} + +void MessageManager::broadcastMessage (const String& value) +{ +} + +void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data) +{ + if (isThisTheMessageThread()) + { + return (*callback) (data); + } + else + { + jassert (dispatcher != nullptr); // trying to call this when the juce system isn't initialised.. + + // If a thread has a MessageManagerLock and then tries to call this method, it'll + // deadlock because the message manager is blocked from running, so can never + // call your function.. + jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + + JUCE_AUTORELEASEPOOL + + CallbackMessagePayload cmp; + cmp.function = callback; + cmp.parameter = data; + cmp.result = 0; + cmp.hasBeenExecuted = false; + + [dispatcher->juceCustomMessageHandler performSelectorOnMainThread: @selector (performCallback:) + withObject: [NSData dataWithBytesNoCopy: &cmp + length: sizeof (cmp) + freeWhenDone: NO] + waitUntilDone: YES]; + + return cmp.result; + } +} + +#endif + +/*** End of inlined file: juce_ios_MessageManager.mm ***/ + + + /*** Start of inlined file: juce_mac_Fonts.mm ***/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). @@ -274049,7 +274254,6 @@ void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSeri /*** End of inlined file: juce_mac_Fonts.mm ***/ - /*** Start of inlined file: juce_mac_CoreGraphicsContext.mm ***/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). @@ -274938,6 +275142,17 @@ Image juce_loadWithCoreImage (InputStream& input) } #endif +Image juce_createImageFromCIImage (CIImage* im, int w, int h) +{ + CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false); + + CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil]; + [cic drawImage: im inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)]; + CGContextFlush (cgImage->context); + + return Image (cgImage); +} + #endif /*** End of inlined file: juce_mac_CoreGraphicsContext.mm ***/ @@ -275732,26 +275947,6 @@ void UIViewComponentPeer::viewFocusLoss() } } -void juce_HandleProcessFocusChange() -{ - if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) - { - if (Process::isForegroundProcess()) - { - currentlyFocusedPeer->handleFocusGain(); - - ModalComponentManager::getInstance()->bringModalComponentsToFront(); - } - else - { - currentlyFocusedPeer->handleFocusLoss(); - - // turn kiosk mode off if we lose focus.. - Desktop::getInstance().setKioskModeComponent (nullptr); - } - } -} - bool UIViewComponentPeer::isFocused() const { return isSharedWindow ? this == currentlyFocusedPeer @@ -276186,203 +276381,6 @@ void Desktop::getCurrentMonitorPositions (Array >& monitorCoord /*** End of inlined file: juce_ios_Windowing.mm ***/ -/*** Start of inlined file: juce_ios_MessageManager.mm ***/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE - -END_JUCE_NAMESPACE - -@interface JuceAppStartupDelegate : NSObject -{ -} - -- (void) applicationDidFinishLaunching: (UIApplication*) application; -- (void) applicationWillTerminate: (UIApplication*) application; - -@end - -@implementation JuceAppStartupDelegate - -- (void) applicationDidFinishLaunching: (UIApplication*) application -{ - initialiseJuce_GUI(); - - if (! JUCEApplication::createInstance()->initialiseApp (String::empty)) - exit (0); -} - -- (void) applicationWillTerminate: (UIApplication*) application -{ - JUCEApplication::appWillTerminateByForce(); -} - -@end - -BEGIN_JUCE_NAMESPACE - -int juce_iOSMain (int argc, const char* argv[]) -{ - return UIApplicationMain (argc, const_cast (argv), nil, @"JuceAppStartupDelegate"); -} - -struct CallbackMessagePayload -{ - MessageCallbackFunction* function; - void* parameter; - void* volatile result; - bool volatile hasBeenExecuted; -}; - -END_JUCE_NAMESPACE - -@interface JuceCustomMessageHandler : NSObject -{ -} - -- (void) performCallback: (id) info; - -@end - -@implementation JuceCustomMessageHandler - -- (void) performCallback: (id) info -{ - if ([info isKindOfClass: [NSData class]]) - { - JUCE_NAMESPACE::CallbackMessagePayload* pl = (JUCE_NAMESPACE::CallbackMessagePayload*) [((NSData*) info) bytes]; - - if (pl != nullptr) - { - pl->result = (*pl->function) (pl->parameter); - pl->hasBeenExecuted = true; - } - } - else - { - jassertfalse; // should never get here! - } -} - -@end - -BEGIN_JUCE_NAMESPACE - -void MessageManager::runDispatchLoop() -{ - jassert (isThisTheMessageThread()); // must only be called by the message thread - runDispatchLoopUntil (-1); -} - -void MessageManager::stopDispatchLoop() -{ - [[[UIApplication sharedApplication] delegate] applicationWillTerminate: [UIApplication sharedApplication]]; - exit (0); // iPhone apps get no mercy.. -} - -bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) -{ - JUCE_AUTORELEASEPOOL - jassert (isThisTheMessageThread()); // must only be called by the message thread - - uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor; - NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001]; - - while (! quitMessagePosted) - { - JUCE_AUTORELEASEPOOL - - [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode - beforeDate: endDate]; - - if (millisecondsToRunFor >= 0 && Time::getMillisecondCounter() >= endTime) - break; - } - - return ! quitMessagePosted; -} - -struct MessageDispatchSystem -{ - MessageDispatchSystem() - : juceCustomMessageHandler (nil) - { - juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init]; - } - - ~MessageDispatchSystem() - { - [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler]; - [juceCustomMessageHandler release]; - } - - JuceCustomMessageHandler* juceCustomMessageHandler; - MessageQueue messageQueue; -}; - -static ScopedPointer dispatcher; - -void MessageManager::doPlatformSpecificInitialisation() -{ - if (dispatcher == nullptr) - dispatcher = new MessageDispatchSystem(); -} - -void MessageManager::doPlatformSpecificShutdown() -{ - dispatcher = nullptr; -} - -bool MessageManager::postMessageToSystemQueue (Message* message) -{ - if (dispatcher != nullptr) - dispatcher->messageQueue.post (message); - - return true; -} - -void MessageManager::broadcastMessage (const String& value) -{ -} - -void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data) -{ - if (isThisTheMessageThread()) - { - return (*callback) (data); - } - else - { - jassert (dispatcher != nullptr); // trying to call this when the juce system isn't initialised.. - - // If a thread has a MessageManagerLock and then tries to call this method, it'll - // deadlock because the message manager is blocked from running, so can never - // call your function.. - jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - JUCE_AUTORELEASEPOOL - - CallbackMessagePayload cmp; - cmp.function = callback; - cmp.parameter = data; - cmp.result = 0; - cmp.hasBeenExecuted = false; - - [dispatcher->juceCustomMessageHandler performSelectorOnMainThread: @selector (performCallback:) - withObject: [NSData dataWithBytesNoCopy: &cmp - length: sizeof (cmp) - freeWhenDone: NO] - waitUntilDone: YES]; - - return cmp.result; - } -} - -#endif - -/*** End of inlined file: juce_ios_MessageManager.mm ***/ - - /*** Start of inlined file: juce_mac_FileChooser.mm ***/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). @@ -278587,6 +278585,428 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) { re #else +/*** Start of inlined file: juce_mac_MessageManager.mm ***/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE + +typedef void (*AppFocusChangeCallback)(); +AppFocusChangeCallback appFocusChangeCallback = nullptr; + +typedef bool (*CheckEventBlockedByModalComps) (NSEvent*); +CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr; + +/* When you use multiple DLLs which share similarly-named obj-c classes - like + for example having more than one juce plugin loaded into a host, then when a + method is called, the actual code that runs might actually be in a different module + than the one you expect... So any calls to library functions or statics that are + made inside obj-c methods will probably end up getting executed in a different DLL's + memory space. Not a great thing to happen - this obviously leads to bizarre crashes. + + To work around this insanity, I'm only allowing obj-c methods to make calls to + virtual methods of an object that's known to live inside the right module's space. +*/ +class AppDelegateRedirector +{ +public: + AppDelegateRedirector() + { + } + + virtual ~AppDelegateRedirector() + { + } + + virtual NSApplicationTerminateReply shouldTerminate() + { + if (JUCEApplication::getInstance() != nullptr) + { + JUCEApplication::getInstance()->systemRequestedQuit(); + + if (! MessageManager::getInstance()->hasStopMessageBeenSent()) + return NSTerminateCancel; + } + + return NSTerminateNow; + } + + virtual void willTerminate() + { + JUCEApplication::appWillTerminateByForce(); + } + + virtual BOOL openFile (NSString* filename) + { + if (JUCEApplication::getInstance() != nullptr) + { + JUCEApplication::getInstance()->anotherInstanceStarted (quotedIfContainsSpaces (filename)); + return YES; + } + + return NO; + } + + virtual void openFiles (NSArray* filenames) + { + StringArray files; + for (unsigned int i = 0; i < [filenames count]; ++i) + files.add (quotedIfContainsSpaces ((NSString*) [filenames objectAtIndex: i])); + + if (files.size() > 0 && JUCEApplication::getInstance() != nullptr) + JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (" ")); + } + + virtual void focusChanged() + { + if (appFocusChangeCallback != nullptr) + (*appFocusChangeCallback)(); + } + + struct CallbackMessagePayload + { + MessageCallbackFunction* function; + void* parameter; + void* volatile result; + bool volatile hasBeenExecuted; + }; + + virtual void performCallback (CallbackMessagePayload* pl) + { + pl->result = (*pl->function) (pl->parameter); + pl->hasBeenExecuted = true; + } + + virtual void deleteSelf() + { + delete this; + } + + void postMessage (Message* const m) + { + messageQueue.post (m); + } + + static NSString* getBroacastEventName() + { + return juceStringToNS ("juce_" + String::toHexString (File::getSpecialLocation (File::currentExecutableFile).hashCode64())); + } + +private: + CFRunLoopRef runLoop; + CFRunLoopSourceRef runLoopSource; + MessageQueue messageQueue; + + static const String quotedIfContainsSpaces (NSString* file) + { + String s (nsStringToJuce (file)); + if (s.containsChar (' ')) + s = s.quoted ('"'); + + return s; + } +}; + +END_JUCE_NAMESPACE +using namespace JUCE_NAMESPACE; + +#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) + +@interface JuceAppDelegate : NSObject +{ +@private + id oldDelegate; + +@public + AppDelegateRedirector* redirector; +} + +- (JuceAppDelegate*) init; +- (void) dealloc; +- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename; +- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames; +- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app; +- (void) applicationWillTerminate: (NSNotification*) aNotification; +- (void) applicationDidBecomeActive: (NSNotification*) aNotification; +- (void) applicationDidResignActive: (NSNotification*) aNotification; +- (void) applicationWillUnhide: (NSNotification*) aNotification; +- (void) performCallback: (id) info; +- (void) broadcastMessageCallback: (NSNotification*) info; +- (void) dummyMethod; +@end + +@implementation JuceAppDelegate + +- (JuceAppDelegate*) init +{ + [super init]; + + redirector = new AppDelegateRedirector(); + + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + + if (JUCEApplication::isStandaloneApp()) + { + oldDelegate = [NSApp delegate]; + [NSApp setDelegate: self]; + + [[NSDistributedNotificationCenter defaultCenter] addObserver: self + selector: @selector (broadcastMessageCallback:) + name: AppDelegateRedirector::getBroacastEventName() + object: nil]; + } + else + { + oldDelegate = nil; + [center addObserver: self selector: @selector (applicationDidResignActive:) + name: NSApplicationDidResignActiveNotification object: NSApp]; + + [center addObserver: self selector: @selector (applicationDidBecomeActive:) + name: NSApplicationDidBecomeActiveNotification object: NSApp]; + + [center addObserver: self selector: @selector (applicationWillUnhide:) + name: NSApplicationWillUnhideNotification object: NSApp]; + } + + return self; +} + +- (void) dealloc +{ + if (oldDelegate != nil) + [NSApp setDelegate: oldDelegate]; + + [[NSDistributedNotificationCenter defaultCenter] removeObserver: self + name: AppDelegateRedirector::getBroacastEventName() + object: nil]; + + redirector->deleteSelf(); + [super dealloc]; +} + +- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app +{ + (void) app; + return redirector->shouldTerminate(); +} + +- (void) applicationWillTerminate: (NSNotification*) aNotification +{ + (void) aNotification; + redirector->willTerminate(); +} + +- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename +{ + (void) app; + return redirector->openFile (filename); +} + +- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames +{ + (void) sender; + return redirector->openFiles (filenames); +} + +- (void) applicationDidBecomeActive: (NSNotification*) notification +{ + (void) notification; + redirector->focusChanged(); +} + +- (void) applicationDidResignActive: (NSNotification*) notification +{ + (void) notification; + redirector->focusChanged(); +} + +- (void) applicationWillUnhide: (NSNotification*) notification +{ + (void) notification; + redirector->focusChanged(); +} + +- (void) performCallback: (id) info +{ + if ([info isKindOfClass: [NSData class]]) + { + AppDelegateRedirector::CallbackMessagePayload* pl + = (AppDelegateRedirector::CallbackMessagePayload*) [((NSData*) info) bytes]; + + if (pl != nullptr) + redirector->performCallback (pl); + } + else + { + jassertfalse; // should never get here! + } +} + +- (void) broadcastMessageCallback: (NSNotification*) n +{ + NSDictionary* dict = (NSDictionary*) [n userInfo]; + const String messageString (nsStringToJuce ((NSString*) [dict valueForKey: @"message"])); + MessageManager::getInstance()->deliverBroadcastMessage (messageString); +} + +- (void) dummyMethod {} // (used as a way of running a dummy thread) + +@end + +BEGIN_JUCE_NAMESPACE + +static JuceAppDelegate* juceAppDelegate = nil; + +void MessageManager::runDispatchLoop() +{ + if (! quitMessagePosted) // check that the quit message wasn't already posted.. + { + JUCE_AUTORELEASEPOOL + + // must only be called by the message thread! + jassert (isThisTheMessageThread()); + + #if JUCE_CATCH_UNHANDLED_EXCEPTIONS + @try + { + [NSApp run]; + } + @catch (NSException* e) + { + // An AppKit exception will kill the app, but at least this provides a chance to log it., + std::runtime_error ex (std::string ("NSException: ") + [[e name] UTF8String] + ", Reason:" + [[e reason] UTF8String]); + JUCEApplication::sendUnhandledException (&ex, __FILE__, __LINE__); + } + @finally + { + } + #else + [NSApp run]; + #endif + } +} + +void MessageManager::stopDispatchLoop() +{ + quitMessagePosted = true; + [NSApp stop: nil]; + [NSApp activateIgnoringOtherApps: YES]; // (if the app is inactive, it sits there and ignores the quit request until the next time it gets activated) + [NSEvent startPeriodicEventsAfterDelay: 0 withPeriod: 0.1]; +} + +#if JUCE_MODAL_LOOPS_PERMITTED +bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) +{ + jassert (isThisTheMessageThread()); // must only be called by the message thread + + uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor; + + while (! quitMessagePosted) + { + JUCE_AUTORELEASEPOOL + + CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.001, true); + + NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask + untilDate: [NSDate dateWithTimeIntervalSinceNow: 0.001] + inMode: NSDefaultRunLoopMode + dequeue: YES]; + + if (e != nil && (isEventBlockedByModalComps == nullptr || ! (*isEventBlockedByModalComps) (e))) + [NSApp sendEvent: e]; + + if (Time::getMillisecondCounter() >= endTime) + break; + } + + return ! quitMessagePosted; +} +#endif + +void initialiseNSApplication() +{ + #if JUCE_MAC + JUCE_AUTORELEASEPOOL + [NSApplication sharedApplication]; + #endif +} + +void MessageManager::doPlatformSpecificInitialisation() +{ + if (juceAppDelegate == nil) + juceAppDelegate = [[JuceAppDelegate alloc] init]; + + // This launches a dummy thread, which forces Cocoa to initialise NSThreads + // correctly (needed prior to 10.5) + if (! [NSThread isMultiThreaded]) + [NSThread detachNewThreadSelector: @selector (dummyMethod) + toTarget: juceAppDelegate + withObject: nil]; +} + +void MessageManager::doPlatformSpecificShutdown() +{ + if (juceAppDelegate != nil) + { + [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; + [[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; + [juceAppDelegate release]; + juceAppDelegate = nil; + } +} + +bool MessageManager::postMessageToSystemQueue (Message* message) +{ + juceAppDelegate->redirector->postMessage (message); + return true; +} + +void MessageManager::broadcastMessage (const String& message) +{ + NSDictionary* info = [NSDictionary dictionaryWithObject: juceStringToNS (message) + forKey: @"message"]; + + [[NSDistributedNotificationCenter defaultCenter] postNotificationName: AppDelegateRedirector::getBroacastEventName() + object: nil + userInfo: info]; +} + +void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data) +{ + if (isThisTheMessageThread()) + { + return (*callback) (data); + } + else + { + // If a thread has a MessageManagerLock and then tries to call this method, it'll + // deadlock because the message manager is blocked from running, so can never + // call your function.. + jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + + JUCE_AUTORELEASEPOOL + + AppDelegateRedirector::CallbackMessagePayload cmp; + cmp.function = callback; + cmp.parameter = data; + cmp.result = 0; + cmp.hasBeenExecuted = false; + + [juceAppDelegate performSelectorOnMainThread: @selector (performCallback:) + withObject: [NSData dataWithBytesNoCopy: &cmp + length: sizeof (cmp) + freeWhenDone: NO] + waitUntilDone: YES]; + + return cmp.result; + } +} + +#endif + +/*** End of inlined file: juce_mac_MessageManager.mm ***/ + + + /*** Start of inlined file: juce_mac_Fonts.mm ***/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). @@ -280219,6 +280639,17 @@ Image juce_loadWithCoreImage (InputStream& input) } #endif +Image juce_createImageFromCIImage (CIImage* im, int w, int h) +{ + CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false); + + CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil]; + [cic drawImage: im inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)]; + CGContextFlush (cgImage->context); + + return Image (cgImage); +} + #endif /*** End of inlined file: juce_mac_CoreGraphicsContext.mm ***/ @@ -280232,6 +280663,11 @@ Image juce_loadWithCoreImage (InputStream& input) class NSViewComponentPeer; +typedef void (*AppFocusChangeCallback)(); +extern AppFocusChangeCallback appFocusChangeCallback; +typedef bool (*CheckEventBlockedByModalComps) (NSEvent*); +extern CheckEventBlockedByModalComps isEventBlockedByModalComps; + END_JUCE_NAMESPACE @interface NSEvent (JuceDeviceDelta) @@ -280500,6 +280936,112 @@ public: static Array keysCurrentlyDown; private: + static void appFocusChanged() + { + keysCurrentlyDown.clear(); + + if (isValidPeer (currentlyFocusedPeer)) + { + if (Process::isForegroundProcess()) + { + currentlyFocusedPeer->handleFocusGain(); + + ModalComponentManager::getInstance()->bringModalComponentsToFront(); + } + else + { + currentlyFocusedPeer->handleFocusLoss(); + + // turn kiosk mode off if we lose focus.. + Desktop::getInstance().setKioskModeComponent (nullptr); + } + } + } + + static bool checkEventBlockedByModalComps (NSEvent* e) + { + if (Component::getNumCurrentlyModalComponents() == 0) + return false; + + NSWindow* const w = [e window]; + if (w == nil || [w worksWhenModal]) + return false; + + bool isKey = false, isInputAttempt = false; + + switch ([e type]) + { + case NSKeyDown: + case NSKeyUp: + isKey = isInputAttempt = true; + break; + + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + isInputAttempt = true; + break; + + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + case NSOtherMouseDragged: + if (Desktop::getInstance().getDraggingMouseSource(0) != nullptr) + return false; + break; + + case NSMouseMoved: + case NSMouseEntered: + case NSMouseExited: + case NSCursorUpdate: + case NSScrollWheel: + case NSTabletPoint: + case NSTabletProximity: + break; + + default: + return false; + } + + for (int i = ComponentPeer::getNumPeers(); --i >= 0;) + { + ComponentPeer* const peer = ComponentPeer::getPeer (i); + NSView* const compView = (NSView*) peer->getNativeHandle(); + + if ([compView window] == w) + { + if (isKey) + { + if (compView == [w firstResponder]) + return false; + } + else + { + NSViewComponentPeer* nsViewPeer = dynamic_cast (peer); + + if ((nsViewPeer == nullptr || ! nsViewPeer->isSharedWindow) + ? NSPointInRect ([e locationInWindow], NSMakeRect (0, 0, [w frame].size.width, [w frame].size.height)) + : NSPointInRect ([compView convertPoint: [e locationInWindow] fromView: nil], [compView bounds])) + return false; + } + } + } + + if (isInputAttempt) + { + if (! [NSApp isActive]) + [NSApp activateIgnoringOtherApps: YES]; + + Component* const modal = Component::getCurrentlyModalComponent (0); + if (modal != nullptr) + modal->inputAttemptWhenModal(); + } + + return true; + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewComponentPeer); }; @@ -281004,6 +281546,9 @@ NSViewComponentPeer::NSViewComponentPeer (Component* const component_, #endif recursiveToFrontCall (false) { + appFocusChangeCallback = appFocusChanged; + isEventBlockedByModalComps = checkEventBlockedByModalComps; + NSRect r = NSMakeRect (0, 0, (CGFloat) component->getWidth(), (CGFloat) component->getHeight()); view = [[JuceNSView alloc] initWithOwner: this withFrame: r]; @@ -281407,28 +281952,6 @@ void NSViewComponentPeer::viewFocusLoss() } } -void juce_HandleProcessFocusChange() -{ - NSViewComponentPeer::keysCurrentlyDown.clear(); - - if (NSViewComponentPeer::isValidPeer (NSViewComponentPeer::currentlyFocusedPeer)) - { - if (Process::isForegroundProcess()) - { - NSViewComponentPeer::currentlyFocusedPeer->handleFocusGain(); - - ModalComponentManager::getInstance()->bringModalComponentsToFront(); - } - else - { - NSViewComponentPeer::currentlyFocusedPeer->handleFocusLoss(); - - // turn kiosk mode off if we lose focus.. - Desktop::getInstance().setKioskModeComponent (nullptr); - } - } -} - bool NSViewComponentPeer::isFocused() const { return isSharedWindow ? this == currentlyFocusedPeer @@ -285156,507 +285679,6 @@ const Array AudioCDReader::findIndexesInTrack (const int /*trackNumber*/) /*** End of inlined file: juce_mac_AudioCDReader.mm ***/ -/*** Start of inlined file: juce_mac_MessageManager.mm ***/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE - -/* When you use multiple DLLs which share similarly-named obj-c classes - like - for example having more than one juce plugin loaded into a host, then when a - method is called, the actual code that runs might actually be in a different module - than the one you expect... So any calls to library functions or statics that are - made inside obj-c methods will probably end up getting executed in a different DLL's - memory space. Not a great thing to happen - this obviously leads to bizarre crashes. - - To work around this insanity, I'm only allowing obj-c methods to make calls to - virtual methods of an object that's known to live inside the right module's space. -*/ -class AppDelegateRedirector -{ -public: - AppDelegateRedirector() - { - } - - virtual ~AppDelegateRedirector() - { - } - - virtual NSApplicationTerminateReply shouldTerminate() - { - if (JUCEApplication::getInstance() != nullptr) - { - JUCEApplication::getInstance()->systemRequestedQuit(); - - if (! MessageManager::getInstance()->hasStopMessageBeenSent()) - return NSTerminateCancel; - } - - return NSTerminateNow; - } - - virtual void willTerminate() - { - JUCEApplication::appWillTerminateByForce(); - } - - virtual BOOL openFile (NSString* filename) - { - if (JUCEApplication::getInstance() != nullptr) - { - JUCEApplication::getInstance()->anotherInstanceStarted (quotedIfContainsSpaces (filename)); - return YES; - } - - return NO; - } - - virtual void openFiles (NSArray* filenames) - { - StringArray files; - for (unsigned int i = 0; i < [filenames count]; ++i) - files.add (quotedIfContainsSpaces ((NSString*) [filenames objectAtIndex: i])); - - if (files.size() > 0 && JUCEApplication::getInstance() != nullptr) - JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (" ")); - } - - virtual void focusChanged() - { - juce_HandleProcessFocusChange(); - } - - struct CallbackMessagePayload - { - MessageCallbackFunction* function; - void* parameter; - void* volatile result; - bool volatile hasBeenExecuted; - }; - - virtual void performCallback (CallbackMessagePayload* pl) - { - pl->result = (*pl->function) (pl->parameter); - pl->hasBeenExecuted = true; - } - - virtual void deleteSelf() - { - delete this; - } - - void postMessage (Message* const m) - { - messageQueue.post (m); - } - - static NSString* getBroacastEventName() - { - return juceStringToNS ("juce_" + String::toHexString (File::getSpecialLocation (File::currentExecutableFile).hashCode64())); - } - -private: - CFRunLoopRef runLoop; - CFRunLoopSourceRef runLoopSource; - MessageQueue messageQueue; - - static const String quotedIfContainsSpaces (NSString* file) - { - String s (nsStringToJuce (file)); - if (s.containsChar (' ')) - s = s.quoted ('"'); - - return s; - } -}; - -END_JUCE_NAMESPACE -using namespace JUCE_NAMESPACE; - -#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) - -@interface JuceAppDelegate : NSObject -{ -@private - id oldDelegate; - -@public - AppDelegateRedirector* redirector; -} - -- (JuceAppDelegate*) init; -- (void) dealloc; -- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename; -- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames; -- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app; -- (void) applicationWillTerminate: (NSNotification*) aNotification; -- (void) applicationDidBecomeActive: (NSNotification*) aNotification; -- (void) applicationDidResignActive: (NSNotification*) aNotification; -- (void) applicationWillUnhide: (NSNotification*) aNotification; -- (void) performCallback: (id) info; -- (void) broadcastMessageCallback: (NSNotification*) info; -- (void) dummyMethod; -@end - -@implementation JuceAppDelegate - -- (JuceAppDelegate*) init -{ - [super init]; - - redirector = new AppDelegateRedirector(); - - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - - if (JUCEApplication::isStandaloneApp()) - { - oldDelegate = [NSApp delegate]; - [NSApp setDelegate: self]; - - [[NSDistributedNotificationCenter defaultCenter] addObserver: self - selector: @selector (broadcastMessageCallback:) - name: AppDelegateRedirector::getBroacastEventName() - object: nil]; - } - else - { - oldDelegate = nil; - [center addObserver: self selector: @selector (applicationDidResignActive:) - name: NSApplicationDidResignActiveNotification object: NSApp]; - - [center addObserver: self selector: @selector (applicationDidBecomeActive:) - name: NSApplicationDidBecomeActiveNotification object: NSApp]; - - [center addObserver: self selector: @selector (applicationWillUnhide:) - name: NSApplicationWillUnhideNotification object: NSApp]; - } - - return self; -} - -- (void) dealloc -{ - if (oldDelegate != nil) - [NSApp setDelegate: oldDelegate]; - - [[NSDistributedNotificationCenter defaultCenter] removeObserver: self - name: AppDelegateRedirector::getBroacastEventName() - object: nil]; - - redirector->deleteSelf(); - [super dealloc]; -} - -- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app -{ - (void) app; - return redirector->shouldTerminate(); -} - -- (void) applicationWillTerminate: (NSNotification*) aNotification -{ - (void) aNotification; - redirector->willTerminate(); -} - -- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename -{ - (void) app; - return redirector->openFile (filename); -} - -- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames -{ - (void) sender; - return redirector->openFiles (filenames); -} - -- (void) applicationDidBecomeActive: (NSNotification*) notification -{ - (void) notification; - redirector->focusChanged(); -} - -- (void) applicationDidResignActive: (NSNotification*) notification -{ - (void) notification; - redirector->focusChanged(); -} - -- (void) applicationWillUnhide: (NSNotification*) notification -{ - (void) notification; - redirector->focusChanged(); -} - -- (void) performCallback: (id) info -{ - if ([info isKindOfClass: [NSData class]]) - { - AppDelegateRedirector::CallbackMessagePayload* pl - = (AppDelegateRedirector::CallbackMessagePayload*) [((NSData*) info) bytes]; - - if (pl != nullptr) - redirector->performCallback (pl); - } - else - { - jassertfalse; // should never get here! - } -} - -- (void) broadcastMessageCallback: (NSNotification*) n -{ - NSDictionary* dict = (NSDictionary*) [n userInfo]; - const String messageString (nsStringToJuce ((NSString*) [dict valueForKey: @"message"])); - MessageManager::getInstance()->deliverBroadcastMessage (messageString); -} - -- (void) dummyMethod {} // (used as a way of running a dummy thread) - -@end - -BEGIN_JUCE_NAMESPACE - -static JuceAppDelegate* juceAppDelegate = nil; - -void MessageManager::runDispatchLoop() -{ - if (! quitMessagePosted) // check that the quit message wasn't already posted.. - { - JUCE_AUTORELEASEPOOL - - // must only be called by the message thread! - jassert (isThisTheMessageThread()); - - #if JUCE_CATCH_UNHANDLED_EXCEPTIONS - @try - { - [NSApp run]; - } - @catch (NSException* e) - { - // An AppKit exception will kill the app, but at least this provides a chance to log it., - std::runtime_error ex (std::string ("NSException: ") + [[e name] UTF8String] + ", Reason:" + [[e reason] UTF8String]); - JUCEApplication::sendUnhandledException (&ex, __FILE__, __LINE__); - } - @finally - { - } - #else - [NSApp run]; - #endif - } -} - -void MessageManager::stopDispatchLoop() -{ - quitMessagePosted = true; - [NSApp stop: nil]; - [NSApp activateIgnoringOtherApps: YES]; // (if the app is inactive, it sits there and ignores the quit request until the next time it gets activated) - [NSEvent startPeriodicEventsAfterDelay: 0 withPeriod: 0.1]; -} - -namespace -{ - bool isEventBlockedByModalComps (NSEvent* e) - { - if (Component::getNumCurrentlyModalComponents() == 0) - return false; - - NSWindow* const w = [e window]; - if (w == nil || [w worksWhenModal]) - return false; - - bool isKey = false, isInputAttempt = false; - - switch ([e type]) - { - case NSKeyDown: - case NSKeyUp: - isKey = isInputAttempt = true; - break; - - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: - isInputAttempt = true; - break; - - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - case NSOtherMouseDragged: - if (Desktop::getInstance().getDraggingMouseSource(0) != nullptr) - return false; - break; - - case NSMouseMoved: - case NSMouseEntered: - case NSMouseExited: - case NSCursorUpdate: - case NSScrollWheel: - case NSTabletPoint: - case NSTabletProximity: - break; - - default: - return false; - } - - for (int i = ComponentPeer::getNumPeers(); --i >= 0;) - { - ComponentPeer* const peer = ComponentPeer::getPeer (i); - NSView* const compView = (NSView*) peer->getNativeHandle(); - - if ([compView window] == w) - { - if (isKey) - { - if (compView == [w firstResponder]) - return false; - } - else - { - NSViewComponentPeer* nsViewPeer = dynamic_cast (peer); - - if ((nsViewPeer == nullptr || ! nsViewPeer->isSharedWindow) - ? NSPointInRect ([e locationInWindow], NSMakeRect (0, 0, [w frame].size.width, [w frame].size.height)) - : NSPointInRect ([compView convertPoint: [e locationInWindow] fromView: nil], [compView bounds])) - return false; - } - } - } - - if (isInputAttempt) - { - if (! [NSApp isActive]) - [NSApp activateIgnoringOtherApps: YES]; - - Component* const modal = Component::getCurrentlyModalComponent (0); - if (modal != nullptr) - modal->inputAttemptWhenModal(); - } - - return true; - } -} - -#if JUCE_MODAL_LOOPS_PERMITTED -bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) -{ - jassert (isThisTheMessageThread()); // must only be called by the message thread - - uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor; - - while (! quitMessagePosted) - { - JUCE_AUTORELEASEPOOL - - CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.001, true); - - NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask - untilDate: [NSDate dateWithTimeIntervalSinceNow: 0.001] - inMode: NSDefaultRunLoopMode - dequeue: YES]; - - if (e != nil && ! isEventBlockedByModalComps (e)) - [NSApp sendEvent: e]; - - if (Time::getMillisecondCounter() >= endTime) - break; - } - - return ! quitMessagePosted; -} -#endif - -void initialiseNSApplication() -{ - #if JUCE_MAC - JUCE_AUTORELEASEPOOL - [NSApplication sharedApplication]; - #endif -} - -void MessageManager::doPlatformSpecificInitialisation() -{ - if (juceAppDelegate == nil) - juceAppDelegate = [[JuceAppDelegate alloc] init]; - - // This launches a dummy thread, which forces Cocoa to initialise NSThreads - // correctly (needed prior to 10.5) - if (! [NSThread isMultiThreaded]) - [NSThread detachNewThreadSelector: @selector (dummyMethod) - toTarget: juceAppDelegate - withObject: nil]; -} - -void MessageManager::doPlatformSpecificShutdown() -{ - if (juceAppDelegate != nil) - { - [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; - [[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; - [juceAppDelegate release]; - juceAppDelegate = nil; - } -} - -bool MessageManager::postMessageToSystemQueue (Message* message) -{ - juceAppDelegate->redirector->postMessage (message); - return true; -} - -void MessageManager::broadcastMessage (const String& message) -{ - NSDictionary* info = [NSDictionary dictionaryWithObject: juceStringToNS (message) - forKey: @"message"]; - - [[NSDistributedNotificationCenter defaultCenter] postNotificationName: AppDelegateRedirector::getBroacastEventName() - object: nil - userInfo: info]; -} - -void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data) -{ - if (isThisTheMessageThread()) - { - return (*callback) (data); - } - else - { - // If a thread has a MessageManagerLock and then tries to call this method, it'll - // deadlock because the message manager is blocked from running, so can never - // call your function.. - jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - JUCE_AUTORELEASEPOOL - - AppDelegateRedirector::CallbackMessagePayload cmp; - cmp.function = callback; - cmp.parameter = data; - cmp.result = 0; - cmp.hasBeenExecuted = false; - - [juceAppDelegate performSelectorOnMainThread: @selector (performCallback:) - withObject: [NSData dataWithBytesNoCopy: &cmp - length: sizeof (cmp) - freeWhenDone: NO] - waitUntilDone: YES]; - - return cmp.result; - } -} - -#endif - -/*** End of inlined file: juce_mac_MessageManager.mm ***/ - - /*** Start of inlined file: juce_mac_WebBrowserComponent.mm ***/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). @@ -287788,10 +287810,18 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE +extern Image juce_createImageFromCIImage (CIImage* im, int w, int h); + class QTCameraDeviceInteral { public: - QTCameraDeviceInteral (CameraDevice* owner, int index) + QTCameraDeviceInteral (CameraDevice* owner, const int index) + : input (nil), + audioDevice (nil), + audioInput (nil), + session (nil), + fileOutput (nil), + imageOutput (nil) { JUCE_AUTORELEASEPOOL @@ -287799,11 +287829,6 @@ public: NSArray* devs = [QTCaptureDevice inputDevicesWithMediaType: QTMediaTypeVideo]; device = (QTCaptureDevice*) [devs objectAtIndex: index]; - input = nil; - audioInput = nil; - audioDevice = nil; - fileOutput = nil; - imageOutput = nil; callbackDelegate = [[QTCaptureCallbackDelegate alloc] initWithOwner: owner internalDev: this]; @@ -287813,7 +287838,7 @@ public: if (err == nil) { - input = [[QTCaptureDeviceInput alloc] initWithDevice: device]; + input = [[QTCaptureDeviceInput alloc] initWithDevice: device]; audioInput = [[QTCaptureDeviceInput alloc] initWithDevice: device]; [session addInput: input error: &err]; @@ -287906,12 +287931,7 @@ public: void callListeners (CIImage* frame, int w, int h) { - CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false); - Image image (cgImage); - - CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil]; - [cic drawImage: frame inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)]; - CGContextFlush (cgImage->context); + Image image (juce_createImageFromCIImage (frame, w, h)); const ScopedLock sl (listenerLock); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 4b4258d839..62d41e1db9 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 54 -#define JUCE_BUILDNUMBER 13 +#define JUCE_BUILDNUMBER 14 /** Current Juce version number. @@ -102,6 +102,14 @@ namespace JuceDummyNamespace {} - Either JUCE_GCC or JUCE_MSVC */ +/* This line is here as a sanity-check to catch syntax errors caused by mistakes in 3rd-party + header files that have been included before this one. If you hit an error at this line, there + must be some kind of syntax problem in whatever code immediately precedes this header. + + It also causes an error if you attempt to build using a C or obj-C compiler rather than a C++ one. +*/ +namespace JuceDummyNamespace {} + #if (defined (_WIN32) || defined (_WIN64)) #define JUCE_WIN32 1 #define JUCE_WINDOWS 1 @@ -111,7 +119,9 @@ namespace JuceDummyNamespace {} #elif defined (LINUX) || defined (__linux__) #define JUCE_LINUX 1 #elif defined (__APPLE_CPP__) || defined(__APPLE_CC__) + #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) #include // (needed to find out what platform we're using) + #undef Point #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #define JUCE_IPHONE 1 @@ -848,10 +858,6 @@ namespace JuceDummyNamespace {} #if JUCE_MSVC #include #pragma warning (pop) - - #if ! JUCE_PUBLIC_INCLUDES - #pragma warning (4: 4511 4512 4100) // (enable some warnings that are turned off in VC8) - #endif #endif #if JUCE_ANDROID @@ -25129,9 +25135,9 @@ public: #define __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__ -/*** Start of inlined file: juce_Graphics.h ***/ -#ifndef __JUCE_GRAPHICS_JUCEHEADER__ -#define __JUCE_GRAPHICS_JUCEHEADER__ +/*** Start of inlined file: juce_GraphicsContext.h ***/ +#ifndef __JUCE_GRAPHICSCONTEXT_JUCEHEADER__ +#define __JUCE_GRAPHICSCONTEXT_JUCEHEADER__ /*** Start of inlined file: juce_Font.h ***/ @@ -29627,9 +29633,9 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Graphics); }; -#endif // __JUCE_GRAPHICS_JUCEHEADER__ +#endif // __JUCE_GRAPHICSCONTEXT_JUCEHEADER__ -/*** End of inlined file: juce_Graphics.h ***/ +/*** End of inlined file: juce_GraphicsContext.h ***/ /** A graphical effect filter that can be applied to components. @@ -43362,7 +43368,7 @@ public: Make sure that you delete any UI components that belong to this plugin before deleting the plugin. */ - virtual ~AudioPluginInstance(); + virtual ~AudioPluginInstance() {} /** Fills-in the appropriate parts of this plugin description object. */ @@ -43373,11 +43379,11 @@ public: E.g. For a VST, this value can be cast to an AEffect*. For an AudioUnit, it can be cast to an AudioUnit handle. */ - virtual void* getPlatformSpecificData(); + virtual void* getPlatformSpecificData() { return nullptr; } protected: - AudioPluginInstance(); + AudioPluginInstance() {} JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance); }; @@ -43582,7 +43588,6 @@ private: #endif -#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__ /*** Start of inlined file: juce_VSTMidiEventList.h ***/ #ifdef __aeffect__ @@ -43747,7 +43752,6 @@ private: /*** End of inlined file: juce_VSTMidiEventList.h ***/ -#endif #ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__ /*** Start of inlined file: juce_VSTPluginFormat.h ***/ @@ -67170,7 +67174,7 @@ private: #endif -#ifndef __JUCE_GRAPHICS_JUCEHEADER__ +#ifndef __JUCE_GRAPHICSCONTEXT_JUCEHEADER__ #endif #ifndef __JUCE_JUSTIFICATION_JUCEHEADER__ diff --git a/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp b/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp index 3091c9af99..0f2167b45a 100644 --- a/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp @@ -38,14 +38,14 @@ BEGIN_JUCE_NAMESPACE namespace FlacNamespace { -#if JUCE_INCLUDE_FLAC_CODE +#if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE) #if JUCE_MSVC - #pragma warning (disable: 4505 181 111) -#endif + #pragma warning (disable: 4505 181 111) + #endif #define FLAC__NO_DLL 1 - #if ! defined (SIZE_MAX) + #ifndef SIZE_MAX #define SIZE_MAX 0xffffffff #endif diff --git a/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp b/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp index f8ec68cb8d..b9e844c1c3 100644 --- a/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp @@ -38,7 +38,7 @@ BEGIN_JUCE_NAMESPACE namespace OggVorbisNamespace { -#if JUCE_INCLUDE_OGGVORBIS_CODE +#if JUCE_INCLUDE_OGGVORBIS_CODE || ! defined (JUCE_INCLUDE_OGGVORBIS_CODE) #include "oggvorbis/vorbisenc.h" #include "oggvorbis/codec.h" #include "oggvorbis/vorbisfile.h" diff --git a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp index 1473af2690..9b4f09f0ef 100644 --- a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp @@ -46,11 +46,13 @@ Alternatively, if you don't need any QuickTime services, just turn off the JUCE_QUICKTIME flag in juce_Config.h */ + #undef SIZE_MAX #include #include #include #include #include + #undef SIZE_MAX #if JUCE_MSVC #pragma warning (pop) diff --git a/src/audio/plugin_host/juce_AudioPluginInstance.cpp b/src/audio/plugin_host/juce_AudioPluginInstance.cpp deleted file mode 100644 index ba7913d2f2..0000000000 --- a/src/audio/plugin_host/juce_AudioPluginInstance.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-11 by Raw Material Software Ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the GNU General - Public License (Version 2), as published by the Free Software Foundation. - A copy of the license is included in the JUCE distribution, or can be found - online at www.gnu.org/licenses. - - 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. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.rawmaterialsoftware.com/juce for more information. - - ============================================================================== -*/ - -#define JUCE_PLUGIN_HOST 1 - -#include "../../core/juce_StandardHeader.h" - -BEGIN_JUCE_NAMESPACE - -#include "juce_AudioPluginInstance.h" - - -//============================================================================== -AudioPluginInstance::AudioPluginInstance() -{ -} - -AudioPluginInstance::~AudioPluginInstance() -{ -} - -void* AudioPluginInstance::getPlatformSpecificData() -{ - return nullptr; -} - -END_JUCE_NAMESPACE diff --git a/src/audio/plugin_host/juce_AudioPluginInstance.h b/src/audio/plugin_host/juce_AudioPluginInstance.h index 9d7fd221f9..28a56755c0 100644 --- a/src/audio/plugin_host/juce_AudioPluginInstance.h +++ b/src/audio/plugin_host/juce_AudioPluginInstance.h @@ -48,7 +48,7 @@ public: Make sure that you delete any UI components that belong to this plugin before deleting the plugin. */ - virtual ~AudioPluginInstance(); + virtual ~AudioPluginInstance() {} //============================================================================== /** Fills-in the appropriate parts of this plugin description object. @@ -60,11 +60,11 @@ public: E.g. For a VST, this value can be cast to an AEffect*. For an AudioUnit, it can be cast to an AudioUnit handle. */ - virtual void* getPlatformSpecificData(); + virtual void* getPlatformSpecificData() { return nullptr; } protected: //============================================================================== - AudioPluginInstance(); + AudioPluginInstance() {} JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance); }; diff --git a/src/audio/plugin_host/juce_PluginDescription.cpp b/src/audio/plugin_host/juce_PluginDescription.cpp index 806ea8b893..908cd911dc 100644 --- a/src/audio/plugin_host/juce_PluginDescription.cpp +++ b/src/audio/plugin_host/juce_PluginDescription.cpp @@ -117,18 +117,18 @@ bool PluginDescription::loadFromXml (const XmlElement& xml) { if (xml.hasTagName ("PLUGIN")) { - name = xml.getStringAttribute ("name"); - descriptiveName = xml.getStringAttribute ("name", name); - pluginFormatName = xml.getStringAttribute ("format"); - category = xml.getStringAttribute ("category"); - manufacturerName = xml.getStringAttribute ("manufacturer"); - version = xml.getStringAttribute ("version"); - fileOrIdentifier = xml.getStringAttribute ("file"); - uid = xml.getStringAttribute ("uid").getHexValue32(); - isInstrument = xml.getBoolAttribute ("isInstrument", false); - lastFileModTime = Time (xml.getStringAttribute ("fileTime").getHexValue64()); - numInputChannels = xml.getIntAttribute ("numInputs"); - numOutputChannels = xml.getIntAttribute ("numOutputs"); + name = xml.getStringAttribute ("name"); + descriptiveName = xml.getStringAttribute ("descriptiveName", name); + pluginFormatName = xml.getStringAttribute ("format"); + category = xml.getStringAttribute ("category"); + manufacturerName = xml.getStringAttribute ("manufacturer"); + version = xml.getStringAttribute ("version"); + fileOrIdentifier = xml.getStringAttribute ("file"); + uid = xml.getStringAttribute ("uid").getHexValue32(); + isInstrument = xml.getBoolAttribute ("isInstrument", false); + lastFileModTime = Time (xml.getStringAttribute ("fileTime").getHexValue64()); + numInputChannels = xml.getIntAttribute ("numInputs"); + numOutputChannels = xml.getIntAttribute ("numOutputs"); return true; } diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 266894d5e0..e7e740cc5b 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 54 -#define JUCE_BUILDNUMBER 13 +#define JUCE_BUILDNUMBER 14 /** Current Juce version number. diff --git a/src/core/juce_TargetPlatform.h b/src/core/juce_TargetPlatform.h index 19a5d56b9d..380f88507d 100644 --- a/src/core/juce_TargetPlatform.h +++ b/src/core/juce_TargetPlatform.h @@ -58,7 +58,9 @@ namespace JuceDummyNamespace {} #elif defined (LINUX) || defined (__linux__) #define JUCE_LINUX 1 #elif defined (__APPLE_CPP__) || defined(__APPLE_CC__) + #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) #include // (needed to find out what platform we're using) + #undef Point #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #define JUCE_IPHONE 1 diff --git a/src/native/mac/juce_mac_CameraDevice.mm b/src/native/mac/juce_mac_CameraDevice.mm index 56425cff2b..bdc8caf18e 100644 --- a/src/native/mac/juce_mac_CameraDevice.mm +++ b/src/native/mac/juce_mac_CameraDevice.mm @@ -62,11 +62,19 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE +extern Image juce_createImageFromCIImage (CIImage* im, int w, int h); + //============================================================================== class QTCameraDeviceInteral { public: - QTCameraDeviceInteral (CameraDevice* owner, int index) + QTCameraDeviceInteral (CameraDevice* owner, const int index) + : input (nil), + audioDevice (nil), + audioInput (nil), + session (nil), + fileOutput (nil), + imageOutput (nil) { JUCE_AUTORELEASEPOOL @@ -74,11 +82,6 @@ public: NSArray* devs = [QTCaptureDevice inputDevicesWithMediaType: QTMediaTypeVideo]; device = (QTCaptureDevice*) [devs objectAtIndex: index]; - input = nil; - audioInput = nil; - audioDevice = nil; - fileOutput = nil; - imageOutput = nil; callbackDelegate = [[QTCaptureCallbackDelegate alloc] initWithOwner: owner internalDev: this]; @@ -88,7 +91,7 @@ public: if (err == nil) { - input = [[QTCaptureDeviceInput alloc] initWithDevice: device]; + input = [[QTCaptureDeviceInput alloc] initWithDevice: device]; audioInput = [[QTCaptureDeviceInput alloc] initWithDevice: device]; [session addInput: input error: &err]; @@ -181,12 +184,7 @@ public: void callListeners (CIImage* frame, int w, int h) { - CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false); - Image image (cgImage); - - CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil]; - [cic drawImage: frame inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)]; - CGContextFlush (cgImage->context); + Image image (juce_createImageFromCIImage (frame, w, h)); const ScopedLock sl (listenerLock); diff --git a/src/native/mac/juce_mac_CoreGraphicsContext.mm b/src/native/mac/juce_mac_CoreGraphicsContext.mm index afa24c2415..deaf774756 100644 --- a/src/native/mac/juce_mac_CoreGraphicsContext.mm +++ b/src/native/mac/juce_mac_CoreGraphicsContext.mm @@ -922,4 +922,15 @@ Image juce_loadWithCoreImage (InputStream& input) } #endif +Image juce_createImageFromCIImage (CIImage* im, int w, int h) +{ + CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false); + + CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil]; + [cic drawImage: im inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)]; + CGContextFlush (cgImage->context); + + return Image (cgImage); +} + #endif diff --git a/src/native/mac/juce_mac_NativeIncludes.h b/src/native/mac/juce_mac_NativeIncludes.h index 94c8e53df3..f97132541c 100644 --- a/src/native/mac/juce_mac_NativeIncludes.h +++ b/src/native/mac/juce_mac_NativeIncludes.h @@ -43,6 +43,7 @@ #include #endif #else + #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) #import #import #if JUCE_BUILD_NATIVE @@ -61,6 +62,7 @@ || ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) #include #endif + #undef Point #include #endif diff --git a/src/native/mac/juce_mac_ObjCSuffix.h b/src/native/mac/juce_mac_ObjCSuffix.h index 4ca70e22e6..835825ef68 100644 --- a/src/native/mac/juce_mac_ObjCSuffix.h +++ b/src/native/mac/juce_mac_ObjCSuffix.h @@ -23,6 +23,9 @@ ============================================================================== */ +#ifndef __JUCE_MAC_OBJCSUFFIX_JUCEHEADER__ +#define __JUCE_MAC_OBJCSUFFIX_JUCEHEADER__ + /** This suffix is used for naming all Obj-C classes that are used inside juce. Because of the flat naming structure used by Obj-C, you can get horrible situations where @@ -43,5 +46,7 @@ #ifndef DOXYGEN #define appendMacro1(a, b, c, d, e) a ## _ ## b ## _ ## c ## _ ## d ## _ ## e #define appendMacro2(a, b, c, d, e) appendMacro1(a, b, c, d, e) - #define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_BUILDNUMBER, JUCE_ObjCExtraSuffix) + #define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_BUILDNUMBER, JUCE_ObjCExtraSuffix) #endif + +#endif // __JUCE_MAC_OBJCSUFFIX_JUCEHEADER__ diff --git a/src/native/windows/juce_win32_DirectSound.cpp b/src/native/windows/juce_win32_DirectSound.cpp index d8e1ebda9d..ac08b03696 100644 --- a/src/native/windows/juce_win32_DirectSound.cpp +++ b/src/native/windows/juce_win32_DirectSound.cpp @@ -1377,5 +1377,6 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() } #undef log +#undef logError #endif diff --git a/src/native/windows/juce_win32_HiddenMessageWindow.h b/src/native/windows/juce_win32_HiddenMessageWindow.h new file mode 100644 index 0000000000..fcc5bab563 --- /dev/null +++ b/src/native/windows/juce_win32_HiddenMessageWindow.h @@ -0,0 +1,128 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-11 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + 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. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCE_WIN32_HIDDENMESSAGEWINDOW_JUCEHEADER__ +#define __JUCE_WIN32_HIDDENMESSAGEWINDOW_JUCEHEADER__ + +//============================================================================== +class HiddenMessageWindow +{ +public: + HiddenMessageWindow (const TCHAR* const messageWindowName, WNDPROC wndProc) + { + String className ("JUCE_"); + className << String::toHexString (Time::getHighResolutionTicks()); + + HMODULE moduleHandle = (HMODULE) Process::getCurrentModuleInstanceHandle(); + + WNDCLASSEX wc = { 0 }; + wc.cbSize = sizeof (wc); + wc.lpfnWndProc = wndProc; + wc.cbWndExtra = 4; + wc.hInstance = moduleHandle; + wc.lpszClassName = className.toWideCharPointer(); + + atom = RegisterClassEx (&wc); + jassert (atom != 0); + + hwnd = CreateWindow (getClassNameFromAtom(), messageWindowName, + 0, 0, 0, 0, 0, 0, 0, moduleHandle, 0); + jassert (hwnd != 0); + } + + ~HiddenMessageWindow() + { + DestroyWindow (hwnd); + UnregisterClass (getClassNameFromAtom(), 0); + } + + inline HWND getHWND() const noexcept { return hwnd; } + +private: + ATOM atom; + HWND hwnd; + + LPCTSTR getClassNameFromAtom() noexcept { return (LPCTSTR) MAKELONG (atom, 0); } +}; + +//============================================================================== +class JuceWindowIdentifier +{ +public: + static bool isJUCEWindow (HWND hwnd) noexcept + { + return GetWindowLong (hwnd, GWLP_USERDATA) == improbableWindowNumber; + } + + static void setAsJUCEWindow (HWND hwnd, bool isJuceWindow) noexcept + { + SetWindowLongPtr (hwnd, GWLP_USERDATA, isJuceWindow ? improbableWindowNumber : 0); + } + +private: + enum { improbableWindowNumber = 0xf965aa01 }; +}; + +//============================================================================== +class DeviceChangeDetector : private Timer +{ +public: + DeviceChangeDetector (const wchar_t* const name) + : messageWindow (name, (WNDPROC) deviceChangeEventCallback) + { + SetWindowLongPtr (messageWindow.getHWND(), GWLP_USERDATA, (LONG_PTR) this); + } + + virtual ~DeviceChangeDetector() {} + +protected: + virtual void systemDeviceChanged() = 0; + +private: + HiddenMessageWindow messageWindow; + + static LRESULT CALLBACK deviceChangeEventCallback (HWND h, const UINT message, + const WPARAM wParam, const LPARAM lParam) + { + if (message == WM_DEVICECHANGE + && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/ + || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/ + || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/)) + { + // We'll pause before sending a message, because on device removal, the OS hasn't always updated + // its device lists correctly at this point. This also helps avoid repeated callbacks. + ((DeviceChangeDetector*) GetWindowLongPtr (h, GWLP_USERDATA))->startTimer (500); + } + + return DefWindowProc (h, message, wParam, lParam); + } + + void timerCallback() + { + systemDeviceChanged(); + } +}; + +#endif // __JUCE_WIN32_HIDDENMESSAGEWINDOW_JUCEHEADER__ diff --git a/src/native/windows/juce_win32_Messaging.cpp b/src/native/windows/juce_win32_Messaging.cpp index c3b23bec0d..3310cc24f2 100644 --- a/src/native/windows/juce_win32_Messaging.cpp +++ b/src/native/windows/juce_win32_Messaging.cpp @@ -27,67 +27,7 @@ // compiled on its own). #if JUCE_INCLUDED_FILE - -//============================================================================== -class HiddenMessageWindow -{ -public: - HiddenMessageWindow (const TCHAR* const messageWindowName, WNDPROC wndProc) - { - String className ("JUCE_"); - className << String::toHexString (Time::getHighResolutionTicks()); - - HMODULE moduleHandle = (HMODULE) Process::getCurrentModuleInstanceHandle(); - - WNDCLASSEX wc = { 0 }; - wc.cbSize = sizeof (wc); - wc.lpfnWndProc = wndProc; - wc.cbWndExtra = 4; - wc.hInstance = moduleHandle; - wc.lpszClassName = className.toWideCharPointer(); - - atom = RegisterClassEx (&wc); - jassert (atom != 0); - - hwnd = CreateWindow (getClassNameFromAtom(), messageWindowName, - 0, 0, 0, 0, 0, 0, 0, moduleHandle, 0); - jassert (hwnd != 0); - } - - ~HiddenMessageWindow() - { - DestroyWindow (hwnd); - UnregisterClass (getClassNameFromAtom(), 0); - } - - inline HWND getHWND() const noexcept { return hwnd; } - -private: - ATOM atom; - HWND hwnd; - - LPCTSTR getClassNameFromAtom() noexcept { return (LPCTSTR) MAKELONG (atom, 0); } -}; - - -//============================================================================== -class JuceWindowIdentifier -{ -public: - static bool isJUCEWindow (HWND hwnd) noexcept - { - return GetWindowLong (hwnd, GWLP_USERDATA) == improbableWindowNumber; - } - - static void setAsJUCEWindow (HWND hwnd, bool isJuceWindow) noexcept - { - SetWindowLongPtr (hwnd, GWLP_USERDATA, isJuceWindow ? improbableWindowNumber : 0); - } - -private: - enum { improbableWindowNumber = 0xf965aa01 }; -}; - +extern HWND juce_messageWindowHandle; //============================================================================== namespace WindowsMessageHelpers @@ -341,44 +281,4 @@ void MessageManager::doPlatformSpecificShutdown() OleUninitialize(); } -//============================================================================== -class DeviceChangeDetector : private Timer // (Used by various audio classes) -{ -public: - DeviceChangeDetector (const wchar_t* const name) - : messageWindow (name, (WNDPROC) deviceChangeEventCallback) - { - SetWindowLongPtr (messageWindow.getHWND(), GWLP_USERDATA, (LONG_PTR) this); - } - - virtual ~DeviceChangeDetector() {} - -protected: - virtual void systemDeviceChanged() = 0; - -private: - HiddenMessageWindow messageWindow; - - static LRESULT CALLBACK deviceChangeEventCallback (HWND h, const UINT message, - const WPARAM wParam, const LPARAM lParam) - { - if (message == WM_DEVICECHANGE - && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/ - || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/ - || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/)) - { - // We'll pause before sending a message, because on device removal, the OS hasn't always updated - // its device lists correctly at this point. This also helps avoid repeated callbacks. - ((DeviceChangeDetector*) GetWindowLongPtr (h, GWLP_USERDATA))->startTimer (500); - } - - return DefWindowProc (h, message, wParam, lParam); - } - - void timerCallback() - { - systemDeviceChanged(); - } -}; - #endif diff --git a/src/native/windows/juce_win32_NativeCode.cpp b/src/native/windows/juce_win32_NativeCode.cpp index 69d2c9ec4b..9cc5b0651d 100644 --- a/src/native/windows/juce_win32_NativeCode.cpp +++ b/src/native/windows/juce_win32_NativeCode.cpp @@ -106,6 +106,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_win32_Registry.cpp" #if ! JUCE_ONLY_BUILD_CORE_LIBRARY + #include "juce_win32_HiddenMessageWindow.h" #include "juce_win32_Messaging.cpp" #include "juce_win32_Fonts.cpp" #include "juce_win32_Direct2DGraphicsContext.cpp" diff --git a/src/native/windows/juce_win32_Network.cpp b/src/native/windows/juce_win32_Network.cpp index 67f891860c..4f49dfedb1 100644 --- a/src/native/windows/juce_win32_Network.cpp +++ b/src/native/windows/juce_win32_Network.cpp @@ -291,12 +291,11 @@ private: request = FtpOpenFile (connection, uc.lpszUrlPath, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_NEED_FILE, 0); else - openHTTPConnection (uc, sessionHandle, progressCallback, progressCallbackContext); + openHTTPConnection (uc, progressCallback, progressCallbackContext); } } - void openHTTPConnection (URL_COMPONENTS& uc, HINTERNET sessionHandle, - URL::OpenStreamProgressCallback* progressCallback, + void openHTTPConnection (URL_COMPONENTS& uc, URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) { const TCHAR* mimeTypes[] = { _T("*/*"), 0 };