From 1fc8f483e24b988887d15b45984ccee04f2af15d Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Mon, 12 Oct 2009 13:30:04 +0100 Subject: [PATCH] Tweaked lots of code to help things compile on the iPhone (still work-in-progress). --- build/macosx/Juce.xcodeproj/project.pbxproj | 1296 +- build/win32/vc8/JUCE.vcproj | 4 + .../wrapper/juce_NPAPI_GlueCode.cpp | 16 +- .../macosx/jucedemo.xcodeproj/project.pbxproj | 2 +- extras/juce demo/src/ApplicationStartup.cpp | 7 +- extras/juce demo/src/demos/WidgetsDemo.cpp | 4 + extras/juce demo/src/juce_AppConfig.h | 15 +- juce.h | 8 +- juce_Config.h | 4 +- juce_amalgamated.cpp | 10928 +++++----------- juce_amalgamated.h | 335 +- src/application/juce_Application.cpp | 101 +- src/application/juce_Application.h | 6 + .../flac/libFLAC/juce_FlacHeader.h | 6 +- .../audio_file_formats/juce_AudioCDReader.h | 2 +- .../juce_FlacAudioFormat.cpp | 8 +- .../juce_OggVorbisAudioFormat.cpp | 1 + .../juce_QuickTimeAudioFormat.cpp | 12 +- .../oggvorbis/juce_OggVorbisHeader.h | 3 +- src/audio/devices/juce_AudioDeviceManager.cpp | 4 +- .../formats/juce_AudioUnitPluginFormat.mm | 1 + .../plugins/formats/juce_VSTPluginFormat.cpp | 1 + src/core/juce_Atomic.h | 9 +- src/core/juce_DataConversions.h | 14 +- src/core/juce_MathsFunctions.h | 4 +- src/core/juce_PlatformDefs.h | 142 +- src/core/juce_PlatformUtilities.h | 4 +- src/core/juce_StandardHeader.h | 3 +- src/core/juce_SystemStats.cpp | 8 +- src/core/juce_TargetPlatform.h | 169 + src/core/juce_Time.cpp | 8 +- src/events/juce_MessageManager.cpp | 2 +- .../juce_DirectoryContentsList.cpp | 2 +- .../filebrowser/juce_FileBrowserComponent.cpp | 4 +- .../filebrowser/juce_FileChooser.cpp | 2 +- .../special/juce_ActiveXControlComponent.h | 2 +- .../special/juce_QuickTimeMovieComponent.h | 4 +- .../special/juce_SystemTrayIconComponent.cpp | 2 +- .../special/juce_SystemTrayIconComponent.h | 2 +- .../juce_LowLevelGraphicsSoftwareRenderer.cpp | 6 +- src/io/files/juce_File.cpp | 12 +- src/io/network/juce_Socket.cpp | 36 +- src/juce_amalgamated_template.cpp | 19 +- src/native/juce_iphone_NativeCode.mm | 111 - src/native/juce_mac_NativeCode.mm | 51 +- src/native/mac/juce_iphone_Audio.cpp | 449 + src/native/mac/juce_iphone_Fonts.mm | 352 + src/native/mac/juce_iphone_MessageManager.mm | 325 + src/native/mac/juce_iphone_MiscUtilities.mm | 40 + src/native/mac/juce_iphone_NativeIncludes.h | 58 - .../mac/juce_iphone_UIViewComponentPeer.mm | 926 ++ src/native/mac/juce_mac_CameraDevice.mm | 2 - src/native/mac/juce_mac_CoreMidi.cpp | 48 + src/native/mac/juce_mac_FileChooser.mm | 22 + src/native/mac/juce_mac_Files.mm | 62 +- src/native/mac/juce_mac_MouseCursor.mm | 12 + src/native/mac/juce_mac_NativeIncludes.h | 37 +- src/native/mac/juce_mac_OpenGLComponent.mm | 19 + src/native/mac/juce_mac_Strings.mm | 4 +- .../mac/juce_mac_WebBrowserComponent.mm | 68 + .../windows/juce_win32_NativeIncludes.h | 1 + 61 files changed, 7598 insertions(+), 8207 deletions(-) create mode 100644 src/core/juce_TargetPlatform.h delete mode 100644 src/native/juce_iphone_NativeCode.mm create mode 100644 src/native/mac/juce_iphone_Audio.cpp create mode 100644 src/native/mac/juce_iphone_Fonts.mm create mode 100644 src/native/mac/juce_iphone_MessageManager.mm delete mode 100644 src/native/mac/juce_iphone_NativeIncludes.h create mode 100644 src/native/mac/juce_iphone_UIViewComponentPeer.mm diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index 3dd0f56e42..a01e34aabe 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -8,6 +8,609 @@ /* Begin PBXBuildFile section */ 840F80BC092B399D005E7B4E /* juce.h in Headers */ = {isa = PBXBuildFile; fileRef = 840F80BB092B399D005E7B4E /* juce.h */; }; + 84816E5710809D07008FEC33 /* juce_iphone_Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */; }; + 84816E5810809D07008FEC33 /* juce_iphone_Fonts.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5210809D07008FEC33 /* juce_iphone_Fonts.mm */; }; + 84816E5910809D07008FEC33 /* juce_iphone_MessageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */; }; + 84816E5A10809D07008FEC33 /* juce_iphone_MiscUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5410809D07008FEC33 /* juce_iphone_MiscUtilities.mm */; }; + 84816E5C10809D07008FEC33 /* juce_iphone_UIViewComponentPeer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5610809D07008FEC33 /* juce_iphone_UIViewComponentPeer.mm */; }; + 84816E5D10809DCB008FEC33 /* juce.h in Headers */ = {isa = PBXBuildFile; fileRef = 840F80BB092B399D005E7B4E /* juce.h */; }; + 84816E5E10809DCB008FEC33 /* juce_ActionBroadcaster.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E94B104036B3006A1807 /* juce_ActionBroadcaster.h */; }; + 84816E5F10809DCB008FEC33 /* juce_ActionListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E94C104036B3006A1807 /* juce_ActionListener.h */; }; + 84816E6010809DCB008FEC33 /* juce_ActionListenerList.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E94E104036B3006A1807 /* juce_ActionListenerList.h */; }; + 84816E6110809DCB008FEC33 /* juce_AffineTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5810403709006A1807 /* juce_AffineTransform.h */; }; + 84816E6210809DCB008FEC33 /* juce_AiffAudioFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6F510403614006A1807 /* juce_AiffAudioFormat.h */; }; + 84816E6310809DCB008FEC33 /* juce_AlertWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0810403709006A1807 /* juce_AlertWindow.h */; }; + 84816E6410809DCB008FEC33 /* juce_Application.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6DD10403605006A1807 /* juce_Application.h */; }; + 84816E6510809DCB008FEC33 /* juce_ApplicationCommandID.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6DE10403605006A1807 /* juce_ApplicationCommandID.h */; }; + 84816E6610809DCB008FEC33 /* juce_ApplicationCommandInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6E010403605006A1807 /* juce_ApplicationCommandInfo.h */; }; + 84816E6710809DCB008FEC33 /* juce_ApplicationCommandManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6E210403605006A1807 /* juce_ApplicationCommandManager.h */; }; + 84816E6810809DCB008FEC33 /* juce_ApplicationCommandTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6E410403605006A1807 /* juce_ApplicationCommandTarget.h */; }; + 84816E6910809DCB008FEC33 /* juce_ApplicationProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6E610403605006A1807 /* juce_ApplicationProperties.h */; }; + 84816E6A10809DCB008FEC33 /* juce_Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8D010403671006A1807 /* juce_Array.h */; }; + 84816E6B10809DCB008FEC33 /* juce_ArrayAllocationBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8D110403671006A1807 /* juce_ArrayAllocationBase.h */; }; + 84816E6C10809DCB008FEC33 /* juce_ArrowButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA4F10403708006A1807 /* juce_ArrowButton.h */; }; + 84816E6D10809DCB008FEC33 /* juce_AsyncUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E950104036B3006A1807 /* juce_AsyncUpdater.h */; }; + 84816E6E10809DCB008FEC33 /* juce_Atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90510403681006A1807 /* juce_Atomic.h */; }; + 84816E6F10809DCB008FEC33 /* juce_AudioCDBurner.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6F610403614006A1807 /* juce_AudioCDBurner.h */; }; + 84816E7010809DCB008FEC33 /* juce_AudioCDReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6F810403614006A1807 /* juce_AudioCDReader.h */; }; + 84816E7110809DCB008FEC33 /* juce_AudioDataConverters.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7B310403614006A1807 /* juce_AudioDataConverters.h */; }; + 84816E7210809DCB008FEC33 /* juce_AudioDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7A910403614006A1807 /* juce_AudioDeviceManager.h */; }; + 84816E7310809DCB008FEC33 /* juce_AudioDeviceSelectorComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAF010403709006A1807 /* juce_AudioDeviceSelectorComponent.h */; }; + 84816E7410809DCB008FEC33 /* juce_AudioFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6FA10403614006A1807 /* juce_AudioFormat.h */; }; + 84816E7510809DCB008FEC33 /* juce_AudioFormatManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6FC10403614006A1807 /* juce_AudioFormatManager.h */; }; + 84816E7610809DCB008FEC33 /* juce_AudioFormatReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6FD10403614006A1807 /* juce_AudioFormatReader.h */; }; + 84816E7710809DCB008FEC33 /* juce_AudioFormatReaderSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79410403614006A1807 /* juce_AudioFormatReaderSource.h */; }; + 84816E7810809DCB008FEC33 /* juce_AudioFormatWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6FE10403614006A1807 /* juce_AudioFormatWriter.h */; }; + 84816E7910809DCB008FEC33 /* juce_AudioIODevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7AB10403614006A1807 /* juce_AudioIODevice.h */; }; + 84816E7A10809DCB008FEC33 /* juce_AudioIODeviceType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7AD10403614006A1807 /* juce_AudioIODeviceType.h */; }; + 84816E7B10809DCB008FEC33 /* juce_AudioPlayHead.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7DE10403615006A1807 /* juce_AudioPlayHead.h */; }; + 84816E7C10809DCB008FEC33 /* juce_AudioPluginFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7C710403614006A1807 /* juce_AudioPluginFormat.h */; }; + 84816E7D10809DCB008FEC33 /* juce_AudioPluginFormatManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7C910403614006A1807 /* juce_AudioPluginFormatManager.h */; }; + 84816E7E10809DCB008FEC33 /* juce_AudioPluginInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7CB10403614006A1807 /* juce_AudioPluginInstance.h */; }; + 84816E7F10809DCB008FEC33 /* juce_AudioProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7E010403615006A1807 /* juce_AudioProcessor.h */; }; + 84816E8010809DCB008FEC33 /* juce_AudioProcessorEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7E210403615006A1807 /* juce_AudioProcessorEditor.h */; }; + 84816E8110809DCB008FEC33 /* juce_AudioProcessorGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7E410403615006A1807 /* juce_AudioProcessorGraph.h */; }; + 84816E8210809DCB008FEC33 /* juce_AudioProcessorListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7E510403615006A1807 /* juce_AudioProcessorListener.h */; }; + 84816E8310809DCB008FEC33 /* juce_AudioProcessorPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7E710403615006A1807 /* juce_AudioProcessorPlayer.h */; }; + 84816E8410809DCB008FEC33 /* juce_AudioSampleBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7B510403614006A1807 /* juce_AudioSampleBuffer.h */; }; + 84816E8510809DCB008FEC33 /* juce_AudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79510403614006A1807 /* juce_AudioSource.h */; }; + 84816E8610809DCB008FEC33 /* juce_AudioSourcePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79710403614006A1807 /* juce_AudioSourcePlayer.h */; }; + 84816E8710809DCB008FEC33 /* juce_AudioSubsectionReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E70010403614006A1807 /* juce_AudioSubsectionReader.h */; }; + 84816E8810809DCB008FEC33 /* juce_AudioThumbnail.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E70210403614006A1807 /* juce_AudioThumbnail.h */; }; + 84816E8910809DCB008FEC33 /* juce_AudioThumbnailCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E70410403614006A1807 /* juce_AudioThumbnailCache.h */; }; + 84816E8A10809DCB008FEC33 /* juce_AudioTransportSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79910403614006A1807 /* juce_AudioTransportSource.h */; }; + 84816E8B10809DCB008FEC33 /* juce_AudioUnitPluginFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7D510403614006A1807 /* juce_AudioUnitPluginFormat.h */; }; + 84816E8C10809DCB008FEC33 /* juce_BitArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8D310403671006A1807 /* juce_BitArray.h */; }; + 84816E8D10809DCB008FEC33 /* juce_BlowFish.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E942104036B3006A1807 /* juce_BlowFish.h */; }; + 84816E8E10809DCB008FEC33 /* juce_BooleanPropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAE010403709006A1807 /* juce_BooleanPropertyComponent.h */; }; + 84816E8F10809DCB008FEC33 /* juce_BorderSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5A10403709006A1807 /* juce_BorderSize.h */; }; + 84816E9010809DCB008FEC33 /* juce_Brush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1C10403709006A1807 /* juce_Brush.h */; }; + 84816E9110809DCB008FEC33 /* juce_BubbleComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAF210403709006A1807 /* juce_BubbleComponent.h */; }; + 84816E9210809DCB008FEC33 /* juce_BubbleMessageComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAF410403709006A1807 /* juce_BubbleMessageComponent.h */; }; + 84816E9310809DCB008FEC33 /* juce_BufferedInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E99F104036D6006A1807 /* juce_BufferedInputStream.h */; }; + 84816E9410809DCB008FEC33 /* juce_BufferingAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79B10403614006A1807 /* juce_BufferingAudioSource.h */; }; + 84816E9510809DCB008FEC33 /* juce_Button.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5110403708006A1807 /* juce_Button.h */; }; + 84816E9610809DCB008FEC33 /* juce_ButtonPropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAE210403709006A1807 /* juce_ButtonPropertyComponent.h */; }; + 84816E9710809DCB008FEC33 /* juce_CallbackMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E951104036B3006A1807 /* juce_CallbackMessage.h */; }; + 84816E9810809DCB008FEC33 /* juce_CameraDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6C10403709006A1807 /* juce_CameraDevice.h */; }; + 84816E9910809DCB008FEC33 /* juce_ChangeBroadcaster.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E953104036B3006A1807 /* juce_ChangeBroadcaster.h */; }; + 84816E9A10809DCB008FEC33 /* juce_ChangeListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E954104036B3006A1807 /* juce_ChangeListener.h */; }; + 84816E9B10809DCB008FEC33 /* juce_ChangeListenerList.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E956104036B3006A1807 /* juce_ChangeListenerList.h */; }; + 84816E9C10809DCB008FEC33 /* juce_ChannelRemappingAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79D10403614006A1807 /* juce_ChannelRemappingAudioSource.h */; }; + 84816E9D10809DCB008FEC33 /* juce_CharacterFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9CB104036D6006A1807 /* juce_CharacterFunctions.h */; }; + 84816E9E10809DCB008FEC33 /* juce_ChoicePropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAE410403709006A1807 /* juce_ChoicePropertyComponent.h */; }; + 84816E9F10809DCB008FEC33 /* juce_Colour.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2A10403709006A1807 /* juce_Colour.h */; }; + 84816EA010809DCB008FEC33 /* juce_ColourGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2610403709006A1807 /* juce_ColourGradient.h */; }; + 84816EA110809DCB008FEC33 /* juce_Colours.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2810403709006A1807 /* juce_Colours.h */; }; + 84816EA210809DCB008FEC33 /* juce_ColourSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAF610403709006A1807 /* juce_ColourSelector.h */; }; + 84816EA310809DCB008FEC33 /* juce_ComboBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6210403709006A1807 /* juce_ComboBox.h */; }; + 84816EA410809DCB008FEC33 /* juce_Component.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA4710403708006A1807 /* juce_Component.h */; }; + 84816EA510809DCB008FEC33 /* juce_ComponentAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAA510403709006A1807 /* juce_ComponentAnimator.h */; }; + 84816EA610809DCB008FEC33 /* juce_ComponentBoundsConstrainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAA710403709006A1807 /* juce_ComponentBoundsConstrainer.h */; }; + 84816EA710809DCB008FEC33 /* juce_ComponentDeletionWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA4810403708006A1807 /* juce_ComponentDeletionWatcher.h */; }; + 84816EA810809DCB008FEC33 /* juce_ComponentDragger.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EACF10403709006A1807 /* juce_ComponentDragger.h */; }; + 84816EA910809DCB008FEC33 /* juce_ComponentListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA4A10403708006A1807 /* juce_ComponentListener.h */; }; + 84816EAA10809DCB008FEC33 /* juce_ComponentMovementWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAA910403709006A1807 /* juce_ComponentMovementWatcher.h */; }; + 84816EAB10809DCB008FEC33 /* juce_ComponentPeer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0A10403709006A1807 /* juce_ComponentPeer.h */; }; + 84816EAC10809DCB008FEC33 /* juce_CriticalSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9D9104036D6006A1807 /* juce_CriticalSection.h */; }; + 84816EAD10809DCB008FEC33 /* juce_DataConversions.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90410403681006A1807 /* juce_DataConversions.h */; }; + 84816EAE10809DCB008FEC33 /* juce_DeletedAtShutdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E92C1040369C006A1807 /* juce_DeletedAtShutdown.h */; }; + 84816EAF10809DCB008FEC33 /* juce_Desktop.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA4C10403708006A1807 /* juce_Desktop.h */; }; + 84816EB010809DCB008FEC33 /* juce_DialogWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0C10403709006A1807 /* juce_DialogWindow.h */; }; + 84816EB110809DCB008FEC33 /* juce_DirectoryContentsDisplayComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7D10403709006A1807 /* juce_DirectoryContentsDisplayComponent.h */; }; + 84816EB210809DCB008FEC33 /* juce_DirectoryContentsList.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7F10403709006A1807 /* juce_DirectoryContentsList.h */; }; + 84816EB310809DCB008FEC33 /* juce_DirectoryIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E98B104036D6006A1807 /* juce_DirectoryIterator.h */; }; + 84816EB410809DCB008FEC33 /* juce_DocumentWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0E10403709006A1807 /* juce_DocumentWindow.h */; }; + 84816EB510809DCB008FEC33 /* juce_DragAndDropContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAD110403709006A1807 /* juce_DragAndDropContainer.h */; }; + 84816EB610809DCB008FEC33 /* juce_DragAndDropTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAD210403709006A1807 /* juce_DragAndDropTarget.h */; }; + 84816EB710809DCB008FEC33 /* juce_Drawable.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3B10403709006A1807 /* juce_Drawable.h */; }; + 84816EB810809DCB008FEC33 /* juce_DrawableButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5310403708006A1807 /* juce_DrawableButton.h */; }; + 84816EB910809DCB008FEC33 /* juce_DrawableComposite.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3D10403709006A1807 /* juce_DrawableComposite.h */; }; + 84816EBA10809DCB008FEC33 /* juce_DrawableImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3F10403709006A1807 /* juce_DrawableImage.h */; }; + 84816EBB10809DCB008FEC33 /* juce_DrawablePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4110403709006A1807 /* juce_DrawablePath.h */; }; + 84816EBC10809DCB008FEC33 /* juce_DrawableText.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4310403709006A1807 /* juce_DrawableText.h */; }; + 84816EBD10809DCB008FEC33 /* juce_DropShadowEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4710403709006A1807 /* juce_DropShadowEffect.h */; }; + 84816EBE10809DCB008FEC33 /* juce_DropShadower.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAF810403709006A1807 /* juce_DropShadower.h */; }; + 84816EBF10809DCB008FEC33 /* juce_EdgeTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2D10403709006A1807 /* juce_EdgeTable.h */; }; + 84816EC010809DCB008FEC33 /* juce_ElementComparator.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8D410403671006A1807 /* juce_ElementComparator.h */; }; + 84816EC110809DCB008FEC33 /* juce_File.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E98D104036D6006A1807 /* juce_File.h */; }; + 84816EC210809DCB008FEC33 /* juce_FileBasedDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E92F1040369C006A1807 /* juce_FileBasedDocument.h */; }; + 84816EC310809DCB008FEC33 /* juce_FileBrowserComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8110403709006A1807 /* juce_FileBrowserComponent.h */; }; + 84816EC410809DCB008FEC33 /* juce_FileBrowserListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8210403709006A1807 /* juce_FileBrowserListener.h */; }; + 84816EC510809DCB008FEC33 /* juce_FileChooser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8410403709006A1807 /* juce_FileChooser.h */; }; + 84816EC610809DCB008FEC33 /* juce_FileChooserDialogBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8610403709006A1807 /* juce_FileChooserDialogBox.h */; }; + 84816EC710809DCB008FEC33 /* juce_FileDragAndDropTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAD310403709006A1807 /* juce_FileDragAndDropTarget.h */; }; + 84816EC810809DCB008FEC33 /* juce_FileFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8810403709006A1807 /* juce_FileFilter.h */; }; + 84816EC910809DCB008FEC33 /* juce_FileInputSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9A1104036D6006A1807 /* juce_FileInputSource.h */; }; + 84816ECA10809DCB008FEC33 /* juce_FileInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E98F104036D6006A1807 /* juce_FileInputStream.h */; }; + 84816ECB10809DCB008FEC33 /* juce_FileListComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8A10403709006A1807 /* juce_FileListComponent.h */; }; + 84816ECC10809DCB008FEC33 /* juce_FileLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90210403681006A1807 /* juce_FileLogger.h */; }; + 84816ECD10809DCB008FEC33 /* juce_FilenameComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8C10403709006A1807 /* juce_FilenameComponent.h */; }; + 84816ECE10809DCB008FEC33 /* juce_FileOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E991104036D6006A1807 /* juce_FileOutputStream.h */; }; + 84816ECF10809DCB008FEC33 /* juce_FilePreviewComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8D10403709006A1807 /* juce_FilePreviewComponent.h */; }; + 84816ED010809DCB008FEC33 /* juce_FileSearchPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E993104036D6006A1807 /* juce_FileSearchPath.h */; }; + 84816ED110809DCB008FEC33 /* juce_FileSearchPathListComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA8F10403709006A1807 /* juce_FileSearchPathListComponent.h */; }; + 84816ED210809DCB008FEC33 /* juce_FileTreeComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA9110403709006A1807 /* juce_FileTreeComponent.h */; }; + 84816ED310809DCB008FEC33 /* juce_FlacAudioFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E70510403614006A1807 /* juce_FlacAudioFormat.h */; }; + 84816ED410809DCB008FEC33 /* juce_Font.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4F10403709006A1807 /* juce_Font.h */; }; + 84816ED510809DCB008FEC33 /* juce_GenericAudioProcessorEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7E910403615006A1807 /* juce_GenericAudioProcessorEditor.h */; }; + 84816ED610809DCB008FEC33 /* juce_GIFLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7710403709006A1807 /* juce_GIFLoader.h */; }; + 84816ED710809DCB008FEC33 /* juce_GlowEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4910403709006A1807 /* juce_GlowEffect.h */; }; + 84816ED810809DCB008FEC33 /* juce_GlyphArrangement.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5110403709006A1807 /* juce_GlyphArrangement.h */; }; + 84816ED910809DCB008FEC33 /* juce_GradientBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1E10403709006A1807 /* juce_GradientBrush.h */; }; + 84816EDA10809DCB008FEC33 /* juce_Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2F10403709006A1807 /* juce_Graphics.h */; }; + 84816EDB10809DCB008FEC33 /* juce_GroupComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAAB10403709006A1807 /* juce_GroupComponent.h */; }; + 84816EDC10809DCB008FEC33 /* juce_GZIPCompressorOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9A3104036D6006A1807 /* juce_GZIPCompressorOutputStream.h */; }; + 84816EDD10809DCB008FEC33 /* juce_GZIPDecompressorInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9A5104036D6006A1807 /* juce_GZIPDecompressorInputStream.h */; }; + 84816EDE10809DCB008FEC33 /* juce_HyperlinkButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5510403709006A1807 /* juce_HyperlinkButton.h */; }; + 84816EDF10809DCB008FEC33 /* juce_IIRFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7B710403614006A1807 /* juce_IIRFilter.h */; }; + 84816EE010809DCB008FEC33 /* juce_IIRFilterAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E79F10403614006A1807 /* juce_IIRFilterAudioSource.h */; }; + 84816EE110809DCB008FEC33 /* juce_Image.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6E10403709006A1807 /* juce_Image.h */; }; + 84816EE210809DCB008FEC33 /* juce_ImageBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2010403709006A1807 /* juce_ImageBrush.h */; }; + 84816EE310809DCB008FEC33 /* juce_ImageButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5710403709006A1807 /* juce_ImageButton.h */; }; + 84816EE410809DCB008FEC33 /* juce_ImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7010403709006A1807 /* juce_ImageCache.h */; }; + 84816EE510809DCB008FEC33 /* juce_ImageConvolutionKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7210403709006A1807 /* juce_ImageConvolutionKernel.h */; }; + 84816EE610809DCB008FEC33 /* juce_ImageEffectFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4A10403709006A1807 /* juce_ImageEffectFilter.h */; }; + 84816EE710809DCB008FEC33 /* juce_ImageFileFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB7410403709006A1807 /* juce_ImageFileFormat.h */; }; + 84816EE810809DCB008FEC33 /* juce_ImagePreviewComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA9310403709006A1807 /* juce_ImagePreviewComponent.h */; }; + 84816EE910809DCB008FEC33 /* juce_Initialisation.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90110403681006A1807 /* juce_Initialisation.h */; }; + 84816EEA10809DCB008FEC33 /* juce_InputSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9A6104036D6006A1807 /* juce_InputSource.h */; }; + 84816EEB10809DCB008FEC33 /* juce_InputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9C6104036D6006A1807 /* juce_InputStream.h */; }; + 84816EEC10809DCB008FEC33 /* juce_InterprocessConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E958104036B3006A1807 /* juce_InterprocessConnection.h */; }; + 84816EED10809DCB008FEC33 /* juce_InterprocessConnectionServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E95A104036B3006A1807 /* juce_InterprocessConnectionServer.h */; }; + 84816EEE10809DCB008FEC33 /* juce_InterProcessLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9DB104036D6006A1807 /* juce_InterProcessLock.h */; }; + 84816EF010809DCB008FEC33 /* juce_Justification.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3110403709006A1807 /* juce_Justification.h */; }; + 84816EF110809DCB008FEC33 /* juce_KeyboardFocusTraverser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA9810403709006A1807 /* juce_KeyboardFocusTraverser.h */; }; + 84816EF210809DCB008FEC33 /* juce_KeyListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA9A10403709006A1807 /* juce_KeyListener.h */; }; + 84816EF310809DCB008FEC33 /* juce_KeyMappingEditorComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA9C10403709006A1807 /* juce_KeyMappingEditorComponent.h */; }; + 84816EF410809DCB008FEC33 /* juce_KeyPress.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA9E10403709006A1807 /* juce_KeyPress.h */; }; + 84816EF510809DCB008FEC33 /* juce_KeyPressMappingSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAA010403709006A1807 /* juce_KeyPressMappingSet.h */; }; + 84816EF610809DCB008FEC33 /* juce_KnownPluginList.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7CD10403614006A1807 /* juce_KnownPluginList.h */; }; + 84816EF710809DCB008FEC33 /* juce_Label.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6410403709006A1807 /* juce_Label.h */; }; + 84816EF810809DCB008FEC33 /* juce_LassoComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAD410403709006A1807 /* juce_LassoComponent.h */; }; + 84816EF910809DCB008FEC33 /* juce_Line.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5C10403709006A1807 /* juce_Line.h */; }; + 84816EFA10809DCB008FEC33 /* juce_ListBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6610403709006A1807 /* juce_ListBox.h */; }; + 84816EFB10809DCB008FEC33 /* juce_LocalisedStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9CD104036D6006A1807 /* juce_LocalisedStrings.h */; }; + 84816EFC10809DCB008FEC33 /* juce_Logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8FF10403681006A1807 /* juce_Logger.h */; }; + 84816EFD10809DCB008FEC33 /* juce_LookAndFeel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAC210403709006A1807 /* juce_LookAndFeel.h */; }; + 84816EFE10809DCB008FEC33 /* juce_LowLevelGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3210403709006A1807 /* juce_LowLevelGraphicsContext.h */; }; + 84816EFF10809DCB008FEC33 /* juce_LowLevelGraphicsPostScriptRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3410403709006A1807 /* juce_LowLevelGraphicsPostScriptRenderer.h */; }; + 84816F0010809DCB008FEC33 /* juce_LowLevelGraphicsSoftwareRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3610403709006A1807 /* juce_LowLevelGraphicsSoftwareRenderer.h */; }; + 84816F0110809DCB008FEC33 /* juce_mac_CarbonViewWrapperComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 8484E9A9103C9595008B7C6C /* juce_mac_CarbonViewWrapperComponent.h */; }; + 84816F0210809DCB008FEC33 /* juce_mac_NativeIncludes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8484E9B4103C9595008B7C6C /* juce_mac_NativeIncludes.h */; }; + 84816F0310809DCB008FEC33 /* juce_mac_ObjCSuffix.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A63C01107DF286000326FD /* juce_mac_ObjCSuffix.h */; }; + 84816F0410809DCB008FEC33 /* juce_MagnifierComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAFA10403709006A1807 /* juce_MagnifierComponent.h */; }; + 84816F0510809DCB008FEC33 /* juce_MathsFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8FD10403681006A1807 /* juce_MathsFunctions.h */; }; + 84816F0610809DCB008FEC33 /* juce_MD5.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E944104036B3006A1807 /* juce_MD5.h */; }; + 84816F0710809DCB008FEC33 /* juce_Memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8FE10403681006A1807 /* juce_Memory.h */; }; + 84816F0810809DCB008FEC33 /* juce_MemoryBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8D610403671006A1807 /* juce_MemoryBlock.h */; }; + 84816F0910809DCB008FEC33 /* juce_MemoryInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9A8104036D6006A1807 /* juce_MemoryInputStream.h */; }; + 84816F0A10809DCB008FEC33 /* juce_MemoryOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9AA104036D6006A1807 /* juce_MemoryOutputStream.h */; }; + 84816F0B10809DCB008FEC33 /* juce_MenuBarComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAC710403709006A1807 /* juce_MenuBarComponent.h */; }; + 84816F0C10809DCB008FEC33 /* juce_MenuBarModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAC910403709006A1807 /* juce_MenuBarModel.h */; }; + 84816F0D10809DCB008FEC33 /* juce_Message.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E95C104036B3006A1807 /* juce_Message.h */; }; + 84816F0E10809DCB008FEC33 /* juce_MessageListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E95E104036B3006A1807 /* juce_MessageListener.h */; }; + 84816F0F10809DCB008FEC33 /* juce_MessageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E960104036B3006A1807 /* juce_MessageManager.h */; }; + 84816F1010809DCB008FEC33 /* juce_MidiBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7BA10403614006A1807 /* juce_MidiBuffer.h */; }; + 84816F1110809DCB008FEC33 /* juce_MidiFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7BC10403614006A1807 /* juce_MidiFile.h */; }; + 84816F1210809DCB008FEC33 /* juce_MidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7AE10403614006A1807 /* juce_MidiInput.h */; }; + 84816F1310809DCB008FEC33 /* juce_MidiKeyboardComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAFC10403709006A1807 /* juce_MidiKeyboardComponent.h */; }; + 84816F1410809DCB008FEC33 /* juce_MidiKeyboardState.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7BE10403614006A1807 /* juce_MidiKeyboardState.h */; }; + 84816F1510809DCB008FEC33 /* juce_MidiMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7C010403614006A1807 /* juce_MidiMessage.h */; }; + 84816F1610809DCB008FEC33 /* juce_MidiMessageCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7C210403614006A1807 /* juce_MidiMessageCollector.h */; }; + 84816F1710809DCB008FEC33 /* juce_MidiMessageSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7C410403614006A1807 /* juce_MidiMessageSequence.h */; }; + 84816F1810809DCB008FEC33 /* juce_MidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7B010403614006A1807 /* juce_MidiOutput.h */; }; + 84816F1910809DCB008FEC33 /* juce_MixerAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7A110403614006A1807 /* juce_MixerAudioSource.h */; }; + 84816F1A10809DCB008FEC33 /* juce_ModifierKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAA210403709006A1807 /* juce_ModifierKeys.h */; }; + 84816F1B10809DCB008FEC33 /* juce_MouseCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAD510403709006A1807 /* juce_MouseCursor.h */; }; + 84816F1C10809DCB008FEC33 /* juce_MouseEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAD710403709006A1807 /* juce_MouseEvent.h */; }; + 84816F1D10809DCB008FEC33 /* juce_MouseHoverDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAD910403709006A1807 /* juce_MouseHoverDetector.h */; }; + 84816F1E10809DCB008FEC33 /* juce_MouseListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EADB10403709006A1807 /* juce_MouseListener.h */; }; + 84816F1F10809DCB008FEC33 /* juce_MultiDocumentPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAAD10403709006A1807 /* juce_MultiDocumentPanel.h */; }; + 84816F2010809DCB008FEC33 /* juce_MultiTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E962104036B3006A1807 /* juce_MultiTimer.h */; }; + 84816F2110809DCB008FEC33 /* juce_NamedPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E995104036D6006A1807 /* juce_NamedPipe.h */; }; + 84816F2210809DCB008FEC33 /* juce_NSViewComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAFD10403709006A1807 /* juce_NSViewComponent.h */; }; + 84816F2310809DCB008FEC33 /* juce_OggVorbisAudioFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E70610403614006A1807 /* juce_OggVorbisAudioFormat.h */; }; + 84816F2410809DCB008FEC33 /* juce_OldSchoolLookAndFeel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAC410403709006A1807 /* juce_OldSchoolLookAndFeel.h */; }; + 84816F2510809DCB008FEC33 /* juce_OpenGLComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAFF10403709006A1807 /* juce_OpenGLComponent.h */; }; + 84816F2610809DCB008FEC33 /* juce_OutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9C8104036D6006A1807 /* juce_OutputStream.h */; }; + 84816F2710809DCB008FEC33 /* juce_OwnedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8D710403671006A1807 /* juce_OwnedArray.h */; }; + 84816F2810809DCB008FEC33 /* juce_Path.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5E10403709006A1807 /* juce_Path.h */; }; + 84816F2910809DCB008FEC33 /* juce_PathIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6010403709006A1807 /* juce_PathIterator.h */; }; + 84816F2A10809DCB008FEC33 /* juce_PathStrokeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6210403709006A1807 /* juce_PathStrokeType.h */; }; + 84816F2B10809DCB008FEC33 /* juce_PerformanceCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90910403681006A1807 /* juce_PerformanceCounter.h */; }; + 84816F2C10809DCB008FEC33 /* juce_PixelFormats.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2910403709006A1807 /* juce_PixelFormats.h */; }; + 84816F2D10809DCB008FEC33 /* juce_PlatformDefs.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8FA10403681006A1807 /* juce_PlatformDefs.h */; }; + 84816F2E10809DCB008FEC33 /* juce_PlatformUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90A10403681006A1807 /* juce_PlatformUtilities.h */; }; + 84816F2F10809DCB008FEC33 /* juce_PluginDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7CF10403614006A1807 /* juce_PluginDescription.h */; }; + 84816F3010809DCB008FEC33 /* juce_PluginDirectoryScanner.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7D110403614006A1807 /* juce_PluginDirectoryScanner.h */; }; + 84816F3110809DCB008FEC33 /* juce_PluginListComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7D310403614006A1807 /* juce_PluginListComponent.h */; }; + 84816F3210809DCB008FEC33 /* juce_Point.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6410403709006A1807 /* juce_Point.h */; }; + 84816F3310809DCB008FEC33 /* juce_PopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EACB10403709006A1807 /* juce_PopupMenu.h */; }; + 84816F3410809DCB008FEC33 /* juce_PopupMenuCustomComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EACC10403709006A1807 /* juce_PopupMenuCustomComponent.h */; }; + 84816F3510809DCB008FEC33 /* juce_PositionableAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7A210403614006A1807 /* juce_PositionableAudioSource.h */; }; + 84816F3610809DCB008FEC33 /* juce_PositionedRectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6610403709006A1807 /* juce_PositionedRectangle.h */; }; + 84816F3710809DCB008FEC33 /* juce_posix_SharedCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8484E9D6103C95A6008B7C6C /* juce_posix_SharedCode.h */; }; + 84816F3810809DCB008FEC33 /* juce_PreferencesPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0110403709006A1807 /* juce_PreferencesPanel.h */; }; + 84816F3910809DCB008FEC33 /* juce_Primes.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E946104036B3006A1807 /* juce_Primes.h */; }; + 84816F3A10809DCB008FEC33 /* juce_Process.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9DC104036D6006A1807 /* juce_Process.h */; }; + 84816F3B10809DCB008FEC33 /* juce_ProgressBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6810403709006A1807 /* juce_ProgressBar.h */; }; + 84816F3C10809DCB008FEC33 /* juce_PropertiesFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9291040369C006A1807 /* juce_PropertiesFile.h */; }; + 84816F3D10809DCB008FEC33 /* juce_PropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAE610403709006A1807 /* juce_PropertyComponent.h */; }; + 84816F3E10809DCB008FEC33 /* juce_PropertyPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAE810403709006A1807 /* juce_PropertyPanel.h */; }; + 84816F3F10809DCB008FEC33 /* juce_PropertySet.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8D910403671006A1807 /* juce_PropertySet.h */; }; + 84816F4010809DCB008FEC33 /* juce_QuickTimeAudioFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E70710403614006A1807 /* juce_QuickTimeAudioFormat.h */; }; + 84816F4110809DCB008FEC33 /* juce_QuickTimeMovieComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0210403709006A1807 /* juce_QuickTimeMovieComponent.h */; }; + 84816F4210809DCB008FEC33 /* juce_Random.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8FC10403681006A1807 /* juce_Random.h */; }; + 84816F4310809DCB008FEC33 /* juce_ReadWriteLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9DE104036D6006A1807 /* juce_ReadWriteLock.h */; }; + 84816F4410809DCB008FEC33 /* juce_RecentlyOpenedFilesList.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E92E1040369C006A1807 /* juce_RecentlyOpenedFilesList.h */; }; + 84816F4510809DCB008FEC33 /* juce_Rectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6810403709006A1807 /* juce_Rectangle.h */; }; + 84816F4610809DCB008FEC33 /* juce_RectangleList.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB6A10403709006A1807 /* juce_RectangleList.h */; }; + 84816F4710809DCB008FEC33 /* juce_RectanglePlacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB3810403709006A1807 /* juce_RectanglePlacement.h */; }; + 84816F4810809DCB008FEC33 /* juce_ReduceOpacityEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB4C10403709006A1807 /* juce_ReduceOpacityEffect.h */; }; + 84816F4910809DCB008FEC33 /* juce_ReferenceCountedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8DA10403671006A1807 /* juce_ReferenceCountedArray.h */; }; + 84816F4A10809DCB008FEC33 /* juce_ReferenceCountedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8DB10403671006A1807 /* juce_ReferenceCountedObject.h */; }; + 84816F4B10809DCB008FEC33 /* juce_RelativeTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8F910403681006A1807 /* juce_RelativeTime.h */; }; + 84816F4C10809DCB008FEC33 /* juce_ResamplingAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7A410403614006A1807 /* juce_ResamplingAudioSource.h */; }; + 84816F4D10809DCB008FEC33 /* juce_ResizableBorderComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAAF10403709006A1807 /* juce_ResizableBorderComponent.h */; }; + 84816F4E10809DCB008FEC33 /* juce_ResizableCornerComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAB110403709006A1807 /* juce_ResizableCornerComponent.h */; }; + 84816F4F10809DCB008FEC33 /* juce_ResizableWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1010403709006A1807 /* juce_ResizableWindow.h */; }; + 84816F5010809DCB008FEC33 /* juce_RSAKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E948104036B3006A1807 /* juce_RSAKey.h */; }; + 84816F5110809DCB008FEC33 /* juce_Sampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7EC10403615006A1807 /* juce_Sampler.h */; }; + 84816F5210809DCB008FEC33 /* juce_ScopedLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9DF104036D6006A1807 /* juce_ScopedLock.h */; }; + 84816F5310809DCB008FEC33 /* juce_ScopedReadLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9E0104036D6006A1807 /* juce_ScopedReadLock.h */; }; + 84816F5410809DCB008FEC33 /* juce_ScopedTryLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9E1104036D6006A1807 /* juce_ScopedTryLock.h */; }; + 84816F5510809DCB008FEC33 /* juce_ScopedWriteLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9E2104036D6006A1807 /* juce_ScopedWriteLock.h */; }; + 84816F5610809DCB008FEC33 /* juce_ScrollBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAB310403709006A1807 /* juce_ScrollBar.h */; }; + 84816F5710809DCB008FEC33 /* juce_SelectedItemSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E92B1040369C006A1807 /* juce_SelectedItemSet.h */; }; + 84816F5810809DCB008FEC33 /* juce_ShapeButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5910403709006A1807 /* juce_ShapeButton.h */; }; + 84816F5910809DCB008FEC33 /* juce_Singleton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8F710403681006A1807 /* juce_Singleton.h */; }; + 84816F5A10809DCB008FEC33 /* juce_Slider.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6A10403709006A1807 /* juce_Slider.h */; }; + 84816F5B10809DCB008FEC33 /* juce_SliderListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6B10403709006A1807 /* juce_SliderListener.h */; }; + 84816F5C10809DCB008FEC33 /* juce_SliderPropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAEA10403709006A1807 /* juce_SliderPropertyComponent.h */; }; + 84816F5D10809DCB008FEC33 /* juce_Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E99A104036D6006A1807 /* juce_Socket.h */; }; + 84816F5E10809DCB008FEC33 /* juce_SolidColourBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB2210403709006A1807 /* juce_SolidColourBrush.h */; }; + 84816F5F10809DCB008FEC33 /* juce_SortedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8DC10403671006A1807 /* juce_SortedSet.h */; }; + 84816F6010809DCB008FEC33 /* juce_SparseSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8DD10403671006A1807 /* juce_SparseSet.h */; }; + 84816F6110809DCB008FEC33 /* juce_SplashScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1210403709006A1807 /* juce_SplashScreen.h */; }; + 84816F6210809DCB008FEC33 /* juce_StandardHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90B10403681006A1807 /* juce_StandardHeader.h */; }; + 84816F6310809DCB008FEC33 /* juce_StretchableLayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAB510403709006A1807 /* juce_StretchableLayoutManager.h */; }; + 84816F6410809DCB008FEC33 /* juce_StretchableLayoutResizerBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAB710403709006A1807 /* juce_StretchableLayoutResizerBar.h */; }; + 84816F6510809DCB008FEC33 /* juce_StretchableObjectResizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAB910403709006A1807 /* juce_StretchableObjectResizer.h */; }; + 84816F6610809DCB008FEC33 /* juce_String.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9CF104036D6006A1807 /* juce_String.h */; }; + 84816F6710809DCB008FEC33 /* juce_StringArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9D1104036D6006A1807 /* juce_StringArray.h */; }; + 84816F6810809DCB008FEC33 /* juce_StringPairArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9D3104036D6006A1807 /* juce_StringPairArray.h */; }; + 84816F6910809DCB008FEC33 /* juce_SubregionStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9AC104036D6006A1807 /* juce_SubregionStream.h */; }; + 84816F6A10809DCB008FEC33 /* juce_Synthesiser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7EE10403615006A1807 /* juce_Synthesiser.h */; }; + 84816F6B10809DCB008FEC33 /* juce_SystemClipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9271040369C006A1807 /* juce_SystemClipboard.h */; }; + 84816F6C10809DCB008FEC33 /* juce_SystemStats.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8F610403681006A1807 /* juce_SystemStats.h */; }; + 84816F6D10809DCB008FEC33 /* juce_SystemTrayIconComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0410403709006A1807 /* juce_SystemTrayIconComponent.h */; }; + 84816F6E10809DCB008FEC33 /* juce_TabbedButtonBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EABB10403709006A1807 /* juce_TabbedButtonBar.h */; }; + 84816F6F10809DCB008FEC33 /* juce_TabbedComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EABD10403709006A1807 /* juce_TabbedComponent.h */; }; + 84816F7010809DCB008FEC33 /* juce_TableHeaderComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6D10403709006A1807 /* juce_TableHeaderComponent.h */; }; + 84816F7110809DCB008FEC33 /* juce_TableListBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA6F10403709006A1807 /* juce_TableListBox.h */; }; + 84816F7210809DCB008FEC33 /* juce_TextButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5B10403709006A1807 /* juce_TextButton.h */; }; + 84816F7310809DCB008FEC33 /* juce_TextEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7110403709006A1807 /* juce_TextEditor.h */; }; + 84816F7410809DCB008FEC33 /* juce_TextLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5310403709006A1807 /* juce_TextLayout.h */; }; + 84816F7510809DCB008FEC33 /* juce_TextPropertyComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EAEC10403709006A1807 /* juce_TextPropertyComponent.h */; }; + 84816F7610809DCB008FEC33 /* juce_Thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9E4104036D6006A1807 /* juce_Thread.h */; }; + 84816F7710809DCB008FEC33 /* juce_ThreadPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9E6104036D6006A1807 /* juce_ThreadPool.h */; }; + 84816F7810809DCB008FEC33 /* juce_ThreadWithProgressWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1410403709006A1807 /* juce_ThreadWithProgressWindow.h */; }; + 84816F7910809DCB008FEC33 /* juce_Time.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8F310403681006A1807 /* juce_Time.h */; }; + 84816F7A10809DCB008FEC33 /* juce_Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E964104036B3006A1807 /* juce_Timer.h */; }; + 84816F7B10809DCB008FEC33 /* juce_TimeSliceThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9E8104036D6006A1807 /* juce_TimeSliceThread.h */; }; + 84816F7C10809DCB008FEC33 /* juce_ToggleButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5D10403709006A1807 /* juce_ToggleButton.h */; }; + 84816F7D10809DCB008FEC33 /* juce_ToneGeneratorAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7A610403614006A1807 /* juce_ToneGeneratorAudioSource.h */; }; + 84816F7E10809DCB008FEC33 /* juce_Toolbar.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7310403709006A1807 /* juce_Toolbar.h */; }; + 84816F7F10809DCB008FEC33 /* juce_ToolbarButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA5F10403709006A1807 /* juce_ToolbarButton.h */; }; + 84816F8010809DCB008FEC33 /* juce_ToolbarItemComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7510403709006A1807 /* juce_ToolbarItemComponent.h */; }; + 84816F8110809DCB008FEC33 /* juce_ToolbarItemFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7610403709006A1807 /* juce_ToolbarItemFactory.h */; }; + 84816F8210809DCB008FEC33 /* juce_ToolbarItemPalette.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7810403709006A1807 /* juce_ToolbarItemPalette.h */; }; + 84816F8310809DCB008FEC33 /* juce_TooltipClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EADD10403709006A1807 /* juce_TooltipClient.h */; }; + 84816F8410809DCB008FEC33 /* juce_TooltipWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1610403709006A1807 /* juce_TooltipWindow.h */; }; + 84816F8510809DCB008FEC33 /* juce_TopLevelWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB1810403709006A1807 /* juce_TopLevelWindow.h */; }; + 84816F8610809DCB008FEC33 /* juce_TreeView.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA7A10403709006A1807 /* juce_TreeView.h */; }; + 84816F8710809DCB008FEC33 /* juce_Typeface.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB5510403709006A1807 /* juce_Typeface.h */; }; + 84816F8810809DCB008FEC33 /* juce_UndoableAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E92A1040369C006A1807 /* juce_UndoableAction.h */; }; + 84816F8910809DCB008FEC33 /* juce_UndoManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9261040369C006A1807 /* juce_UndoManager.h */; }; + 84816F8A10809DCB008FEC33 /* juce_URL.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E99C104036D6006A1807 /* juce_URL.h */; }; + 84816F8B10809DCB008FEC33 /* juce_Uuid.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E90710403681006A1807 /* juce_Uuid.h */; }; + 84816F8C10809DCB008FEC33 /* juce_Variant.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8DF10403671006A1807 /* juce_Variant.h */; }; + 84816F8D10809DCB008FEC33 /* juce_Viewport.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EABF10403709006A1807 /* juce_Viewport.h */; }; + 84816F8E10809DCB008FEC33 /* juce_VoidArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E8E010403671006A1807 /* juce_VoidArray.h */; }; + 84816F8F10809DCB008FEC33 /* juce_VSTMidiEventList.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7D810403614006A1807 /* juce_VSTMidiEventList.h */; }; + 84816F9010809DCB008FEC33 /* juce_VSTPluginFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E7D910403614006A1807 /* juce_VSTPluginFormat.h */; }; + 84816F9110809DCB008FEC33 /* juce_WaitableEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9E9104036D6006A1807 /* juce_WaitableEvent.h */; }; + 84816F9210809DCB008FEC33 /* juce_WavAudioFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E70810403614006A1807 /* juce_WavAudioFormat.h */; }; + 84816F9310809DCB008FEC33 /* juce_WebBrowserComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EB0510403709006A1807 /* juce_WebBrowserComponent.h */; }; + 84816F9410809DCB008FEC33 /* juce_WildcardFileFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1EA9510403709006A1807 /* juce_WildcardFileFilter.h */; }; + 84816F9510809DCB008FEC33 /* juce_XmlDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9D5104036D6006A1807 /* juce_XmlDocument.h */; }; + 84816F9610809DCB008FEC33 /* juce_XmlElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E9D7104036D6006A1807 /* juce_XmlElement.h */; }; + 84816F9710809DCB008FEC33 /* juce_ZipFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E997104036D6006A1807 /* juce_ZipFile.h */; }; + 84816F9810809E00008FEC33 /* juce_ActionBroadcaster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E94A104036B3006A1807 /* juce_ActionBroadcaster.cpp */; }; + 84816F9910809E00008FEC33 /* juce_ActionListenerList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E94D104036B3006A1807 /* juce_ActionListenerList.cpp */; }; + 84816F9A10809E00008FEC33 /* juce_AffineTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5710403709006A1807 /* juce_AffineTransform.cpp */; }; + 84816F9B10809E00008FEC33 /* juce_AiffAudioFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6F410403614006A1807 /* juce_AiffAudioFormat.cpp */; }; + 84816F9C10809E00008FEC33 /* juce_AlertWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB0710403709006A1807 /* juce_AlertWindow.cpp */; }; + 84816F9D10809E00008FEC33 /* juce_Application.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6DC10403605006A1807 /* juce_Application.cpp */; }; + 84816F9E10809E00008FEC33 /* juce_ApplicationCommandInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6DF10403605006A1807 /* juce_ApplicationCommandInfo.cpp */; }; + 84816F9F10809E00008FEC33 /* juce_ApplicationCommandManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6E110403605006A1807 /* juce_ApplicationCommandManager.cpp */; }; + 84816FA010809E00008FEC33 /* juce_ApplicationCommandTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6E310403605006A1807 /* juce_ApplicationCommandTarget.cpp */; }; + 84816FA110809E00008FEC33 /* juce_ApplicationProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6E510403605006A1807 /* juce_ApplicationProperties.cpp */; }; + 84816FA210809E00008FEC33 /* juce_ArrowButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA4E10403708006A1807 /* juce_ArrowButton.cpp */; }; + 84816FA310809E00008FEC33 /* juce_AsyncUpdater.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E94F104036B3006A1807 /* juce_AsyncUpdater.cpp */; }; + 84816FA410809E00008FEC33 /* juce_AudioCDReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6F710403614006A1807 /* juce_AudioCDReader.cpp */; }; + 84816FA510809E00008FEC33 /* juce_AudioDataConverters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7B210403614006A1807 /* juce_AudioDataConverters.cpp */; }; + 84816FA610809E00008FEC33 /* juce_AudioDeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7A810403614006A1807 /* juce_AudioDeviceManager.cpp */; }; + 84816FA710809E00008FEC33 /* juce_AudioDeviceSelectorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAEF10403709006A1807 /* juce_AudioDeviceSelectorComponent.cpp */; }; + 84816FA810809E00008FEC33 /* juce_AudioFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6F910403614006A1807 /* juce_AudioFormat.cpp */; }; + 84816FA910809E00008FEC33 /* juce_AudioFormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6FB10403614006A1807 /* juce_AudioFormatManager.cpp */; }; + 84816FAA10809E00008FEC33 /* juce_AudioFormatReaderSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E79310403614006A1807 /* juce_AudioFormatReaderSource.cpp */; }; + 84816FAB10809E00008FEC33 /* juce_AudioIODevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7AA10403614006A1807 /* juce_AudioIODevice.cpp */; }; + 84816FAC10809E00008FEC33 /* juce_AudioIODeviceType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7AC10403614006A1807 /* juce_AudioIODeviceType.cpp */; }; + 84816FAD10809E00008FEC33 /* juce_AudioPluginFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7C610403614006A1807 /* juce_AudioPluginFormat.cpp */; }; + 84816FAE10809E00008FEC33 /* juce_AudioPluginFormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7C810403614006A1807 /* juce_AudioPluginFormatManager.cpp */; }; + 84816FAF10809E00008FEC33 /* juce_AudioPluginInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7CA10403614006A1807 /* juce_AudioPluginInstance.cpp */; }; + 84816FB010809E00008FEC33 /* juce_AudioProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7DF10403615006A1807 /* juce_AudioProcessor.cpp */; }; + 84816FB110809E00008FEC33 /* juce_AudioProcessorEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7E110403615006A1807 /* juce_AudioProcessorEditor.cpp */; }; + 84816FB210809E00008FEC33 /* juce_AudioProcessorGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7E310403615006A1807 /* juce_AudioProcessorGraph.cpp */; }; + 84816FB310809E00008FEC33 /* juce_AudioProcessorPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7E610403615006A1807 /* juce_AudioProcessorPlayer.cpp */; }; + 84816FB410809E00008FEC33 /* juce_AudioSampleBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7B410403614006A1807 /* juce_AudioSampleBuffer.cpp */; }; + 84816FB510809E00008FEC33 /* juce_AudioSourcePlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E79610403614006A1807 /* juce_AudioSourcePlayer.cpp */; }; + 84816FB610809E00008FEC33 /* juce_AudioSubsectionReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6FF10403614006A1807 /* juce_AudioSubsectionReader.cpp */; }; + 84816FB710809E00008FEC33 /* juce_AudioThumbnail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E70110403614006A1807 /* juce_AudioThumbnail.cpp */; }; + 84816FB810809E00008FEC33 /* juce_AudioThumbnailCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E70310403614006A1807 /* juce_AudioThumbnailCache.cpp */; }; + 84816FB910809E00008FEC33 /* juce_AudioTransportSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E79810403614006A1807 /* juce_AudioTransportSource.cpp */; }; + 84816FBA10809E00008FEC33 /* juce_AudioUnitPluginFormat.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7DC10403614006A1807 /* juce_AudioUnitPluginFormat.mm */; }; + 84816FBB10809E00008FEC33 /* juce_BitArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8D210403671006A1807 /* juce_BitArray.cpp */; }; + 84816FBC10809E00008FEC33 /* juce_BlowFish.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E941104036B3006A1807 /* juce_BlowFish.cpp */; }; + 84816FBD10809E00008FEC33 /* juce_BooleanPropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EADF10403709006A1807 /* juce_BooleanPropertyComponent.cpp */; }; + 84816FBE10809E00008FEC33 /* juce_BorderSize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5910403709006A1807 /* juce_BorderSize.cpp */; }; + 84816FBF10809E00008FEC33 /* juce_Brush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1B10403709006A1807 /* juce_Brush.cpp */; }; + 84816FC010809E00008FEC33 /* juce_BubbleComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAF110403709006A1807 /* juce_BubbleComponent.cpp */; }; + 84816FC110809E00008FEC33 /* juce_BubbleMessageComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAF310403709006A1807 /* juce_BubbleMessageComponent.cpp */; }; + 84816FC210809E00008FEC33 /* juce_BufferedInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E99E104036D6006A1807 /* juce_BufferedInputStream.cpp */; }; + 84816FC310809E00008FEC33 /* juce_BufferingAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E79A10403614006A1807 /* juce_BufferingAudioSource.cpp */; }; + 84816FC410809E00008FEC33 /* juce_Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5010403708006A1807 /* juce_Button.cpp */; }; + 84816FC510809E00008FEC33 /* juce_ButtonPropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAE110403709006A1807 /* juce_ButtonPropertyComponent.cpp */; }; + 84816FC610809E00008FEC33 /* juce_ChangeBroadcaster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E952104036B3006A1807 /* juce_ChangeBroadcaster.cpp */; }; + 84816FC710809E00008FEC33 /* juce_ChangeListenerList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E955104036B3006A1807 /* juce_ChangeListenerList.cpp */; }; + 84816FC810809E00008FEC33 /* juce_ChannelRemappingAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E79C10403614006A1807 /* juce_ChannelRemappingAudioSource.cpp */; }; + 84816FC910809E00008FEC33 /* juce_CharacterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9CA104036D6006A1807 /* juce_CharacterFunctions.cpp */; }; + 84816FCA10809E00008FEC33 /* juce_ChoicePropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAE310403709006A1807 /* juce_ChoicePropertyComponent.cpp */; }; + 84816FCB10809E00008FEC33 /* juce_Colour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2410403709006A1807 /* juce_Colour.cpp */; }; + 84816FCC10809E00008FEC33 /* juce_ColourGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2510403709006A1807 /* juce_ColourGradient.cpp */; }; + 84816FCD10809E00008FEC33 /* juce_Colours.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2710403709006A1807 /* juce_Colours.cpp */; }; + 84816FCE10809E00008FEC33 /* juce_ColourSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAF510403709006A1807 /* juce_ColourSelector.cpp */; }; + 84816FCF10809E00008FEC33 /* juce_ComboBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6110403709006A1807 /* juce_ComboBox.cpp */; }; + 84816FD010809E00008FEC33 /* juce_Component.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA4610403708006A1807 /* juce_Component.cpp */; }; + 84816FD110809E00008FEC33 /* juce_ComponentAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAA410403709006A1807 /* juce_ComponentAnimator.cpp */; }; + 84816FD210809E00008FEC33 /* juce_ComponentBoundsConstrainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAA610403709006A1807 /* juce_ComponentBoundsConstrainer.cpp */; }; + 84816FD310809E00008FEC33 /* juce_ComponentDragger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EACE10403709006A1807 /* juce_ComponentDragger.cpp */; }; + 84816FD410809E00008FEC33 /* juce_ComponentListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA4910403708006A1807 /* juce_ComponentListener.cpp */; }; + 84816FD510809E00008FEC33 /* juce_ComponentMovementWatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAA810403709006A1807 /* juce_ComponentMovementWatcher.cpp */; }; + 84816FD610809E00008FEC33 /* juce_ComponentPeer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB0910403709006A1807 /* juce_ComponentPeer.cpp */; }; + 84816FD710809E00008FEC33 /* juce_DeletedAtShutdown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9321040369C006A1807 /* juce_DeletedAtShutdown.cpp */; }; + 84816FD810809E00008FEC33 /* juce_Desktop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA4B10403708006A1807 /* juce_Desktop.cpp */; }; + 84816FD910809E00008FEC33 /* juce_DialogWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB0B10403709006A1807 /* juce_DialogWindow.cpp */; }; + 84816FDA10809E00008FEC33 /* juce_DirectoryContentsDisplayComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA7C10403709006A1807 /* juce_DirectoryContentsDisplayComponent.cpp */; }; + 84816FDB10809E00008FEC33 /* juce_DirectoryContentsList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA7E10403709006A1807 /* juce_DirectoryContentsList.cpp */; }; + 84816FDC10809E00008FEC33 /* juce_DirectoryIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E98A104036D6006A1807 /* juce_DirectoryIterator.cpp */; }; + 84816FDD10809E00008FEC33 /* juce_DocumentWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB0D10403709006A1807 /* juce_DocumentWindow.cpp */; }; + 84816FDE10809E00008FEC33 /* juce_DragAndDropContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAD010403709006A1807 /* juce_DragAndDropContainer.cpp */; }; + 84816FDF10809E00008FEC33 /* juce_Drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB3A10403709006A1807 /* juce_Drawable.cpp */; }; + 84816FE010809E00008FEC33 /* juce_DrawableButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5210403708006A1807 /* juce_DrawableButton.cpp */; }; + 84816FE110809E00008FEC33 /* juce_DrawableComposite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB3C10403709006A1807 /* juce_DrawableComposite.cpp */; }; + 84816FE210809E00008FEC33 /* juce_DrawableImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB3E10403709006A1807 /* juce_DrawableImage.cpp */; }; + 84816FE310809E00008FEC33 /* juce_DrawablePath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4010403709006A1807 /* juce_DrawablePath.cpp */; }; + 84816FE410809E00008FEC33 /* juce_DrawableText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4210403709006A1807 /* juce_DrawableText.cpp */; }; + 84816FE510809E00008FEC33 /* juce_DropShadowEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4610403709006A1807 /* juce_DropShadowEffect.cpp */; }; + 84816FE610809E00008FEC33 /* juce_DropShadower.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAF710403709006A1807 /* juce_DropShadower.cpp */; }; + 84816FE710809E00008FEC33 /* juce_EdgeTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2C10403709006A1807 /* juce_EdgeTable.cpp */; }; + 84816FE810809E00008FEC33 /* juce_File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E98C104036D6006A1807 /* juce_File.cpp */; }; + 84816FE910809E00008FEC33 /* juce_FileBasedDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9311040369C006A1807 /* juce_FileBasedDocument.cpp */; }; + 84816FEA10809E00008FEC33 /* juce_FileBrowserComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA8010403709006A1807 /* juce_FileBrowserComponent.cpp */; }; + 84816FEB10809E00008FEC33 /* juce_FileChooser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA8310403709006A1807 /* juce_FileChooser.cpp */; }; + 84816FEC10809E00008FEC33 /* juce_FileChooserDialogBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA8510403709006A1807 /* juce_FileChooserDialogBox.cpp */; }; + 84816FED10809E00008FEC33 /* juce_FileFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA8710403709006A1807 /* juce_FileFilter.cpp */; }; + 84816FEE10809E00008FEC33 /* juce_FileInputSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9A0104036D6006A1807 /* juce_FileInputSource.cpp */; }; + 84816FEF10809E00008FEC33 /* juce_FileInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E98E104036D6006A1807 /* juce_FileInputStream.cpp */; }; + 84816FF010809E00008FEC33 /* juce_FileListComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA8910403709006A1807 /* juce_FileListComponent.cpp */; }; + 84816FF110809E00008FEC33 /* juce_FileLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E90310403681006A1807 /* juce_FileLogger.cpp */; }; + 84816FF210809E00008FEC33 /* juce_FilenameComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA8B10403709006A1807 /* juce_FilenameComponent.cpp */; }; + 84816FF310809E00008FEC33 /* juce_FileOutputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E990104036D6006A1807 /* juce_FileOutputStream.cpp */; }; + 84816FF410809E00008FEC33 /* juce_FileSearchPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E992104036D6006A1807 /* juce_FileSearchPath.cpp */; }; + 84816FF510809E00008FEC33 /* juce_FileSearchPathListComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA8E10403709006A1807 /* juce_FileSearchPathListComponent.cpp */; }; + 84816FF610809E00008FEC33 /* juce_FileTreeComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9010403709006A1807 /* juce_FileTreeComponent.cpp */; }; + 84816FF710809E00008FEC33 /* juce_FlacAudioFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E70B10403614006A1807 /* juce_FlacAudioFormat.cpp */; }; + 84816FF810809E00008FEC33 /* juce_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4E10403709006A1807 /* juce_Font.cpp */; }; + 84816FF910809E00008FEC33 /* juce_GenericAudioProcessorEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7E810403615006A1807 /* juce_GenericAudioProcessorEditor.cpp */; }; + 84816FFA10809E00008FEC33 /* juce_GIFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7610403709006A1807 /* juce_GIFLoader.cpp */; }; + 84816FFB10809E00008FEC33 /* juce_GlowEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4810403709006A1807 /* juce_GlowEffect.cpp */; }; + 84816FFC10809E00008FEC33 /* juce_GlyphArrangement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5010403709006A1807 /* juce_GlyphArrangement.cpp */; }; + 84816FFD10809E00008FEC33 /* juce_GradientBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1D10403709006A1807 /* juce_GradientBrush.cpp */; }; + 84816FFE10809E00008FEC33 /* juce_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2E10403709006A1807 /* juce_Graphics.cpp */; }; + 84816FFF10809E00008FEC33 /* juce_GroupComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAAA10403709006A1807 /* juce_GroupComponent.cpp */; }; + 8481700010809E00008FEC33 /* juce_GZIPCompressorOutputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9A2104036D6006A1807 /* juce_GZIPCompressorOutputStream.cpp */; }; + 8481700110809E00008FEC33 /* juce_GZIPDecompressorInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9A4104036D6006A1807 /* juce_GZIPDecompressorInputStream.cpp */; }; + 8481700210809E00008FEC33 /* juce_HyperlinkButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5410403708006A1807 /* juce_HyperlinkButton.cpp */; }; + 8481700310809E00008FEC33 /* juce_IIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7B610403614006A1807 /* juce_IIRFilter.cpp */; }; + 8481700410809E00008FEC33 /* juce_IIRFilterAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E79E10403614006A1807 /* juce_IIRFilterAudioSource.cpp */; }; + 8481700510809E00008FEC33 /* juce_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6D10403709006A1807 /* juce_Image.cpp */; }; + 8481700610809E00008FEC33 /* juce_ImageBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1F10403709006A1807 /* juce_ImageBrush.cpp */; }; + 8481700710809E00008FEC33 /* juce_ImageButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5610403709006A1807 /* juce_ImageButton.cpp */; }; + 8481700810809E00008FEC33 /* juce_ImageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6F10403709006A1807 /* juce_ImageCache.cpp */; }; + 8481700910809E00008FEC33 /* juce_ImageConvolutionKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7110403709006A1807 /* juce_ImageConvolutionKernel.cpp */; }; + 8481700A10809E00008FEC33 /* juce_ImageFileFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7310403709006A1807 /* juce_ImageFileFormat.cpp */; }; + 8481700B10809E00008FEC33 /* juce_ImagePreviewComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9210403709006A1807 /* juce_ImagePreviewComponent.cpp */; }; + 8481700C10809E00008FEC33 /* juce_InputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9C5104036D6006A1807 /* juce_InputStream.cpp */; }; + 8481700D10809E00008FEC33 /* juce_InterprocessConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E957104036B3006A1807 /* juce_InterprocessConnection.cpp */; }; + 8481700E10809E00008FEC33 /* juce_InterprocessConnectionServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E959104036B3006A1807 /* juce_InterprocessConnectionServer.cpp */; }; + 8481700F10809E00008FEC33 /* juce_InterProcessLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9DA104036D6006A1807 /* juce_InterProcessLock.cpp */; }; + 8481701010809E00008FEC33 /* juce_iphone_Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */; }; + 8481701110809E00008FEC33 /* juce_iphone_Fonts.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5210809D07008FEC33 /* juce_iphone_Fonts.mm */; }; + 8481701210809E00008FEC33 /* juce_iphone_MessageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */; }; + 8481701310809E00008FEC33 /* juce_iphone_MiscUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5410809D07008FEC33 /* juce_iphone_MiscUtilities.mm */; }; + 8481701410809E00008FEC33 /* juce_iphone_UIViewComponentPeer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5610809D07008FEC33 /* juce_iphone_UIViewComponentPeer.mm */; }; + 8481701510809E00008FEC33 /* juce_JPEGLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7810403709006A1807 /* juce_JPEGLoader.cpp */; }; + 8481701610809E00008FEC33 /* juce_Justification.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB3010403709006A1807 /* juce_Justification.cpp */; }; + 8481701710809E00008FEC33 /* juce_KeyboardFocusTraverser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9710403709006A1807 /* juce_KeyboardFocusTraverser.cpp */; }; + 8481701810809E00008FEC33 /* juce_KeyListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9910403709006A1807 /* juce_KeyListener.cpp */; }; + 8481701910809E00008FEC33 /* juce_KeyMappingEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9B10403709006A1807 /* juce_KeyMappingEditorComponent.cpp */; }; + 8481701A10809E00008FEC33 /* juce_KeyPress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9D10403709006A1807 /* juce_KeyPress.cpp */; }; + 8481701B10809E00008FEC33 /* juce_KeyPressMappingSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9F10403709006A1807 /* juce_KeyPressMappingSet.cpp */; }; + 8481701C10809E00008FEC33 /* juce_KnownPluginList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7CC10403614006A1807 /* juce_KnownPluginList.cpp */; }; + 8481701D10809E00008FEC33 /* juce_Label.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6310403709006A1807 /* juce_Label.cpp */; }; + 8481701E10809E00008FEC33 /* juce_Line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5B10403709006A1807 /* juce_Line.cpp */; }; + 8481701F10809E00008FEC33 /* juce_ListBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6510403709006A1807 /* juce_ListBox.cpp */; }; + 8481702010809E00008FEC33 /* juce_LocalisedStrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9CC104036D6006A1807 /* juce_LocalisedStrings.cpp */; }; + 8481702110809E00008FEC33 /* juce_Logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E90010403681006A1807 /* juce_Logger.cpp */; }; + 8481702210809E00008FEC33 /* juce_LookAndFeel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAC110403709006A1807 /* juce_LookAndFeel.cpp */; }; + 8481702310809E00008FEC33 /* juce_LowLevelGraphicsPostScriptRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB3310403709006A1807 /* juce_LowLevelGraphicsPostScriptRenderer.cpp */; }; + 8481702410809E00008FEC33 /* juce_LowLevelGraphicsSoftwareRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB3510403709006A1807 /* juce_LowLevelGraphicsSoftwareRenderer.cpp */; }; + 8481702510809E00008FEC33 /* juce_mac_AppleRemote.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9A6103C9595008B7C6C /* juce_mac_AppleRemote.mm */; }; + 8481702610809E00008FEC33 /* juce_mac_AudioCDBurner.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9A7103C9595008B7C6C /* juce_mac_AudioCDBurner.mm */; }; + 8481702710809E00008FEC33 /* juce_mac_CameraDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9A8103C9595008B7C6C /* juce_mac_CameraDevice.mm */; }; + 8481702810809E00008FEC33 /* juce_mac_CoreAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9AA103C9595008B7C6C /* juce_mac_CoreAudio.cpp */; }; + 8481702910809E00008FEC33 /* juce_mac_CoreMidi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9AB103C9595008B7C6C /* juce_mac_CoreMidi.cpp */; }; + 8481702A10809E00008FEC33 /* juce_mac_Debugging.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9AC103C9595008B7C6C /* juce_mac_Debugging.mm */; }; + 8481702B10809E00008FEC33 /* juce_mac_FileChooser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9AD103C9595008B7C6C /* juce_mac_FileChooser.mm */; }; + 8481702C10809E00008FEC33 /* juce_mac_Files.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9AE103C9595008B7C6C /* juce_mac_Files.mm */; }; + 8481702D10809E00008FEC33 /* juce_mac_Fonts.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9AF103C9595008B7C6C /* juce_mac_Fonts.mm */; }; + 8481702E10809E00008FEC33 /* juce_mac_MainMenu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B0103C9595008B7C6C /* juce_mac_MainMenu.mm */; }; + 8481702F10809E00008FEC33 /* juce_mac_MessageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B1103C9595008B7C6C /* juce_mac_MessageManager.mm */; }; + 8481703010809E00008FEC33 /* juce_mac_MiscUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B2103C9595008B7C6C /* juce_mac_MiscUtilities.mm */; }; + 8481703110809E00008FEC33 /* juce_mac_MouseCursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B3103C9595008B7C6C /* juce_mac_MouseCursor.mm */; }; + 8481703210809E00008FEC33 /* juce_mac_NativeCode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9A4103C958A008B7C6C /* juce_mac_NativeCode.mm */; }; + 8481703310809E00008FEC33 /* juce_mac_Network.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B5103C9595008B7C6C /* juce_mac_Network.mm */; }; + 8481703410809E00008FEC33 /* juce_mac_NSViewComponent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B6103C9595008B7C6C /* juce_mac_NSViewComponent.mm */; }; + 8481703510809E00008FEC33 /* juce_mac_NSViewComponentPeer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B7103C9595008B7C6C /* juce_mac_NSViewComponentPeer.mm */; }; + 8481703610809E00008FEC33 /* juce_mac_OpenGLComponent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B8103C9595008B7C6C /* juce_mac_OpenGLComponent.mm */; }; + 8481703710809E00008FEC33 /* juce_mac_QuickTimeMovieComponent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9B9103C9595008B7C6C /* juce_mac_QuickTimeMovieComponent.mm */; }; + 8481703810809E00008FEC33 /* juce_mac_Strings.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9BA103C9595008B7C6C /* juce_mac_Strings.mm */; }; + 8481703910809E00008FEC33 /* juce_mac_SystemStats.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9BB103C9595008B7C6C /* juce_mac_SystemStats.mm */; }; + 8481703A10809E00008FEC33 /* juce_mac_Threads.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9BC103C9595008B7C6C /* juce_mac_Threads.mm */; }; + 8481703B10809E00008FEC33 /* juce_mac_WebBrowserComponent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9BD103C9595008B7C6C /* juce_mac_WebBrowserComponent.mm */; }; + 8481703C10809E00008FEC33 /* juce_MagnifierComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAF910403709006A1807 /* juce_MagnifierComponent.cpp */; }; + 8481703D10809E00008FEC33 /* juce_MD5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E943104036B3006A1807 /* juce_MD5.cpp */; }; + 8481703E10809E00008FEC33 /* juce_MemoryBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8D510403671006A1807 /* juce_MemoryBlock.cpp */; }; + 8481703F10809E00008FEC33 /* juce_MemoryInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9A7104036D6006A1807 /* juce_MemoryInputStream.cpp */; }; + 8481704010809E00008FEC33 /* juce_MemoryOutputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9A9104036D6006A1807 /* juce_MemoryOutputStream.cpp */; }; + 8481704110809E00008FEC33 /* juce_MenuBarComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAC610403709006A1807 /* juce_MenuBarComponent.cpp */; }; + 8481704210809E00008FEC33 /* juce_MenuBarModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAC810403709006A1807 /* juce_MenuBarModel.cpp */; }; + 8481704310809E00008FEC33 /* juce_Message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E95B104036B3006A1807 /* juce_Message.cpp */; }; + 8481704410809E00008FEC33 /* juce_MessageListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E95D104036B3006A1807 /* juce_MessageListener.cpp */; }; + 8481704510809E00008FEC33 /* juce_MessageManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E95F104036B3006A1807 /* juce_MessageManager.cpp */; }; + 8481704610809E00008FEC33 /* juce_MidiBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7B910403614006A1807 /* juce_MidiBuffer.cpp */; }; + 8481704710809E00008FEC33 /* juce_MidiFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7BB10403614006A1807 /* juce_MidiFile.cpp */; }; + 8481704810809E00008FEC33 /* juce_MidiKeyboardComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAFB10403709006A1807 /* juce_MidiKeyboardComponent.cpp */; }; + 8481704910809E00008FEC33 /* juce_MidiKeyboardState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7BD10403614006A1807 /* juce_MidiKeyboardState.cpp */; }; + 8481704A10809E00008FEC33 /* juce_MidiMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7BF10403614006A1807 /* juce_MidiMessage.cpp */; }; + 8481704B10809E00008FEC33 /* juce_MidiMessageCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7C110403614006A1807 /* juce_MidiMessageCollector.cpp */; }; + 8481704C10809E00008FEC33 /* juce_MidiMessageSequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7C310403614006A1807 /* juce_MidiMessageSequence.cpp */; }; + 8481704D10809E00008FEC33 /* juce_MidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7AF10403614006A1807 /* juce_MidiOutput.cpp */; }; + 8481704E10809E00008FEC33 /* juce_MixerAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7A010403614006A1807 /* juce_MixerAudioSource.cpp */; }; + 8481704F10809E00008FEC33 /* juce_ModifierKeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAA110403709006A1807 /* juce_ModifierKeys.cpp */; }; + 8481705010809E00008FEC33 /* juce_MouseCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAD610403709006A1807 /* juce_MouseCursor.cpp */; }; + 8481705110809E00008FEC33 /* juce_MouseEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAD810403709006A1807 /* juce_MouseEvent.cpp */; }; + 8481705210809E00008FEC33 /* juce_MouseHoverDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EADA10403709006A1807 /* juce_MouseHoverDetector.cpp */; }; + 8481705310809E00008FEC33 /* juce_MouseListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EADC10403709006A1807 /* juce_MouseListener.cpp */; }; + 8481705410809E00008FEC33 /* juce_MultiDocumentPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAAC10403709006A1807 /* juce_MultiDocumentPanel.cpp */; }; + 8481705510809E00008FEC33 /* juce_MultiTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E961104036B3006A1807 /* juce_MultiTimer.cpp */; }; + 8481705610809E00008FEC33 /* juce_NamedPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E994104036D6006A1807 /* juce_NamedPipe.cpp */; }; + 8481705710809E00008FEC33 /* juce_OggVorbisAudioFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E70C10403614006A1807 /* juce_OggVorbisAudioFormat.cpp */; }; + 8481705810809E00008FEC33 /* juce_OldSchoolLookAndFeel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAC310403709006A1807 /* juce_OldSchoolLookAndFeel.cpp */; }; + 8481705910809E00008FEC33 /* juce_OpenGLComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAFE10403709006A1807 /* juce_OpenGLComponent.cpp */; }; + 8481705A10809E00008FEC33 /* juce_OutputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9C7104036D6006A1807 /* juce_OutputStream.cpp */; }; + 8481705B10809E00008FEC33 /* juce_Path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5D10403709006A1807 /* juce_Path.cpp */; }; + 8481705C10809E00008FEC33 /* juce_PathIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5F10403709006A1807 /* juce_PathIterator.cpp */; }; + 8481705D10809E00008FEC33 /* juce_PathStrokeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6110403709006A1807 /* juce_PathStrokeType.cpp */; }; + 8481705E10809E00008FEC33 /* juce_PerformanceCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E90810403681006A1807 /* juce_PerformanceCounter.cpp */; }; + 8481705F10809E00008FEC33 /* juce_PluginDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7CE10403614006A1807 /* juce_PluginDescription.cpp */; }; + 8481706010809E00008FEC33 /* juce_PluginDirectoryScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7D010403614006A1807 /* juce_PluginDirectoryScanner.cpp */; }; + 8481706110809E00008FEC33 /* juce_PluginListComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7D210403614006A1807 /* juce_PluginListComponent.cpp */; }; + 8481706210809E00008FEC33 /* juce_PNGLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB7910403709006A1807 /* juce_PNGLoader.cpp */; }; + 8481706310809E00008FEC33 /* juce_Point.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6310403709006A1807 /* juce_Point.cpp */; }; + 8481706410809E00008FEC33 /* juce_PopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EACA10403709006A1807 /* juce_PopupMenu.cpp */; }; + 8481706510809E00008FEC33 /* juce_PositionedRectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6510403709006A1807 /* juce_PositionedRectangle.cpp */; }; + 8481706610809E00008FEC33 /* juce_posix_NamedPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9D7103C95A6008B7C6C /* juce_posix_NamedPipe.cpp */; }; + 8481706710809E00008FEC33 /* juce_PreferencesPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB0010403709006A1807 /* juce_PreferencesPanel.cpp */; }; + 8481706810809E00008FEC33 /* juce_Primes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E945104036B3006A1807 /* juce_Primes.cpp */; }; + 8481706910809E00008FEC33 /* juce_ProgressBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6710403709006A1807 /* juce_ProgressBar.cpp */; }; + 8481706A10809E00008FEC33 /* juce_PropertiesFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E92D1040369C006A1807 /* juce_PropertiesFile.cpp */; }; + 8481706B10809E00008FEC33 /* juce_PropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAE510403709006A1807 /* juce_PropertyComponent.cpp */; }; + 8481706C10809E00008FEC33 /* juce_PropertyPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAE710403709006A1807 /* juce_PropertyPanel.cpp */; }; + 8481706D10809E00008FEC33 /* juce_PropertySet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8D810403671006A1807 /* juce_PropertySet.cpp */; }; + 8481706E10809E00008FEC33 /* juce_QuickTimeAudioFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E70A10403614006A1807 /* juce_QuickTimeAudioFormat.cpp */; }; + 8481706F10809E00008FEC33 /* juce_Random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8FB10403681006A1807 /* juce_Random.cpp */; }; + 8481707010809E00008FEC33 /* juce_ReadWriteLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9DD104036D6006A1807 /* juce_ReadWriteLock.cpp */; }; + 8481707110809E00008FEC33 /* juce_RecentlyOpenedFilesList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9301040369C006A1807 /* juce_RecentlyOpenedFilesList.cpp */; }; + 8481707210809E00008FEC33 /* juce_Rectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6710403709006A1807 /* juce_Rectangle.cpp */; }; + 8481707310809E00008FEC33 /* juce_RectangleList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB6910403709006A1807 /* juce_RectangleList.cpp */; }; + 8481707410809E00008FEC33 /* juce_RectanglePlacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB3710403709006A1807 /* juce_RectanglePlacement.cpp */; }; + 8481707510809E00008FEC33 /* juce_ReduceOpacityEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4B10403709006A1807 /* juce_ReduceOpacityEffect.cpp */; }; + 8481707610809E00008FEC33 /* juce_RelativeTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8F810403681006A1807 /* juce_RelativeTime.cpp */; }; + 8481707710809E00008FEC33 /* juce_ResamplingAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7A310403614006A1807 /* juce_ResamplingAudioSource.cpp */; }; + 8481707810809E00008FEC33 /* juce_ResizableBorderComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAAE10403709006A1807 /* juce_ResizableBorderComponent.cpp */; }; + 8481707910809E00008FEC33 /* juce_ResizableCornerComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAB010403709006A1807 /* juce_ResizableCornerComponent.cpp */; }; + 8481707A10809E00008FEC33 /* juce_ResizableWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB0F10403709006A1807 /* juce_ResizableWindow.cpp */; }; + 8481707B10809E00008FEC33 /* juce_RSAKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E947104036B3006A1807 /* juce_RSAKey.cpp */; }; + 8481707C10809E00008FEC33 /* juce_Sampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7EB10403615006A1807 /* juce_Sampler.cpp */; }; + 8481707D10809E00008FEC33 /* juce_ScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAB210403709006A1807 /* juce_ScrollBar.cpp */; }; + 8481707E10809E00008FEC33 /* juce_ShapeButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5810403709006A1807 /* juce_ShapeButton.cpp */; }; + 8481707F10809E00008FEC33 /* juce_Slider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6910403709006A1807 /* juce_Slider.cpp */; }; + 8481708010809E00008FEC33 /* juce_SliderPropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAE910403709006A1807 /* juce_SliderPropertyComponent.cpp */; }; + 8481708110809E00008FEC33 /* juce_Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E999104036D6006A1807 /* juce_Socket.cpp */; }; + 8481708210809E00008FEC33 /* juce_SolidColourBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB2110403709006A1807 /* juce_SolidColourBrush.cpp */; }; + 8481708310809E00008FEC33 /* juce_SplashScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1110403709006A1807 /* juce_SplashScreen.cpp */; }; + 8481708410809E00008FEC33 /* juce_StretchableLayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAB410403709006A1807 /* juce_StretchableLayoutManager.cpp */; }; + 8481708510809E00008FEC33 /* juce_StretchableLayoutResizerBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAB610403709006A1807 /* juce_StretchableLayoutResizerBar.cpp */; }; + 8481708610809E00008FEC33 /* juce_StretchableObjectResizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAB810403709006A1807 /* juce_StretchableObjectResizer.cpp */; }; + 8481708710809E00008FEC33 /* juce_String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9CE104036D6006A1807 /* juce_String.cpp */; }; + 8481708810809E00008FEC33 /* juce_StringArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9D0104036D6006A1807 /* juce_StringArray.cpp */; }; + 8481708910809E00008FEC33 /* juce_StringPairArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9D2104036D6006A1807 /* juce_StringPairArray.cpp */; }; + 8481708A10809E00008FEC33 /* juce_SubregionStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9AB104036D6006A1807 /* juce_SubregionStream.cpp */; }; + 8481708B10809E00008FEC33 /* juce_SVGParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB4410403709006A1807 /* juce_SVGParser.cpp */; }; + 8481708C10809E00008FEC33 /* juce_Synthesiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7ED10403615006A1807 /* juce_Synthesiser.cpp */; }; + 8481708D10809E00008FEC33 /* juce_SystemStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8F510403681006A1807 /* juce_SystemStats.cpp */; }; + 8481708E10809E00008FEC33 /* juce_SystemTrayIconComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB0310403709006A1807 /* juce_SystemTrayIconComponent.cpp */; }; + 8481708F10809E00008FEC33 /* juce_TabbedButtonBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EABA10403709006A1807 /* juce_TabbedButtonBar.cpp */; }; + 8481709010809E00008FEC33 /* juce_TabbedComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EABC10403709006A1807 /* juce_TabbedComponent.cpp */; }; + 8481709110809E00008FEC33 /* juce_TableHeaderComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6C10403709006A1807 /* juce_TableHeaderComponent.cpp */; }; + 8481709210809E00008FEC33 /* juce_TableListBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA6E10403709006A1807 /* juce_TableListBox.cpp */; }; + 8481709310809E00008FEC33 /* juce_TextButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5A10403709006A1807 /* juce_TextButton.cpp */; }; + 8481709410809E00008FEC33 /* juce_TextEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA7010403709006A1807 /* juce_TextEditor.cpp */; }; + 8481709510809E00008FEC33 /* juce_TextLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5210403709006A1807 /* juce_TextLayout.cpp */; }; + 8481709610809E00008FEC33 /* juce_TextPropertyComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EAEB10403709006A1807 /* juce_TextPropertyComponent.cpp */; }; + 8481709710809E00008FEC33 /* juce_Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9E3104036D6006A1807 /* juce_Thread.cpp */; }; + 8481709810809E00008FEC33 /* juce_ThreadPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9E5104036D6006A1807 /* juce_ThreadPool.cpp */; }; + 8481709910809E00008FEC33 /* juce_ThreadWithProgressWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1310403709006A1807 /* juce_ThreadWithProgressWindow.cpp */; }; + 8481709A10809E00008FEC33 /* juce_Time.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8F410403681006A1807 /* juce_Time.cpp */; }; + 8481709B10809E00008FEC33 /* juce_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E963104036B3006A1807 /* juce_Timer.cpp */; }; + 8481709C10809E00008FEC33 /* juce_TimeSliceThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9E7104036D6006A1807 /* juce_TimeSliceThread.cpp */; }; + 8481709D10809E00008FEC33 /* juce_ToggleButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5C10403709006A1807 /* juce_ToggleButton.cpp */; }; + 8481709E10809E00008FEC33 /* juce_ToneGeneratorAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7A510403614006A1807 /* juce_ToneGeneratorAudioSource.cpp */; }; + 8481709F10809E00008FEC33 /* juce_Toolbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA7210403709006A1807 /* juce_Toolbar.cpp */; }; + 848170A010809E00008FEC33 /* juce_ToolbarButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA5E10403709006A1807 /* juce_ToolbarButton.cpp */; }; + 848170A110809E00008FEC33 /* juce_ToolbarItemComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA7410403709006A1807 /* juce_ToolbarItemComponent.cpp */; }; + 848170A210809E00008FEC33 /* juce_ToolbarItemPalette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA7710403709006A1807 /* juce_ToolbarItemPalette.cpp */; }; + 848170A310809E00008FEC33 /* juce_TooltipWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1510403709006A1807 /* juce_TooltipWindow.cpp */; }; + 848170A410809E00008FEC33 /* juce_TopLevelWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB1710403709006A1807 /* juce_TopLevelWindow.cpp */; }; + 848170A510809E00008FEC33 /* juce_TreeView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA7910403709006A1807 /* juce_TreeView.cpp */; }; + 848170A610809E00008FEC33 /* juce_Typeface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EB5410403709006A1807 /* juce_Typeface.cpp */; }; + 848170A710809E00008FEC33 /* juce_UndoManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9281040369C006A1807 /* juce_UndoManager.cpp */; }; + 848170A810809E00008FEC33 /* juce_URL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E99B104036D6006A1807 /* juce_URL.cpp */; }; + 848170A910809E00008FEC33 /* juce_Uuid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E90610403681006A1807 /* juce_Uuid.cpp */; }; + 848170AA10809E00008FEC33 /* juce_Variant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E8DE10403671006A1807 /* juce_Variant.cpp */; }; + 848170AB10809E00008FEC33 /* juce_Viewport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EABE10403709006A1807 /* juce_Viewport.cpp */; }; + 848170AC10809E00008FEC33 /* juce_VSTPluginFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7DA10403614006A1807 /* juce_VSTPluginFormat.cpp */; }; + 848170AD10809E00008FEC33 /* juce_VSTPluginFormat.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E7DB10403614006A1807 /* juce_VSTPluginFormat.mm */; }; + 848170AE10809E00008FEC33 /* juce_WavAudioFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E70910403614006A1807 /* juce_WavAudioFormat.cpp */; }; + 848170AF10809E00008FEC33 /* juce_WildcardFileFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1EA9410403709006A1807 /* juce_WildcardFileFilter.cpp */; }; + 848170B010809E00008FEC33 /* juce_XmlDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9D4104036D6006A1807 /* juce_XmlDocument.cpp */; }; + 848170B110809E00008FEC33 /* juce_XmlElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E9D6104036D6006A1807 /* juce_XmlElement.cpp */; }; + 848170B210809E00008FEC33 /* juce_ZipFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E996104036D6006A1807 /* juce_ZipFile.cpp */; }; + 8481730F10832513008FEC33 /* juce_TargetPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 8481730E10832513008FEC33 /* juce_TargetPlatform.h */; }; 8484E9A5103C958A008B7C6C /* juce_mac_NativeCode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9A4103C958A008B7C6C /* juce_mac_NativeCode.mm */; }; 8484E9BE103C9595008B7C6C /* juce_mac_AppleRemote.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9A6103C9595008B7C6C /* juce_mac_AppleRemote.mm */; }; 8484E9BF103C9595008B7C6C /* juce_mac_AudioCDBurner.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9A7103C9595008B7C6C /* juce_mac_AudioCDBurner.mm */; }; @@ -605,6 +1208,13 @@ 840F80BB092B399D005E7B4E /* juce.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; name = juce.h; path = ../../juce.h; sourceTree = SOURCE_ROOT; }; 8456EC6508A2A6C80087C412 /* juce_Config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; name = juce_Config.h; path = ../../juce_Config.h; sourceTree = SOURCE_ROOT; }; 8456EC6908A2A6F00087C412 /* JUCE changelist.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = "JUCE changelist.txt"; path = "../../docs/JUCE changelist.txt"; sourceTree = SOURCE_ROOT; }; + 84816E3510809B4F008FEC33 /* libjucedebug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjucedebug.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_iphone_Audio.cpp; sourceTree = ""; }; + 84816E5210809D07008FEC33 /* juce_iphone_Fonts.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_iphone_Fonts.mm; sourceTree = ""; }; + 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_iphone_MessageManager.mm; sourceTree = ""; }; + 84816E5410809D07008FEC33 /* juce_iphone_MiscUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_iphone_MiscUtilities.mm; sourceTree = ""; }; + 84816E5610809D07008FEC33 /* juce_iphone_UIViewComponentPeer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_iphone_UIViewComponentPeer.mm; sourceTree = ""; }; + 8481730E10832513008FEC33 /* juce_TargetPlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_TargetPlatform.h; sourceTree = ""; }; 8484E9A4103C958A008B7C6C /* juce_mac_NativeCode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = juce_mac_NativeCode.mm; path = ../../src/native/juce_mac_NativeCode.mm; sourceTree = SOURCE_ROOT; }; 8484E9A6103C9595008B7C6C /* juce_mac_AppleRemote.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = juce_mac_AppleRemote.mm; path = ../../src/native/mac/juce_mac_AppleRemote.mm; sourceTree = SOURCE_ROOT; }; 8484E9A7103C9595008B7C6C /* juce_mac_AudioCDBurner.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = juce_mac_AudioCDBurner.mm; path = ../../src/native/mac/juce_mac_AudioCDBurner.mm; sourceTree = SOURCE_ROOT; }; @@ -1200,6 +1810,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 84816E3310809B4F008FEC33 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; D289987405E68DCB004EDB86 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1246,6 +1863,7 @@ isa = PBXGroup; children = ( D2AAC046055464E500DB518D /* libjucedebug.a */, + 84816E3510809B4F008FEC33 /* libjucedebug.a */, ); name = Products; sourceTree = ""; @@ -1281,6 +1899,11 @@ 8484E9BD103C9595008B7C6C /* juce_mac_WebBrowserComponent.mm */, 8484E9D6103C95A6008B7C6C /* juce_posix_SharedCode.h */, 8484E9D7103C95A6008B7C6C /* juce_posix_NamedPipe.cpp */, + 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */, + 84816E5210809D07008FEC33 /* juce_iphone_Fonts.mm */, + 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */, + 84816E5410809D07008FEC33 /* juce_iphone_MiscUtilities.mm */, + 84816E5610809D07008FEC33 /* juce_iphone_UIViewComponentPeer.mm */, ); name = "native mac code"; path = ../../src/native/mac; @@ -1555,6 +2178,7 @@ 84F1E90910403681006A1807 /* juce_PerformanceCounter.h */, 84F1E90A10403681006A1807 /* juce_PlatformUtilities.h */, 84F1E90B10403681006A1807 /* juce_StandardHeader.h */, + 8481730E10832513008FEC33 /* juce_TargetPlatform.h */, ); name = core; path = ../../src/core; @@ -2246,6 +2870,327 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 84816E3110809B4F008FEC33 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 84816E5D10809DCB008FEC33 /* juce.h in Headers */, + 84816E5E10809DCB008FEC33 /* juce_ActionBroadcaster.h in Headers */, + 84816E5F10809DCB008FEC33 /* juce_ActionListener.h in Headers */, + 84816E6010809DCB008FEC33 /* juce_ActionListenerList.h in Headers */, + 84816E6110809DCB008FEC33 /* juce_AffineTransform.h in Headers */, + 84816E6210809DCB008FEC33 /* juce_AiffAudioFormat.h in Headers */, + 84816E6310809DCB008FEC33 /* juce_AlertWindow.h in Headers */, + 84816E6410809DCB008FEC33 /* juce_Application.h in Headers */, + 84816E6510809DCB008FEC33 /* juce_ApplicationCommandID.h in Headers */, + 84816E6610809DCB008FEC33 /* juce_ApplicationCommandInfo.h in Headers */, + 84816E6710809DCB008FEC33 /* juce_ApplicationCommandManager.h in Headers */, + 84816E6810809DCB008FEC33 /* juce_ApplicationCommandTarget.h in Headers */, + 84816E6910809DCB008FEC33 /* juce_ApplicationProperties.h in Headers */, + 84816E6A10809DCB008FEC33 /* juce_Array.h in Headers */, + 84816E6B10809DCB008FEC33 /* juce_ArrayAllocationBase.h in Headers */, + 84816E6C10809DCB008FEC33 /* juce_ArrowButton.h in Headers */, + 84816E6D10809DCB008FEC33 /* juce_AsyncUpdater.h in Headers */, + 84816E6E10809DCB008FEC33 /* juce_Atomic.h in Headers */, + 84816E6F10809DCB008FEC33 /* juce_AudioCDBurner.h in Headers */, + 84816E7010809DCB008FEC33 /* juce_AudioCDReader.h in Headers */, + 84816E7110809DCB008FEC33 /* juce_AudioDataConverters.h in Headers */, + 84816E7210809DCB008FEC33 /* juce_AudioDeviceManager.h in Headers */, + 84816E7310809DCB008FEC33 /* juce_AudioDeviceSelectorComponent.h in Headers */, + 84816E7410809DCB008FEC33 /* juce_AudioFormat.h in Headers */, + 84816E7510809DCB008FEC33 /* juce_AudioFormatManager.h in Headers */, + 84816E7610809DCB008FEC33 /* juce_AudioFormatReader.h in Headers */, + 84816E7710809DCB008FEC33 /* juce_AudioFormatReaderSource.h in Headers */, + 84816E7810809DCB008FEC33 /* juce_AudioFormatWriter.h in Headers */, + 84816E7910809DCB008FEC33 /* juce_AudioIODevice.h in Headers */, + 84816E7A10809DCB008FEC33 /* juce_AudioIODeviceType.h in Headers */, + 84816E7B10809DCB008FEC33 /* juce_AudioPlayHead.h in Headers */, + 84816E7C10809DCB008FEC33 /* juce_AudioPluginFormat.h in Headers */, + 84816E7D10809DCB008FEC33 /* juce_AudioPluginFormatManager.h in Headers */, + 84816E7E10809DCB008FEC33 /* juce_AudioPluginInstance.h in Headers */, + 84816E7F10809DCB008FEC33 /* juce_AudioProcessor.h in Headers */, + 84816E8010809DCB008FEC33 /* juce_AudioProcessorEditor.h in Headers */, + 84816E8110809DCB008FEC33 /* juce_AudioProcessorGraph.h in Headers */, + 84816E8210809DCB008FEC33 /* juce_AudioProcessorListener.h in Headers */, + 84816E8310809DCB008FEC33 /* juce_AudioProcessorPlayer.h in Headers */, + 84816E8410809DCB008FEC33 /* juce_AudioSampleBuffer.h in Headers */, + 84816E8510809DCB008FEC33 /* juce_AudioSource.h in Headers */, + 84816E8610809DCB008FEC33 /* juce_AudioSourcePlayer.h in Headers */, + 84816E8710809DCB008FEC33 /* juce_AudioSubsectionReader.h in Headers */, + 84816E8810809DCB008FEC33 /* juce_AudioThumbnail.h in Headers */, + 84816E8910809DCB008FEC33 /* juce_AudioThumbnailCache.h in Headers */, + 84816E8A10809DCB008FEC33 /* juce_AudioTransportSource.h in Headers */, + 84816E8B10809DCB008FEC33 /* juce_AudioUnitPluginFormat.h in Headers */, + 84816E8C10809DCB008FEC33 /* juce_BitArray.h in Headers */, + 84816E8D10809DCB008FEC33 /* juce_BlowFish.h in Headers */, + 84816E8E10809DCB008FEC33 /* juce_BooleanPropertyComponent.h in Headers */, + 84816E8F10809DCB008FEC33 /* juce_BorderSize.h in Headers */, + 84816E9010809DCB008FEC33 /* juce_Brush.h in Headers */, + 84816E9110809DCB008FEC33 /* juce_BubbleComponent.h in Headers */, + 84816E9210809DCB008FEC33 /* juce_BubbleMessageComponent.h in Headers */, + 84816E9310809DCB008FEC33 /* juce_BufferedInputStream.h in Headers */, + 84816E9410809DCB008FEC33 /* juce_BufferingAudioSource.h in Headers */, + 84816E9510809DCB008FEC33 /* juce_Button.h in Headers */, + 84816E9610809DCB008FEC33 /* juce_ButtonPropertyComponent.h in Headers */, + 84816E9710809DCB008FEC33 /* juce_CallbackMessage.h in Headers */, + 84816E9810809DCB008FEC33 /* juce_CameraDevice.h in Headers */, + 84816E9910809DCB008FEC33 /* juce_ChangeBroadcaster.h in Headers */, + 84816E9A10809DCB008FEC33 /* juce_ChangeListener.h in Headers */, + 84816E9B10809DCB008FEC33 /* juce_ChangeListenerList.h in Headers */, + 84816E9C10809DCB008FEC33 /* juce_ChannelRemappingAudioSource.h in Headers */, + 84816E9D10809DCB008FEC33 /* juce_CharacterFunctions.h in Headers */, + 84816E9E10809DCB008FEC33 /* juce_ChoicePropertyComponent.h in Headers */, + 84816E9F10809DCB008FEC33 /* juce_Colour.h in Headers */, + 84816EA010809DCB008FEC33 /* juce_ColourGradient.h in Headers */, + 84816EA110809DCB008FEC33 /* juce_Colours.h in Headers */, + 84816EA210809DCB008FEC33 /* juce_ColourSelector.h in Headers */, + 84816EA310809DCB008FEC33 /* juce_ComboBox.h in Headers */, + 84816EA410809DCB008FEC33 /* juce_Component.h in Headers */, + 84816EA510809DCB008FEC33 /* juce_ComponentAnimator.h in Headers */, + 84816EA610809DCB008FEC33 /* juce_ComponentBoundsConstrainer.h in Headers */, + 84816EA710809DCB008FEC33 /* juce_ComponentDeletionWatcher.h in Headers */, + 84816EA810809DCB008FEC33 /* juce_ComponentDragger.h in Headers */, + 84816EA910809DCB008FEC33 /* juce_ComponentListener.h in Headers */, + 84816EAA10809DCB008FEC33 /* juce_ComponentMovementWatcher.h in Headers */, + 84816EAB10809DCB008FEC33 /* juce_ComponentPeer.h in Headers */, + 84816EAC10809DCB008FEC33 /* juce_CriticalSection.h in Headers */, + 84816EAD10809DCB008FEC33 /* juce_DataConversions.h in Headers */, + 84816EAE10809DCB008FEC33 /* juce_DeletedAtShutdown.h in Headers */, + 84816EAF10809DCB008FEC33 /* juce_Desktop.h in Headers */, + 84816EB010809DCB008FEC33 /* juce_DialogWindow.h in Headers */, + 84816EB110809DCB008FEC33 /* juce_DirectoryContentsDisplayComponent.h in Headers */, + 84816EB210809DCB008FEC33 /* juce_DirectoryContentsList.h in Headers */, + 84816EB310809DCB008FEC33 /* juce_DirectoryIterator.h in Headers */, + 84816EB410809DCB008FEC33 /* juce_DocumentWindow.h in Headers */, + 84816EB510809DCB008FEC33 /* juce_DragAndDropContainer.h in Headers */, + 84816EB610809DCB008FEC33 /* juce_DragAndDropTarget.h in Headers */, + 84816EB710809DCB008FEC33 /* juce_Drawable.h in Headers */, + 84816EB810809DCB008FEC33 /* juce_DrawableButton.h in Headers */, + 84816EB910809DCB008FEC33 /* juce_DrawableComposite.h in Headers */, + 84816EBA10809DCB008FEC33 /* juce_DrawableImage.h in Headers */, + 84816EBB10809DCB008FEC33 /* juce_DrawablePath.h in Headers */, + 84816EBC10809DCB008FEC33 /* juce_DrawableText.h in Headers */, + 84816EBD10809DCB008FEC33 /* juce_DropShadowEffect.h in Headers */, + 84816EBE10809DCB008FEC33 /* juce_DropShadower.h in Headers */, + 84816EBF10809DCB008FEC33 /* juce_EdgeTable.h in Headers */, + 84816EC010809DCB008FEC33 /* juce_ElementComparator.h in Headers */, + 84816EC110809DCB008FEC33 /* juce_File.h in Headers */, + 84816EC210809DCB008FEC33 /* juce_FileBasedDocument.h in Headers */, + 84816EC310809DCB008FEC33 /* juce_FileBrowserComponent.h in Headers */, + 84816EC410809DCB008FEC33 /* juce_FileBrowserListener.h in Headers */, + 84816EC510809DCB008FEC33 /* juce_FileChooser.h in Headers */, + 84816EC610809DCB008FEC33 /* juce_FileChooserDialogBox.h in Headers */, + 84816EC710809DCB008FEC33 /* juce_FileDragAndDropTarget.h in Headers */, + 84816EC810809DCB008FEC33 /* juce_FileFilter.h in Headers */, + 84816EC910809DCB008FEC33 /* juce_FileInputSource.h in Headers */, + 84816ECA10809DCB008FEC33 /* juce_FileInputStream.h in Headers */, + 84816ECB10809DCB008FEC33 /* juce_FileListComponent.h in Headers */, + 84816ECC10809DCB008FEC33 /* juce_FileLogger.h in Headers */, + 84816ECD10809DCB008FEC33 /* juce_FilenameComponent.h in Headers */, + 84816ECE10809DCB008FEC33 /* juce_FileOutputStream.h in Headers */, + 84816ECF10809DCB008FEC33 /* juce_FilePreviewComponent.h in Headers */, + 84816ED010809DCB008FEC33 /* juce_FileSearchPath.h in Headers */, + 84816ED110809DCB008FEC33 /* juce_FileSearchPathListComponent.h in Headers */, + 84816ED210809DCB008FEC33 /* juce_FileTreeComponent.h in Headers */, + 84816ED310809DCB008FEC33 /* juce_FlacAudioFormat.h in Headers */, + 84816ED410809DCB008FEC33 /* juce_Font.h in Headers */, + 84816ED510809DCB008FEC33 /* juce_GenericAudioProcessorEditor.h in Headers */, + 84816ED610809DCB008FEC33 /* juce_GIFLoader.h in Headers */, + 84816ED710809DCB008FEC33 /* juce_GlowEffect.h in Headers */, + 84816ED810809DCB008FEC33 /* juce_GlyphArrangement.h in Headers */, + 84816ED910809DCB008FEC33 /* juce_GradientBrush.h in Headers */, + 84816EDA10809DCB008FEC33 /* juce_Graphics.h in Headers */, + 84816EDB10809DCB008FEC33 /* juce_GroupComponent.h in Headers */, + 84816EDC10809DCB008FEC33 /* juce_GZIPCompressorOutputStream.h in Headers */, + 84816EDD10809DCB008FEC33 /* juce_GZIPDecompressorInputStream.h in Headers */, + 84816EDE10809DCB008FEC33 /* juce_HyperlinkButton.h in Headers */, + 84816EDF10809DCB008FEC33 /* juce_IIRFilter.h in Headers */, + 84816EE010809DCB008FEC33 /* juce_IIRFilterAudioSource.h in Headers */, + 84816EE110809DCB008FEC33 /* juce_Image.h in Headers */, + 84816EE210809DCB008FEC33 /* juce_ImageBrush.h in Headers */, + 84816EE310809DCB008FEC33 /* juce_ImageButton.h in Headers */, + 84816EE410809DCB008FEC33 /* juce_ImageCache.h in Headers */, + 84816EE510809DCB008FEC33 /* juce_ImageConvolutionKernel.h in Headers */, + 84816EE610809DCB008FEC33 /* juce_ImageEffectFilter.h in Headers */, + 84816EE710809DCB008FEC33 /* juce_ImageFileFormat.h in Headers */, + 84816EE810809DCB008FEC33 /* juce_ImagePreviewComponent.h in Headers */, + 84816EE910809DCB008FEC33 /* juce_Initialisation.h in Headers */, + 84816EEA10809DCB008FEC33 /* juce_InputSource.h in Headers */, + 84816EEB10809DCB008FEC33 /* juce_InputStream.h in Headers */, + 84816EEC10809DCB008FEC33 /* juce_InterprocessConnection.h in Headers */, + 84816EED10809DCB008FEC33 /* juce_InterprocessConnectionServer.h in Headers */, + 84816EEE10809DCB008FEC33 /* juce_InterProcessLock.h in Headers */, + 84816EF010809DCB008FEC33 /* juce_Justification.h in Headers */, + 84816EF110809DCB008FEC33 /* juce_KeyboardFocusTraverser.h in Headers */, + 84816EF210809DCB008FEC33 /* juce_KeyListener.h in Headers */, + 84816EF310809DCB008FEC33 /* juce_KeyMappingEditorComponent.h in Headers */, + 84816EF410809DCB008FEC33 /* juce_KeyPress.h in Headers */, + 84816EF510809DCB008FEC33 /* juce_KeyPressMappingSet.h in Headers */, + 84816EF610809DCB008FEC33 /* juce_KnownPluginList.h in Headers */, + 84816EF710809DCB008FEC33 /* juce_Label.h in Headers */, + 84816EF810809DCB008FEC33 /* juce_LassoComponent.h in Headers */, + 84816EF910809DCB008FEC33 /* juce_Line.h in Headers */, + 84816EFA10809DCB008FEC33 /* juce_ListBox.h in Headers */, + 84816EFB10809DCB008FEC33 /* juce_LocalisedStrings.h in Headers */, + 84816EFC10809DCB008FEC33 /* juce_Logger.h in Headers */, + 84816EFD10809DCB008FEC33 /* juce_LookAndFeel.h in Headers */, + 84816EFE10809DCB008FEC33 /* juce_LowLevelGraphicsContext.h in Headers */, + 84816EFF10809DCB008FEC33 /* juce_LowLevelGraphicsPostScriptRenderer.h in Headers */, + 84816F0010809DCB008FEC33 /* juce_LowLevelGraphicsSoftwareRenderer.h in Headers */, + 84816F0110809DCB008FEC33 /* juce_mac_CarbonViewWrapperComponent.h in Headers */, + 84816F0210809DCB008FEC33 /* juce_mac_NativeIncludes.h in Headers */, + 84816F0310809DCB008FEC33 /* juce_mac_ObjCSuffix.h in Headers */, + 84816F0410809DCB008FEC33 /* juce_MagnifierComponent.h in Headers */, + 84816F0510809DCB008FEC33 /* juce_MathsFunctions.h in Headers */, + 84816F0610809DCB008FEC33 /* juce_MD5.h in Headers */, + 84816F0710809DCB008FEC33 /* juce_Memory.h in Headers */, + 84816F0810809DCB008FEC33 /* juce_MemoryBlock.h in Headers */, + 84816F0910809DCB008FEC33 /* juce_MemoryInputStream.h in Headers */, + 84816F0A10809DCB008FEC33 /* juce_MemoryOutputStream.h in Headers */, + 84816F0B10809DCB008FEC33 /* juce_MenuBarComponent.h in Headers */, + 84816F0C10809DCB008FEC33 /* juce_MenuBarModel.h in Headers */, + 84816F0D10809DCB008FEC33 /* juce_Message.h in Headers */, + 84816F0E10809DCB008FEC33 /* juce_MessageListener.h in Headers */, + 84816F0F10809DCB008FEC33 /* juce_MessageManager.h in Headers */, + 84816F1010809DCB008FEC33 /* juce_MidiBuffer.h in Headers */, + 84816F1110809DCB008FEC33 /* juce_MidiFile.h in Headers */, + 84816F1210809DCB008FEC33 /* juce_MidiInput.h in Headers */, + 84816F1310809DCB008FEC33 /* juce_MidiKeyboardComponent.h in Headers */, + 84816F1410809DCB008FEC33 /* juce_MidiKeyboardState.h in Headers */, + 84816F1510809DCB008FEC33 /* juce_MidiMessage.h in Headers */, + 84816F1610809DCB008FEC33 /* juce_MidiMessageCollector.h in Headers */, + 84816F1710809DCB008FEC33 /* juce_MidiMessageSequence.h in Headers */, + 84816F1810809DCB008FEC33 /* juce_MidiOutput.h in Headers */, + 84816F1910809DCB008FEC33 /* juce_MixerAudioSource.h in Headers */, + 84816F1A10809DCB008FEC33 /* juce_ModifierKeys.h in Headers */, + 84816F1B10809DCB008FEC33 /* juce_MouseCursor.h in Headers */, + 84816F1C10809DCB008FEC33 /* juce_MouseEvent.h in Headers */, + 84816F1D10809DCB008FEC33 /* juce_MouseHoverDetector.h in Headers */, + 84816F1E10809DCB008FEC33 /* juce_MouseListener.h in Headers */, + 84816F1F10809DCB008FEC33 /* juce_MultiDocumentPanel.h in Headers */, + 84816F2010809DCB008FEC33 /* juce_MultiTimer.h in Headers */, + 84816F2110809DCB008FEC33 /* juce_NamedPipe.h in Headers */, + 84816F2210809DCB008FEC33 /* juce_NSViewComponent.h in Headers */, + 84816F2310809DCB008FEC33 /* juce_OggVorbisAudioFormat.h in Headers */, + 84816F2410809DCB008FEC33 /* juce_OldSchoolLookAndFeel.h in Headers */, + 84816F2510809DCB008FEC33 /* juce_OpenGLComponent.h in Headers */, + 84816F2610809DCB008FEC33 /* juce_OutputStream.h in Headers */, + 84816F2710809DCB008FEC33 /* juce_OwnedArray.h in Headers */, + 84816F2810809DCB008FEC33 /* juce_Path.h in Headers */, + 84816F2910809DCB008FEC33 /* juce_PathIterator.h in Headers */, + 84816F2A10809DCB008FEC33 /* juce_PathStrokeType.h in Headers */, + 84816F2B10809DCB008FEC33 /* juce_PerformanceCounter.h in Headers */, + 84816F2C10809DCB008FEC33 /* juce_PixelFormats.h in Headers */, + 84816F2D10809DCB008FEC33 /* juce_PlatformDefs.h in Headers */, + 84816F2E10809DCB008FEC33 /* juce_PlatformUtilities.h in Headers */, + 84816F2F10809DCB008FEC33 /* juce_PluginDescription.h in Headers */, + 84816F3010809DCB008FEC33 /* juce_PluginDirectoryScanner.h in Headers */, + 84816F3110809DCB008FEC33 /* juce_PluginListComponent.h in Headers */, + 84816F3210809DCB008FEC33 /* juce_Point.h in Headers */, + 84816F3310809DCB008FEC33 /* juce_PopupMenu.h in Headers */, + 84816F3410809DCB008FEC33 /* juce_PopupMenuCustomComponent.h in Headers */, + 84816F3510809DCB008FEC33 /* juce_PositionableAudioSource.h in Headers */, + 84816F3610809DCB008FEC33 /* juce_PositionedRectangle.h in Headers */, + 84816F3710809DCB008FEC33 /* juce_posix_SharedCode.h in Headers */, + 84816F3810809DCB008FEC33 /* juce_PreferencesPanel.h in Headers */, + 84816F3910809DCB008FEC33 /* juce_Primes.h in Headers */, + 84816F3A10809DCB008FEC33 /* juce_Process.h in Headers */, + 84816F3B10809DCB008FEC33 /* juce_ProgressBar.h in Headers */, + 84816F3C10809DCB008FEC33 /* juce_PropertiesFile.h in Headers */, + 84816F3D10809DCB008FEC33 /* juce_PropertyComponent.h in Headers */, + 84816F3E10809DCB008FEC33 /* juce_PropertyPanel.h in Headers */, + 84816F3F10809DCB008FEC33 /* juce_PropertySet.h in Headers */, + 84816F4010809DCB008FEC33 /* juce_QuickTimeAudioFormat.h in Headers */, + 84816F4110809DCB008FEC33 /* juce_QuickTimeMovieComponent.h in Headers */, + 84816F4210809DCB008FEC33 /* juce_Random.h in Headers */, + 84816F4310809DCB008FEC33 /* juce_ReadWriteLock.h in Headers */, + 84816F4410809DCB008FEC33 /* juce_RecentlyOpenedFilesList.h in Headers */, + 84816F4510809DCB008FEC33 /* juce_Rectangle.h in Headers */, + 84816F4610809DCB008FEC33 /* juce_RectangleList.h in Headers */, + 84816F4710809DCB008FEC33 /* juce_RectanglePlacement.h in Headers */, + 84816F4810809DCB008FEC33 /* juce_ReduceOpacityEffect.h in Headers */, + 84816F4910809DCB008FEC33 /* juce_ReferenceCountedArray.h in Headers */, + 84816F4A10809DCB008FEC33 /* juce_ReferenceCountedObject.h in Headers */, + 84816F4B10809DCB008FEC33 /* juce_RelativeTime.h in Headers */, + 84816F4C10809DCB008FEC33 /* juce_ResamplingAudioSource.h in Headers */, + 84816F4D10809DCB008FEC33 /* juce_ResizableBorderComponent.h in Headers */, + 84816F4E10809DCB008FEC33 /* juce_ResizableCornerComponent.h in Headers */, + 84816F4F10809DCB008FEC33 /* juce_ResizableWindow.h in Headers */, + 84816F5010809DCB008FEC33 /* juce_RSAKey.h in Headers */, + 84816F5110809DCB008FEC33 /* juce_Sampler.h in Headers */, + 84816F5210809DCB008FEC33 /* juce_ScopedLock.h in Headers */, + 84816F5310809DCB008FEC33 /* juce_ScopedReadLock.h in Headers */, + 84816F5410809DCB008FEC33 /* juce_ScopedTryLock.h in Headers */, + 84816F5510809DCB008FEC33 /* juce_ScopedWriteLock.h in Headers */, + 84816F5610809DCB008FEC33 /* juce_ScrollBar.h in Headers */, + 84816F5710809DCB008FEC33 /* juce_SelectedItemSet.h in Headers */, + 84816F5810809DCB008FEC33 /* juce_ShapeButton.h in Headers */, + 84816F5910809DCB008FEC33 /* juce_Singleton.h in Headers */, + 84816F5A10809DCB008FEC33 /* juce_Slider.h in Headers */, + 84816F5B10809DCB008FEC33 /* juce_SliderListener.h in Headers */, + 84816F5C10809DCB008FEC33 /* juce_SliderPropertyComponent.h in Headers */, + 84816F5D10809DCB008FEC33 /* juce_Socket.h in Headers */, + 84816F5E10809DCB008FEC33 /* juce_SolidColourBrush.h in Headers */, + 84816F5F10809DCB008FEC33 /* juce_SortedSet.h in Headers */, + 84816F6010809DCB008FEC33 /* juce_SparseSet.h in Headers */, + 84816F6110809DCB008FEC33 /* juce_SplashScreen.h in Headers */, + 84816F6210809DCB008FEC33 /* juce_StandardHeader.h in Headers */, + 84816F6310809DCB008FEC33 /* juce_StretchableLayoutManager.h in Headers */, + 84816F6410809DCB008FEC33 /* juce_StretchableLayoutResizerBar.h in Headers */, + 84816F6510809DCB008FEC33 /* juce_StretchableObjectResizer.h in Headers */, + 84816F6610809DCB008FEC33 /* juce_String.h in Headers */, + 84816F6710809DCB008FEC33 /* juce_StringArray.h in Headers */, + 84816F6810809DCB008FEC33 /* juce_StringPairArray.h in Headers */, + 84816F6910809DCB008FEC33 /* juce_SubregionStream.h in Headers */, + 84816F6A10809DCB008FEC33 /* juce_Synthesiser.h in Headers */, + 84816F6B10809DCB008FEC33 /* juce_SystemClipboard.h in Headers */, + 84816F6C10809DCB008FEC33 /* juce_SystemStats.h in Headers */, + 84816F6D10809DCB008FEC33 /* juce_SystemTrayIconComponent.h in Headers */, + 84816F6E10809DCB008FEC33 /* juce_TabbedButtonBar.h in Headers */, + 84816F6F10809DCB008FEC33 /* juce_TabbedComponent.h in Headers */, + 84816F7010809DCB008FEC33 /* juce_TableHeaderComponent.h in Headers */, + 84816F7110809DCB008FEC33 /* juce_TableListBox.h in Headers */, + 84816F7210809DCB008FEC33 /* juce_TextButton.h in Headers */, + 84816F7310809DCB008FEC33 /* juce_TextEditor.h in Headers */, + 84816F7410809DCB008FEC33 /* juce_TextLayout.h in Headers */, + 84816F7510809DCB008FEC33 /* juce_TextPropertyComponent.h in Headers */, + 84816F7610809DCB008FEC33 /* juce_Thread.h in Headers */, + 84816F7710809DCB008FEC33 /* juce_ThreadPool.h in Headers */, + 84816F7810809DCB008FEC33 /* juce_ThreadWithProgressWindow.h in Headers */, + 84816F7910809DCB008FEC33 /* juce_Time.h in Headers */, + 84816F7A10809DCB008FEC33 /* juce_Timer.h in Headers */, + 84816F7B10809DCB008FEC33 /* juce_TimeSliceThread.h in Headers */, + 84816F7C10809DCB008FEC33 /* juce_ToggleButton.h in Headers */, + 84816F7D10809DCB008FEC33 /* juce_ToneGeneratorAudioSource.h in Headers */, + 84816F7E10809DCB008FEC33 /* juce_Toolbar.h in Headers */, + 84816F7F10809DCB008FEC33 /* juce_ToolbarButton.h in Headers */, + 84816F8010809DCB008FEC33 /* juce_ToolbarItemComponent.h in Headers */, + 84816F8110809DCB008FEC33 /* juce_ToolbarItemFactory.h in Headers */, + 84816F8210809DCB008FEC33 /* juce_ToolbarItemPalette.h in Headers */, + 84816F8310809DCB008FEC33 /* juce_TooltipClient.h in Headers */, + 84816F8410809DCB008FEC33 /* juce_TooltipWindow.h in Headers */, + 84816F8510809DCB008FEC33 /* juce_TopLevelWindow.h in Headers */, + 84816F8610809DCB008FEC33 /* juce_TreeView.h in Headers */, + 84816F8710809DCB008FEC33 /* juce_Typeface.h in Headers */, + 84816F8810809DCB008FEC33 /* juce_UndoableAction.h in Headers */, + 84816F8910809DCB008FEC33 /* juce_UndoManager.h in Headers */, + 84816F8A10809DCB008FEC33 /* juce_URL.h in Headers */, + 84816F8B10809DCB008FEC33 /* juce_Uuid.h in Headers */, + 84816F8C10809DCB008FEC33 /* juce_Variant.h in Headers */, + 84816F8D10809DCB008FEC33 /* juce_Viewport.h in Headers */, + 84816F8E10809DCB008FEC33 /* juce_VoidArray.h in Headers */, + 84816F8F10809DCB008FEC33 /* juce_VSTMidiEventList.h in Headers */, + 84816F9010809DCB008FEC33 /* juce_VSTPluginFormat.h in Headers */, + 84816F9110809DCB008FEC33 /* juce_WaitableEvent.h in Headers */, + 84816F9210809DCB008FEC33 /* juce_WavAudioFormat.h in Headers */, + 84816F9310809DCB008FEC33 /* juce_WebBrowserComponent.h in Headers */, + 84816F9410809DCB008FEC33 /* juce_WildcardFileFilter.h in Headers */, + 84816F9510809DCB008FEC33 /* juce_XmlDocument.h in Headers */, + 84816F9610809DCB008FEC33 /* juce_XmlElement.h in Headers */, + 84816F9710809DCB008FEC33 /* juce_ZipFile.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D2AAC043055464E500DB518D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -2564,12 +3509,30 @@ 84F1ECE61040370A006A1807 /* juce_ImageFileFormat.h in Headers */, 84F1ECE81040370A006A1807 /* juce_GIFLoader.h in Headers */, 84A63C02107DF286000326FD /* juce_mac_ObjCSuffix.h in Headers */, + 8481730F10832513008FEC33 /* juce_TargetPlatform.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 84816E3410809B4F008FEC33 /* Juce (iPhone) */ = { + isa = PBXNativeTarget; + buildConfigurationList = 84816E3810809BC1008FEC33 /* Build configuration list for PBXNativeTarget "Juce (iPhone)" */; + buildPhases = ( + 84816E3110809B4F008FEC33 /* Headers */, + 84816E3210809B4F008FEC33 /* Sources */, + 84816E3310809B4F008FEC33 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Juce (iPhone)"; + productName = "Juce (iPhone)"; + productReference = 84816E3510809B4F008FEC33 /* libjucedebug.a */; + productType = "com.apple.product-type.library.static"; + }; D2AAC045055464E500DB518D /* Juce */ = { isa = PBXNativeTarget; buildConfigurationList = 84A487F708A22DD800752A2B /* Build configuration list for PBXNativeTarget "Juce" */; @@ -2600,11 +3563,302 @@ projectRoot = ""; targets = ( D2AAC045055464E500DB518D /* Juce */, + 84816E3410809B4F008FEC33 /* Juce (iPhone) */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ + 84816E3210809B4F008FEC33 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84816F9810809E00008FEC33 /* juce_ActionBroadcaster.cpp in Sources */, + 84816F9910809E00008FEC33 /* juce_ActionListenerList.cpp in Sources */, + 84816F9A10809E00008FEC33 /* juce_AffineTransform.cpp in Sources */, + 84816F9B10809E00008FEC33 /* juce_AiffAudioFormat.cpp in Sources */, + 84816F9C10809E00008FEC33 /* juce_AlertWindow.cpp in Sources */, + 84816F9D10809E00008FEC33 /* juce_Application.cpp in Sources */, + 84816F9E10809E00008FEC33 /* juce_ApplicationCommandInfo.cpp in Sources */, + 84816F9F10809E00008FEC33 /* juce_ApplicationCommandManager.cpp in Sources */, + 84816FA010809E00008FEC33 /* juce_ApplicationCommandTarget.cpp in Sources */, + 84816FA110809E00008FEC33 /* juce_ApplicationProperties.cpp in Sources */, + 84816FA210809E00008FEC33 /* juce_ArrowButton.cpp in Sources */, + 84816FA310809E00008FEC33 /* juce_AsyncUpdater.cpp in Sources */, + 84816FA410809E00008FEC33 /* juce_AudioCDReader.cpp in Sources */, + 84816FA510809E00008FEC33 /* juce_AudioDataConverters.cpp in Sources */, + 84816FA610809E00008FEC33 /* juce_AudioDeviceManager.cpp in Sources */, + 84816FA710809E00008FEC33 /* juce_AudioDeviceSelectorComponent.cpp in Sources */, + 84816FA810809E00008FEC33 /* juce_AudioFormat.cpp in Sources */, + 84816FA910809E00008FEC33 /* juce_AudioFormatManager.cpp in Sources */, + 84816FAA10809E00008FEC33 /* juce_AudioFormatReaderSource.cpp in Sources */, + 84816FAB10809E00008FEC33 /* juce_AudioIODevice.cpp in Sources */, + 84816FAC10809E00008FEC33 /* juce_AudioIODeviceType.cpp in Sources */, + 84816FAD10809E00008FEC33 /* juce_AudioPluginFormat.cpp in Sources */, + 84816FAE10809E00008FEC33 /* juce_AudioPluginFormatManager.cpp in Sources */, + 84816FAF10809E00008FEC33 /* juce_AudioPluginInstance.cpp in Sources */, + 84816FB010809E00008FEC33 /* juce_AudioProcessor.cpp in Sources */, + 84816FB110809E00008FEC33 /* juce_AudioProcessorEditor.cpp in Sources */, + 84816FB210809E00008FEC33 /* juce_AudioProcessorGraph.cpp in Sources */, + 84816FB310809E00008FEC33 /* juce_AudioProcessorPlayer.cpp in Sources */, + 84816FB410809E00008FEC33 /* juce_AudioSampleBuffer.cpp in Sources */, + 84816FB510809E00008FEC33 /* juce_AudioSourcePlayer.cpp in Sources */, + 84816FB610809E00008FEC33 /* juce_AudioSubsectionReader.cpp in Sources */, + 84816FB710809E00008FEC33 /* juce_AudioThumbnail.cpp in Sources */, + 84816FB810809E00008FEC33 /* juce_AudioThumbnailCache.cpp in Sources */, + 84816FB910809E00008FEC33 /* juce_AudioTransportSource.cpp in Sources */, + 84816FBA10809E00008FEC33 /* juce_AudioUnitPluginFormat.mm in Sources */, + 84816FBB10809E00008FEC33 /* juce_BitArray.cpp in Sources */, + 84816FBC10809E00008FEC33 /* juce_BlowFish.cpp in Sources */, + 84816FBD10809E00008FEC33 /* juce_BooleanPropertyComponent.cpp in Sources */, + 84816FBE10809E00008FEC33 /* juce_BorderSize.cpp in Sources */, + 84816FBF10809E00008FEC33 /* juce_Brush.cpp in Sources */, + 84816FC010809E00008FEC33 /* juce_BubbleComponent.cpp in Sources */, + 84816FC110809E00008FEC33 /* juce_BubbleMessageComponent.cpp in Sources */, + 84816FC210809E00008FEC33 /* juce_BufferedInputStream.cpp in Sources */, + 84816FC310809E00008FEC33 /* juce_BufferingAudioSource.cpp in Sources */, + 84816FC410809E00008FEC33 /* juce_Button.cpp in Sources */, + 84816FC510809E00008FEC33 /* juce_ButtonPropertyComponent.cpp in Sources */, + 84816FC610809E00008FEC33 /* juce_ChangeBroadcaster.cpp in Sources */, + 84816FC710809E00008FEC33 /* juce_ChangeListenerList.cpp in Sources */, + 84816FC810809E00008FEC33 /* juce_ChannelRemappingAudioSource.cpp in Sources */, + 84816FC910809E00008FEC33 /* juce_CharacterFunctions.cpp in Sources */, + 84816FCA10809E00008FEC33 /* juce_ChoicePropertyComponent.cpp in Sources */, + 84816FCB10809E00008FEC33 /* juce_Colour.cpp in Sources */, + 84816FCC10809E00008FEC33 /* juce_ColourGradient.cpp in Sources */, + 84816FCD10809E00008FEC33 /* juce_Colours.cpp in Sources */, + 84816FCE10809E00008FEC33 /* juce_ColourSelector.cpp in Sources */, + 84816FCF10809E00008FEC33 /* juce_ComboBox.cpp in Sources */, + 84816FD010809E00008FEC33 /* juce_Component.cpp in Sources */, + 84816FD110809E00008FEC33 /* juce_ComponentAnimator.cpp in Sources */, + 84816FD210809E00008FEC33 /* juce_ComponentBoundsConstrainer.cpp in Sources */, + 84816FD310809E00008FEC33 /* juce_ComponentDragger.cpp in Sources */, + 84816FD410809E00008FEC33 /* juce_ComponentListener.cpp in Sources */, + 84816FD510809E00008FEC33 /* juce_ComponentMovementWatcher.cpp in Sources */, + 84816FD610809E00008FEC33 /* juce_ComponentPeer.cpp in Sources */, + 84816FD710809E00008FEC33 /* juce_DeletedAtShutdown.cpp in Sources */, + 84816FD810809E00008FEC33 /* juce_Desktop.cpp in Sources */, + 84816FD910809E00008FEC33 /* juce_DialogWindow.cpp in Sources */, + 84816FDA10809E00008FEC33 /* juce_DirectoryContentsDisplayComponent.cpp in Sources */, + 84816FDB10809E00008FEC33 /* juce_DirectoryContentsList.cpp in Sources */, + 84816FDC10809E00008FEC33 /* juce_DirectoryIterator.cpp in Sources */, + 84816FDD10809E00008FEC33 /* juce_DocumentWindow.cpp in Sources */, + 84816FDE10809E00008FEC33 /* juce_DragAndDropContainer.cpp in Sources */, + 84816FDF10809E00008FEC33 /* juce_Drawable.cpp in Sources */, + 84816FE010809E00008FEC33 /* juce_DrawableButton.cpp in Sources */, + 84816FE110809E00008FEC33 /* juce_DrawableComposite.cpp in Sources */, + 84816FE210809E00008FEC33 /* juce_DrawableImage.cpp in Sources */, + 84816FE310809E00008FEC33 /* juce_DrawablePath.cpp in Sources */, + 84816FE410809E00008FEC33 /* juce_DrawableText.cpp in Sources */, + 84816FE510809E00008FEC33 /* juce_DropShadowEffect.cpp in Sources */, + 84816FE610809E00008FEC33 /* juce_DropShadower.cpp in Sources */, + 84816FE710809E00008FEC33 /* juce_EdgeTable.cpp in Sources */, + 84816FE810809E00008FEC33 /* juce_File.cpp in Sources */, + 84816FE910809E00008FEC33 /* juce_FileBasedDocument.cpp in Sources */, + 84816FEA10809E00008FEC33 /* juce_FileBrowserComponent.cpp in Sources */, + 84816FEB10809E00008FEC33 /* juce_FileChooser.cpp in Sources */, + 84816FEC10809E00008FEC33 /* juce_FileChooserDialogBox.cpp in Sources */, + 84816FED10809E00008FEC33 /* juce_FileFilter.cpp in Sources */, + 84816FEE10809E00008FEC33 /* juce_FileInputSource.cpp in Sources */, + 84816FEF10809E00008FEC33 /* juce_FileInputStream.cpp in Sources */, + 84816FF010809E00008FEC33 /* juce_FileListComponent.cpp in Sources */, + 84816FF110809E00008FEC33 /* juce_FileLogger.cpp in Sources */, + 84816FF210809E00008FEC33 /* juce_FilenameComponent.cpp in Sources */, + 84816FF310809E00008FEC33 /* juce_FileOutputStream.cpp in Sources */, + 84816FF410809E00008FEC33 /* juce_FileSearchPath.cpp in Sources */, + 84816FF510809E00008FEC33 /* juce_FileSearchPathListComponent.cpp in Sources */, + 84816FF610809E00008FEC33 /* juce_FileTreeComponent.cpp in Sources */, + 84816FF710809E00008FEC33 /* juce_FlacAudioFormat.cpp in Sources */, + 84816FF810809E00008FEC33 /* juce_Font.cpp in Sources */, + 84816FF910809E00008FEC33 /* juce_GenericAudioProcessorEditor.cpp in Sources */, + 84816FFA10809E00008FEC33 /* juce_GIFLoader.cpp in Sources */, + 84816FFB10809E00008FEC33 /* juce_GlowEffect.cpp in Sources */, + 84816FFC10809E00008FEC33 /* juce_GlyphArrangement.cpp in Sources */, + 84816FFD10809E00008FEC33 /* juce_GradientBrush.cpp in Sources */, + 84816FFE10809E00008FEC33 /* juce_Graphics.cpp in Sources */, + 84816FFF10809E00008FEC33 /* juce_GroupComponent.cpp in Sources */, + 8481700010809E00008FEC33 /* juce_GZIPCompressorOutputStream.cpp in Sources */, + 8481700110809E00008FEC33 /* juce_GZIPDecompressorInputStream.cpp in Sources */, + 8481700210809E00008FEC33 /* juce_HyperlinkButton.cpp in Sources */, + 8481700310809E00008FEC33 /* juce_IIRFilter.cpp in Sources */, + 8481700410809E00008FEC33 /* juce_IIRFilterAudioSource.cpp in Sources */, + 8481700510809E00008FEC33 /* juce_Image.cpp in Sources */, + 8481700610809E00008FEC33 /* juce_ImageBrush.cpp in Sources */, + 8481700710809E00008FEC33 /* juce_ImageButton.cpp in Sources */, + 8481700810809E00008FEC33 /* juce_ImageCache.cpp in Sources */, + 8481700910809E00008FEC33 /* juce_ImageConvolutionKernel.cpp in Sources */, + 8481700A10809E00008FEC33 /* juce_ImageFileFormat.cpp in Sources */, + 8481700B10809E00008FEC33 /* juce_ImagePreviewComponent.cpp in Sources */, + 8481700C10809E00008FEC33 /* juce_InputStream.cpp in Sources */, + 8481700D10809E00008FEC33 /* juce_InterprocessConnection.cpp in Sources */, + 8481700E10809E00008FEC33 /* juce_InterprocessConnectionServer.cpp in Sources */, + 8481700F10809E00008FEC33 /* juce_InterProcessLock.cpp in Sources */, + 8481701010809E00008FEC33 /* juce_iphone_Audio.cpp in Sources */, + 8481701110809E00008FEC33 /* juce_iphone_Fonts.mm in Sources */, + 8481701210809E00008FEC33 /* juce_iphone_MessageManager.mm in Sources */, + 8481701310809E00008FEC33 /* juce_iphone_MiscUtilities.mm in Sources */, + 8481701410809E00008FEC33 /* juce_iphone_UIViewComponentPeer.mm in Sources */, + 8481701510809E00008FEC33 /* juce_JPEGLoader.cpp in Sources */, + 8481701610809E00008FEC33 /* juce_Justification.cpp in Sources */, + 8481701710809E00008FEC33 /* juce_KeyboardFocusTraverser.cpp in Sources */, + 8481701810809E00008FEC33 /* juce_KeyListener.cpp in Sources */, + 8481701910809E00008FEC33 /* juce_KeyMappingEditorComponent.cpp in Sources */, + 8481701A10809E00008FEC33 /* juce_KeyPress.cpp in Sources */, + 8481701B10809E00008FEC33 /* juce_KeyPressMappingSet.cpp in Sources */, + 8481701C10809E00008FEC33 /* juce_KnownPluginList.cpp in Sources */, + 8481701D10809E00008FEC33 /* juce_Label.cpp in Sources */, + 8481701E10809E00008FEC33 /* juce_Line.cpp in Sources */, + 8481701F10809E00008FEC33 /* juce_ListBox.cpp in Sources */, + 8481702010809E00008FEC33 /* juce_LocalisedStrings.cpp in Sources */, + 8481702110809E00008FEC33 /* juce_Logger.cpp in Sources */, + 8481702210809E00008FEC33 /* juce_LookAndFeel.cpp in Sources */, + 8481702310809E00008FEC33 /* juce_LowLevelGraphicsPostScriptRenderer.cpp in Sources */, + 8481702410809E00008FEC33 /* juce_LowLevelGraphicsSoftwareRenderer.cpp in Sources */, + 8481702510809E00008FEC33 /* juce_mac_AppleRemote.mm in Sources */, + 8481702610809E00008FEC33 /* juce_mac_AudioCDBurner.mm in Sources */, + 8481702710809E00008FEC33 /* juce_mac_CameraDevice.mm in Sources */, + 8481702810809E00008FEC33 /* juce_mac_CoreAudio.cpp in Sources */, + 8481702910809E00008FEC33 /* juce_mac_CoreMidi.cpp in Sources */, + 8481702A10809E00008FEC33 /* juce_mac_Debugging.mm in Sources */, + 8481702B10809E00008FEC33 /* juce_mac_FileChooser.mm in Sources */, + 8481702C10809E00008FEC33 /* juce_mac_Files.mm in Sources */, + 8481702D10809E00008FEC33 /* juce_mac_Fonts.mm in Sources */, + 8481702E10809E00008FEC33 /* juce_mac_MainMenu.mm in Sources */, + 8481702F10809E00008FEC33 /* juce_mac_MessageManager.mm in Sources */, + 8481703010809E00008FEC33 /* juce_mac_MiscUtilities.mm in Sources */, + 8481703110809E00008FEC33 /* juce_mac_MouseCursor.mm in Sources */, + 8481703210809E00008FEC33 /* juce_mac_NativeCode.mm in Sources */, + 8481703310809E00008FEC33 /* juce_mac_Network.mm in Sources */, + 8481703410809E00008FEC33 /* juce_mac_NSViewComponent.mm in Sources */, + 8481703510809E00008FEC33 /* juce_mac_NSViewComponentPeer.mm in Sources */, + 8481703610809E00008FEC33 /* juce_mac_OpenGLComponent.mm in Sources */, + 8481703710809E00008FEC33 /* juce_mac_QuickTimeMovieComponent.mm in Sources */, + 8481703810809E00008FEC33 /* juce_mac_Strings.mm in Sources */, + 8481703910809E00008FEC33 /* juce_mac_SystemStats.mm in Sources */, + 8481703A10809E00008FEC33 /* juce_mac_Threads.mm in Sources */, + 8481703B10809E00008FEC33 /* juce_mac_WebBrowserComponent.mm in Sources */, + 8481703C10809E00008FEC33 /* juce_MagnifierComponent.cpp in Sources */, + 8481703D10809E00008FEC33 /* juce_MD5.cpp in Sources */, + 8481703E10809E00008FEC33 /* juce_MemoryBlock.cpp in Sources */, + 8481703F10809E00008FEC33 /* juce_MemoryInputStream.cpp in Sources */, + 8481704010809E00008FEC33 /* juce_MemoryOutputStream.cpp in Sources */, + 8481704110809E00008FEC33 /* juce_MenuBarComponent.cpp in Sources */, + 8481704210809E00008FEC33 /* juce_MenuBarModel.cpp in Sources */, + 8481704310809E00008FEC33 /* juce_Message.cpp in Sources */, + 8481704410809E00008FEC33 /* juce_MessageListener.cpp in Sources */, + 8481704510809E00008FEC33 /* juce_MessageManager.cpp in Sources */, + 8481704610809E00008FEC33 /* juce_MidiBuffer.cpp in Sources */, + 8481704710809E00008FEC33 /* juce_MidiFile.cpp in Sources */, + 8481704810809E00008FEC33 /* juce_MidiKeyboardComponent.cpp in Sources */, + 8481704910809E00008FEC33 /* juce_MidiKeyboardState.cpp in Sources */, + 8481704A10809E00008FEC33 /* juce_MidiMessage.cpp in Sources */, + 8481704B10809E00008FEC33 /* juce_MidiMessageCollector.cpp in Sources */, + 8481704C10809E00008FEC33 /* juce_MidiMessageSequence.cpp in Sources */, + 8481704D10809E00008FEC33 /* juce_MidiOutput.cpp in Sources */, + 8481704E10809E00008FEC33 /* juce_MixerAudioSource.cpp in Sources */, + 8481704F10809E00008FEC33 /* juce_ModifierKeys.cpp in Sources */, + 8481705010809E00008FEC33 /* juce_MouseCursor.cpp in Sources */, + 8481705110809E00008FEC33 /* juce_MouseEvent.cpp in Sources */, + 8481705210809E00008FEC33 /* juce_MouseHoverDetector.cpp in Sources */, + 8481705310809E00008FEC33 /* juce_MouseListener.cpp in Sources */, + 8481705410809E00008FEC33 /* juce_MultiDocumentPanel.cpp in Sources */, + 8481705510809E00008FEC33 /* juce_MultiTimer.cpp in Sources */, + 8481705610809E00008FEC33 /* juce_NamedPipe.cpp in Sources */, + 8481705710809E00008FEC33 /* juce_OggVorbisAudioFormat.cpp in Sources */, + 8481705810809E00008FEC33 /* juce_OldSchoolLookAndFeel.cpp in Sources */, + 8481705910809E00008FEC33 /* juce_OpenGLComponent.cpp in Sources */, + 8481705A10809E00008FEC33 /* juce_OutputStream.cpp in Sources */, + 8481705B10809E00008FEC33 /* juce_Path.cpp in Sources */, + 8481705C10809E00008FEC33 /* juce_PathIterator.cpp in Sources */, + 8481705D10809E00008FEC33 /* juce_PathStrokeType.cpp in Sources */, + 8481705E10809E00008FEC33 /* juce_PerformanceCounter.cpp in Sources */, + 8481705F10809E00008FEC33 /* juce_PluginDescription.cpp in Sources */, + 8481706010809E00008FEC33 /* juce_PluginDirectoryScanner.cpp in Sources */, + 8481706110809E00008FEC33 /* juce_PluginListComponent.cpp in Sources */, + 8481706210809E00008FEC33 /* juce_PNGLoader.cpp in Sources */, + 8481706310809E00008FEC33 /* juce_Point.cpp in Sources */, + 8481706410809E00008FEC33 /* juce_PopupMenu.cpp in Sources */, + 8481706510809E00008FEC33 /* juce_PositionedRectangle.cpp in Sources */, + 8481706610809E00008FEC33 /* juce_posix_NamedPipe.cpp in Sources */, + 8481706710809E00008FEC33 /* juce_PreferencesPanel.cpp in Sources */, + 8481706810809E00008FEC33 /* juce_Primes.cpp in Sources */, + 8481706910809E00008FEC33 /* juce_ProgressBar.cpp in Sources */, + 8481706A10809E00008FEC33 /* juce_PropertiesFile.cpp in Sources */, + 8481706B10809E00008FEC33 /* juce_PropertyComponent.cpp in Sources */, + 8481706C10809E00008FEC33 /* juce_PropertyPanel.cpp in Sources */, + 8481706D10809E00008FEC33 /* juce_PropertySet.cpp in Sources */, + 8481706E10809E00008FEC33 /* juce_QuickTimeAudioFormat.cpp in Sources */, + 8481706F10809E00008FEC33 /* juce_Random.cpp in Sources */, + 8481707010809E00008FEC33 /* juce_ReadWriteLock.cpp in Sources */, + 8481707110809E00008FEC33 /* juce_RecentlyOpenedFilesList.cpp in Sources */, + 8481707210809E00008FEC33 /* juce_Rectangle.cpp in Sources */, + 8481707310809E00008FEC33 /* juce_RectangleList.cpp in Sources */, + 8481707410809E00008FEC33 /* juce_RectanglePlacement.cpp in Sources */, + 8481707510809E00008FEC33 /* juce_ReduceOpacityEffect.cpp in Sources */, + 8481707610809E00008FEC33 /* juce_RelativeTime.cpp in Sources */, + 8481707710809E00008FEC33 /* juce_ResamplingAudioSource.cpp in Sources */, + 8481707810809E00008FEC33 /* juce_ResizableBorderComponent.cpp in Sources */, + 8481707910809E00008FEC33 /* juce_ResizableCornerComponent.cpp in Sources */, + 8481707A10809E00008FEC33 /* juce_ResizableWindow.cpp in Sources */, + 8481707B10809E00008FEC33 /* juce_RSAKey.cpp in Sources */, + 8481707C10809E00008FEC33 /* juce_Sampler.cpp in Sources */, + 8481707D10809E00008FEC33 /* juce_ScrollBar.cpp in Sources */, + 8481707E10809E00008FEC33 /* juce_ShapeButton.cpp in Sources */, + 8481707F10809E00008FEC33 /* juce_Slider.cpp in Sources */, + 8481708010809E00008FEC33 /* juce_SliderPropertyComponent.cpp in Sources */, + 8481708110809E00008FEC33 /* juce_Socket.cpp in Sources */, + 8481708210809E00008FEC33 /* juce_SolidColourBrush.cpp in Sources */, + 8481708310809E00008FEC33 /* juce_SplashScreen.cpp in Sources */, + 8481708410809E00008FEC33 /* juce_StretchableLayoutManager.cpp in Sources */, + 8481708510809E00008FEC33 /* juce_StretchableLayoutResizerBar.cpp in Sources */, + 8481708610809E00008FEC33 /* juce_StretchableObjectResizer.cpp in Sources */, + 8481708710809E00008FEC33 /* juce_String.cpp in Sources */, + 8481708810809E00008FEC33 /* juce_StringArray.cpp in Sources */, + 8481708910809E00008FEC33 /* juce_StringPairArray.cpp in Sources */, + 8481708A10809E00008FEC33 /* juce_SubregionStream.cpp in Sources */, + 8481708B10809E00008FEC33 /* juce_SVGParser.cpp in Sources */, + 8481708C10809E00008FEC33 /* juce_Synthesiser.cpp in Sources */, + 8481708D10809E00008FEC33 /* juce_SystemStats.cpp in Sources */, + 8481708E10809E00008FEC33 /* juce_SystemTrayIconComponent.cpp in Sources */, + 8481708F10809E00008FEC33 /* juce_TabbedButtonBar.cpp in Sources */, + 8481709010809E00008FEC33 /* juce_TabbedComponent.cpp in Sources */, + 8481709110809E00008FEC33 /* juce_TableHeaderComponent.cpp in Sources */, + 8481709210809E00008FEC33 /* juce_TableListBox.cpp in Sources */, + 8481709310809E00008FEC33 /* juce_TextButton.cpp in Sources */, + 8481709410809E00008FEC33 /* juce_TextEditor.cpp in Sources */, + 8481709510809E00008FEC33 /* juce_TextLayout.cpp in Sources */, + 8481709610809E00008FEC33 /* juce_TextPropertyComponent.cpp in Sources */, + 8481709710809E00008FEC33 /* juce_Thread.cpp in Sources */, + 8481709810809E00008FEC33 /* juce_ThreadPool.cpp in Sources */, + 8481709910809E00008FEC33 /* juce_ThreadWithProgressWindow.cpp in Sources */, + 8481709A10809E00008FEC33 /* juce_Time.cpp in Sources */, + 8481709B10809E00008FEC33 /* juce_Timer.cpp in Sources */, + 8481709C10809E00008FEC33 /* juce_TimeSliceThread.cpp in Sources */, + 8481709D10809E00008FEC33 /* juce_ToggleButton.cpp in Sources */, + 8481709E10809E00008FEC33 /* juce_ToneGeneratorAudioSource.cpp in Sources */, + 8481709F10809E00008FEC33 /* juce_Toolbar.cpp in Sources */, + 848170A010809E00008FEC33 /* juce_ToolbarButton.cpp in Sources */, + 848170A110809E00008FEC33 /* juce_ToolbarItemComponent.cpp in Sources */, + 848170A210809E00008FEC33 /* juce_ToolbarItemPalette.cpp in Sources */, + 848170A310809E00008FEC33 /* juce_TooltipWindow.cpp in Sources */, + 848170A410809E00008FEC33 /* juce_TopLevelWindow.cpp in Sources */, + 848170A510809E00008FEC33 /* juce_TreeView.cpp in Sources */, + 848170A610809E00008FEC33 /* juce_Typeface.cpp in Sources */, + 848170A710809E00008FEC33 /* juce_UndoManager.cpp in Sources */, + 848170A810809E00008FEC33 /* juce_URL.cpp in Sources */, + 848170A910809E00008FEC33 /* juce_Uuid.cpp in Sources */, + 848170AA10809E00008FEC33 /* juce_Variant.cpp in Sources */, + 848170AB10809E00008FEC33 /* juce_Viewport.cpp in Sources */, + 848170AC10809E00008FEC33 /* juce_VSTPluginFormat.cpp in Sources */, + 848170AD10809E00008FEC33 /* juce_VSTPluginFormat.mm in Sources */, + 848170AE10809E00008FEC33 /* juce_WavAudioFormat.cpp in Sources */, + 848170AF10809E00008FEC33 /* juce_WildcardFileFilter.cpp in Sources */, + 848170B010809E00008FEC33 /* juce_XmlDocument.cpp in Sources */, + 848170B110809E00008FEC33 /* juce_XmlElement.cpp in Sources */, + 848170B210809E00008FEC33 /* juce_ZipFile.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D2AAC044055464E500DB518D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2887,12 +4141,41 @@ 84F1ECE71040370A006A1807 /* juce_GIFLoader.cpp in Sources */, 84F1ECE91040370A006A1807 /* juce_JPEGLoader.cpp in Sources */, 84F1ECEA1040370A006A1807 /* juce_PNGLoader.cpp in Sources */, + 84816E5710809D07008FEC33 /* juce_iphone_Audio.cpp in Sources */, + 84816E5810809D07008FEC33 /* juce_iphone_Fonts.mm in Sources */, + 84816E5910809D07008FEC33 /* juce_iphone_MessageManager.mm in Sources */, + 84816E5A10809D07008FEC33 /* juce_iphone_MiscUtilities.mm in Sources */, + 84816E5C10809D07008FEC33 /* juce_iphone_UIViewComponentPeer.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ + 84816E3610809B50008FEC33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = 4.2; + PREBINDING = NO; + SDKROOT = iphoneos3.0; + }; + name = Debug; + }; + 84816E3710809B50008FEC33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PREBINDING = NO; + SDKROOT = iphoneos3.0; + ZERO_LINK = NO; + }; + name = Release; + }; 84A487F808A22DD800752A2B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2900,8 +4183,8 @@ ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + MACOSX_DEPLOYMENT_TARGET = 10.4; MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Debug; }; @@ -2930,7 +4213,6 @@ "DEBUG=1", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; - GCC_VERSION = 4.0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PRODUCT_NAME = jucedebug; @@ -2952,7 +4234,6 @@ "NDEBUG=1", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; - GCC_VERSION = 4.0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PRODUCT_NAME = juce; @@ -2965,6 +4246,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 84816E3810809BC1008FEC33 /* Build configuration list for PBXNativeTarget "Juce (iPhone)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 84816E3610809B50008FEC33 /* Debug */, + 84816E3710809B50008FEC33 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; 84A487F708A22DD800752A2B /* Build configuration list for PBXNativeTarget "Juce" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/build/win32/vc8/JUCE.vcproj b/build/win32/vc8/JUCE.vcproj index f070b89d39..18facd3cc7 100644 --- a/build/win32/vc8/JUCE.vcproj +++ b/build/win32/vc8/JUCE.vcproj @@ -1041,6 +1041,10 @@ RelativePath="..\..\..\src\core\juce_SystemStats.h" > + + diff --git a/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp index a4baa5764d..d19dcab10b 100644 --- a/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp +++ b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp @@ -120,10 +120,10 @@ NPError NP_GetValue (void* future, NPPVariable variable, void* value) return NPP_GetValue ((NPP_t*) future, variable, value); } -#if JUCE_WIN32 || JUCE_MAC +#if JUCE_WINDOWS || JUCE_MAC NPError OSCALL NP_GetEntryPoints (NPPluginFuncs* funcs) { -#if JUCE_WIN32 +#if JUCE_WINDOWS #pragma EXPORTED_FUNCTION #endif @@ -162,7 +162,7 @@ NPError OSCALL NP_Initialize (NPNetscapeFuncs* funcs #endif ) { -#if JUCE_WIN32 +#if JUCE_WINDOWS #pragma EXPORTED_FUNCTION #endif @@ -201,7 +201,7 @@ NPError OSCALL NP_Initialize (NPNetscapeFuncs* funcs NPError OSCALL NP_Shutdown() { -#if JUCE_WIN32 +#if JUCE_WINDOWS #pragma EXPORTED_FUNCTION #endif @@ -269,7 +269,7 @@ public: child (0) { log ("BrowserPluginHolderComponent created"); -#if JUCE_WIN32 +#if JUCE_WINDOWS parentHWND = 0; oldWinProc = 0; #else @@ -314,7 +314,7 @@ public: private: //============================================================================== -#if JUCE_WIN32 +#if JUCE_WINDOWS HWND parentHWND; WNDPROC oldWinProc; @@ -1160,7 +1160,7 @@ const String BrowserPluginComponent::getBrowserVersion() const } //============================================================================== -#if JUCE_WIN32 +#if JUCE_WINDOWS extern const String getActiveXBrowserURL (const BrowserPluginComponent* comp); #endif @@ -1168,7 +1168,7 @@ const String BrowserPluginComponent::getBrowserURL() const { String result; -#if JUCE_WIN32 +#if JUCE_WINDOWS result = getActiveXBrowserURL (this); if (result.isNotEmpty()) diff --git a/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj b/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj index 6b4f1fabf9..5aaba8332d 100644 --- a/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj +++ b/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj @@ -321,9 +321,9 @@ GCC_VERSION = 4.0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.4; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = macosx10.4; }; name = Debug; }; diff --git a/extras/juce demo/src/ApplicationStartup.cpp b/extras/juce demo/src/ApplicationStartup.cpp index 5a83d0a5ea..fab310f558 100644 --- a/extras/juce demo/src/ApplicationStartup.cpp +++ b/extras/juce demo/src/ApplicationStartup.cpp @@ -26,7 +26,6 @@ #include "jucedemo_headers.h" #include "MainDemoWindow.h" - //============================================================================== class JUCEDemoApplication : public JUCEApplication { @@ -63,7 +62,13 @@ public: { // just create the main window... theMainWindow = new MainDemoWindow(); + +#if JUCE_IPHONE + theMainWindow->setVisible (true); + theMainWindow->setBounds (0, 20, 320, 460); +#else theMainWindow->centreWithSize (700, 600); +#endif theMainWindow->setVisible (true); // this little function just demonstrates a few system info calls diff --git a/extras/juce demo/src/demos/WidgetsDemo.cpp b/extras/juce demo/src/demos/WidgetsDemo.cpp index 32046987a2..92278410d2 100644 --- a/extras/juce demo/src/demos/WidgetsDemo.cpp +++ b/extras/juce demo/src/demos/WidgetsDemo.cpp @@ -1262,6 +1262,8 @@ public: = AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, T("This is an ok/cancel AlertWindow"), T("And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah.")); + + (void) userPickedOk; // (just avoids a compiler warning about unused variables) } else if (result == 111) { @@ -1285,6 +1287,8 @@ public: { // this is the item they chose in the drop-down list.. const int optionIndexChosen = w.getComboBoxComponent (T("option"))->getSelectedItemIndex(); + (void) optionIndexChosen; // (just avoids a compiler warning about unused variables) + // this is the text they entered.. String text = w.getTextEditorContents (T("text")); diff --git a/extras/juce demo/src/juce_AppConfig.h b/extras/juce demo/src/juce_AppConfig.h index 7a23626dc2..dab6165235 100644 --- a/extras/juce demo/src/juce_AppConfig.h +++ b/extras/juce demo/src/juce_AppConfig.h @@ -38,6 +38,8 @@ to an explicit 0 or 1 in here. */ +#include "../../../src/core/juce_TargetPlatform.h" + //#define JUCE_ONLY_BUILD_CORE_LIBRARY 1 //#define JUCE_FORCE_DEBUG 1 //#define JUCE_LOG_ASSERTIONS 1 @@ -45,12 +47,17 @@ //#define JUCE_ASIO 1 //#define JUCE_ALSA 1 -#ifdef _MSC_VER +#if JUCE_WINDOWS || JUCE_IPHONE #define JUCE_QUICKTIME 0 // (This is disabled here by default because on windows it requires the QT SDK, // but you can turn it on again if you've got the SDK) #endif -#define JUCE_OPENGL 1 +#if JUCE_IPHONE + #define JUCE_OPENGL 0 +#else + #define JUCE_OPENGL 1 +#endif + //#define JUCE_USE_FLAC 1 //#define JUCE_USE_OGGVORBIS 1 //#define JUCE_USE_CDBURNER 1 @@ -60,8 +67,8 @@ #define JUCE_PLUGINHOST_VST 0 #define JUCE_PLUGINHOST_AU 0 -#ifndef LINUX - #define JUCE_USE_CAMERA 1 +#if JUCE_LINUX || JUCE_IPHONE + #define JUCE_USE_CAMERA 0 #endif //#define JUCE_CHECK_MEMORY_LEAKS 1 diff --git a/juce.h b/juce.h index 63d951e6b3..a6f3936fe9 100644 --- a/juce.h +++ b/juce.h @@ -45,7 +45,7 @@ BEGIN_JUCE_NAMESPACE #pragma warning (disable: 4786) // (old vc6 warning about long class names) #endif -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE #pragma align=natural #endif @@ -65,7 +65,7 @@ BEGIN_JUCE_NAMESPACE #pragma pack (pop) #endif -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE #pragma align=reset #endif @@ -102,7 +102,7 @@ END_JUCE_NAMESPACE files, you may need to use the juce_WithoutMacros.h file - see the comments in that file for more information. */ - #if JUCE_WIN32 && ! JUCE_DONT_DEFINE_MACROS + #if JUCE_WINDOWS && ! JUCE_DONT_DEFINE_MACROS #define Rectangle JUCE_NAMESPACE::Rectangle #endif #endif @@ -176,7 +176,7 @@ END_JUCE_NAMESPACE return JUCE_NAMESPACE::JUCEApplication::main (argc, argv, new AppClass()); \ } -#elif JUCE_WIN32 +#elif JUCE_WINDOWS #ifdef _CONSOLE #define START_JUCE_APPLICATION(AppClass) \ diff --git a/juce_Config.h b/juce_Config.h index bc9a47cade..df63b1957d 100644 --- a/juce_Config.h +++ b/juce_Config.h @@ -101,7 +101,7 @@ On Windows, if you enable this, you'll need to have the QuickTime SDK installed, and its header files will need to be on your include path. */ -#if ! (defined (JUCE_QUICKTIME) || defined (LINUX) || defined (TARGET_OS_IPHONE) || defined (TARGET_IPHONE_SIMULATOR) || (defined (_WIN32) && ! defined (_MSC_VER))) +#if ! (defined (JUCE_QUICKTIME) || JUCE_LINUX || JUCE_IPHONE || (JUCE_WINDOWS && ! JUCE_MSVC)) #define JUCE_QUICKTIME 1 #endif @@ -133,7 +133,7 @@ /** This flag lets you enable support for CD-burning. You might want to disable it to build without the MS SDK under windows. */ -#if (! defined (JUCE_USE_CDBURNER)) && ! (defined (_WIN32) && ! defined (_MSC_VER)) +#if (! defined (JUCE_USE_CDBURNER)) && ! (JUCE_WINDOWS && ! JUCE_MSVC) #define JUCE_USE_CDBURNER 1 #endif diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 759c7c5260..ee44319a0b 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -38,6 +38,147 @@ #error #endif +/********* Start of inlined file: juce_TargetPlatform.h *********/ +#ifndef __JUCE_TARGETPLATFORM_JUCEHEADER__ +#define __JUCE_TARGETPLATFORM_JUCEHEADER__ + +/* This file figures out which platform is being built, and defines some macros + that the rest of the code can use for OS-specific compilation. + + Macros that will be set here are: + + - One of JUCE_WINDOWS, JUCE_MAC or JUCE_LINUX. + - Either JUCE_32BIT or JUCE_64BIT, depending on the architecture. + - Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN. + - Either JUCE_INTEL or JUCE_PPC + - Either JUCE_GCC or JUCE_MSVC +*/ + +#if (defined (_WIN32) || defined (_WIN64)) + #define JUCE_WIN32 1 + #define JUCE_WINDOWS 1 +#elif defined (LINUX) || defined (__linux__) + #define JUCE_LINUX 1 +#elif defined(__APPLE_CPP__) || defined(__APPLE_CC__) + #include // (needed to find out what platform we're using) + + #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + #define JUCE_IPHONE 1 + #else + #define JUCE_MAC 1 + #endif +#else + #error "Unknown platform!" +#endif + +#if JUCE_WINDOWS + #ifdef _MSC_VER + #ifdef _WIN64 + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + #endif + + #ifdef _DEBUG + #define JUCE_DEBUG 1 + #endif + + /** If defined, this indicates that the processor is little-endian. */ + #define JUCE_LITTLE_ENDIAN 1 + + #define JUCE_INTEL 1 +#endif + +#if JUCE_MAC + + #ifndef NDEBUG + #define JUCE_DEBUG 1 + #endif + + #ifdef __LITTLE_ENDIAN__ + #define JUCE_LITTLE_ENDIAN 1 + #else + #define JUCE_BIG_ENDIAN 1 + #endif + + #if defined (__ppc__) || defined (__ppc64__) + #define JUCE_PPC 1 + #else + #define JUCE_INTEL 1 + #endif + + #ifdef __LP64__ + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + + #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3) + #error "Building for OSX 10.2 is no longer supported!" + #endif + + #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) + #define MACOS_10_3_OR_EARLIER 1 + #endif + + #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) + #define MACOS_10_4_OR_EARLIER 1 + #endif +#endif + +#if JUCE_IPHONE + + #ifndef NDEBUG + #define JUCE_DEBUG 1 + #endif + + #ifdef __LITTLE_ENDIAN__ + #define JUCE_LITTLE_ENDIAN 1 + #else + #define JUCE_BIG_ENDIAN 1 + #endif +#endif + +#if JUCE_LINUX + + #ifdef _DEBUG + #define JUCE_DEBUG 1 + #endif + + // Allow override for big-endian Linux platforms + #ifndef JUCE_BIG_ENDIAN + #define JUCE_LITTLE_ENDIAN 1 + #endif + + #if defined (__LP64__) || defined (_LP64) + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + + #define JUCE_INTEL 1 +#endif + +// Compiler type macros. + +#ifdef __GNUC__ + #define JUCE_GCC 1 +#elif defined (_MSC_VER) + #define JUCE_MSVC 1 + + #if _MSC_VER >= 1400 + #define JUCE_USE_INTRINSICS 1 + #endif +#else + #error unknown compiler +#endif + +#endif // __JUCE_PLATFORMDEFS_JUCEHEADER__ +/********* End of inlined file: juce_TargetPlatform.h *********/ + + // FORCE_AMALGAMATOR_INCLUDE + /********* Start of inlined file: juce_Config.h *********/ #ifndef __JUCE_CONFIG_JUCEHEADER__ #define __JUCE_CONFIG_JUCEHEADER__ @@ -111,7 +252,7 @@ On Windows, if you enable this, you'll need to have the QuickTime SDK installed, and its header files will need to be on your include path. */ -#if ! (defined (JUCE_QUICKTIME) || defined (LINUX) || defined (TARGET_OS_IPHONE) || defined (TARGET_IPHONE_SIMULATOR) || (defined (_WIN32) && ! defined (_MSC_VER))) +#if ! (defined (JUCE_QUICKTIME) || JUCE_LINUX || JUCE_IPHONE || (JUCE_WINDOWS && ! JUCE_MSVC)) #define JUCE_QUICKTIME 1 #endif @@ -139,7 +280,7 @@ /** This flag lets you enable support for CD-burning. You might want to disable it to build without the MS SDK under windows. */ -#if (! defined (JUCE_USE_CDBURNER)) && ! (defined (_WIN32) && ! defined (_MSC_VER)) +#if (! defined (JUCE_USE_CDBURNER)) && ! (JUCE_WINDOWS && ! JUCE_MSVC) #define JUCE_USE_CDBURNER 1 #endif @@ -261,7 +402,7 @@ // FORCE_AMALGAMATOR_INCLUDE //============================================================================== -#ifdef _WIN32 +#if JUCE_WINDOWS /********* Start of inlined file: juce_win32_NativeIncludes.h *********/ @@ -448,7 +589,7 @@ public: #endif // __JUCE_WIN32_NATIVEINCLUDES_JUCEHEADER__ /********* End of inlined file: juce_win32_NativeIncludes.h *********/ -#elif defined (LINUX) +#elif JUCE_LINUX /********* Start of inlined file: juce_linux_NativeIncludes.h *********/ #ifndef __JUCE_LINUX_NATIVEINCLUDES_JUCEHEADER__ @@ -542,42 +683,7 @@ public: #endif // __JUCE_LINUX_NATIVEINCLUDES_JUCEHEADER__ /********* End of inlined file: juce_linux_NativeIncludes.h *********/ -#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - -/********* Start of inlined file: juce_iphone_NativeIncludes.h *********/ -#ifndef __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ -#define __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ - -/* - This file wraps together all the mac-specific code, so that - we can include all the native headers just once, and compile all our - platform-specific stuff in one big lump, keeping it out of the way of - the rest of the codebase. -*/ - -#import -#import -#import -#import -#import -#import -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ -/********* End of inlined file: juce_iphone_NativeIncludes.h *********/ - -#else +#elif JUCE_MAC || JUCE_IPHONE /********* Start of inlined file: juce_mac_NativeIncludes.h *********/ #ifndef __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ @@ -590,22 +696,33 @@ public: the rest of the codebase. */ -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import +#if JUCE_IPHONE + #import + #import + #import + #import + #import + #import + #include +#else + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #include + #include +#endif #include #include -#include #include #include #include @@ -624,6 +741,8 @@ public: #endif // __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ /********* End of inlined file: juce_mac_NativeIncludes.h *********/ +#else + #error "Unknown platform!" #endif //============================================================================== @@ -1403,7 +1522,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() { if (! juceInitialisedNonGUI) { -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE const ScopedAutoReleasePool pool; #endif @@ -1435,7 +1554,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() } } -#if JUCE_WIN32 +#if JUCE_WINDOWS // This is imported from the sockets code.. typedef int (__stdcall juce_CloseWin32SocketLibCall) (void); extern juce_CloseWin32SocketLibCall* juce_CloseWin32SocketLib; @@ -1449,11 +1568,11 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI() { if (juceInitialisedNonGUI) { -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE const ScopedAutoReleasePool pool; #endif -#if JUCE_WIN32 +#if JUCE_WINDOWS // need to shut down sockets if they were used.. if (juce_CloseWin32SocketLib != 0) (*juce_CloseWin32SocketLib)(); @@ -1526,7 +1645,7 @@ END_JUCE_NAMESPACE #pragma warning (push) #endif -#ifndef JUCE_WIN32 +#ifndef JUCE_WINDOWS #include #else #include @@ -1579,7 +1698,7 @@ static void millisToLocal (const int64 millis, struct tm& result) throw() { time_t now = (time_t) (seconds); -#if JUCE_WIN32 +#if JUCE_WINDOWS #ifdef USE_NEW_SECURE_TIME_FNS if (now >= 0 && now <= 0x793406fff) localtime_s (&result, &now); @@ -1682,7 +1801,7 @@ int64 Time::currentTimeMillis() throw() { // get the time once using normal library calls, and store the difference needed to // turn the millisecond counter into a real time. -#if JUCE_WIN32 +#if JUCE_WINDOWS struct _timeb t; #ifdef USE_NEW_SECURE_TIME_FNS _ftime_s (&t); @@ -1927,7 +2046,7 @@ const String Time::getTimeZone() const throw() { String zone[2]; -#if JUCE_WIN32 +#if JUCE_WINDOWS _tzset(); #ifdef USE_NEW_SECURE_TIME_FNS @@ -5758,7 +5877,7 @@ END_JUCE_NAMESPACE #pragma warning (push) #endif -#ifndef JUCE_WIN32 +#if ! JUCE_WINDOWS #include #endif @@ -5822,7 +5941,7 @@ static const String parseAbsolutePath (String path) throw() if (path.isEmpty()) return String::empty; -#if JUCE_WIN32 +#if JUCE_WINDOWS // Windows.. path = path.replaceCharacter (T('/'), T('\\')); @@ -5984,7 +6103,7 @@ bool File::hasWriteAccess() const throw() if (exists()) return juce_canWriteToFile (fullPath); -#ifndef JUCE_WIN32 +#if ! JUCE_WINDOWS else if ((! isDirectory()) && fullPath.containsChar (separator)) return getParentDirectory().hasWriteAccess(); else @@ -6154,7 +6273,7 @@ bool File::isAChildOf (const File& potentialParent) const throw() bool File::isAbsolutePath (const String& path) throw() { return path.startsWithChar (T('/')) || path.startsWithChar (T('\\')) -#if JUCE_WIN32 +#if JUCE_WINDOWS || (path.isNotEmpty() && ((const String&) path)[1] == T(':')); #else || path.startsWithChar (T('~')); @@ -6175,7 +6294,7 @@ const File File::getChildFile (String relativePath) const throw() if (relativePath[0] == T('.')) { -#if JUCE_WIN32 +#if JUCE_WINDOWS relativePath = relativePath.replaceCharacter (T('/'), T('\\')).trimStart(); #else relativePath = relativePath.replaceCharacter (T('\\'), T('/')).trimStart(); @@ -6798,7 +6917,7 @@ const String File::getRelativePathFrom (const File& dir) const throw() while (dirPath.isNotEmpty()) { -#if JUCE_WIN32 +#if JUCE_WINDOWS thisPath = T("..\\") + thisPath; #else thisPath = T("../") + thisPath; @@ -7228,7 +7347,8 @@ END_JUCE_NAMESPACE /********* End of inlined file: juce_NamedPipe.cpp *********/ /********* Start of inlined file: juce_Socket.cpp *********/ -#ifdef _WIN32 + +#if JUCE_WINDOWS #include #ifdef _MSC_VER @@ -7236,16 +7356,14 @@ END_JUCE_NAMESPACE #endif #else - #if defined (LINUX) || defined (__linux__) + #if JUCE_LINUX #include #include #include #include #include - #else - #if (MACOSX_DEPLOYMENT_TARGET <= MAC_OS_X_VERSION_10_4) && ! (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) - #include - #endif + #elif (MACOSX_DEPLOYMENT_TARGET <= MAC_OS_X_VERSION_10_4) && ! JUCE_IPHONE + #include #endif #include @@ -7262,7 +7380,7 @@ BEGIN_JUCE_NAMESPACE typedef int juce_socklen_t; #endif -#if JUCE_WIN32 +#if JUCE_WINDOWS typedef int (__stdcall juce_CloseWin32SocketLibCall) (void); juce_CloseWin32SocketLibCall* juce_CloseWin32SocketLib = 0; @@ -7322,7 +7440,7 @@ static int readSocket (const int handle, { int bytesThisTime; -#if JUCE_WIN32 +#if JUCE_WINDOWS bytesThisTime = recv (handle, ((char*) destBuffer) + bytesRead, maxBytesToRead - bytesRead, 0); #else while ((bytesThisTime = ::read (handle, ((char*) destBuffer) + bytesRead, maxBytesToRead - bytesRead)) < 0 @@ -7375,7 +7493,7 @@ static int waitForReadiness (const int handle, const bool forReading, fd_set* const prset = forReading ? &rset : 0; fd_set* const pwset = forReading ? 0 : &wset; -#if JUCE_WIN32 +#if JUCE_WINDOWS if (select (handle + 1, prset, pwset, 0, timeoutp) < 0) return -1; #else @@ -7409,7 +7527,7 @@ static int waitForReadiness (const int handle, const bool forReading, static bool setSocketBlockingState (const int handle, const bool shouldBlock) throw() { -#if JUCE_WIN32 +#if JUCE_WINDOWS u_long nonBlocking = shouldBlock ? 0 : 1; if (ioctlsocket (handle, FIONBIO, &nonBlocking) != 0) @@ -7475,7 +7593,7 @@ static bool connectSocket (int volatile& handle, if (result < 0) { -#if JUCE_WIN32 +#if JUCE_WINDOWS if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EINPROGRESS) @@ -7501,7 +7619,7 @@ StreamingSocket::StreamingSocket() connected (false), isListener (false) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif } @@ -7515,7 +7633,7 @@ StreamingSocket::StreamingSocket (const String& hostName_, connected (true), isListener (false) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif @@ -7538,7 +7656,7 @@ int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite) if (isListener || ! connected) return -1; -#if JUCE_WIN32 +#if JUCE_WINDOWS return send (handle, (const char*) sourceBuffer, numBytesToWrite, 0); #else int result; @@ -7595,7 +7713,7 @@ bool StreamingSocket::connect (const String& remoteHostName, void StreamingSocket::close() { -#if JUCE_WIN32 +#if JUCE_WINDOWS closesocket (handle); connected = false; #else @@ -7685,7 +7803,7 @@ DatagramSocket::DatagramSocket (const int localPortNumber, const bool allowBroad allowBroadcast (allowBroadcast_), serverAddress (0) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif @@ -7702,7 +7820,7 @@ DatagramSocket::DatagramSocket (const String& hostName_, const int portNumber_, allowBroadcast (false), serverAddress (0) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif @@ -7720,7 +7838,7 @@ DatagramSocket::~DatagramSocket() void DatagramSocket::close() { -#if JUCE_WIN32 +#if JUCE_WINDOWS closesocket (handle); connected = false; #else @@ -16077,12 +16195,18 @@ static JUCEApplication* appInstance = 0; JUCEApplication::JUCEApplication() : appReturnValue (0), - stillInitialising (true) + stillInitialising (true), + appLock (0) { } JUCEApplication::~JUCEApplication() { + if (appLock != 0) + { + appLock->exit(); + delete appLock; + } } JUCEApplication* JUCEApplication::getInstance() throw() @@ -16174,68 +16298,65 @@ bool JUCEApplication::perform (const InvocationInfo& info) } int JUCEApplication::main (String& commandLine, JUCEApplication* const app) +{ + if (! app->initialiseApp (commandLine)) + return 0; + + // now loop until a quit message is received.. + JUCE_TRY + { + MessageManager::getInstance()->runDispatchLoop(); + } +#if JUCE_CATCH_UNHANDLED_EXCEPTIONS + catch (const std::exception& e) + { + app->unhandledException (&e, __FILE__, __LINE__); + } + catch (...) + { + app->unhandledException (0, __FILE__, __LINE__); + } +#endif + + return shutdownAppAndClearUp(); +} + +bool JUCEApplication::initialiseApp (String& commandLine) { jassert (appInstance == 0); - appInstance = app; + appInstance = this; - app->commandLineParameters = commandLine.trim(); + commandLineParameters = commandLine.trim(); commandLine = String::empty; initialiseJuce_GUI(); InterProcessLock* appLock = 0; - if (! app->moreThanOneInstanceAllowed()) + if (! moreThanOneInstanceAllowed()) { - appLock = new InterProcessLock ("juceAppLock_" + app->getApplicationName()); + appLock = new InterProcessLock ("juceAppLock_" + getApplicationName()); if (! appLock->enter(0)) { - MessageManager::broadcastMessage (app->getApplicationName() + "/" + app->commandLineParameters); + MessageManager::broadcastMessage (getApplicationName() + "/" + commandLineParameters); delete appInstance; appInstance = 0; DBG ("Another instance is running - quitting..."); - return 0; + return false; } } - JUCE_TRY - { - juce_setCurrentThreadName ("Juce Message Thread"); - - // let the app do its setting-up.. - app->initialise (app->commandLineParameters); - - // register for broadcast new app messages - MessageManager::getInstance()->registerBroadcastListener (app); - - app->stillInitialising = false; - - // now loop until a quit message is received.. - MessageManager::getInstance()->runDispatchLoop(); + // let the app do its setting-up.. + initialise (commandLineParameters); - MessageManager::getInstance()->deregisterBroadcastListener (app); + // register for broadcast new app messages + MessageManager::getInstance()->registerBroadcastListener (this); - if (appLock != 0) - { - appLock->exit(); - delete appLock; - } - } -#if JUCE_CATCH_UNHANDLED_EXCEPTIONS - catch (const std::exception& e) - { - app->unhandledException (&e, __FILE__, __LINE__); - } - catch (...) - { - app->unhandledException (0, __FILE__, __LINE__); - } -#endif - - return shutdownAppAndClearUp(); + stillInitialising = false; + return true; } int JUCEApplication::shutdownAppAndClearUp() @@ -16244,6 +16365,8 @@ int JUCEApplication::shutdownAppAndClearUp() JUCEApplication* const app = appInstance; int returnValue = 0; + MessageManager::getInstance()->deregisterBroadcastListener (app); + static bool reentrancyCheck = false; if (! reentrancyCheck) @@ -16283,9 +16406,18 @@ int JUCEApplication::shutdownAppAndClearUp() return returnValue; } +#if JUCE_IPHONE + extern int juce_IPhoneMain (int argc, char* argv[], JUCEApplication* app); +#endif + int JUCEApplication::main (int argc, char* argv[], JUCEApplication* const newApp) { +#if JUCE_IPHONE + const ScopedAutoReleasePool pool; + return juce_IPhoneMain (argc, argv, newApp); +#else + #if JUCE_MAC const ScopedAutoReleasePool pool; #endif @@ -16295,6 +16427,7 @@ int JUCEApplication::main (int argc, char* argv[], cmd << String::fromUTF8 ((const uint8*) argv[i]) << T(' '); return JUCEApplication::main (cmd, newApp); +#endif } void JUCEApplication::actionListenerCallback (const String& message) @@ -16309,7 +16442,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI() { if (! juceInitialisedGUI) { -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE const ScopedAutoReleasePool pool; #endif juceInitialisedGUI = true; @@ -16317,8 +16450,9 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI() initialiseJuce_NonGUI(); MessageManager::getInstance(); LookAndFeel::setDefaultLookAndFeel (0); + juce_setCurrentThreadName ("Juce Message Thread"); -#if JUCE_WIN32 && JUCE_DEBUG +#if JUCE_WINDOWS && JUCE_DEBUG // This section is just for catching people who mess up their project settings and // turn RTTI off.. try @@ -20346,16 +20480,16 @@ END_JUCE_NAMESPACE /********* Start of inlined file: juce_QuickTimeAudioFormat.cpp *********/ -#if JUCE_QUICKTIME +#if JUCE_QUICKTIME && ! (JUCE_64BIT || JUCE_IPHONE) -#if ! defined (_WIN32) +#if ! JUCE_WINDOWS #include #include #include #include #include #else - #ifdef _MSC_VER + #if JUCE_MSVC #pragma warning (push) #pragma warning (disable : 4100) #endif @@ -20372,13 +20506,11 @@ END_JUCE_NAMESPACE #include #include - #ifdef _MSC_VER + #if JUCE_MSVC #pragma warning (pop) #endif #endif -#if ! (JUCE_MAC && JUCE_64BIT) - BEGIN_JUCE_NAMESPACE bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); @@ -20712,7 +20844,6 @@ AudioFormatWriter* QuickTimeAudioFormat::createWriterFor (OutputStream* /*stream END_JUCE_NAMESPACE -#endif #endif /********* End of inlined file: juce_QuickTimeAudioFormat.cpp *********/ @@ -23158,10 +23289,10 @@ AudioIODeviceType* juce_createAudioIODeviceType_ALSA(); void AudioDeviceManager::createAudioDeviceTypes (OwnedArray & list) { - #if JUCE_WIN32 + #if JUCE_WINDOWS #if JUCE_WASAPI if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) - list.add (juce_createAudioIODeviceType_WASAPI()); + list.add (juce_createAudioIODeviceType_WASAPI()); #endif #if JUCE_DIRECTSOUND @@ -36942,7 +37073,7 @@ void MessageManager::deliverMessage (void* message) delete m; } -#if ! JUCE_MAC +#if ! (JUCE_MAC || JUCE_IPHONE) void MessageManager::runDispatchLoop() { jassert (isThisTheMessageThread()); // must only be called by the message thread @@ -53421,7 +53552,7 @@ bool DirectoryContentsList::checkNextFile (bool& hasChanged) int DirectoryContentsList::compareElements (const DirectoryContentsList::FileInfo* const first, const DirectoryContentsList::FileInfo* const second) throw() { -#if JUCE_WIN32 +#if JUCE_WINDOWS if (first->isDirectory != second->isDirectory) return first->isDirectory ? -1 : 1; #endif @@ -53781,7 +53912,7 @@ void FileBrowserComponent::fileDoubleClicked (const File& f) bool FileBrowserComponent::keyPressed (const KeyPress& key) { -#if JUCE_LINUX || JUCE_WIN32 +#if JUCE_LINUX || JUCE_WINDOWS if (key.getModifiers().isCommandDown() && (key.getKeyCode() == 'H' || key.getKeyCode() == 'h')) { @@ -53877,7 +54008,7 @@ const BitArray FileBrowserComponent::getRoots (StringArray& rootNames, StringArr { BitArray separators; -#if JUCE_WIN32 +#if JUCE_WINDOWS OwnedArray roots; File::findFileSystemRoots (roots); rootPaths.clear(); @@ -54037,7 +54168,7 @@ bool FileChooser::showDialog (const bool isDirectory, jassert (previewComponent == 0 || (previewComponent->getWidth() > 10 && previewComponent->getHeight() > 10)); -#if JUCE_WIN32 +#if JUCE_WINDOWS if (useNativeDialogBox) #else if (useNativeDialogBox && (previewComponent == 0)) @@ -71624,7 +71755,7 @@ END_JUCE_NAMESPACE /********* Start of inlined file: juce_SystemTrayIconComponent.cpp *********/ -#if JUCE_WIN32 || JUCE_LINUX +#if JUCE_WINDOWS || JUCE_LINUX BEGIN_JUCE_NAMESPACE @@ -77752,11 +77883,11 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE -#if ! (defined (JUCE_MAC) || (defined (JUCE_WIN32) && defined (JUCE_64BIT))) +#if (JUCE_WINDOWS || JUCE_LINUX) && ! JUCE_64BIT #define JUCE_USE_SSE_INSTRUCTIONS 1 #endif -#if defined (JUCE_DEBUG) && JUCE_MSVC +#if JUCE_DEBUG && JUCE_MSVC #pragma warning (disable: 4714) #endif @@ -77879,7 +78010,7 @@ static void blendRectRGB (uint8* pixels, const int w, int h, const int stride, c if (alpha <= 0) return; -#if defined (JUCE_USE_SSE_INSTRUCTIONS) && ! JUCE_64BIT +#if JUCE_USE_SSE_INSTRUCTIONS if (SystemStats::hasSSE()) { int64 rgb0 = (((int64) blendColour.getRed()) << 32) @@ -100191,12 +100322,12 @@ END_JUCE_NAMESPACE /********* Start of inlined file: juce_FlacAudioFormat.cpp *********/ -#ifdef _MSC_VER +#if JUCE_USE_FLAC + +#if JUCE_WINDOWS #include #endif -#if JUCE_USE_FLAC - #ifdef _MSC_VER #pragma warning (disable : 4505) #pragma warning (push) @@ -107213,11 +107344,11 @@ done1: #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -107365,11 +107496,11 @@ unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v) #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -108862,11 +108993,11 @@ FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *v #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -110002,11 +110133,11 @@ FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw) #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -110411,11 +110542,11 @@ void FLAC__cpu_info(FLAC__CPUInfo *info) #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -110544,11 +110675,11 @@ unsigned FLAC__crc16(const FLAC__byte *data, unsigned len) #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -111117,11 +111248,11 @@ void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -111415,11 +111546,11 @@ FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned p #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -112001,11 +112132,11 @@ FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_s #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -113551,11 +113682,11 @@ unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned m #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -114042,11 +114173,11 @@ FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -114278,11 +114409,11 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real * #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -117673,11 +117804,11 @@ FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_d #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -122142,11 +122273,11 @@ FILE *get_binary_stdout_(void) #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -122686,11 +122817,11 @@ FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif /********* End of inlined file: juce_FlacHeader.h *********/ @@ -124141,7 +124272,7 @@ extern int ov_halfrate_p(OggVorbis_File *vf); // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -124920,7 +125051,7 @@ int main(void){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -126701,7 +126832,7 @@ int main(void){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -127854,7 +127985,7 @@ void _analysis_output(char *base,int i,float *v,int n,int bark,int dB, // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -128099,7 +128230,7 @@ int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -129085,7 +129216,7 @@ float *vorbis_window(vorbis_dsp_state *v,int W){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -129686,7 +129817,7 @@ int main(){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -130052,7 +130183,7 @@ void _ve_envelope_shift(envelope_lookup *e,long shift){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -130273,7 +130404,7 @@ vorbis_func_floor floor0_exportbundle={ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -131330,7 +131461,7 @@ vorbis_func_floor floor1_exportbundle={ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -131944,7 +132075,7 @@ Carsten Bormann // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -132064,7 +132195,7 @@ void vorbis_lpc_predict(float *coeff,float *prime,int m, // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -132115,7 +132246,7 @@ extern float vorbis_fromdBlook_i(long a); // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -132458,7 +132589,7 @@ void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -133080,7 +133211,7 @@ int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -133908,7 +134039,7 @@ vorbis_func_mapping mapping0_exportbundle={ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -134444,7 +134575,7 @@ void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -136422,7 +136553,7 @@ void hf_reduction(vorbis_info_psy_global *g, // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -136467,7 +136598,7 @@ vorbis_func_mapping *_mapping_P[]={ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -137347,7 +137478,7 @@ vorbis_func_residue residue2_exportbundle={ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -138078,7 +138209,7 @@ int main(){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -139316,7 +139447,7 @@ void drft_clear(drft_lookup *l){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -139478,7 +139609,7 @@ int vorbis_synthesis_halfrate_p(vorbis_info *vi){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -177831,7 +177962,7 @@ int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -179804,7 +179935,7 @@ int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){ // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping // tasks.. -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif /********* End of inlined file: juce_OggVorbisHeader.h *********/ @@ -231604,7 +231735,7 @@ END_JUCE_NAMESPACE #endif //============================================================================== -#if JUCE_WIN32 +#if JUCE_WINDOWS /********* Start of inlined file: juce_win32_NativeCode.cpp *********/ @@ -256018,7 +256149,7 @@ END_JUCE_NAMESPACE #endif -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE /********* Start of inlined file: juce_mac_NativeCode.mm *********/ /* @@ -256203,7 +256334,7 @@ void SystemClipboard::copyTextToClipboard (const String& text) throw() { #if JUCE_IPHONE [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text) - forPasteboardType: (NSString*) kUTTypePlainText]; + forPasteboardType: @"public.text"]; #else [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: nil]; @@ -256216,7 +256347,7 @@ void SystemClipboard::copyTextToClipboard (const String& text) throw() const String SystemClipboard::getTextFromClipboard() throw() { #if JUCE_IPHONE - NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: (NSString*) kUTTypePlainText]; + NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"]; #else NSString* text = [[NSPasteboard generalPasteboard] stringForType: NSStringPboardType]; #endif @@ -257895,8 +258026,13 @@ const String File::getVersion() const throw() const File File::getLinkedTarget() const throw() { +#if JUCE_IPHONE || (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) NSString* dest = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath: juceStringToNS (getFullPathName()) error: nil]; +#else + NSString* dest = [[NSFileManager defaultManager] pathContentOfSymbolicLinkAtPath: juceStringToNS (getFullPathName())]; +#endif + if (dest != nil) return File (nsStringToJuce (dest)); @@ -257930,31 +258066,6 @@ struct FindFileStruct String parentDir; }; -void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile, - bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, - Time* creationTime, bool* isReadOnly) throw() -{ - NSDirectoryEnumerator* e = [[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory)]; - - if (e != 0) - { - FindFileStruct* ff = new FindFileStruct(); - ff->enumerator = [e retain]; - ff->parentDir = directory; - - if (! ff->parentDir.endsWithChar (File::separator)) - ff->parentDir += File::separator; - - if (juce_findFileNext (ff, firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly)) - return ff; - - [e release]; - delete ff; - } - - return 0; -} - bool juce_findFileNext (void* handle, String& resultFile, bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw() { @@ -258002,6 +258113,31 @@ bool juce_findFileNext (void* handle, String& resultFile, return true; } +void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile, + bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, + Time* creationTime, bool* isReadOnly) throw() +{ + NSDirectoryEnumerator* e = [[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory)]; + + if (e != 0) + { + FindFileStruct* ff = new FindFileStruct(); + ff->enumerator = [e retain]; + ff->parentDir = directory; + + if (! ff->parentDir.endsWithChar (File::separator)) + ff->parentDir += File::separator; + + if (juce_findFileNext (ff, firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly)) + return ff; + + [e release]; + delete ff; + } + + return 0; +} + void juce_findFileClose (void* handle) throw() { FindFileStruct* ff = (FindFileStruct*) handle; @@ -258034,7 +258170,7 @@ bool juce_launchFile (const String& fileName, const String& parameters) throw() { #if JUCE_IPHONE - return false; // is this possible? + return [[UIApplication sharedApplication] openURL: [NSURL fileURLWithPath: juceStringToNS (fileName)]]; #else const ScopedAutoReleasePool pool; @@ -258097,7 +258233,12 @@ const String PlatformUtilities::makePathFromFSRef (FSRef* file) OSType PlatformUtilities::getTypeOfFile (const String& filename) { const ScopedAutoReleasePool pool; + +#if JUCE_IPHONE || (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + NSDictionary* fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath: juceStringToNS (filename) error: nil]; +#else NSDictionary* fileDict = [[NSFileManager defaultManager] fileAttributesAtPath: juceStringToNS (filename) traverseLink: NO]; +#endif return (OSType) [fileDict objectForKey: NSFileHFSTypeCode]; } @@ -258114,6 +258255,150 @@ bool PlatformUtilities::isBundle (const String& filename) #endif /********* End of inlined file: juce_mac_Files.mm *********/ +#if JUCE_IPHONE + +/********* Start of inlined file: juce_iphone_MiscUtilities.mm *********/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#ifdef JUCE_INCLUDED_FILE + +static JUCEApplication* juce_intialisingApp; + +END_JUCE_NAMESPACE + +@interface JuceAppStartupDelegate : NSObject +{ +} + +- (void) applicationDidFinishLaunching: (UIApplication*) application; +- (void) applicationWillResignActive: (UIApplication*) application; + +@end + +@implementation JuceAppStartupDelegate + +- (void) applicationDidFinishLaunching: (UIApplication*) application +{ + String dummy; + if (! juce_intialisingApp->initialiseApp (dummy)) + { + // (should quit) + } +} + +- (void) applicationWillResignActive: (UIApplication*) application +{ + JUCEApplication::shutdownAppAndClearUp(); +} + +@end + +BEGIN_JUCE_NAMESPACE + +int juce_IPhoneMain (int argc, char* argv[], JUCEApplication* app) +{ + juce_intialisingApp = app; + return UIApplicationMain (argc, argv, nil, @"JuceAppStartupDelegate"); +} + +ScopedAutoReleasePool::ScopedAutoReleasePool() +{ + pool = [[NSAutoreleasePool alloc] init]; +} + +ScopedAutoReleasePool::~ScopedAutoReleasePool() +{ + [((NSAutoreleasePool*) pool) release]; +} + +void PlatformUtilities::beep() +{ + //xxx + //AudioServicesPlaySystemSound (); +} + +void PlatformUtilities::addItemToDock (const File& file) +{ +} + +#if ! JUCE_ONLY_BUILD_CORE_LIBRARY + +bool AlertWindow::showNativeDialogBox (const String& title, + const String& bodyText, + bool isOkCancel) +{ + const ScopedAutoReleasePool pool; + + UIAlertView *alert = [[[UIAlertView alloc] initWithTitle: juceStringToNS (title) + message: juceStringToNS (title) + delegate: nil + cancelButtonTitle: @"OK" + otherButtonTitles: (isOkCancel ? @"Cancel" : nil), nil] autorelease]; + alert.cancelButtonIndex = alert.firstOtherButtonIndex; + [alert show]; + + // xxx need to use a delegate to find which button was clicked + return false; +} + +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) +{ + jassertfalse // not implemented! + return false; +} + +bool DragAndDropContainer::performExternalDragDropOfText (const String& text) +{ + jassertfalse // not implemented! + return false; +} + +bool Desktop::canUseSemiTransparentWindows() throw() +{ + return true; +} + +void Desktop::getMousePosition (int& x, int& y) throw() +{ + x = 0; + y = 0; +} + +void Desktop::setMousePosition (int x, int y) throw() +{ +} + +void Desktop::setScreenSaverEnabled (const bool isEnabled) throw() +{ + [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled]; +} + +bool Desktop::isScreenSaverEnabled() throw() +{ + return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; +} + +void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool clipToWorkArea) throw() +{ + const ScopedAutoReleasePool pool; + monitorCoords.clear(); + + CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame] + : [[UIScreen mainScreen] bounds]; + + monitorCoords.add (Rectangle ((int) r.origin.x, + (int) r.origin.y, + (int) r.size.width, + (int) r.size.height)); +} + +#endif + +#endif +/********* End of inlined file: juce_iphone_MiscUtilities.mm *********/ + +#else + /********* Start of inlined file: juce_mac_MiscUtilities.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). @@ -258346,6 +258631,8 @@ void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool c #endif /********* End of inlined file: juce_mac_MiscUtilities.mm *********/ +#endif + /********* Start of inlined file: juce_mac_Debugging.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). @@ -258391,104 +258678,64 @@ bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw() /********* End of inlined file: juce_mac_Debugging.mm *********/ #if ! JUCE_ONLY_BUILD_CORE_LIBRARY + #if JUCE_IPHONE -/********* Start of inlined file: juce_mac_NSViewComponentPeer.mm *********/ +/********* Start of inlined file: juce_iphone_UIViewComponentPeer.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). #ifdef JUCE_INCLUDED_FILE -class NSViewComponentPeer; +class UIViewComponentPeer; END_JUCE_NAMESPACE -#define JuceNSView MakeObjCClassName(JuceNSView) +#define JuceUIView MakeObjCClassName(JuceUIView) -@interface JuceNSView : NSView +@interface JuceUIView : UIView { @public - NSViewComponentPeer* owner; - NSNotificationCenter* notificationCenter; + UIViewComponentPeer* owner; } -- (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner withFrame: (NSRect) frame; +- (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner withFrame: (CGRect) frame; - (void) dealloc; -- (BOOL) isOpaque; -- (void) drawRect: (NSRect) r; +- (void) drawRect: (CGRect) r; -- (void) mouseDown: (NSEvent*) ev; -- (void) asyncMouseDown: (NSEvent*) ev; -- (void) mouseUp: (NSEvent*) ev; -- (void) asyncMouseUp: (NSEvent*) ev; -- (void) mouseDragged: (NSEvent*) ev; -- (void) mouseMoved: (NSEvent*) ev; -- (void) mouseEntered: (NSEvent*) ev; -- (void) mouseExited: (NSEvent*) ev; -- (void) rightMouseDown: (NSEvent*) ev; -- (void) rightMouseDragged: (NSEvent*) ev; -- (void) rightMouseUp: (NSEvent*) ev; -- (void) otherMouseDown: (NSEvent*) ev; -- (void) otherMouseDragged: (NSEvent*) ev; -- (void) otherMouseUp: (NSEvent*) ev; -- (void) scrollWheel: (NSEvent*) ev; -- (BOOL) acceptsFirstMouse: (NSEvent*) ev; -- (void) frameChanged: (NSNotification*) n; - -- (void) keyDown: (NSEvent*) ev; -- (void) keyUp: (NSEvent*) ev; -- (void) flagsChanged: (NSEvent*) ev; -#if MACOS_10_4_OR_EARLIER -- (BOOL) performKeyEquivalent: (NSEvent*) ev; -#endif +- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event; +- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event; +- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event; +- (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event; - (BOOL) becomeFirstResponder; - (BOOL) resignFirstResponder; -- (BOOL) acceptsFirstResponder; - -- (NSArray*) getSupportedDragTypes; -- (BOOL) sendDragCallback: (int) type sender: (id ) sender; -- (NSDragOperation) draggingEntered: (id ) sender; -- (NSDragOperation) draggingUpdated: (id ) sender; -- (void) draggingEnded: (id ) sender; -- (void) draggingExited: (id ) sender; -- (BOOL) prepareForDragOperation: (id ) sender; -- (BOOL) performDragOperation: (id ) sender; -- (void) concludeDragOperation: (id ) sender; +- (BOOL) canBecomeFirstResponder; @end -#define JuceNSWindow MakeObjCClassName(JuceNSWindow) +#define JuceUIWindow MakeObjCClassName(JuceUIWindow) -#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 -@interface JuceNSWindow : NSWindow -#else -@interface JuceNSWindow : NSWindow -#endif +@interface JuceUIWindow : UIWindow { @private - NSViewComponentPeer* owner; + UIViewComponentPeer* owner; bool isZooming; } -- (void) setOwner: (NSViewComponentPeer*) owner; -- (BOOL) canBecomeKeyWindow; +- (void) setOwner: (UIViewComponentPeer*) owner; - (void) becomeKeyWindow; -- (BOOL) windowShouldClose: (id) window; -- (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; -- (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; -- (void) zoom: (id) sender; @end BEGIN_JUCE_NAMESPACE -class NSViewComponentPeer : public ComponentPeer +class UIViewComponentPeer : public ComponentPeer { public: - NSViewComponentPeer (Component* const component, + UIViewComponentPeer (Component* const component, const int windowStyleFlags, - NSView* viewToAttachTo); + UIView* viewToAttachTo); - ~NSViewComponentPeer(); + ~UIViewComponentPeer(); void* getNativeHandle() const; void setVisible (bool shouldBeVisible); @@ -258513,44 +258760,13 @@ public: void toBehind (ComponentPeer* other); void setIcon (const Image& newIcon); - /* 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. - */ - virtual void redirectMouseDown (NSEvent* ev); - virtual void redirectMouseUp (NSEvent* ev); - virtual void redirectMouseDrag (NSEvent* ev); - virtual void redirectMouseMove (NSEvent* ev); - virtual void redirectMouseEnter (NSEvent* ev); - virtual void redirectMouseExit (NSEvent* ev); - virtual void redirectMouseWheel (NSEvent* ev); - - bool handleKeyEvent (NSEvent* ev, bool isKeyDown); - virtual bool redirectKeyDown (NSEvent* ev); - virtual bool redirectKeyUp (NSEvent* ev); - virtual void redirectModKeyChange (NSEvent* ev); -#if MACOS_10_4_OR_EARLIER - virtual bool redirectPerformKeyEquivalent (NSEvent* ev); -#endif - - virtual BOOL sendDragCallback (int type, id sender); - - virtual bool isOpaque(); - virtual void drawRect (NSRect r); + virtual void drawRect (CGRect r); virtual bool canBecomeKeyWindow(); virtual bool windowShouldClose(); virtual void redirectMovedOrResized(); - virtual NSRect constrainRect (NSRect r); - - static void showArrowCursorIfNeeded(); + virtual CGRect constrainRect (CGRect r); virtual void viewFocusGain(); virtual void viewFocusLoss(); @@ -258563,194 +258779,123 @@ public: juce_UseDebuggingNewOperator - NSWindow* window; - JuceNSView* view; + UIWindow* window; + JuceUIView* view; bool isSharedWindow, fullScreen; }; END_JUCE_NAMESPACE -@implementation JuceNSView +@implementation JuceUIView -- (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner_ - withFrame: (NSRect) frame +- (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner_ + withFrame: (CGRect) frame { [super initWithFrame: frame]; owner = owner_; - notificationCenter = [NSNotificationCenter defaultCenter]; - - [notificationCenter addObserver: self - selector: @selector (frameChanged:) - name: NSViewFrameDidChangeNotification - object: self]; - - if (! owner_->isSharedWindow) - { - [notificationCenter addObserver: self - selector: @selector (frameChanged:) - name: NSWindowDidMoveNotification - object: owner_->window]; - } - - [self registerForDraggedTypes: [self getSupportedDragTypes]]; - return self; } - (void) dealloc { - [notificationCenter removeObserver: self]; [super dealloc]; } -- (void) drawRect: (NSRect) r +- (void) drawRect: (CGRect) r { if (owner != 0) owner->drawRect (r); } -- (BOOL) isOpaque -{ - return owner == 0 || owner->isOpaque(); -} - -- (void) mouseDown: (NSEvent*) ev -{ - // In some host situations, the host will stop modal loops from working - // correctly if they're called from a mouse event, so we'll trigger - // the event asynchronously.. - if (JUCEApplication::getInstance() == 0) - [self performSelectorOnMainThread: @selector (asyncMouseDown:) - withObject: ev - waitUntilDone: NO]; - else - [self asyncMouseDown: ev]; -} - -- (void) asyncMouseDown: (NSEvent*) ev -{ - if (owner != 0) - owner->redirectMouseDown (ev); -} - -- (void) mouseUp: (NSEvent*) ev -{ - // In some host situations, the host will stop modal loops from working - // correctly if they're called from a mouse event, so we'll trigger - // the event asynchronously.. - if (JUCEApplication::getInstance() == 0) - [self performSelectorOnMainThread: @selector (asyncMouseUp:) - withObject: ev - waitUntilDone: NO]; - else - [self asyncMouseUp: ev]; -} - -- (void) asyncMouseUp: (NSEvent*) ev -{ - if (owner != 0) - owner->redirectMouseUp (ev); -} - -- (void) mouseDragged: (NSEvent*) ev +bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() { - if (owner != 0) - owner->redirectMouseDrag (ev); + return false; } -- (void) mouseMoved: (NSEvent*) ev -{ - if (owner != 0) - owner->redirectMouseMove (ev); -} +static int currentModifiers = 0; -- (void) mouseEntered: (NSEvent*) ev +const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() { - if (owner != 0) - owner->redirectMouseEnter (ev); + return ModifierKeys (currentModifiers); } -- (void) mouseExited: (NSEvent*) ev +void ModifierKeys::updateCurrentModifiers() throw() { - if (owner != 0) - owner->redirectMouseExit (ev); + currentModifierFlags = currentModifiers; } -- (void) rightMouseDown: (NSEvent*) ev +static int getModifierForButtonNumber (const int num) throw() { - [self mouseDown: ev]; + return num == 0 ? ModifierKeys::leftButtonModifier + : (num == 1 ? ModifierKeys::rightButtonModifier + : (num == 2 ? ModifierKeys::middleButtonModifier : 0)); } -- (void) rightMouseDragged: (NSEvent*) ev -{ - [self mouseDragged: ev]; -} +static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0; } -- (void) rightMouseUp: (NSEvent*) ev +- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event { - [self mouseUp: ev]; -} + NSArray* const t = [[event touchesForView: self] allObjects]; -- (void) otherMouseDown: (NSEvent*) ev -{ - [self mouseDown: ev]; -} + switch ([t count]) + { + case 1: // One finger.. + { + CGPoint p = [[t objectAtIndex: 0] locationInView: self]; + currentModifiers |= getModifierForButtonNumber (0); -- (void) otherMouseDragged: (NSEvent*) ev -{ - [self mouseDragged: ev]; -} + owner->handleMouseDown (p.x, p.y, getMouseTime (event)); + } -- (void) otherMouseUp: (NSEvent*) ev -{ - [self mouseUp: ev]; + default: + //xxx multi-touch.. + break; + } } -- (void) scrollWheel: (NSEvent*) ev +- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner != 0) - owner->redirectMouseWheel (ev); -} + NSArray* const t = [[event touchesForView: self] allObjects]; -- (BOOL) acceptsFirstMouse: (NSEvent*) ev -{ - return YES; -} + switch ([t count]) + { + case 1: // One finger.. + { + CGPoint p = [[t objectAtIndex: 0] locationInView: self]; + owner->handleMouseDrag (p.x, p.y, getMouseTime (event)); + } -- (void) frameChanged: (NSNotification*) n -{ - if (owner != 0) - owner->redirectMovedOrResized(); + default: + //xxx multi-touch.. + break; + } } -- (void) keyDown: (NSEvent*) ev +- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner == 0 || ! owner->redirectKeyDown (ev)) - [super keyDown: ev]; -} + NSArray* const t = [[event touchesForView: self] allObjects]; -- (void) keyUp: (NSEvent*) ev -{ - if (owner == 0 || ! owner->redirectKeyUp (ev)) - [super keyUp: ev]; -} + switch ([t count]) + { + case 1: // One finger.. + { + CGPoint p = [[t objectAtIndex: 0] locationInView: self]; + const int oldMods = currentModifiers; + currentModifiers &= ~getModifierForButtonNumber (0); + owner->handleMouseUp (oldMods, p.x, p.y, getMouseTime (event)); + } -- (void) flagsChanged: (NSEvent*) ev -{ - if (owner != 0) - owner->redirectModKeyChange (ev); + default: + //xxx multi-touch.. + break; + } } -#if MACOS_10_4_OR_EARLIER -- (BOOL) performKeyEquivalent: (NSEvent*) ev +- (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner != 0 && owner->redirectPerformKeyEquivalent (ev)) - return true; - - return [super performKeyEquivalent: ev]; + [self touchesEnded: touches withEvent: event]; } -#endif - (BOOL) becomeFirstResponder { @@ -258768,76 +258913,21 @@ END_JUCE_NAMESPACE return true; } -- (BOOL) acceptsFirstResponder +- (BOOL) canBecomeFirstResponder { return owner != 0 && owner->canBecomeKeyWindow(); } -- (NSArray*) getSupportedDragTypes -{ - return [NSArray arrayWithObjects: NSFilenamesPboardType, /*NSFilesPromisePboardType, NSStringPboardType,*/ nil]; -} - -- (BOOL) sendDragCallback: (int) type sender: (id ) sender -{ - return owner != 0 && owner->sendDragCallback (type, sender); -} - -- (NSDragOperation) draggingEntered: (id ) sender -{ - if ([self sendDragCallback: 0 sender: sender]) - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric; - else - return NSDragOperationNone; -} - -- (NSDragOperation) draggingUpdated: (id ) sender -{ - if ([self sendDragCallback: 0 sender: sender]) - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric; - else - return NSDragOperationNone; -} - -- (void) draggingEnded: (id ) sender -{ - [self sendDragCallback: 1 sender: sender]; -} - -- (void) draggingExited: (id ) sender -{ - [self sendDragCallback: 1 sender: sender]; -} - -- (BOOL) prepareForDragOperation: (id ) sender -{ - return YES; -} - -- (BOOL) performDragOperation: (id ) sender -{ - return [self sendDragCallback: 2 sender: sender]; -} - -- (void) concludeDragOperation: (id ) sender -{ -} - @end -@implementation JuceNSWindow +@implementation JuceUIWindow -- (void) setOwner: (NSViewComponentPeer*) owner_ +- (void) setOwner: (UIViewComponentPeer*) owner_ { owner = owner_; isZooming = false; } -- (BOOL) canBecomeKeyWindow -{ - return owner != 0 && owner->canBecomeKeyWindow(); -} - - (void) becomeKeyWindow { [super becomeKeyWindow]; @@ -258846,57 +258936,14 @@ END_JUCE_NAMESPACE owner->grabFocus(); } -- (BOOL) windowShouldClose: (id) window -{ - return owner == 0 || owner->windowShouldClose(); -} - -- (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen -{ - if (owner != 0) - frameRect = owner->constrainRect (frameRect); - - return frameRect; -} - -- (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize -{ - if (isZooming) - return proposedFrameSize; - - NSRect frameRect = [self frame]; - frameRect.origin.y -= proposedFrameSize.height - frameRect.size.height; - frameRect.size = proposedFrameSize; - - if (owner != 0) - frameRect = owner->constrainRect (frameRect); - - return frameRect.size; -} - -- (void) zoom: (id) sender -{ - isZooming = true; - [super zoom: sender]; - isZooming = false; -} - -- (void) windowWillMove: (NSNotification*) notification -{ - if (juce::Component::getCurrentlyModalComponent() != 0 - && owner->getComponent()->isCurrentlyBlockedByAnotherModalComponent() - && (owner->getStyleFlags() & juce::ComponentPeer::windowHasTitleBar) != 0) - juce::Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); -} - @end BEGIN_JUCE_NAMESPACE -class JuceNSImage +class JuceUIImage { public: - JuceNSImage (const int width, const int height, const bool hasAlpha) + JuceUIImage (const int width, const int height, const bool hasAlpha) : juceImage (hasAlpha ? Image::ARGB : Image::RGB, width, height, hasAlpha) { @@ -258905,60 +258952,42 @@ public: imageData = juceImage.lockPixelDataReadWrite (0, 0, width, height, lineStride, pixelStride); - imageRep = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes: &imageData - pixelsWide: width - pixelsHigh: height - bitsPerSample: 8 - samplesPerPixel: pixelStride - hasAlpha: hasAlpha - isPlanar: NO - colorSpaceName: NSCalibratedRGBColorSpace - bitmapFormat: /*NSAlphaFirstBitmapFormat*/ (NSBitmapFormat) 0 - bytesPerRow: lineStride - bitsPerPixel: 8 * pixelStride ]; + CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0); + + imageRef = CGImageCreate (width, height, + 8, pixelStride * 8, lineStride, + CGColorSpaceCreateDeviceRGB(), + hasAlpha ? (kCGImageAlphaFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault, + provider, + 0, + true, kCGRenderingIntentDefault); juceImage.releasePixelDataReadWrite (imageData); + + uiImage = [[UIImage imageWithCGImage: imageRef] retain]; } - ~JuceNSImage() + ~JuceUIImage() { - [imageRep release]; + [uiImage release]; + CFRelease (imageRef); } Image& getJuceImage() throw() { return juceImage; } - void draw (const float x, const float y, - const RectangleList& clip, - const int originX, const int originY) const + void draw (const float x, const float y) const { - // Our data is BGRA and the damned image rep only takes RGBA, so - // we need to byte-swap the active areas if there's an alpha channel... - if (juceImage.hasAlphaChannel()) - { - RectangleList::Iterator iter (clip); - while (iter.next()) - { - const Rectangle* const r = iter.getRectangle(); - - swapRGBOrder (r->getX() + originX, - r->getY() + originY, - r->getWidth(), - r->getHeight()); - } - } - - NSPoint p; - p.x = x; - p.y = y; - [imageRep drawAtPoint: p]; + [uiImage drawAtPoint: CGPointMake (x, y) + blendMode: kCGBlendModeCopy + alpha: 1.0f]; } - void drawNSImage (NSImage* imageToDraw) + void drawUIImage (UIImage* imageToDraw) { const ScopedAutoReleasePool pool; - [NSGraphicsContext saveGraphicsState]; + jassertfalse + /*[NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]]; @@ -258971,16 +259000,19 @@ public: [NSGraphicsContext restoreGraphicsState]; if (juceImage.hasAlphaChannel()) - swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight()); + swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());*/ + } private: Image juceImage; - NSBitmapImageRep* imageRep; + CGImageRef imageRef; + CGDataProviderRef provider; + UIImage* uiImage; uint8* imageData; int pixelStride, lineStride; - void swapRGBOrder (const int x, const int y, const int w, int h) const +/* void swapRGBOrder (const int x, const int y, const int w, int h) const { #if JUCE_BIG_ENDIAN jassert (pixelStride == 4); @@ -259013,120 +259045,25 @@ private: p += pixelStride; } } - } + }*/ }; -static ComponentPeer* currentlyFocusedPeer = 0; -static VoidArray keysCurrentlyDown; - -bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() -{ - if (keysCurrentlyDown.contains ((void*) keyCode)) - return true; - - if (keyCode >= 'A' && keyCode <= 'Z' - && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode))) - return true; - - if (keyCode >= 'a' && keyCode <= 'z' - && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toUpperCase ((tchar) keyCode))) - return true; - - return false; -} - -static int getKeyCodeFromEvent (NSEvent* ev) -{ - const String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); - int keyCode = unmodified[0]; - - if (keyCode == 0x19) // (backwards-tab) - keyCode = '\t'; - else if (keyCode == 0x03) // (enter) - keyCode = '\r'; - - return keyCode; -} - -static int currentModifiers = 0; - -static void updateModifiers (NSEvent* e) -{ - int m = currentModifiers & ~(ModifierKeys::shiftModifier | ModifierKeys::ctrlModifier - | ModifierKeys::altModifier | ModifierKeys::commandModifier); - - if (([e modifierFlags] & NSShiftKeyMask) != 0) - m |= ModifierKeys::shiftModifier; - - if (([e modifierFlags] & NSControlKeyMask) != 0) - m |= ModifierKeys::ctrlModifier; - - if (([e modifierFlags] & NSAlternateKeyMask) != 0) - m |= ModifierKeys::altModifier; - - if (([e modifierFlags] & NSCommandKeyMask) != 0) - m |= ModifierKeys::commandModifier; - - currentModifiers = m; -} - -static void updateKeysDown (NSEvent* ev, bool isKeyDown) -{ - updateModifiers (ev); - int keyCode = getKeyCodeFromEvent (ev); - - if (keyCode != 0) - { - if (isKeyDown) - keysCurrentlyDown.addIfNotAlreadyThere ((void*) keyCode); - else - keysCurrentlyDown.removeValue ((void*) keyCode); - } -} - -const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() -{ - return ModifierKeys (currentModifiers); -} - -void ModifierKeys::updateCurrentModifiers() throw() -{ - currentModifierFlags = currentModifiers; -} - -static int64 getMouseTime (NSEvent* e) { return (int64) [e timestamp] * 1000.0; } - -static void getMousePos (NSEvent* e, NSView* view, int& x, int& y) -{ - NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil]; - x = roundFloatToInt (p.x); - y = roundFloatToInt ([view frame].size.height - p.y); -} - -static int getModifierForButtonNumber (const int num) throw() -{ - return num == 0 ? ModifierKeys::leftButtonModifier - : (num == 1 ? ModifierKeys::rightButtonModifier - : (num == 2 ? ModifierKeys::middleButtonModifier : 0)); -} - -NSViewComponentPeer::NSViewComponentPeer (Component* const component, +UIViewComponentPeer::UIViewComponentPeer (Component* const component, const int windowStyleFlags, - NSView* viewToAttachTo) + UIView* viewToAttachTo) : ComponentPeer (component, windowStyleFlags), window (0), view (0), isSharedWindow (viewToAttachTo != 0), fullScreen (false) { - NSRect r; + CGRect r; r.origin.x = 0; r.origin.y = 0; r.size.width = (float) component->getWidth(); r.size.height = (float) component->getHeight(); - view = [[JuceNSView alloc] initWithOwner: this withFrame: r]; - [view setPostsFrameChangedNotifications: YES]; + view = [[JuceUIView alloc] initWithOwner: this withFrame: r]; if (isSharedWindow) { @@ -259139,54 +259076,23 @@ NSViewComponentPeer::NSViewComponentPeer (Component* const component, { r.origin.x = (float) component->getX(); r.origin.y = (float) component->getY(); - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); - - unsigned int style = 0; - if ((windowStyleFlags & windowHasTitleBar) == 0) - style = NSBorderlessWindowMask; - else - style = NSTitledWindowMask; - - if ((windowStyleFlags & windowHasMinimiseButton) != 0) - style |= NSMiniaturizableWindowMask; - - if ((windowStyleFlags & windowHasCloseButton) != 0) - style |= NSClosableWindowMask; - - if ((windowStyleFlags & windowIsResizable) != 0) - style |= NSResizableWindowMask; - - window = [[JuceNSWindow alloc] initWithContentRect: r - styleMask: style - backing: NSBackingStoreBuffered - defer: YES]; + r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height); - [((JuceNSWindow*) window) setOwner: this]; - [window orderOut: nil]; - [window setDelegate: (JuceNSWindow*) window]; - [window setOpaque: component->isOpaque()]; - [window setHasShadow: ((windowStyleFlags & windowHasDropShadow) != 0)]; + window = [[JuceUIWindow alloc] init]; + window.frame = r; + [((JuceUIWindow*) window) setOwner: this]; if (component->isAlwaysOnTop()) - [window setLevel: NSFloatingWindowLevel]; - - [window setContentView: view]; - [window setAutodisplay: YES]; - [window setAcceptsMouseMovedEvents: YES]; - - // We'll both retain and also release this on closing because plugin hosts can unexpectedly - // close the window for us, and also tend to get cause trouble if setReleasedWhenClosed is NO. - [window setReleasedWhenClosed: YES]; - [window retain]; + window.windowLevel = UIWindowLevelAlert; - [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0]; - [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0]; + [window addSubview: view]; + view.frame = CGRectMake (0, 0, r.size.width, r.size.height); } setTitle (component->getName()); } -NSViewComponentPeer::~NSViewComponentPeer() +UIViewComponentPeer::~UIViewComponentPeer() { view->owner = 0; [view removeFromSuperview]; @@ -259194,57 +259100,43 @@ NSViewComponentPeer::~NSViewComponentPeer() if (! isSharedWindow) { - [((JuceNSWindow*) window) setOwner: 0]; - [window close]; + [((JuceUIWindow*) window) setOwner: 0]; [window release]; } } -void* NSViewComponentPeer::getNativeHandle() const +void* UIViewComponentPeer::getNativeHandle() const { return view; } -void NSViewComponentPeer::setVisible (bool shouldBeVisible) +void UIViewComponentPeer::setVisible (bool shouldBeVisible) { - if (isSharedWindow) - { - [view setHidden: ! shouldBeVisible]; - } - else - { - if (shouldBeVisible) - [window orderFront: nil]; - else - [window orderOut: nil]; - } + view.hidden = ! shouldBeVisible; } -void NSViewComponentPeer::setTitle (const String& title) +void UIViewComponentPeer::setTitle (const String& title) { - const ScopedAutoReleasePool pool; - - if (! isSharedWindow) - [window setTitle: juceStringToNS (title)]; + // xxx is this possible? } -void NSViewComponentPeer::setPosition (int x, int y) +void UIViewComponentPeer::setPosition (int x, int y) { setBounds (x, y, component->getWidth(), component->getHeight(), false); } -void NSViewComponentPeer::setSize (int w, int h) +void UIViewComponentPeer::setSize (int w, int h) { setBounds (component->getX(), component->getY(), w, h, false); } -void NSViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNowFullScreen) +void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNowFullScreen) { fullScreen = isNowFullScreen; w = jmax (0, w); h = jmax (0, h); - NSRect r; + CGRect r; r.origin.x = (float) x; r.origin.y = (float) y; r.size.width = (float) w; @@ -259252,35 +259144,35 @@ void NSViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNo if (isSharedWindow) { - r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); + //r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); if ([view frame].size.width != r.size.width || [view frame].size.height != r.size.height) - [view setNeedsDisplay: true]; + [view setNeedsDisplay]; - [view setFrame: r]; + view.frame = r; } else { - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); + //r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height); - [window setFrame: [window frameRectForContentRect: r] - display: true]; + window.frame = r; + view.frame = CGRectMake (0, 0, r.size.width, r.size.height); } } -void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool global) const +void UIViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool global) const { - NSRect r = [view frame]; + CGRect r = [view frame]; if (global && [view window] != 0) { r = [view convertRect: r toView: nil]; - NSRect wr = [[view window] frame]; + CGRect wr = [[view window] frame]; r.origin.x += wr.origin.x; r.origin.y += wr.origin.y; - y = (int) ([[[NSScreen screens] objectAtIndex:0] frame].size.height - r.origin.y - r.size.height); + y = (int) ([[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height); } else { @@ -259292,26 +259184,26 @@ void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool h = (int) r.size.height; } -void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h) const +void UIViewComponentPeer::getBounds (int& x, int& y, int& w, int& h) const { getBounds (x, y, w, h, ! isSharedWindow); } -int NSViewComponentPeer::getScreenX() const +int UIViewComponentPeer::getScreenX() const { int x, y, w, h; getBounds (x, y, w, h, true); return x; } -int NSViewComponentPeer::getScreenY() const +int UIViewComponentPeer::getScreenY() const { int x, y, w, h; getBounds (x, y, w, h, true); return y; } -void NSViewComponentPeer::relativePositionToGlobal (int& x, int& y) +void UIViewComponentPeer::relativePositionToGlobal (int& x, int& y) { int wx, wy, ww, wh; getBounds (wx, wy, ww, wh, true); @@ -259319,7 +259211,7 @@ void NSViewComponentPeer::relativePositionToGlobal (int& x, int& y) y += wy; } -void NSViewComponentPeer::globalPositionToRelative (int& x, int& y) +void UIViewComponentPeer::globalPositionToRelative (int& x, int& y) { int wx, wy, ww, wh; getBounds (wx, wy, ww, wh, true); @@ -259327,14 +259219,14 @@ void NSViewComponentPeer::globalPositionToRelative (int& x, int& y) y -= wy; } -NSRect NSViewComponentPeer::constrainRect (NSRect r) +CGRect UIViewComponentPeer::constrainRect (CGRect r) { if (constrainer != 0) { - NSRect current = [window frame]; - current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; + CGRect current = [window frame]; + current.origin.y = [[UIScreen mainScreen] bounds].size.height - current.origin.y - current.size.height; - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; + r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height; int x = (int) r.origin.x; int y = (int) r.origin.y; @@ -259353,7 +259245,7 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) x == original.getX() && x + w != original.getRight()); r.origin.x = x; - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - y; + r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.size.height - y; r.size.width = w; r.size.height = h; } @@ -259361,23 +259253,17 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) return r; } -void NSViewComponentPeer::setMinimised (bool shouldBeMinimised) +void UIViewComponentPeer::setMinimised (bool shouldBeMinimised) { - if (! isSharedWindow) - { - if (shouldBeMinimised) - [window miniaturize: nil]; - else - [window deminiaturize: nil]; - } + // xxx } -bool NSViewComponentPeer::isMinimised() const +bool UIViewComponentPeer::isMinimised() const { - return window != 0 && [window isMiniaturized]; + return false; } -void NSViewComponentPeer::setFullScreen (bool shouldBeFullScreen) +void UIViewComponentPeer::setFullScreen (bool shouldBeFullScreen) { if (! isSharedWindow) { @@ -259397,22 +259283,22 @@ void NSViewComponentPeer::setFullScreen (bool shouldBeFullScreen) } } -bool NSViewComponentPeer::isFullScreen() const +bool UIViewComponentPeer::isFullScreen() const { return fullScreen; } -bool NSViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const +bool UIViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const { if (((unsigned int) x) >= (unsigned int) component->getWidth() || ((unsigned int) y) >= (unsigned int) component->getHeight()) return false; - NSPoint p; + CGPoint p; p.x = (float) x; p.y = (float) y; - NSView* v = [view hitTest: p]; + UIView* v = [view hitTest: p withEvent: nil]; if (trueIfInAChildWindow) return v != nil; @@ -259420,14 +259306,14 @@ bool NSViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) con return v == view; } -const BorderSize NSViewComponentPeer::getFrameSize() const +const BorderSize UIViewComponentPeer::getFrameSize() const { BorderSize b; if (! isSharedWindow) { - NSRect v = [view convertRect: [view frame] toView: nil]; - NSRect w = [window frame]; + CGRect v = [view convertRect: [view frame] toView: nil]; + CGRect w = [window frame]; b.setTop ((int) (w.size.height - (v.origin.y + v.size.height))); b.setBottom ((int) v.origin.y); @@ -259438,59 +259324,45 @@ const BorderSize NSViewComponentPeer::getFrameSize() const return b; } -bool NSViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) +bool UIViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) { if (! isSharedWindow) - { - [window setLevel: alwaysOnTop ? NSFloatingWindowLevel - : NSNormalWindowLevel]; - } + window.windowLevel = alwaysOnTop ? UIWindowLevelAlert : UIWindowLevelNormal; return true; } -void NSViewComponentPeer::toFront (bool makeActiveWindow) +void UIViewComponentPeer::toFront (bool makeActiveWindow) { if (isSharedWindow) - { - [[view superview] addSubview: view - positioned: NSWindowAbove - relativeTo: nil]; - } + [[view superview] bringSubviewToFront: view]; if (window != 0 && component->isVisible()) - { - if (makeActiveWindow) - [window makeKeyAndOrderFront: nil]; - else - [window orderFront: nil]; - } + [window makeKeyAndVisible]; } -void NSViewComponentPeer::toBehind (ComponentPeer* other) +void UIViewComponentPeer::toBehind (ComponentPeer* other) { - NSViewComponentPeer* o = (NSViewComponentPeer*) other; + UIViewComponentPeer* o = (UIViewComponentPeer*) other; if (isSharedWindow) { - [[view superview] addSubview: view - positioned: NSWindowBelow - relativeTo: o->view]; + [[view superview] insertSubview: view belowSubview: o->view]; } else { - [window orderWindow: NSWindowBelow - relativeTo: o->window != 0 ? [o->window windowNumber] - : nil ]; + jassertfalse // don't know how to do this } } -void NSViewComponentPeer::setIcon (const Image& /*newIcon*/) +void UIViewComponentPeer::setIcon (const Image& /*newIcon*/) { // to do.. } -void NSViewComponentPeer::viewFocusGain() +static UIViewComponentPeer* currentlyFocusedPeer = 0; + +void UIViewComponentPeer::viewFocusGain() { if (currentlyFocusedPeer != this) { @@ -259503,7 +259375,7 @@ void NSViewComponentPeer::viewFocusGain() } } -void NSViewComponentPeer::viewFocusLoss() +void UIViewComponentPeer::viewFocusLoss() { if (currentlyFocusedPeer == this) { @@ -259514,9 +259386,7 @@ void NSViewComponentPeer::viewFocusLoss() void juce_HandleProcessFocusChange() { - keysCurrentlyDown.clear(); - - if (NSViewComponentPeer::isValidPeer (currentlyFocusedPeer)) + if (UIViewComponentPeer::isValidPeer (currentlyFocusedPeer)) { if (Process::isForegroundProcess()) { @@ -259534,281 +259404,55 @@ void juce_HandleProcessFocusChange() } } -bool NSViewComponentPeer::isFocused() const +bool UIViewComponentPeer::isFocused() const { return isSharedWindow ? this == currentlyFocusedPeer : (window != 0 && [window isKeyWindow]); } -void NSViewComponentPeer::grabFocus() +void UIViewComponentPeer::grabFocus() { if (window != 0) { [window makeKeyWindow]; - [window makeFirstResponder: view]; - viewFocusGain(); } } -void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) -{ -} - -bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) -{ - String unicode (nsStringToJuce ([ev characters])); - String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); - int keyCode = getKeyCodeFromEvent (ev); - - //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0])); - //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0])); - - if (unicode.isNotEmpty() || keyCode != 0) - { - if (isKeyDown) - { - bool used = false; - - while (unicode.length() > 0) - { - juce_wchar textCharacter = unicode[0]; - unicode = unicode.substring (1); - - if (([ev modifierFlags] & NSCommandKeyMask) != 0) - textCharacter = 0; - - used = handleKeyUpOrDown (true) || used; - used = handleKeyPress (keyCode, textCharacter) || used; - } - - return used; - } - else - { - if (handleKeyUpOrDown (false)) - return true; - } - } - - return false; -} - -bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) -{ - updateKeysDown (ev, true); - bool used = handleKeyEvent (ev, true); - - if (([ev modifierFlags] & NSCommandKeyMask) != 0) - { - // for command keys, the key-up event is thrown away, so simulate one.. - updateKeysDown (ev, false); - used = (isValidPeer (this) && handleKeyEvent (ev, false)) || used; - } - - // (If we're running modally, don't allow unused keystrokes to be passed - // along to other blocked views..) - if (Component::getCurrentlyModalComponent() != 0) - used = true; - - return used; -} - -bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) -{ - updateKeysDown (ev, false); - return handleKeyEvent (ev, false) - || Component::getCurrentlyModalComponent() != 0; -} - -void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) -{ - updateModifiers (ev); - handleModifierKeysChange(); -} - -#if MACOS_10_4_OR_EARLIER -bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) -{ - if ([ev type] == NSKeyDown) - return redirectKeyDown (ev); - else if ([ev type] == NSKeyUp) - return redirectKeyUp (ev); - - return false; -} -#endif - -void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) -{ - updateModifiers (ev); - currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); - int x, y; - getMousePos (ev, view, x, y); - - handleMouseDown (x, y, getMouseTime (ev)); -} - -void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) -{ - const int oldMods = currentModifiers; - updateModifiers (ev); - currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); - int x, y; - getMousePos (ev, view, x, y); - - handleMouseUp (oldMods, x, y, getMouseTime (ev)); - showArrowCursorIfNeeded(); -} - -void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) -{ - updateModifiers (ev); - currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); - int x, y; - getMousePos (ev, view, x, y); - - handleMouseDrag (x, y, getMouseTime (ev)); -} - -void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) -{ - updateModifiers (ev); - int x, y; - getMousePos (ev, view, x, y); - - handleMouseMove (x, y, getMouseTime (ev)); - showArrowCursorIfNeeded(); -} - -void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) -{ - updateModifiers (ev); - int x, y; - getMousePos (ev, view, x, y); - - handleMouseEnter (x, y, getMouseTime (ev)); -} - -void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) -{ - updateModifiers (ev); - int x, y; - getMousePos (ev, view, x, y); - - handleMouseExit (x, y, getMouseTime (ev)); -} - -void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) -{ - updateModifiers (ev); - - handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), - roundFloatToInt ([ev deltaY] * 10.0f), - getMouseTime (ev)); -} - -void NSViewComponentPeer::showArrowCursorIfNeeded() -{ - if (Component::getComponentUnderMouse() == 0) - { - int mx, my; - Desktop::getInstance().getMousePosition (mx, my); - - if (Desktop::getInstance().findComponentAt (mx, my) == 0) - [[NSCursor arrowCursor] set]; - } -} - -BOOL NSViewComponentPeer::sendDragCallback (int type, id sender) -{ - NSString* bestType - = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; - - if (bestType == nil) - return false; - - NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; - int x = (int) p.x; - int y = (int) ([view frame].size.height - p.y); - - StringArray files; - - id list = [[sender draggingPasteboard] propertyListForType: bestType]; - if (list == nil) - return false; - - if ([list isKindOfClass: [NSArray class]]) - { - NSArray* items = (NSArray*) list; - - for (unsigned int i = 0; i < [items count]; ++i) - files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); - } - - if (files.size() == 0) - return false; - - if (type == 0) - handleFileDragMove (files, x, y); - else if (type == 1) - handleFileDragExit (files); - else if (type == 2) - handleFileDragDrop (files, x, y); - - return true; -} - -bool NSViewComponentPeer::isOpaque() +void UIViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) { - if (! getComponent()->isValidComponent()) - return true; - - return getComponent()->isOpaque(); } -void NSViewComponentPeer::drawRect (NSRect r) +void UIViewComponentPeer::drawRect (CGRect r) { if (r.size.width < 1.0f || r.size.height < 1.0f) return; - const float y = [view frame].size.height - (r.origin.y + r.size.height); + DBG (Rectangle (r.origin.x, r.origin.y, r.size.width, r.size.height).toString()); - JuceNSImage temp ((int) (r.size.width + 0.5f), + const float y = r.origin.y;//[view frame].size.height - (r.origin.y + r.size.height); + + JuceUIImage temp ((int) (r.size.width + 0.5f), (int) (r.size.height + 0.5f), - ! getComponent()->isOpaque()); + true);//! getComponent()->isOpaque()); LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage()); const int originX = -roundFloatToInt (r.origin.x); const int originY = -roundFloatToInt (y); context.setOrigin (originX, originY); - const NSRect* rects = 0; - NSInteger numRects = 0; - [view getRectsBeingDrawn: &rects count: &numRects]; - - RectangleList clip; - for (int i = 0; i < numRects; ++i) - { - clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x), - roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)), - roundFloatToInt (rects[i].size.width), - roundFloatToInt (rects[i].size.height))); - } + handlePaint (context); - if (context.reduceClipRegion (clip)) - { - handlePaint (context); - temp.draw (r.origin.x, r.origin.y, clip, originX, originY); - } + //CGContextClipToRect (UIGraphicsGetCurrentContext(), r); + temp.draw (r.origin.x, r.origin.y); } -bool NSViewComponentPeer::canBecomeKeyWindow() +bool UIViewComponentPeer::canBecomeKeyWindow() { return (getStyleFlags() & juce::ComponentPeer::windowIgnoresKeyPresses) == 0; } -bool NSViewComponentPeer::windowShouldClose() +bool UIViewComponentPeer::windowShouldClose() { if (! isValidPeer (this)) return YES; @@ -259817,93 +259461,77 @@ bool NSViewComponentPeer::windowShouldClose() return NO; } -void NSViewComponentPeer::redirectMovedOrResized() +void UIViewComponentPeer::redirectMovedOrResized() { handleMovedOrResized(); } void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) { - // Very annoyingly, this function has to use the old SetSystemUIMode function, - // which is in Carbon.framework. But, because there's no Cocoa equivalent, it - // is apparently still available in 64-bit apps.. - if (enableOrDisable) - { - SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0); - kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); - } - else - { - SetSystemUIMode (kUIModeNormal, 0); - } } -void NSViewComponentPeer::repaint (int x, int y, int w, int h) +void UIViewComponentPeer::repaint (int x, int y, int w, int h) { [view setNeedsDisplayInRect: - NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)), + CGRectMake ((float) x, (float) y,//([view frame].size.height - (y + h)), (float) w, (float) h)]; } -void NSViewComponentPeer::performAnyPendingRepaintsNow() +void UIViewComponentPeer::performAnyPendingRepaintsNow() { - [view displayIfNeeded]; } ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) { - return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo); + return new UIViewComponentPeer (this, styleFlags, (UIView*) windowToAttachTo); } -static Image* NSImageToJuceImage (NSImage* image) +static Image* UIImageToJuceImage (UIImage* image) { - JuceNSImage juceIm ((int) [image size].width, + JuceUIImage juceIm ((int) [image size].width, (int) [image size].height, true); - juceIm.drawNSImage (image); + juceIm.drawUIImage (image); return juceIm.getJuceImage().createCopy(); } Image* juce_createIconForFile (const File& file) { - const ScopedAutoReleasePool pool; - - NSImage* im = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())]; - return NSImageToJuceImage (im); + return 0; } const int KeyPress::spaceKey = ' '; const int KeyPress::returnKey = 0x0d; const int KeyPress::escapeKey = 0x1b; const int KeyPress::backspaceKey = 0x7f; -const int KeyPress::leftKey = NSLeftArrowFunctionKey; -const int KeyPress::rightKey = NSRightArrowFunctionKey; -const int KeyPress::upKey = NSUpArrowFunctionKey; -const int KeyPress::downKey = NSDownArrowFunctionKey; -const int KeyPress::pageUpKey = NSPageUpFunctionKey; -const int KeyPress::pageDownKey = NSPageDownFunctionKey; -const int KeyPress::endKey = NSEndFunctionKey; -const int KeyPress::homeKey = NSHomeFunctionKey; -const int KeyPress::deleteKey = NSDeleteFunctionKey; +const int KeyPress::leftKey = 0x1000; +const int KeyPress::rightKey = 0x1001; +const int KeyPress::upKey = 0x1002; +const int KeyPress::downKey = 0x1003; +const int KeyPress::pageUpKey = 0x1004; +const int KeyPress::pageDownKey = 0x1005; +const int KeyPress::endKey = 0x1006; +const int KeyPress::homeKey = 0x1007; +const int KeyPress::deleteKey = 0x1008; const int KeyPress::insertKey = -1; const int KeyPress::tabKey = 9; -const int KeyPress::F1Key = NSF1FunctionKey; -const int KeyPress::F2Key = NSF2FunctionKey; -const int KeyPress::F3Key = NSF3FunctionKey; -const int KeyPress::F4Key = NSF4FunctionKey; -const int KeyPress::F5Key = NSF5FunctionKey; -const int KeyPress::F6Key = NSF6FunctionKey; -const int KeyPress::F7Key = NSF7FunctionKey; -const int KeyPress::F8Key = NSF8FunctionKey; -const int KeyPress::F9Key = NSF9FunctionKey; -const int KeyPress::F10Key = NSF10FunctionKey; -const int KeyPress::F11Key = NSF1FunctionKey; -const int KeyPress::F12Key = NSF12FunctionKey; -const int KeyPress::F13Key = NSF13FunctionKey; -const int KeyPress::F14Key = NSF14FunctionKey; -const int KeyPress::F15Key = NSF15FunctionKey; -const int KeyPress::F16Key = NSF16FunctionKey; +const int KeyPress::F1Key = 0x2001; +const int KeyPress::F2Key = 0x2002; +const int KeyPress::F3Key = 0x2003; +const int KeyPress::F4Key = 0x2004; +const int KeyPress::F5Key = 0x2005; +const int KeyPress::F6Key = 0x2006; +const int KeyPress::F7Key = 0x2007; +const int KeyPress::F8Key = 0x2008; +const int KeyPress::F9Key = 0x2009; +const int KeyPress::F10Key = 0x200a; +const int KeyPress::F11Key = 0x200b; +const int KeyPress::F12Key = 0x200c; +const int KeyPress::F13Key = 0x200d; +const int KeyPress::F14Key = 0x200e; +const int KeyPress::F15Key = 0x200f; +const int KeyPress::F16Key = 0x2010; const int KeyPress::numberPad0 = 0x30020; const int KeyPress::numberPad1 = 0x30021; const int KeyPress::numberPad2 = 0x30022; @@ -259928,553 +259556,789 @@ const int KeyPress::fastForwardKey = 0x30002; const int KeyPress::rewindKey = 0x30003; #endif -/********* End of inlined file: juce_mac_NSViewComponentPeer.mm *********/ +/********* End of inlined file: juce_iphone_UIViewComponentPeer.mm *********/ -/********* Start of inlined file: juce_mac_MouseCursor.mm *********/ +/********* Start of inlined file: juce_iphone_Fonts.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). #ifdef JUCE_INCLUDED_FILE -static NSImage* juceImageToNSImage (const Image& image) +class FontHelper { - const ScopedAutoReleasePool pool; - int lineStride, pixelStride; - const uint8* pixels = image.lockPixelDataReadOnly (0, 0, image.getWidth(), image.getHeight(), - lineStride, pixelStride); - - NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes: NULL - pixelsWide: image.getWidth() - pixelsHigh: image.getHeight() - bitsPerSample: 8 - samplesPerPixel: image.hasAlphaChannel() ? 4 : 3 - hasAlpha: image.hasAlphaChannel() - isPlanar: NO - colorSpaceName: NSCalibratedRGBColorSpace - bitmapFormat: (NSBitmapFormat) 0 - bytesPerRow: lineStride - bitsPerPixel: pixelStride * 8]; - - unsigned char* newData = [rep bitmapData]; - memcpy (newData, pixels, lineStride * image.getHeight()); - image.releasePixelDataReadOnly (pixels); - - NSImage* im = [[NSImage alloc] init]; - [im addRepresentation: rep]; - [rep release]; + UIFont* font; - return im; -} +public: + String name; + bool isBold, isItalic, needsItalicTransform; + float fontSize, totalSize, ascent; + int refCount; -void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw() -{ - NSImage* im = juceImageToNSImage (image); - NSCursor* c = [[NSCursor alloc] initWithImage: im - hotSpot: NSMakePoint (hotspotX, hotspotY)]; - [im release]; + FontHelper (const String& name_, + const bool bold_, + const bool italic_, + const float size_) + : font (0), + name (name_), + isBold (bold_), + isItalic (italic_), + needsItalicTransform (false), + fontSize (size_), + refCount (1) + { + //attributes = [[NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] + // forKey: NSLigatureAttributeName] retain]; - return (void*) c; -} + font = [UIFont fontWithName: juceStringToNS (name_) size: size_]; -static void* juce_cursorFromData (const unsigned char* data, const int size, float hx, float hy) throw() -{ - Image* const im = ImageFileFormat::loadFrom ((const char*) data, size); - jassert (im != 0); + if (italic_) + { +/* NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; - if (im == 0) - return 0; + if (newFont == font) + needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform.. - void* const curs = juce_createMouseCursorFromImage (*im, - (int) (hx * im->getWidth()), - (int) (hy * im->getHeight())); - delete im; - return curs; -} + font = newFont;*/ + } -static void* juce_cursorFromWebKitFile (const char* filename, float hx, float hy) -{ - File f ("/System/Library/Frameworks/WebKit.framework/Frameworks/WebCore.framework/Resources"); +// if (bold_) + // font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; - MemoryBlock mb; - if (f.getChildFile (filename).loadFileAsData (mb)) - return juce_cursorFromData ((const unsigned char*) mb.getData(), mb.getSize(), hx, hy); + [font retain]; - return 0; -} + ascent = fabsf (font.ascender); + totalSize = ascent + fabsf (font.descender); + } -void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw() -{ - const ScopedAutoReleasePool pool; - NSCursor* c = 0; + ~FontHelper() + { + [font release]; + } - switch (type) + bool getPathAndKerning (const juce_wchar char1, + const juce_wchar char2, + Path* path, + float& kerning, + float* ascent, + float* descent) { - case MouseCursor::NormalCursor: - c = [NSCursor arrowCursor]; - break; + const ScopedAutoReleasePool pool; - case MouseCursor::NoCursor: - { - Image blank (Image::ARGB, 8, 8, true); - return juce_createMouseCursorFromImage (blank, 0, 0); - } + return false; +/* if (font == 0 + || ! [[font coveredCharacterSet] longCharacterIsMember: (UTF32Char) char1]) + return false; - case MouseCursor::DraggingHandCursor: - c = [NSCursor openHandCursor]; - break; + String chars; + chars << ' ' << char1 << char2; - case MouseCursor::CopyingCursor: - return juce_cursorFromWebKitFile ("copyCursor.png", 0, 0); + NSTextStorage* textStorage = [[[NSTextStorage alloc] initWithString: juceStringToNS (chars) + attributes: attributes] autorelease]; + NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; + NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; + [layoutManager addTextContainer: textContainer]; + [textStorage addLayoutManager: layoutManager]; + [textStorage setFont: font]; - case MouseCursor::WaitCursor: - c = [NSCursor arrowCursor]; // avoid this on the mac, let the OS provide the beachball - break; - //return juce_cursorFromWebKitFile ("waitCursor.png", 0.5f, 0.5f); + unsigned int glyphIndex = [layoutManager glyphRangeForCharacterRange: NSMakeRange (1, 1) + actualCharacterRange: 0].location; + NSPoint p1 = [layoutManager locationForGlyphAtIndex: glyphIndex]; + NSPoint p2 = [layoutManager locationForGlyphAtIndex: glyphIndex + 1]; + kerning = p2.x - p1.x; - case MouseCursor::IBeamCursor: - c = [NSCursor IBeamCursor]; - break; + if (ascent != 0) + *ascent = this->ascent; - case MouseCursor::PointingHandCursor: - c = [NSCursor pointingHandCursor]; - break; + if (descent != 0) + *descent = fabsf ([font descender]); - case MouseCursor::LeftRightResizeCursor: - c = [NSCursor resizeLeftRightCursor]; - break; + if (path != 0) + { + NSBezierPath* bez = [NSBezierPath bezierPath]; + [bez moveToPoint: NSMakePoint (0, 0)]; + [bez appendBezierPathWithGlyph: [layoutManager glyphAtIndex: glyphIndex] + inFont: font]; - case MouseCursor::LeftEdgeResizeCursor: - c = [NSCursor resizeLeftCursor]; - break; + for (int i = 0; i < [bez elementCount]; ++i) + { + NSPoint p[3]; + switch ([bez elementAtIndex: i associatedPoints: p]) + { + case NSMoveToBezierPathElement: + path->startNewSubPath (p[0].x, -p[0].y); + break; + case NSLineToBezierPathElement: + path->lineTo (p[0].x, -p[0].y); + break; + case NSCurveToBezierPathElement: + path->cubicTo (p[0].x, -p[0].y, p[1].x, -p[1].y, p[2].x, -p[2].y); + break; + case NSClosePathBezierPathElement: + path->closeSubPath(); + break; + default: + jassertfalse + break; + } + } - case MouseCursor::RightEdgeResizeCursor: - c = [NSCursor resizeRightCursor]; - break; + if (needsItalicTransform) + path->applyTransform (AffineTransform::identity.sheared (-0.15, 0)); + } - case MouseCursor::UpDownResizeCursor: - case MouseCursor::TopEdgeResizeCursor: - case MouseCursor::BottomEdgeResizeCursor: - return juce_cursorFromWebKitFile ("northSouthResizeCursor.png", 0.5f, 0.5f); + return kerning != 0;*/ + } - case MouseCursor::TopLeftCornerResizeCursor: - case MouseCursor::BottomRightCornerResizeCursor: - return juce_cursorFromWebKitFile ("northWestSouthEastResizeCursor.png", 0.5f, 0.5f); + juce_wchar getDefaultChar() + { + return 0; + } +}; - case MouseCursor::TopRightCornerResizeCursor: - case MouseCursor::BottomLeftCornerResizeCursor: - return juce_cursorFromWebKitFile ("northEastSouthWestResizeCursor.png", 0.5f, 0.5f); +class FontHelperCache : public Timer, + public DeletedAtShutdown +{ + VoidArray cache; - case MouseCursor::UpDownLeftRightResizeCursor: - return juce_cursorFromWebKitFile ("moveCursor.png", 0.5f, 0.5f); +public: + FontHelperCache() + { + } - case MouseCursor::CrosshairCursor: - c = [NSCursor crosshairCursor]; - break; + ~FontHelperCache() + { + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); + delete f; + } + + clearSingletonInstance(); } - [c retain]; - return (void*) c; + FontHelper* getFont (const String& name, + const bool bold, + const bool italic, + const float size = 1024) + { + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); + + if (f->name == name + && f->isBold == bold + && f->isItalic == italic + && f->fontSize == size) + { + f->refCount++; + return f; + } + } + + FontHelper* const f = new FontHelper (name, bold, italic, size); + cache.add (f); + return f; + } + + void releaseFont (FontHelper* f) + { + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f2 = (FontHelper*) cache.getUnchecked(i); + + if (f == f2) + { + f->refCount--; + + if (f->refCount == 0) + startTimer (5000); + + break; + } + } + } + + void timerCallback() + { + stopTimer(); + + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); + + if (f->refCount == 0) + { + cache.remove (i); + delete f; + } + } + + if (cache.size() == 0) + delete this; + } + + juce_DeclareSingleton_SingleThreaded_Minimal (FontHelperCache) +}; + +juce_ImplementSingleton_SingleThreaded (FontHelperCache) + +void Typeface::initialiseTypefaceCharacteristics (const String& fontName, + bool bold, + bool italic, + bool addAllGlyphsToFont) throw() +{ + // This method is only safe to be called from the normal UI thread.. + jassert (MessageManager::getInstance()->isThisTheMessageThread()); + + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (fontName, bold, italic); + + clear(); + setAscent (helper->ascent / helper->totalSize); + setName (fontName); + setDefaultCharacter (helper->getDefaultChar()); + setBold (bold); + setItalic (italic); + + if (addAllGlyphsToFont) + { + //xxx + jassertfalse + } + + FontHelperCache::getInstance()->releaseFont (helper); } -void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw() +bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() { - NSCursor* c = (NSCursor*) cursorHandle; - [c release]; + // This method is only safe to be called from the normal UI thread.. + jassert (MessageManager::getInstance()->isThisTheMessageThread()); + + if (character == 0) + return false; + + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (getName(), isBold(), isItalic()); + + Path path; + float width; + bool foundOne = false; + + if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) + { + path.applyTransform (AffineTransform::scale (1.0f / helper->totalSize, + 1.0f / helper->totalSize)); + + addGlyph (character, path, width / helper->totalSize); + + for (int i = 0; i < glyphs.size(); ++i) + { + const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i); + + float kerning; + if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) + { + kerning = (kerning - width) / helper->totalSize; + + if (kerning != 0) + addKerningPair (character, g->getCharacter(), kerning); + } + + if (helper->getPathAndKerning (g->getCharacter(), character, 0, kerning, 0, 0)) + { + kerning = kerning / helper->totalSize - g->width; + + if (kerning != 0) + addKerningPair (g->getCharacter(), character, kerning); + } + } + + foundOne = true; + } + + FontHelperCache::getInstance()->releaseFont (helper); + return foundOne; } -void MouseCursor::showInAllWindows() const throw() +const StringArray Font::findAllTypefaceNames() throw() { - showInWindow (0); + StringArray names; + + const ScopedAutoReleasePool pool; + NSArray* fonts = [UIFont familyNames]; + + for (unsigned int i = 0; i < [fonts count]; ++i) + names.add (nsStringToJuce ((NSString*) [fonts objectAtIndex: i])); + + names.sort (true); + return names; } -void MouseCursor::showInWindow (ComponentPeer*) const throw() +void Typeface::getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw() { - NSCursor* const c = (NSCursor*) getHandle(); - [c set]; + defaultSans = "Lucida Grande"; + defaultSerif = "Times New Roman"; + defaultFixed = "Monaco"; } #endif -/********* End of inlined file: juce_mac_MouseCursor.mm *********/ +/********* End of inlined file: juce_iphone_Fonts.mm *********/ -/********* Start of inlined file: juce_mac_NSViewComponent.mm *********/ +/********* Start of inlined file: juce_iphone_MessageManager.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). #ifdef JUCE_INCLUDED_FILE -class NSViewComponentInternal : public ComponentMovementWatcher +struct CallbackMessagePayload { - Component* const owner; - NSViewComponentPeer* currentPeer; - bool wasShowing; + MessageCallbackFunction* function; + void* parameter; + void* volatile result; + bool volatile hasBeenExecuted; +}; + +/* 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: - NSView* const view; + AppDelegateRedirector() {} + virtual ~AppDelegateRedirector() {} - NSViewComponentInternal (NSView* const view_, Component* const owner_) - : ComponentMovementWatcher (owner_), - owner (owner_), - currentPeer (0), - wasShowing (false), - view (view_) + virtual BOOL openFile (const NSString* filename) { - [view_ retain]; + if (JUCEApplication::getInstance() != 0) + { + JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); + return YES; + } - if (owner_->isShowing()) - componentPeerChanged(); + return NO; } - ~NSViewComponentInternal() + virtual void openFiles (NSArray* filenames) { - [view removeFromSuperview]; - [view release]; + StringArray files; + for (unsigned int i = 0; i < [filenames count]; ++i) + files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); + + if (files.size() > 0 && JUCEApplication::getInstance() != 0) + { + JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); + } } - void componentMovedOrResized (Component& comp, bool wasMoved, bool wasResized) + virtual void focusChanged() { - ComponentMovementWatcher::componentMovedOrResized (comp, wasMoved, wasResized); - - // The ComponentMovementWatcher version of this method avoids calling - // us when the top-level comp is resized, but for an NSView we need to know this - // because with inverted co-ords, we need to update the position even if the - // top-left pos hasn't changed - if (comp.isOnDesktop() && wasResized) - componentMovedOrResized (wasMoved, wasResized); + juce_HandleProcessFocusChange(); } - void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) + virtual void deliverMessage (void* message) { - Component* const topComp = owner->getTopLevelComponent(); - - if (topComp->getPeer() != 0) - { - int x = 0, y = 0; - owner->relativePositionToOtherComponent (topComp, x, y); - - NSRect r; - r.origin.x = (float) x; - r.origin.y = (float) y; - r.size.width = (float) owner->getWidth(); - r.size.height = (float) owner->getHeight(); - r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); - - [view setFrame: r]; - } + // no need for an mm lock here - deliverMessage locks it + MessageManager::getInstance()->deliverMessage (message); } - void componentPeerChanged() + virtual void performCallback (CallbackMessagePayload* pl) { - NSViewComponentPeer* const peer = dynamic_cast (owner->getPeer()); - - if (currentPeer != peer) - { - [view removeFromSuperview]; - currentPeer = peer; - - if (peer != 0) - { - [peer->view addSubview: view]; - componentMovedOrResized (false, false); - } - } - - [view setHidden: ! owner->isShowing()]; + pl->result = (*pl->function) (pl->parameter); + pl->hasBeenExecuted = true; } - void componentVisibilityChanged (Component&) + virtual void deleteSelf() { - componentPeerChanged(); + delete this; } +}; - juce_UseDebuggingNewOperator +END_JUCE_NAMESPACE +using namespace JUCE_NAMESPACE; -private: - NSViewComponentInternal (const NSViewComponentInternal&); - const NSViewComponentInternal& operator= (const NSViewComponentInternal&); -}; +#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) -NSViewComponent::NSViewComponent() - : info (0) +static int numPendingMessages = 0; + +@interface JuceAppDelegate : NSObject { +@private + id oldDelegate; + AppDelegateRedirector* redirector; + +@public + bool flushingMessages; } -NSViewComponent::~NSViewComponent() +- (JuceAppDelegate*) init; +- (void) dealloc; +- (BOOL) application: (UIApplication*) application handleOpenURL: (NSURL*) url; +- (void) applicationDidBecomeActive: (NSNotification*) aNotification; +- (void) applicationDidResignActive: (NSNotification*) aNotification; +- (void) applicationWillUnhide: (NSNotification*) aNotification; +- (void) customEvent: (id) data; +- (void) performCallback: (id) info; +- (void) dummyMethod; +@end + +@implementation JuceAppDelegate + +- (JuceAppDelegate*) init { - delete info; + [super init]; + + redirector = new AppDelegateRedirector(); + numPendingMessages = 0; + flushingMessages = false; + + oldDelegate = [[UIApplication sharedApplication] delegate]; + [[UIApplication sharedApplication] setDelegate: self]; + + return self; } -void NSViewComponent::setView (void* view) +- (void) dealloc { - if (view != getView()) - { - deleteAndZero (info); + if (oldDelegate != 0) + [[UIApplication sharedApplication] setDelegate: oldDelegate]; - if (view != 0) - info = new NSViewComponentInternal ((NSView*) view, this); - } + redirector->deleteSelf(); + [super dealloc]; } -void* NSViewComponent::getView() const +- (BOOL) application: (UIApplication*) application handleOpenURL: (NSURL*) url { - return info == 0 ? 0 : info->view; + return redirector->openFile ([url absoluteString]); } -void NSViewComponent::paint (Graphics& g) +- (void) applicationDidBecomeActive: (NSNotification*) aNotification { + redirector->focusChanged(); } -#endif -/********* End of inlined file: juce_mac_NSViewComponent.mm *********/ - -/********* Start of inlined file: juce_mac_AppleRemote.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE - -AppleRemoteDevice::AppleRemoteDevice() - : device (0), - queue (0), - remoteId (0) +- (void) applicationDidResignActive: (NSNotification*) aNotification { + redirector->focusChanged(); } -AppleRemoteDevice::~AppleRemoteDevice() +- (void) applicationWillUnhide: (NSNotification*) aNotification { - stop(); + redirector->focusChanged(); } -static io_object_t getAppleRemoteDevice() throw() +- (void) customEvent: (id) n { - CFMutableDictionaryRef dict = IOServiceMatching ("AppleIRController"); - - io_iterator_t iter = 0; - io_object_t iod = 0; + atomicDecrement (numPendingMessages); - if (IOServiceGetMatchingServices (kIOMasterPortDefault, dict, &iter) == kIOReturnSuccess - && iter != 0) - { - iod = IOIteratorNext (iter); - } + NSData* data = (NSData*) n; + void* message = 0; + [data getBytes: &message length: sizeof (message)]; + [data release]; - IOObjectRelease (iter); - return iod; + if (message != 0 && ! flushingMessages) + redirector->deliverMessage (message); } -static bool createAppleRemoteInterface (io_object_t iod, void** device) throw() +- (void) performCallback: (id) info { - jassert (*device == 0); - io_name_t classname; + if ([info isKindOfClass: [NSData class]]) + { + CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; - if (IOObjectGetClass (iod, classname) == kIOReturnSuccess) + if (pl != 0) + redirector->performCallback (pl); + } + else { - IOCFPlugInInterface** cfPlugInInterface = 0; - SInt32 score = 0; + jassertfalse // should never get here! + } +} - if (IOCreatePlugInInterfaceForService (iod, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &cfPlugInInterface, - &score) == kIOReturnSuccess) - { - HRESULT hr = (*cfPlugInInterface)->QueryInterface (cfPlugInInterface, - CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), - device); +- (void) dummyMethod {} // (used as a way of running a dummy thread) - (void) hr; +@end - (*cfPlugInInterface)->Release (cfPlugInInterface); - } - } +BEGIN_JUCE_NAMESPACE - return *device != 0; +static JuceAppDelegate* juceAppDelegate = 0; + +void MessageManager::runDispatchLoop() +{ + jassert (isThisTheMessageThread()); // must only be called by the message thread + + runDispatchLoopUntil (-1); } -bool AppleRemoteDevice::start (const bool inExclusiveMode) throw() +static const int quitMessageId = 0xfffff321; + +void MessageManager::stopDispatchLoop() { - if (queue != 0) - return true; + Message* const m = new Message (quitMessageId, 0, 0, 0); + m->messageRecipient = 0; + postMessageToQueue (m); - stop(); + quitMessagePosted = true; +} - bool result = false; - io_object_t iod = getAppleRemoteDevice(); +bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) +{ + const ScopedAutoReleasePool pool; + jassert (isThisTheMessageThread()); // must only be called by the message thread - if (iod != 0) + uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor; + NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001]; + + while (! quitMessagePosted) { - if (createAppleRemoteInterface (iod, &device) && open (inExclusiveMode)) - result = true; - else - stop(); + const ScopedAutoReleasePool pool; - IOObjectRelease (iod); + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode + beforeDate: endDate]; + + if (millisecondsToRunFor >= 0 && Time::getMillisecondCounter() >= endTime) + break; } - return result; + return ! quitMessagePosted; } -void AppleRemoteDevice::stop() throw() +void MessageManager::doPlatformSpecificInitialisation() { - if (queue != 0) - { - (*(IOHIDQueueInterface**) queue)->stop ((IOHIDQueueInterface**) queue); - (*(IOHIDQueueInterface**) queue)->dispose ((IOHIDQueueInterface**) queue); - (*(IOHIDQueueInterface**) queue)->Release ((IOHIDQueueInterface**) queue); - queue = 0; - } + if (juceAppDelegate == 0) + juceAppDelegate = [[JuceAppDelegate alloc] init]; +} - if (device != 0) +void MessageManager::doPlatformSpecificShutdown() +{ + if (juceAppDelegate != 0) { - (*(IOHIDDeviceInterface**) device)->close ((IOHIDDeviceInterface**) device); - (*(IOHIDDeviceInterface**) device)->Release ((IOHIDDeviceInterface**) device); - device = 0; + [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; + [[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; + + // Annoyingly, cancelPerformSelectorsWithTarget can't actually cancel the messages + // sent by performSelectorOnMainThread, so need to manually flush these before quitting.. + juceAppDelegate->flushingMessages = true; + + for (int i = 100; --i >= 0 && numPendingMessages > 0;) + { + const ScopedAutoReleasePool pool; + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode + beforeDate: [NSDate dateWithTimeIntervalSinceNow: 5 * 0.001]]; + } + + [juceAppDelegate release]; + juceAppDelegate = 0; } } -bool AppleRemoteDevice::isActive() const throw() +bool juce_postMessageToSystemQueue (void* message) { - return queue != 0; + atomicIncrement (numPendingMessages); + + [juceAppDelegate performSelectorOnMainThread: @selector (customEvent:) + withObject: (id) [[NSData alloc] initWithBytes: &message length: (int) sizeof (message)] + waitUntilDone: NO]; + return true; } -static void appleRemoteQueueCallback (void* const target, const IOReturn result, void*, void*) +void MessageManager::broadcastMessage (const String& value) throw() { - if (result == kIOReturnSuccess) - ((AppleRemoteDevice*) target)->handleCallbackInternal(); } -bool AppleRemoteDevice::open (const bool openInExclusiveMode) throw() +void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, + void* data) { - Array cookies; + 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()); - CFArrayRef elements; - IOHIDDeviceInterface122** const device122 = (IOHIDDeviceInterface122**) device; + const ScopedAutoReleasePool pool; - if ((*device122)->copyMatchingElements (device122, 0, &elements) != kIOReturnSuccess) - return false; + CallbackMessagePayload cmp; + cmp.function = callback; + cmp.parameter = data; + cmp.result = 0; + cmp.hasBeenExecuted = false; - for (int i = 0; i < CFArrayGetCount (elements); ++i) - { - CFDictionaryRef element = (CFDictionaryRef) CFArrayGetValueAtIndex (elements, i); + [juceAppDelegate performSelectorOnMainThread: @selector (performCallback:) + withObject: [NSData dataWithBytesNoCopy: &cmp + length: sizeof (cmp) + freeWhenDone: NO] + waitUntilDone: YES]; - // get the cookie - CFTypeRef object = CFDictionaryGetValue (element, CFSTR (kIOHIDElementCookieKey)); + return cmp.result; + } +} - if (object == 0 || CFGetTypeID (object) != CFNumberGetTypeID()) - continue; +#endif +/********* End of inlined file: juce_iphone_MessageManager.mm *********/ - long number; - if (! CFNumberGetValue ((CFNumberRef) object, kCFNumberLongType, &number)) - continue; +/********* Start of inlined file: juce_mac_FileChooser.mm *********/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#ifdef JUCE_INCLUDED_FILE - cookies.add ((int) number); - } +#if JUCE_MAC - CFRelease (elements); +END_JUCE_NAMESPACE +using namespace JUCE_NAMESPACE; - if ((*(IOHIDDeviceInterface**) device) - ->open ((IOHIDDeviceInterface**) device, - openInExclusiveMode ? kIOHIDOptionsTypeSeizeDevice - : kIOHIDOptionsTypeNone) == KERN_SUCCESS) - { - queue = (*(IOHIDDeviceInterface**) device)->allocQueue ((IOHIDDeviceInterface**) device); +#define JuceFileChooserDelegate MakeObjCClassName(JuceFileChooserDelegate) - if (queue != 0) - { - (*(IOHIDQueueInterface**) queue)->create ((IOHIDQueueInterface**) queue, 0, 12); +#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +@interface JuceFileChooserDelegate : NSObject +#else +@interface JuceFileChooserDelegate : NSObject +#endif +{ + StringArray* filters; +} - for (int i = 0; i < cookies.size(); ++i) - { - IOHIDElementCookie cookie = (IOHIDElementCookie) cookies.getUnchecked(i); - (*(IOHIDQueueInterface**) queue)->addElement ((IOHIDQueueInterface**) queue, cookie, 0); - } +- (JuceFileChooserDelegate*) initWithFilters: (StringArray*) filters_; +- (void) dealloc; +- (BOOL) panel: (id) sender shouldShowFilename: (NSString*) filename; - CFRunLoopSourceRef eventSource; +@end - if ((*(IOHIDQueueInterface**) queue) - ->createAsyncEventSource ((IOHIDQueueInterface**) queue, &eventSource) == KERN_SUCCESS) - { - if ((*(IOHIDQueueInterface**) queue)->setEventCallout ((IOHIDQueueInterface**) queue, - appleRemoteQueueCallback, this, 0) == KERN_SUCCESS) - { - CFRunLoopAddSource (CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); +@implementation JuceFileChooserDelegate +- (JuceFileChooserDelegate*) initWithFilters: (StringArray*) filters_ +{ + [super init]; + filters = filters_; + return self; +} - (*(IOHIDQueueInterface**) queue)->start ((IOHIDQueueInterface**) queue); +- (void) dealloc +{ + delete filters; + [super dealloc]; +} - return true; - } - } - } - } +- (BOOL) panel: (id) sender shouldShowFilename: (NSString*) filename +{ + const String fname (nsStringToJuce (filename)); - return false; + for (int i = filters->size(); --i >= 0;) + if (fname.matchesWildcard ((*filters)[i], true)) + return true; + + return File (fname).isDirectory(); } +@end -void AppleRemoteDevice::handleCallbackInternal() +BEGIN_JUCE_NAMESPACE + +void FileChooser::showPlatformDialog (OwnedArray& results, + const String& title, + const File& currentFileOrDirectory, + const String& filter, + bool selectsDirectory, + bool isSaveDialogue, + bool warnAboutOverwritingExistingFiles, + bool selectMultipleFiles, + FilePreviewComponent* extraInfoComponent) { - int totalValues = 0; - AbsoluteTime nullTime = { 0, 0 }; - char cookies [12]; - int numCookies = 0; + const ScopedAutoReleasePool pool; - while (numCookies < numElementsInArray (cookies)) + StringArray* filters = new StringArray(); + filters->addTokens (filter.replaceCharacters (T(",:"), T(";;")), T(";"), 0); + filters->trim(); + filters->removeEmptyStrings(); + + JuceFileChooserDelegate* delegate = [[JuceFileChooserDelegate alloc] initWithFilters: filters]; + [delegate autorelease]; + + NSSavePanel* panel = isSaveDialogue ? [NSSavePanel savePanel] + : [NSOpenPanel openPanel]; + + [panel setTitle: juceStringToNS (title)]; + + if (! isSaveDialogue) { - IOHIDEventStruct e; + NSOpenPanel* openPanel = (NSOpenPanel*) panel; + [openPanel setCanChooseDirectories: selectsDirectory]; + [openPanel setCanChooseFiles: ! selectsDirectory]; + [openPanel setAllowsMultipleSelection: selectMultipleFiles]; + } - if ((*(IOHIDQueueInterface**) queue)->getNextEvent ((IOHIDQueueInterface**) queue, &e, nullTime, 0) != kIOReturnSuccess) - break; + [panel setDelegate: delegate]; - if ((int) e.elementCookie == 19) + String directory, filename; + + if (currentFileOrDirectory.isDirectory()) + { + directory = currentFileOrDirectory.getFullPathName(); + } + else + { + directory = currentFileOrDirectory.getParentDirectory().getFullPathName(); + filename = currentFileOrDirectory.getFileName(); + } + + if ([panel runModalForDirectory: juceStringToNS (directory) + file: juceStringToNS (filename)] + == NSOKButton) + { + if (isSaveDialogue) { - remoteId = e.value; - buttonPressed (switched, false); + results.add (new File (nsStringToJuce ([panel filename]))); } else { - totalValues += e.value; - cookies [numCookies++] = (char) (pointer_sized_int) e.elementCookie; + NSOpenPanel* openPanel = (NSOpenPanel*) panel; + NSArray* urls = [openPanel filenames]; + for (unsigned int i = 0; i < [urls count]; ++i) + { + NSString* f = [urls objectAtIndex: i]; + results.add (new File (nsStringToJuce (f))); + } } } - cookies [numCookies++] = 0; - //DBG (String::toHexString ((uint8*) cookies, numCookies, 1) + " " + String (totalValues)); - - static const char buttonPatterns[] = - { - 0x1f, 0x14, 0x12, 0x1f, 0x14, 0x12, 0, - 0x1f, 0x15, 0x12, 0x1f, 0x15, 0x12, 0, - 0x1f, 0x1d, 0x1c, 0x12, 0, - 0x1f, 0x1e, 0x1c, 0x12, 0, - 0x1f, 0x16, 0x12, 0x1f, 0x16, 0x12, 0, - 0x1f, 0x17, 0x12, 0x1f, 0x17, 0x12, 0, - 0x1f, 0x12, 0x04, 0x02, 0, - 0x1f, 0x12, 0x03, 0x02, 0, - 0x1f, 0x12, 0x1f, 0x12, 0, - 0x23, 0x1f, 0x12, 0x23, 0x1f, 0x12, 0, - 19, 0 - }; + [panel setDelegate: nil]; +} - int buttonNum = (int) menuButton; - int i = 0; +#else - while (i < numElementsInArray (buttonPatterns)) - { - if (strcmp (cookies, buttonPatterns + i) == 0) - { - buttonPressed ((ButtonType) buttonNum, totalValues > 0); - break; - } +void FileChooser::showPlatformDialog (OwnedArray& results, + const String& title, + const File& currentFileOrDirectory, + const String& filter, + bool selectsDirectory, + bool isSaveDialogue, + bool warnAboutOverwritingExistingFiles, + bool selectMultipleFiles, + FilePreviewComponent* extraInfoComponent) +{ + const ScopedAutoReleasePool pool; - i += strlen (buttonPatterns + i) + 1; - ++buttonNum; - } + jassertfalse //xxx to do } #endif -/********* End of inlined file: juce_mac_AppleRemote.mm *********/ + +#endif +/********* End of inlined file: juce_mac_FileChooser.mm *********/ /********* Start of inlined file: juce_mac_OpenGLComponent.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_OPENGL +#if JUCE_MAC + END_JUCE_NAMESPACE #define ThreadSafeNSOpenGLView MakeObjCClassName(ThreadSafeNSOpenGLView) @@ -260758,6827 +260622,2666 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/, //jassertfalse //xxx can't see how you do this in cocoa! } +#else + +OpenGLContext* OpenGLContext::createContextForWindow (Component* const component, + const OpenGLPixelFormat& pixelFormat, + const OpenGLContext* const contextToShareWith) +{ + return 0; +} + +void juce_glViewport (const int w, const int h) +{ + //glViewport (0, 0, w, h); +} + +#endif + #endif /********* End of inlined file: juce_mac_OpenGLComponent.mm *********/ -/********* Start of inlined file: juce_mac_MainMenu.mm *********/ +/********* Start of inlined file: juce_mac_MouseCursor.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). #ifdef JUCE_INCLUDED_FILE -class JuceMainMenuHandler; +#if JUCE_MAC -END_JUCE_NAMESPACE -using namespace JUCE_NAMESPACE; +static NSImage* juceImageToNSImage (const Image& image) +{ + const ScopedAutoReleasePool pool; + int lineStride, pixelStride; + const uint8* pixels = image.lockPixelDataReadOnly (0, 0, image.getWidth(), image.getHeight(), + lineStride, pixelStride); -#define JuceMenuCallback MakeObjCClassName(JuceMenuCallback) + NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes: NULL + pixelsWide: image.getWidth() + pixelsHigh: image.getHeight() + bitsPerSample: 8 + samplesPerPixel: image.hasAlphaChannel() ? 4 : 3 + hasAlpha: image.hasAlphaChannel() + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bitmapFormat: (NSBitmapFormat) 0 + bytesPerRow: lineStride + bitsPerPixel: pixelStride * 8]; -#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 -@interface JuceMenuCallback : NSObject -#else -@interface JuceMenuCallback : NSObject -#endif -{ - JuceMainMenuHandler* owner; -} + unsigned char* newData = [rep bitmapData]; + memcpy (newData, pixels, lineStride * image.getHeight()); + image.releasePixelDataReadOnly (pixels); -- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_; -- (void) dealloc; -- (void) menuItemInvoked: (id) menu; -- (void) menuNeedsUpdate: (NSMenu*) menu; -@end -BEGIN_JUCE_NAMESPACE + NSImage* im = [[NSImage alloc] init]; + [im addRepresentation: rep]; + [rep release]; -class JuceMainMenuHandler : private MenuBarModelListener, - private DeletedAtShutdown + return im; +} + +void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw() { -public: - static JuceMainMenuHandler* instance; + NSImage* im = juceImageToNSImage (image); + NSCursor* c = [[NSCursor alloc] initWithImage: im + hotSpot: NSMakePoint (hotspotX, hotspotY)]; + [im release]; - JuceMainMenuHandler() throw() - : currentModel (0), - lastUpdateTime (0) - { - callback = [[JuceMenuCallback alloc] initWithOwner: this]; - } + return (void*) c; +} - ~JuceMainMenuHandler() throw() - { - setMenu (0); +static void* juce_cursorFromData (const unsigned char* data, const int size, float hx, float hy) throw() +{ + Image* const im = ImageFileFormat::loadFrom ((const char*) data, size); + jassert (im != 0); - jassert (instance == this); - instance = 0; + if (im == 0) + return 0; - [callback release]; - } + void* const curs = juce_createMouseCursorFromImage (*im, + (int) (hx * im->getWidth()), + (int) (hy * im->getHeight())); + delete im; + return curs; +} - void setMenu (MenuBarModel* const newMenuBarModel) throw() - { - if (currentModel != newMenuBarModel) - { - if (currentModel != 0) - currentModel->removeListener (this); +static void* juce_cursorFromWebKitFile (const char* filename, float hx, float hy) +{ + File f ("/System/Library/Frameworks/WebKit.framework/Frameworks/WebCore.framework/Resources"); - currentModel = newMenuBarModel; + MemoryBlock mb; + if (f.getChildFile (filename).loadFileAsData (mb)) + return juce_cursorFromData ((const unsigned char*) mb.getData(), mb.getSize(), hx, hy); - if (currentModel != 0) - currentModel->addListener (this); + return 0; +} - menuBarItemsChanged (0); - } - } +void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw() +{ + const ScopedAutoReleasePool pool; + NSCursor* c = 0; - void addSubMenu (NSMenu* parent, const PopupMenu& child, - const String& name, const int menuId, const int tag) + switch (type) { - NSMenuItem* item = [parent addItemWithTitle: juceStringToNS (name) - action: nil - keyEquivalent: @""]; - [item setTag: tag]; + case MouseCursor::NormalCursor: + c = [NSCursor arrowCursor]; + break; - NSMenu* sub = createMenu (child, name, menuId, tag); + case MouseCursor::NoCursor: + { + Image blank (Image::ARGB, 8, 8, true); + return juce_createMouseCursorFromImage (blank, 0, 0); + } - [parent setSubmenu: sub forItem: item]; - [sub setAutoenablesItems: false]; - [sub release]; - } + case MouseCursor::DraggingHandCursor: + c = [NSCursor openHandCursor]; + break; - void updateSubMenu (NSMenuItem* parentItem, const PopupMenu& menuToCopy, - const String& name, const int menuId, const int tag) - { - [parentItem setTag: tag]; - NSMenu* menu = [parentItem submenu]; + case MouseCursor::CopyingCursor: + return juce_cursorFromWebKitFile ("copyCursor.png", 0, 0); - [menu setTitle: juceStringToNS (name)]; + case MouseCursor::WaitCursor: + c = [NSCursor arrowCursor]; // avoid this on the mac, let the OS provide the beachball + break; + //return juce_cursorFromWebKitFile ("waitCursor.png", 0.5f, 0.5f); - while ([menu numberOfItems] > 0) - [menu removeItemAtIndex: 0]; + case MouseCursor::IBeamCursor: + c = [NSCursor IBeamCursor]; + break; - PopupMenu::MenuItemIterator iter (menuToCopy); + case MouseCursor::PointingHandCursor: + c = [NSCursor pointingHandCursor]; + break; - while (iter.next()) - addMenuItem (iter, menu, menuId, tag); + case MouseCursor::LeftRightResizeCursor: + c = [NSCursor resizeLeftRightCursor]; + break; - [menu setAutoenablesItems: false]; - [menu update]; - } + case MouseCursor::LeftEdgeResizeCursor: + c = [NSCursor resizeLeftCursor]; + break; - void menuBarItemsChanged (MenuBarModel*) - { - lastUpdateTime = Time::getMillisecondCounter(); + case MouseCursor::RightEdgeResizeCursor: + c = [NSCursor resizeRightCursor]; + break; - StringArray menuNames; - if (currentModel != 0) - menuNames = currentModel->getMenuBarNames(); + case MouseCursor::UpDownResizeCursor: + case MouseCursor::TopEdgeResizeCursor: + case MouseCursor::BottomEdgeResizeCursor: + return juce_cursorFromWebKitFile ("northSouthResizeCursor.png", 0.5f, 0.5f); - NSMenu* menuBar = [NSApp mainMenu]; - while ([menuBar numberOfItems] > 1 + menuNames.size()) - [menuBar removeItemAtIndex: [menuBar numberOfItems] - 1]; + case MouseCursor::TopLeftCornerResizeCursor: + case MouseCursor::BottomRightCornerResizeCursor: + return juce_cursorFromWebKitFile ("northWestSouthEastResizeCursor.png", 0.5f, 0.5f); - int menuId = 1; + case MouseCursor::TopRightCornerResizeCursor: + case MouseCursor::BottomLeftCornerResizeCursor: + return juce_cursorFromWebKitFile ("northEastSouthWestResizeCursor.png", 0.5f, 0.5f); - for (int i = 0; i < menuNames.size(); ++i) - { - const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames [i])); + case MouseCursor::UpDownLeftRightResizeCursor: + return juce_cursorFromWebKitFile ("moveCursor.png", 0.5f, 0.5f); - if (i >= [menuBar numberOfItems] - 1) - addSubMenu (menuBar, menu, menuNames[i], menuId, i); - else - updateSubMenu ([menuBar itemAtIndex: 1 + i], menu, menuNames[i], menuId, i); - } + case MouseCursor::CrosshairCursor: + c = [NSCursor crosshairCursor]; + break; } - static void flashMenuBar (NSMenu* menu) - { - const unichar f35Key = NSF35FunctionKey; - NSString* f35String = [NSString stringWithCharacters: &f35Key length: 1]; - - NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: @"x" - action: nil - keyEquivalent: f35String]; - [item setTarget: nil]; - [menu insertItem: item atIndex: [menu numberOfItems]]; - [item release]; + [c retain]; + return (void*) c; +} - NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown - location: NSZeroPoint - modifierFlags: NSCommandKeyMask - timestamp: 0 - windowNumber: 0 - context: [NSGraphicsContext currentContext] - characters: f35String - charactersIgnoringModifiers: f35String - isARepeat: NO - keyCode: 0]; - - [menu performKeyEquivalent: f35Event]; - [menu removeItem: item]; - } - - static NSMenuItem* findMenuItem (NSMenu* const menu, const ApplicationCommandTarget::InvocationInfo& info) - { - for (int i = [menu numberOfItems]; --i >= 0;) - { - NSMenuItem* m = [menu itemAtIndex: i]; - if ([m tag] == info.commandID) - return m; - - if ([m submenu] != 0) - { - NSMenuItem* found = findMenuItem ([m submenu], info); - if (found != 0) - return found; - } - } - - return 0; - } - - void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info) - { - NSMenuItem* item = findMenuItem ([NSApp mainMenu], info); - - if (item != 0) - flashMenuBar ([item menu]); - } - - void updateMenus() - { - if (Time::getMillisecondCounter() > lastUpdateTime + 500) - menuBarItemsChanged (0); - } - - void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const - { - if (currentModel != 0) - { - if (commandManager != 0) - { - ApplicationCommandTarget::InvocationInfo info (commandId); - info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu; - - commandManager->invoke (info, true); - } - - currentModel->menuItemSelected (commandId, topLevelIndex); - } - } - - MenuBarModel* currentModel; - uint32 lastUpdateTime; - - void addMenuItem (PopupMenu::MenuItemIterator& iter, NSMenu* menuToAddTo, - const int topLevelMenuId, const int topLevelIndex) - { - NSString* text = juceStringToNS (iter.itemName.upToFirstOccurrenceOf (T(""), false, true)); - - if (text == 0) - text = @""; - - if (iter.isSeparator) - { - [menuToAddTo addItem: [NSMenuItem separatorItem]]; - } - else if (iter.isSectionHeader) - { - NSMenuItem* item = [menuToAddTo addItemWithTitle: text - action: nil - keyEquivalent: @""]; - - [item setEnabled: false]; - } - else if (iter.subMenu != 0) - { - NSMenuItem* item = [menuToAddTo addItemWithTitle: text - action: nil - keyEquivalent: @""]; - - [item setTag: iter.itemId]; - [item setEnabled: iter.isEnabled]; - - NSMenu* sub = createMenu (*iter.subMenu, iter.itemName, topLevelMenuId, topLevelIndex); - [sub setDelegate: nil]; - [menuToAddTo setSubmenu: sub forItem: item]; - } - else - { - NSMenuItem* item = [menuToAddTo addItemWithTitle: text - action: @selector (menuItemInvoked:) - keyEquivalent: @""]; - - [item setTag: iter.itemId]; - [item setEnabled: iter.isEnabled]; - [item setState: iter.isTicked ? NSOnState : NSOffState]; - [item setTarget: (id) callback]; - - NSMutableArray* info = [NSMutableArray arrayWithObject: [NSNumber numberWithUnsignedLongLong: (pointer_sized_int) (void*) iter.commandManager]]; - [info addObject: [NSNumber numberWithInt: topLevelIndex]]; - [item setRepresentedObject: info]; - - if (iter.commandManager != 0) - { - const Array keyPresses (iter.commandManager->getKeyMappings() - ->getKeyPressesAssignedToCommand (iter.itemId)); - - if (keyPresses.size() > 0) - { - const KeyPress& kp = keyPresses.getReference(0); - - juce_wchar key = kp.getTextCharacter(); - - if (kp.getKeyCode() == KeyPress::backspaceKey) - key = NSBackspaceCharacter; - else if (kp.getKeyCode() == KeyPress::deleteKey) - key = NSDeleteCharacter; - else if (key == 0) - key = (juce_wchar) kp.getKeyCode(); - - unsigned int mods = 0; - if (kp.getModifiers().isShiftDown()) - mods |= NSShiftKeyMask; - if (kp.getModifiers().isCtrlDown()) - mods |= NSControlKeyMask; - if (kp.getModifiers().isAltDown()) - mods |= NSAlternateKeyMask; - if (kp.getModifiers().isCommandDown()) - mods |= NSCommandKeyMask; - - [item setKeyEquivalent: juceStringToNS (String::charToString (key))]; - [item setKeyEquivalentModifierMask: mods]; - } - } - } - } - - JuceMenuCallback* callback; -private: - - NSMenu* createMenu (const PopupMenu menu, - const String& menuName, - const int topLevelMenuId, - const int topLevelIndex) - { - NSMenu* m = [[NSMenu alloc] initWithTitle: juceStringToNS (menuName)]; - - [m setAutoenablesItems: false]; - [m setDelegate: callback]; - - PopupMenu::MenuItemIterator iter (menu); - - while (iter.next()) - addMenuItem (iter, m, topLevelMenuId, topLevelIndex); - - [m update]; - return m; - } -}; - -JuceMainMenuHandler* JuceMainMenuHandler::instance = 0; - -END_JUCE_NAMESPACE -@implementation JuceMenuCallback - -- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_ -{ - [super init]; - owner = owner_; - return self; -} - -- (void) dealloc -{ - [super dealloc]; -} - -- (void) menuItemInvoked: (id) menu -{ - NSMenuItem* item = (NSMenuItem*) menu; - - if ([[item representedObject] isKindOfClass: [NSArray class]]) - { - NSArray* info = (NSArray*) [item representedObject]; - - owner->invoke ([item tag], - (ApplicationCommandManager*) (pointer_sized_int) - [((NSNumber*) [info objectAtIndex: 0]) unsignedLongLongValue], - (int) [((NSNumber*) [info objectAtIndex: 1]) intValue]); - } -} - -- (void) menuNeedsUpdate: (NSMenu*) menu; +void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw() { - if (JuceMainMenuHandler::instance != 0) - JuceMainMenuHandler::instance->updateMenus(); + NSCursor* c = (NSCursor*) cursorHandle; + [c release]; } -@end -BEGIN_JUCE_NAMESPACE - -static NSMenu* createStandardAppMenu (NSMenu* menu, const String& appName, - const PopupMenu* extraItems) +void MouseCursor::showInAllWindows() const throw() { - if (extraItems != 0 && JuceMainMenuHandler::instance != 0 && extraItems->getNumItems() > 0) - { - PopupMenu::MenuItemIterator iter (*extraItems); - - while (iter.next()) - JuceMainMenuHandler::instance->addMenuItem (iter, menu, 0, -1); - - [menu addItem: [NSMenuItem separatorItem]]; - } - - NSMenuItem* item; - - // Services... - item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Services", nil) - action: nil keyEquivalent: @""]; - [menu addItem: item]; - [item release]; - NSMenu* servicesMenu = [[NSMenu alloc] initWithTitle: @"Services"]; - [menu setSubmenu: servicesMenu forItem: item]; - [NSApp setServicesMenu: servicesMenu]; - [servicesMenu release]; - [menu addItem: [NSMenuItem separatorItem]]; - - // Hide + Show stuff... - item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Hide " + appName) - action: @selector (hide:) keyEquivalent: @"h"]; - [item setTarget: NSApp]; - [menu addItem: item]; - [item release]; - - item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Hide Others", nil) - action: @selector (hideOtherApplications:) keyEquivalent: @"h"]; - [item setKeyEquivalentModifierMask: NSCommandKeyMask | NSAlternateKeyMask]; - [item setTarget: NSApp]; - [menu addItem: item]; - [item release]; - - item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Show All", nil) - action: @selector (unhideAllApplications:) keyEquivalent: @""]; - [item setTarget: NSApp]; - [menu addItem: item]; - [item release]; - - [menu addItem: [NSMenuItem separatorItem]]; - - // Quit item.... - item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Quit " + appName) - action: @selector (terminate:) keyEquivalent: @"q"]; - - [item setTarget: NSApp]; - [menu addItem: item]; - [item release]; - - return menu; + showInWindow (0); } -// Since our app has no NIB, this initialises a standard app menu... -static void rebuildMainMenu (const PopupMenu* extraItems) +void MouseCursor::showInWindow (ComponentPeer*) const throw() { - // this can't be used in a plugin! - jassert (JUCEApplication::getInstance() != 0); - - if (JUCEApplication::getInstance() != 0) - { - const ScopedAutoReleasePool pool; - - NSMenu* mainMenu = [[NSMenu alloc] initWithTitle: @"MainMenu"]; - NSMenuItem* item = [mainMenu addItemWithTitle: @"Apple" action: nil keyEquivalent: @""]; - - NSMenu* appMenu = [[NSMenu alloc] initWithTitle: @"Apple"]; - - [NSApp performSelector: @selector (setAppleMenu:) withObject: appMenu]; - [mainMenu setSubmenu: appMenu forItem: item]; - - [NSApp setMainMenu: mainMenu]; - createStandardAppMenu (appMenu, JUCEApplication::getInstance()->getApplicationName(), extraItems); - - [appMenu release]; - [mainMenu release]; - } + NSCursor* const c = (NSCursor*) getHandle(); + [c set]; } -void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel, - const PopupMenu* extraAppleMenuItems) throw() -{ - if (getMacMainMenu() != newMenuBarModel) - { - const ScopedAutoReleasePool pool; - - if (newMenuBarModel == 0) - { - delete JuceMainMenuHandler::instance; - jassert (JuceMainMenuHandler::instance == 0); // should be zeroed in the destructor - jassert (extraAppleMenuItems == 0); // you can't specify some extra items without also supplying a model - - extraAppleMenuItems = 0; - } - else - { - if (JuceMainMenuHandler::instance == 0) - JuceMainMenuHandler::instance = new JuceMainMenuHandler(); - - JuceMainMenuHandler::instance->setMenu (newMenuBarModel); - } - } - - rebuildMainMenu (extraAppleMenuItems); - - if (newMenuBarModel != 0) - newMenuBarModel->menuItemsChanged(); -} +#else -MenuBarModel* MenuBarModel::getMacMainMenu() throw() -{ - return JuceMainMenuHandler::instance != 0 - ? JuceMainMenuHandler::instance->currentModel : 0; -} +void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw() { return 0; } +void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw() { return 0; } +void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw() {} +void MouseCursor::showInAllWindows() const throw() {} +void MouseCursor::showInWindow (ComponentPeer*) const throw() {} -void initialiseMainMenu() -{ - if (JUCEApplication::getInstance() != 0) // only needed in an app - rebuildMainMenu (0); -} +#endif #endif -/********* End of inlined file: juce_mac_MainMenu.mm *********/ +/********* End of inlined file: juce_mac_MouseCursor.mm *********/ -/********* Start of inlined file: juce_mac_FileChooser.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). -#ifdef JUCE_INCLUDED_FILE +#if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER + +#if JUCE_MAC END_JUCE_NAMESPACE -using namespace JUCE_NAMESPACE; -#define JuceFileChooserDelegate MakeObjCClassName(JuceFileChooserDelegate) +#define DownloadClickDetector MakeObjCClassName(DownloadClickDetector) -#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 -@interface JuceFileChooserDelegate : NSObject -#else -@interface JuceFileChooserDelegate : NSObject -#endif +@interface DownloadClickDetector : NSObject { - StringArray* filters; + JUCE_NAMESPACE::WebBrowserComponent* ownerComponent; } -- (JuceFileChooserDelegate*) initWithFilters: (StringArray*) filters_; -- (void) dealloc; -- (BOOL) panel: (id) sender shouldShowFilename: (NSString*) filename; +- (DownloadClickDetector*) initWithWebBrowserOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent; +- (void) webView: (WebView*) webView decidePolicyForNavigationAction: (NSDictionary*) actionInformation + request: (NSURLRequest*) request + frame: (WebFrame*) frame + decisionListener: (id) listener; @end -@implementation JuceFileChooserDelegate -- (JuceFileChooserDelegate*) initWithFilters: (StringArray*) filters_ +@implementation DownloadClickDetector + +- (DownloadClickDetector*) initWithWebBrowserOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent_ { [super init]; - filters = filters_; + ownerComponent = ownerComponent_; return self; } -- (void) dealloc -{ - delete filters; - [super dealloc]; -} - -- (BOOL) panel: (id) sender shouldShowFilename: (NSString*) filename +- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary*) actionInformation + request: (NSURLRequest*) request + frame: (WebFrame*) frame + decisionListener: (id ) listener { - const String fname (nsStringToJuce (filename)); - - for (int i = filters->size(); --i >= 0;) - if (fname.matchesWildcard ((*filters)[i], true)) - return true; + NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; - return File (fname).isDirectory(); + if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) + [listener use]; + else + [listener ignore]; } + @end BEGIN_JUCE_NAMESPACE -void FileChooser::showPlatformDialog (OwnedArray& results, - const String& title, - const File& currentFileOrDirectory, - const String& filter, - bool selectsDirectory, - bool isSaveDialogue, - bool warnAboutOverwritingExistingFiles, - bool selectMultipleFiles, - FilePreviewComponent* extraInfoComponent) +class WebBrowserComponentInternal : public NSViewComponent { - const ScopedAutoReleasePool pool; - - StringArray* filters = new StringArray(); - filters->addTokens (filter.replaceCharacters (T(",:"), T(";;")), T(";"), 0); - filters->trim(); - filters->removeEmptyStrings(); - - JuceFileChooserDelegate* delegate = [[JuceFileChooserDelegate alloc] initWithFilters: filters]; - [delegate autorelease]; - - NSSavePanel* panel = isSaveDialogue ? [NSSavePanel savePanel] - : [NSOpenPanel openPanel]; - - [panel setTitle: juceStringToNS (title)]; - - if (! isSaveDialogue) +public: + WebBrowserComponentInternal (WebBrowserComponent* owner) { - NSOpenPanel* openPanel = (NSOpenPanel*) panel; - [openPanel setCanChooseDirectories: selectsDirectory]; - [openPanel setCanChooseFiles: ! selectsDirectory]; - [openPanel setAllowsMultipleSelection: selectMultipleFiles]; - } - - [panel setDelegate: delegate]; - - String directory, filename; + webView = [[WebView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) + frameName: @"" + groupName: @""]; + setView (webView); - if (currentFileOrDirectory.isDirectory()) - { - directory = currentFileOrDirectory.getFullPathName(); + clickListener = [[DownloadClickDetector alloc] initWithWebBrowserOwner: owner]; + [webView setPolicyDelegate: clickListener]; } - else + + ~WebBrowserComponentInternal() { - directory = currentFileOrDirectory.getParentDirectory().getFullPathName(); - filename = currentFileOrDirectory.getFileName(); + [webView setPolicyDelegate: nil]; + [clickListener release]; + setView (0); } - if ([panel runModalForDirectory: juceStringToNS (directory) - file: juceStringToNS (filename)] - == NSOKButton) + void goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) { - if (isSaveDialogue) + NSMutableURLRequest* r + = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (url)] + cachePolicy: NSURLRequestUseProtocolCachePolicy + timeoutInterval: 30.0]; + + if (postData != 0 && postData->getSize() > 0) { - results.add (new File (nsStringToJuce ([panel filename]))); + [r setHTTPMethod: @"POST"]; + [r setHTTPBody: [NSData dataWithBytes: postData->getData() + length: postData->getSize()]]; } - else + + if (headers != 0) { - NSOpenPanel* openPanel = (NSOpenPanel*) panel; - NSArray* urls = [openPanel filenames]; - for (unsigned int i = 0; i < [urls count]; ++i) + for (int i = 0; i < headers->size(); ++i) { - NSString* f = [urls objectAtIndex: i]; - results.add (new File (nsStringToJuce (f))); + const String headerName ((*headers)[i].upToFirstOccurrenceOf (T(":"), false, false).trim()); + const String headerValue ((*headers)[i].fromFirstOccurrenceOf (T(":"), false, false).trim()); + + [r setValue: juceStringToNS (headerValue) + forHTTPHeaderField: juceStringToNS (headerName)]; } } - } - - [panel setDelegate: nil]; -} - -#endif -/********* End of inlined file: juce_mac_FileChooser.mm *********/ - -/********* Start of inlined file: juce_mac_QuickTimeMovieComponent.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE && JUCE_QUICKTIME - -#define theMovie ((QTMovie*) movie) - -QuickTimeMovieComponent::QuickTimeMovieComponent() - : movie (0) -{ - setOpaque (true); - setVisible (true); - - QTMovieView* view = [[QTMovieView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)]; - setView (view); -} - -QuickTimeMovieComponent::~QuickTimeMovieComponent() -{ - closeMovie(); - setView (0); -} - -bool QuickTimeMovieComponent::isQuickTimeAvailable() throw() -{ - return true; -} - -static QTMovie* openMovieFromStream (InputStream* movieStream, File& movieFile) -{ - // unfortunately, QTMovie objects can only be created on the main thread.. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - - QTMovie* movie = 0; - - FileInputStream* const fin = dynamic_cast (movieStream); - - if (fin != 0) - { - movieFile = fin->getFile(); - movie = [QTMovie movieWithFile: juceStringToNS (movieFile.getFullPathName()) - error: nil]; - } - else - { - MemoryBlock temp; - movieStream->readIntoMemoryBlock (temp); - - const char* const suffixesToTry[] = { ".mov", ".mp3", ".avi", ".m4a" }; - - for (int i = 0; i < numElementsInArray (suffixesToTry); ++i) - { - movie = [QTMovie movieWithDataReference: [QTDataReference dataReferenceWithReferenceToData: [NSData dataWithBytes: temp.getData() - length: temp.getSize()] - name: [NSString stringWithUTF8String: suffixesToTry[i]] - MIMEType: @""] - error: nil]; - if (movie != 0) - break; - } + stop(); + [[webView mainFrame] loadRequest: r]; } - return movie; -} - -bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream, - const bool controllerVisible) -{ - closeMovie(); - - if (getPeer() == 0) + void goBack() { - // To open a movie, this component must be visible inside a functioning window, so that - // the QT control can be assigned to the window. - jassertfalse - return false; + [webView goBack]; } - movie = openMovieFromStream (movieStream, movieFile); - - [theMovie retain]; - QTMovieView* view = (QTMovieView*) getView(); - [view setMovie: theMovie]; - [view setControllerVisible: controllerVisible]; - setLooping (looping); - - return movie != nil; -} - -void QuickTimeMovieComponent::closeMovie() -{ - stop(); - QTMovieView* view = (QTMovieView*) getView(); - [view setMovie: nil]; - [theMovie release]; - movie = 0; - movieFile = File::nonexistent; -} - -bool QuickTimeMovieComponent::isMovieOpen() const -{ - return movie != nil; -} - -const File QuickTimeMovieComponent::getCurrentMovieFile() const -{ - return movieFile; -} - -void QuickTimeMovieComponent::play() -{ - [theMovie play]; -} - -void QuickTimeMovieComponent::stop() -{ - [theMovie stop]; -} - -bool QuickTimeMovieComponent::isPlaying() const -{ - return movie != 0 && [theMovie rate] != 0; -} - -void QuickTimeMovieComponent::setPosition (const double seconds) -{ - if (movie != 0) + void goForward() { - QTTime t; - t.timeValue = (uint64) (100000.0 * seconds); - t.timeScale = 100000; - t.flags = 0; - - [theMovie setCurrentTime: t]; + [webView goForward]; } -} - -double QuickTimeMovieComponent::getPosition() const -{ - if (movie == 0) - return 0.0; - - QTTime t = [theMovie currentTime]; - return t.timeValue / (double) t.timeScale; -} - -void QuickTimeMovieComponent::setSpeed (const float newSpeed) -{ - [theMovie setRate: newSpeed]; -} - -double QuickTimeMovieComponent::getMovieDuration() const -{ - if (movie == 0) - return 0.0; - - QTTime t = [theMovie duration]; - return t.timeValue / (double) t.timeScale; -} - -void QuickTimeMovieComponent::setLooping (const bool shouldLoop) -{ - looping = shouldLoop; - - [theMovie setAttribute: [NSNumber numberWithBool: shouldLoop] - forKey: QTMovieLoopsAttribute]; -} - -bool QuickTimeMovieComponent::isLooping() const -{ - return looping; -} - -void QuickTimeMovieComponent::setMovieVolume (const float newVolume) -{ - [theMovie setVolume: newVolume]; -} - -float QuickTimeMovieComponent::getMovieVolume() const -{ - return movie != 0 ? [theMovie volume] : 0.0f; -} - -void QuickTimeMovieComponent::getMovieNormalSize (int& width, int& height) const -{ - width = 0; - height = 0; - if (movie != 0) + void stop() { - NSSize s = [[theMovie attributeForKey: QTMovieNaturalSizeAttribute] sizeValue]; - width = s.width; - height = s.height; + [webView stopLoading: nil]; } -} - -void QuickTimeMovieComponent::paint (Graphics& g) -{ - if (movie == 0) - g.fillAll (Colours::black); -} - -bool QuickTimeMovieComponent::isControllerVisible() const -{ - return controllerVisible; -} - -bool QuickTimeMovieComponent::loadMovie (const File& movieFile_, - const bool isControllerVisible) -{ - const bool ok = loadMovie ((InputStream*) movieFile_.createInputStream(), isControllerVisible); - movieFile = movieFile_; - return ok; -} - -void QuickTimeMovieComponent::goToStart() -{ - setPosition (0.0); -} -void QuickTimeMovieComponent::setBoundsWithCorrectAspectRatio (const Rectangle& spaceToFitWithin, - const RectanglePlacement& placement) -{ - int normalWidth, normalHeight; - getMovieNormalSize (normalWidth, normalHeight); - - if (normalWidth > 0 && normalHeight > 0 && ! spaceToFitWithin.isEmpty()) - { - double x = 0.0, y = 0.0, w = normalWidth, h = normalHeight; - - placement.applyTo (x, y, w, h, - spaceToFitWithin.getX(), spaceToFitWithin.getY(), - spaceToFitWithin.getWidth(), spaceToFitWithin.getHeight()); - - if (w > 0 && h > 0) - { - setBounds (roundDoubleToInt (x), roundDoubleToInt (y), - roundDoubleToInt (w), roundDoubleToInt (h)); - } - } - else + void refresh() { - setBounds (spaceToFitWithin); + [webView reload: nil]; } -} - -#if ! (JUCE_MAC && JUCE_64BIT) - -bool juce_OpenQuickTimeMovieFromStream (InputStream* movieStream, Movie& result, Handle& dataHandle) -{ - if (movieStream == 0) - return false; - File file; - QTMovie* movie = openMovieFromStream (movieStream, file); - - if (movie != nil) - result = [movie quickTimeMovie]; - - return movie != nil; -} - -#endif - -#endif -/********* End of inlined file: juce_mac_QuickTimeMovieComponent.mm *********/ - -/********* Start of inlined file: juce_mac_AudioCDBurner.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE && JUCE_USE_CDBURNER - -END_JUCE_NAMESPACE - -#define OpenDiskDevice MakeObjCClassName(OpenDiskDevice) +private: + WebView* webView; + DownloadClickDetector* clickListener; +}; -@interface OpenDiskDevice : NSObject +WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) + : browser (0), + blankPageShown (false), + unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_) { - DRDevice* device; + setOpaque (true); - NSMutableArray* tracks; + addAndMakeVisible (browser = new WebBrowserComponentInternal (this)); } -- (OpenDiskDevice*) initWithDevice: (DRDevice*) device; -- (void) dealloc; -- (bool) isDiskPresent; -- (int) getNumAvailableAudioBlocks; -- (void) addSourceTrack: (JUCE_NAMESPACE::AudioSource*) source numSamples: (int) numSamples_; -- (void) burn: (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener*) listener errorString: (JUCE_NAMESPACE::String*) error - ejectAfterwards: (bool) shouldEject isFake: (bool) peformFakeBurnForTesting; -@end - -#define AudioTrackProducer MakeObjCClassName(AudioTrackProducer) - -@interface AudioTrackProducer : NSObject +WebBrowserComponent::~WebBrowserComponent() { - JUCE_NAMESPACE::AudioSource* source; - int readPosition, lengthInFrames; + deleteAndZero (browser); } -- (AudioTrackProducer*) init: (int) lengthInFrames; -- (AudioTrackProducer*) initWithAudioSource: (JUCE_NAMESPACE::AudioSource*) source numSamples: (int) lengthInSamples; -- (void) dealloc; -- (void) setupTrackProperties: (DRTrack*) track; - -- (void) cleanupTrackAfterBurn: (DRTrack*) track; -- (BOOL) cleanupTrackAfterVerification:(DRTrack*)track; -- (uint64_t) estimateLengthOfTrack:(DRTrack*)track; -- (BOOL) prepareTrack:(DRTrack*)track forBurn:(DRBurn*)burn - toMedia:(NSDictionary*)mediaInfo; -- (BOOL) prepareTrackForVerification:(DRTrack*)track; -- (uint32_t) produceDataForTrack:(DRTrack*)track intoBuffer:(char*)buffer - length:(uint32_t)bufferLength atAddress:(uint64_t)address - blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags; -- (uint32_t) producePreGapForTrack:(DRTrack*)track - intoBuffer:(char*)buffer length:(uint32_t)bufferLength - atAddress:(uint64_t)address blockSize:(uint32_t)blockSize - ioFlags:(uint32_t*)flags; -- (BOOL) verifyDataForTrack:(DRTrack*)track inBuffer:(const char*)buffer - length:(uint32_t)bufferLength atAddress:(uint64_t)address - blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags; -- (uint32_t) producePreGapForTrack:(DRTrack*)track - intoBuffer:(char*)buffer length:(uint32_t)bufferLength - atAddress:(uint64_t)address blockSize:(uint32_t)blockSize - ioFlags:(uint32_t*)flags; -@end - -@implementation OpenDiskDevice - -- (OpenDiskDevice*) initWithDevice: (DRDevice*) device_ +void WebBrowserComponent::goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) { - [super init]; + lastURL = url; - device = device_; - tracks = [[NSMutableArray alloc] init]; - return self; -} + lastHeaders.clear(); + if (headers != 0) + lastHeaders = *headers; -- (void) dealloc -{ - [tracks release]; - [super dealloc]; -} + lastPostData.setSize (0); + if (postData != 0) + lastPostData = *postData; -- (bool) isDiskPresent -{ - return [device isValid] - && [[[device status] objectForKey: DRDeviceMediaStateKey] - isEqualTo: DRDeviceMediaStateMediaPresent]; -} + blankPageShown = false; -- (int) getNumAvailableAudioBlocks -{ - return [[[[device status] objectForKey: DRDeviceMediaInfoKey] - objectForKey: DRDeviceMediaBlocksFreeKey] intValue]; + browser->goToURL (url, headers, postData); } -- (void) addSourceTrack: (JUCE_NAMESPACE::AudioSource*) source_ numSamples: (int) numSamples_ +void WebBrowserComponent::stop() { - AudioTrackProducer* p = [[AudioTrackProducer alloc] initWithAudioSource: source_ numSamples: numSamples_]; - DRTrack* t = [[DRTrack alloc] initWithProducer: p]; - [p setupTrackProperties: t]; - - [tracks addObject: t]; - - [t release]; - [p release]; + browser->stop(); } -- (void) burn: (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener*) listener errorString: (JUCE_NAMESPACE::String*) error - ejectAfterwards: (bool) shouldEject isFake: (bool) peformFakeBurnForTesting +void WebBrowserComponent::goBack() { - DRBurn* burn = [DRBurn burnForDevice: device]; - - if (! [device acquireExclusiveAccess]) - { - *error = "Couldn't open or write to the CD device"; - return; - } - - [device acquireMediaReservation]; - - NSMutableDictionary* d = [[burn properties] mutableCopy]; - [d autorelease]; - [d setObject: [NSNumber numberWithBool: peformFakeBurnForTesting] forKey: DRBurnTestingKey]; - [d setObject: [NSNumber numberWithBool: false] forKey: DRBurnVerifyDiscKey]; - [d setObject: (shouldEject ? DRBurnCompletionActionEject : DRBurnCompletionActionMount) - forKey: DRBurnCompletionActionKey]; - [burn setProperties: d]; - - [burn writeLayout: tracks]; - - for (;;) - { - JUCE_NAMESPACE::Thread::sleep (300); - float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue]; - - if (listener != 0 && listener->audioCDBurnProgress (progress)) - { - [burn abort]; - *error = "User cancelled the write operation"; - break; - } - - if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateFailed]) - { - *error = "Write operation failed"; - break; - } - else if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateDone]) - { - break; - } - - NSString* err = (NSString*) [[[burn status] objectForKey: DRErrorStatusKey] - objectForKey: DRErrorStatusErrorStringKey]; - - if ([err length] > 0) - { - *error = JUCE_NAMESPACE::String::fromUTF8 ((JUCE_NAMESPACE::uint8*) [err UTF8String]); - break; - } - } - - [device releaseMediaReservation]; - [device releaseExclusiveAccess]; + lastURL = String::empty; + blankPageShown = false; + browser->goBack(); } -@end - -@implementation AudioTrackProducer -- (AudioTrackProducer*) init: (int) lengthInFrames_ +void WebBrowserComponent::goForward() { - lengthInFrames = lengthInFrames_; - readPosition = 0; - return self; + lastURL = String::empty; + browser->goForward(); } -- (void) setupTrackProperties: (DRTrack*) track +void WebBrowserComponent::refresh() { - NSMutableDictionary* p = [[track properties] mutableCopy]; - [p setObject:[DRMSF msfWithFrames: lengthInFrames] forKey: DRTrackLengthKey]; - [p setObject:[NSNumber numberWithUnsignedShort:2352] forKey: DRBlockSizeKey]; - [p setObject:[NSNumber numberWithInt:0] forKey: DRDataFormKey]; - [p setObject:[NSNumber numberWithInt:0] forKey: DRBlockTypeKey]; - [p setObject:[NSNumber numberWithInt:0] forKey: DRTrackModeKey]; - [p setObject:[NSNumber numberWithInt:0] forKey: DRSessionFormatKey]; - - [track setProperties: p]; - [p release]; + browser->refresh(); } -- (AudioTrackProducer*) initWithAudioSource: (JUCE_NAMESPACE::AudioSource*) source_ numSamples: (int) lengthInSamples +void WebBrowserComponent::paint (Graphics& g) { - AudioTrackProducer* s = [self init: (lengthInSamples + 587) / 588]; - - if (s != nil) - s->source = source_; - - return s; } -- (void) dealloc +void WebBrowserComponent::checkWindowAssociation() { - if (source != 0) + if (isShowing()) { - source->releaseResources(); - delete source; + if (blankPageShown) + goBack(); } - - [super dealloc]; -} - -- (void) cleanupTrackAfterBurn: (DRTrack*) track -{ -} - -- (BOOL) cleanupTrackAfterVerification: (DRTrack*) track -{ - return true; -} - -- (uint64_t) estimateLengthOfTrack: (DRTrack*) track -{ - return lengthInFrames; -} - -- (BOOL) prepareTrack: (DRTrack*) track forBurn: (DRBurn*) burn - toMedia: (NSDictionary*) mediaInfo -{ - if (source != 0) - source->prepareToPlay (44100 / 75, 44100); - - readPosition = 0; - return true; -} - -- (BOOL) prepareTrackForVerification: (DRTrack*) track -{ - if (source != 0) - source->prepareToPlay (44100 / 75, 44100); - - return true; -} - -- (uint32_t) produceDataForTrack: (DRTrack*) track intoBuffer: (char*) buffer - length: (uint32_t) bufferLength atAddress: (uint64_t) address - blockSize: (uint32_t) blockSize ioFlags: (uint32_t*) flags -{ - if (source != 0) + else { - const int numSamples = JUCE_NAMESPACE::jmin (bufferLength / 4, (lengthInFrames * (44100 / 75)) - readPosition); - - if (numSamples > 0) + if (unloadPageWhenBrowserIsHidden && ! blankPageShown) { - JUCE_NAMESPACE::AudioSampleBuffer tempBuffer (2, numSamples); - - JUCE_NAMESPACE::AudioSourceChannelInfo info; - info.buffer = &tempBuffer; - info.startSample = 0; - info.numSamples = numSamples; - - source->getNextAudioBlock (info); - - JUCE_NAMESPACE::AudioDataConverters::convertFloatToInt16LE (tempBuffer.getSampleData (0), - buffer, numSamples, 4); - JUCE_NAMESPACE::AudioDataConverters::convertFloatToInt16LE (tempBuffer.getSampleData (1), - buffer + 2, numSamples, 4); - - readPosition += numSamples; - } - - return numSamples * 4; - } - - return 0; -} - -- (uint32_t) producePreGapForTrack: (DRTrack*) track - intoBuffer: (char*) buffer length: (uint32_t) bufferLength - atAddress: (uint64_t) address blockSize: (uint32_t) blockSize - ioFlags: (uint32_t*) flags -{ - zeromem (buffer, bufferLength); - return bufferLength; -} - -- (BOOL) verifyDataForTrack: (DRTrack*) track inBuffer: (const char*) buffer - length: (uint32_t) bufferLength atAddress: (uint64_t) address - blockSize: (uint32_t) blockSize ioFlags: (uint32_t*) flags -{ - return true; -} - -@end - -BEGIN_JUCE_NAMESPACE - -AudioCDBurner::AudioCDBurner (const int deviceIndex) - : internal (0) -{ - OpenDiskDevice* dev = [[OpenDiskDevice alloc] initWithDevice: [[DRDevice devices] objectAtIndex: deviceIndex]]; - - internal = (void*) dev; -} - -AudioCDBurner::~AudioCDBurner() -{ - OpenDiskDevice* dev = (OpenDiskDevice*) internal; - - if (dev != 0) - [dev release]; -} - -AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex) -{ - AudioCDBurner* b = new AudioCDBurner (deviceIndex); - - if (b->internal == 0) - deleteAndZero (b); - - return b; -} - -static NSArray* findDiskBurnerDevices() -{ - NSMutableArray* results = [NSMutableArray array]; - NSArray* devs = [DRDevice devices]; - - if (devs != 0) - { - int num = [devs count]; - int i; - for (i = 0; i < num; ++i) - { - NSDictionary* dic = [[devs objectAtIndex: i] info]; - NSString* name = [dic valueForKey: DRDeviceProductNameKey]; - if (name != nil) - [results addObject: name]; - } - } - - return results; -} - -const StringArray AudioCDBurner::findAvailableDevices() -{ - NSArray* names = findDiskBurnerDevices(); - StringArray s; - - for (unsigned int i = 0; i < [names count]; ++i) - s.add (String::fromUTF8 ((JUCE_NAMESPACE::uint8*) [[names objectAtIndex: i] UTF8String])); - - return s; -} - -bool AudioCDBurner::isDiskPresent() const -{ - OpenDiskDevice* dev = (OpenDiskDevice*) internal; - - return dev != 0 && [dev isDiskPresent]; -} - -int AudioCDBurner::getNumAvailableAudioBlocks() const -{ - OpenDiskDevice* dev = (OpenDiskDevice*) internal; - - return [dev getNumAvailableAudioBlocks]; -} - -bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamps) -{ - OpenDiskDevice* dev = (OpenDiskDevice*) internal; - - if (dev != 0) - { - [dev addSourceTrack: source numSamples: numSamps]; - return true; - } - - return false; -} - -const String AudioCDBurner::burn (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener* listener, - const bool ejectDiscAfterwards, - const bool peformFakeBurnForTesting) -{ - String error ("Couldn't open or write to the CD device"); - - OpenDiskDevice* dev = (OpenDiskDevice*) internal; - - if (dev != 0) - { - error = String::empty; - [dev burn: listener - errorString: &error - ejectAfterwards: ejectDiscAfterwards - isFake: peformFakeBurnForTesting]; - } - - return error; -} - -void AudioCDReader::ejectDisk() -{ - const ScopedAutoReleasePool p; - [[NSWorkspace sharedWorkspace] unmountAndEjectDeviceAtPath: juceStringToNS (volumeDir.getFullPathName())]; -} - -#endif -/********* End of inlined file: juce_mac_AudioCDBurner.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). -#ifdef JUCE_INCLUDED_FILE - -class FontHelper -{ - NSFont* font; - -public: - String name; - bool isBold, isItalic, needsItalicTransform; - float fontSize, totalSize, ascent; - int refCount; - NSMutableDictionary* attributes; - - FontHelper (const String& name_, - const bool bold_, - const bool italic_, - const float size_) - : font (0), - name (name_), - isBold (bold_), - isItalic (italic_), - needsItalicTransform (false), - fontSize (size_), - refCount (1) - { - attributes = [[NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] - forKey: NSLigatureAttributeName] retain]; - - font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; - - if (italic_) - { - NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; - - if (newFont == font) - needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform.. - - font = newFont; - } - - if (bold_) - font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; - - [font retain]; - - ascent = fabsf ([font ascender]); - totalSize = ascent + fabsf ([font descender]); - } - - ~FontHelper() - { - [font release]; - [attributes release]; - } - - bool getPathAndKerning (const juce_wchar char1, - const juce_wchar char2, - Path* path, - float& kerning, - float* ascent, - float* descent) - { - const ScopedAutoReleasePool pool; - - if (font == 0 - || ! [[font coveredCharacterSet] longCharacterIsMember: (UTF32Char) char1]) - return false; - - String chars; - chars << ' ' << char1 << char2; - - NSTextStorage* textStorage = [[[NSTextStorage alloc] initWithString: juceStringToNS (chars) - attributes: attributes] autorelease]; - NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; - NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; - [layoutManager addTextContainer: textContainer]; - [textStorage addLayoutManager: layoutManager]; - [textStorage setFont: font]; - - unsigned int glyphIndex = [layoutManager glyphRangeForCharacterRange: NSMakeRange (1, 1) - actualCharacterRange: 0].location; - NSPoint p1 = [layoutManager locationForGlyphAtIndex: glyphIndex]; - NSPoint p2 = [layoutManager locationForGlyphAtIndex: glyphIndex + 1]; - kerning = p2.x - p1.x; - - if (ascent != 0) - *ascent = this->ascent; - - if (descent != 0) - *descent = fabsf ([font descender]); - - if (path != 0) - { - NSBezierPath* bez = [NSBezierPath bezierPath]; - [bez moveToPoint: NSMakePoint (0, 0)]; - [bez appendBezierPathWithGlyph: [layoutManager glyphAtIndex: glyphIndex] - inFont: font]; - - for (int i = 0; i < [bez elementCount]; ++i) - { - NSPoint p[3]; - switch ([bez elementAtIndex: i associatedPoints: p]) - { - case NSMoveToBezierPathElement: - path->startNewSubPath (p[0].x, -p[0].y); - break; - case NSLineToBezierPathElement: - path->lineTo (p[0].x, -p[0].y); - break; - case NSCurveToBezierPathElement: - path->cubicTo (p[0].x, -p[0].y, p[1].x, -p[1].y, p[2].x, -p[2].y); - break; - case NSClosePathBezierPathElement: - path->closeSubPath(); - break; - default: - jassertfalse - break; - } - } - - if (needsItalicTransform) - path->applyTransform (AffineTransform::identity.sheared (-0.15, 0)); - } - - return kerning != 0; - } - - juce_wchar getDefaultChar() - { - return 0; - } -}; - -class FontHelperCache : public Timer, - public DeletedAtShutdown -{ - VoidArray cache; - -public: - FontHelperCache() - { - } - - ~FontHelperCache() - { - for (int i = cache.size(); --i >= 0;) - { - FontHelper* const f = (FontHelper*) cache.getUnchecked(i); - delete f; - } - - clearSingletonInstance(); - } - - FontHelper* getFont (const String& name, - const bool bold, - const bool italic, - const float size = 1024) - { - for (int i = cache.size(); --i >= 0;) - { - FontHelper* const f = (FontHelper*) cache.getUnchecked(i); - - if (f->name == name - && f->isBold == bold - && f->isItalic == italic - && f->fontSize == size) - { - f->refCount++; - return f; - } - } - - FontHelper* const f = new FontHelper (name, bold, italic, size); - cache.add (f); - return f; - } - - void releaseFont (FontHelper* f) - { - for (int i = cache.size(); --i >= 0;) - { - FontHelper* const f2 = (FontHelper*) cache.getUnchecked(i); - - if (f == f2) - { - f->refCount--; - - if (f->refCount == 0) - startTimer (5000); - - break; - } - } - } - - void timerCallback() - { - stopTimer(); - - for (int i = cache.size(); --i >= 0;) - { - FontHelper* const f = (FontHelper*) cache.getUnchecked(i); - - if (f->refCount == 0) - { - cache.remove (i); - delete f; - } - } - - if (cache.size() == 0) - delete this; - } - - juce_DeclareSingleton_SingleThreaded_Minimal (FontHelperCache) -}; - -juce_ImplementSingleton_SingleThreaded (FontHelperCache) - -void Typeface::initialiseTypefaceCharacteristics (const String& fontName, - bool bold, - bool italic, - bool addAllGlyphsToFont) throw() -{ - // This method is only safe to be called from the normal UI thread.. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - - FontHelper* const helper = FontHelperCache::getInstance() - ->getFont (fontName, bold, italic); - - clear(); - setAscent (helper->ascent / helper->totalSize); - setName (fontName); - setDefaultCharacter (helper->getDefaultChar()); - setBold (bold); - setItalic (italic); - - if (addAllGlyphsToFont) - { - //xxx - jassertfalse - } - - FontHelperCache::getInstance()->releaseFont (helper); -} - -bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() -{ - // This method is only safe to be called from the normal UI thread.. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - - if (character == 0) - return false; - - FontHelper* const helper = FontHelperCache::getInstance() - ->getFont (getName(), isBold(), isItalic()); - - Path path; - float width; - bool foundOne = false; - - if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) - { - path.applyTransform (AffineTransform::scale (1.0f / helper->totalSize, - 1.0f / helper->totalSize)); - - addGlyph (character, path, width / helper->totalSize); - - for (int i = 0; i < glyphs.size(); ++i) - { - const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i); - - float kerning; - if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) - { - kerning = (kerning - width) / helper->totalSize; - - if (kerning != 0) - addKerningPair (character, g->getCharacter(), kerning); - } - - if (helper->getPathAndKerning (g->getCharacter(), character, 0, kerning, 0, 0)) - { - kerning = kerning / helper->totalSize - g->width; - - if (kerning != 0) - addKerningPair (g->getCharacter(), character, kerning); - } - } - - foundOne = true; - } - - FontHelperCache::getInstance()->releaseFont (helper); - return foundOne; -} - -const StringArray Font::findAllTypefaceNames() throw() -{ - StringArray names; - - const ScopedAutoReleasePool pool; - NSArray* fonts = [[NSFontManager sharedFontManager] availableFontFamilies]; - - for (unsigned int i = 0; i < [fonts count]; ++i) - names.add (nsStringToJuce ((NSString*) [fonts objectAtIndex: i])); - - names.sort (true); - return names; -} - -void Typeface::getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw() -{ - defaultSans = "Lucida Grande"; - defaultSerif = "Times New Roman"; - defaultFixed = "Monaco"; -} - -#endif -/********* End of inlined file: juce_mac_Fonts.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). -#ifdef JUCE_INCLUDED_FILE - -struct CallbackMessagePayload -{ - MessageCallbackFunction* function; - void* parameter; - void* volatile result; - bool volatile hasBeenExecuted; -}; - -/* 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() != 0) - { - JUCEApplication::getInstance()->systemRequestedQuit(); - return NSTerminateCancel; - } - - return NSTerminateNow; - } - - virtual BOOL openFile (const NSString* filename) - { - if (JUCEApplication::getInstance() != 0) - { - JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); - return YES; - } - - return NO; - } - - virtual void openFiles (NSArray* filenames) - { - StringArray files; - for (unsigned int i = 0; i < [filenames count]; ++i) - files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); - - if (files.size() > 0 && JUCEApplication::getInstance() != 0) - { - JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); - } - } - - virtual void focusChanged() - { - juce_HandleProcessFocusChange(); - } - - virtual void deliverMessage (void* message) - { - // no need for an mm lock here - deliverMessage locks it - MessageManager::getInstance()->deliverMessage (message); - } - - virtual void performCallback (CallbackMessagePayload* pl) - { - pl->result = (*pl->function) (pl->parameter); - pl->hasBeenExecuted = true; - } - - virtual void deleteSelf() - { - delete this; - } -}; - -END_JUCE_NAMESPACE -using namespace JUCE_NAMESPACE; - -#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) - -static int numPendingMessages = 0; - -@interface JuceAppDelegate : NSObject -{ -@private - id oldDelegate; - AppDelegateRedirector* redirector; - -@public - bool flushingMessages; -} - -- (JuceAppDelegate*) init; -- (void) dealloc; -- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename; -- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames; -- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app; -- (void) applicationDidBecomeActive: (NSNotification*) aNotification; -- (void) applicationDidResignActive: (NSNotification*) aNotification; -- (void) applicationWillUnhide: (NSNotification*) aNotification; -- (void) customEvent: (id) data; -- (void) performCallback: (id) info; -- (void) dummyMethod; -@end - -@implementation JuceAppDelegate - -- (JuceAppDelegate*) init -{ - [super init]; - - redirector = new AppDelegateRedirector(); - numPendingMessages = 0; - flushingMessages = false; - - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - - if (JUCEApplication::getInstance() != 0) - { - oldDelegate = [NSApp delegate]; - [NSApp setDelegate: self]; - } - else - { - oldDelegate = 0; - [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 != 0) - [NSApp setDelegate: oldDelegate]; - - redirector->deleteSelf(); - [super dealloc]; -} - -- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app -{ - return redirector->shouldTerminate(); -} - -- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename -{ - return redirector->openFile (filename); -} - -- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames -{ - return redirector->openFiles (filenames); -} - -- (void) applicationDidBecomeActive: (NSNotification*) aNotification -{ - redirector->focusChanged(); -} - -- (void) applicationDidResignActive: (NSNotification*) aNotification -{ - redirector->focusChanged(); -} - -- (void) applicationWillUnhide: (NSNotification*) aNotification -{ - redirector->focusChanged(); -} - -- (void) customEvent: (id) n -{ - atomicDecrement (numPendingMessages); - - NSData* data = (NSData*) n; - void* message = 0; - [data getBytes: &message length: sizeof (message)]; - [data release]; - - if (message != 0 && ! flushingMessages) - redirector->deliverMessage (message); -} - -- (void) performCallback: (id) info -{ - if ([info isKindOfClass: [NSData class]]) - { - CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; - - if (pl != 0) - redirector->performCallback (pl); - } - else - { - jassertfalse // should never get here! - } -} - -- (void) dummyMethod {} // (used as a way of running a dummy thread) - -@end - -BEGIN_JUCE_NAMESPACE - -static JuceAppDelegate* juceAppDelegate = 0; - -void MessageManager::runDispatchLoop() -{ - if (! quitMessagePosted) // check that the quit message wasn't already posted.. - { - const ScopedAutoReleasePool pool; - - // must only be called by the message thread! - jassert (isThisTheMessageThread()); - - [NSApp run]; - } -} - -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]; -} - -static bool isEventBlockedByModalComps (NSEvent* e) -{ - if (Component::getNumCurrentlyModalComponents() == 0) - return false; - - NSWindow* const w = [e window]; - if (w == 0 || [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 (Component::getComponentUnderMouse() != 0) - 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 - { - if (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 != 0) - modal->inputAttemptWhenModal(); - } - - return true; -} - -bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) -{ - const ScopedAutoReleasePool pool; - jassert (isThisTheMessageThread()); // must only be called by the message thread - - uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor; - NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001]; - - while (! quitMessagePosted) - { - const ScopedAutoReleasePool pool; - - [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode - beforeDate: endDate]; - - NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask - untilDate: endDate - inMode: NSDefaultRunLoopMode - dequeue: YES]; - - if (e != 0 && ! isEventBlockedByModalComps (e)) - [NSApp sendEvent: e]; - - if (Time::getMillisecondCounter() >= endTime) - break; - } - - return ! quitMessagePosted; -} - -void MessageManager::doPlatformSpecificInitialisation() -{ - if (juceAppDelegate == 0) - 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]; - - initialiseMainMenu(); -} - -void MessageManager::doPlatformSpecificShutdown() -{ - if (juceAppDelegate != 0) - { - [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; - [[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; - - // Annoyingly, cancelPerformSelectorsWithTarget can't actually cancel the messages - // sent by performSelectorOnMainThread, so need to manually flush these before quitting.. - juceAppDelegate->flushingMessages = true; - - for (int i = 100; --i >= 0 && numPendingMessages > 0;) - { - const ScopedAutoReleasePool pool; - [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode - beforeDate: [NSDate dateWithTimeIntervalSinceNow: 5 * 0.001]]; - } - - [juceAppDelegate release]; - juceAppDelegate = 0; - } -} - -bool juce_postMessageToSystemQueue (void* message) -{ - atomicIncrement (numPendingMessages); - - [juceAppDelegate performSelectorOnMainThread: @selector (customEvent:) - withObject: (id) [[NSData alloc] initWithBytes: &message length: (int) sizeof (message)] - waitUntilDone: NO]; - return true; -} - -void MessageManager::broadcastMessage (const String& value) throw() -{ -} - -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()); - - const ScopedAutoReleasePool pool; - - 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). -#if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER - -END_JUCE_NAMESPACE - -#define DownloadClickDetector MakeObjCClassName(DownloadClickDetector) - -@interface DownloadClickDetector : NSObject -{ - JUCE_NAMESPACE::WebBrowserComponent* ownerComponent; -} - -- (DownloadClickDetector*) initWithWebBrowserOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent; - -- (void) webView: (WebView*) webView decidePolicyForNavigationAction: (NSDictionary*) actionInformation - request: (NSURLRequest*) request - frame: (WebFrame*) frame - decisionListener: (id) listener; -@end - -@implementation DownloadClickDetector - -- (DownloadClickDetector*) initWithWebBrowserOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent_ -{ - [super init]; - ownerComponent = ownerComponent_; - return self; -} - -- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary*) actionInformation - request: (NSURLRequest*) request - frame: (WebFrame*) frame - decisionListener: (id ) listener -{ - NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; - - if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) - [listener use]; - else - [listener ignore]; -} - -@end - -BEGIN_JUCE_NAMESPACE - -class WebBrowserComponentInternal : public NSViewComponent -{ -public: - WebBrowserComponentInternal (WebBrowserComponent* owner) - { - webView = [[WebView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) - frameName: @"" - groupName: @""]; - setView (webView); - - clickListener = [[DownloadClickDetector alloc] initWithWebBrowserOwner: owner]; - [webView setPolicyDelegate: clickListener]; - } - - ~WebBrowserComponentInternal() - { - [webView setPolicyDelegate: nil]; - [clickListener release]; - setView (0); - } - - void goToURL (const String& url, - const StringArray* headers, - const MemoryBlock* postData) - { - NSMutableURLRequest* r - = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (url)] - cachePolicy: NSURLRequestUseProtocolCachePolicy - timeoutInterval: 30.0]; - - if (postData != 0 && postData->getSize() > 0) - { - [r setHTTPMethod: @"POST"]; - [r setHTTPBody: [NSData dataWithBytes: postData->getData() - length: postData->getSize()]]; - } - - if (headers != 0) - { - for (int i = 0; i < headers->size(); ++i) - { - const String headerName ((*headers)[i].upToFirstOccurrenceOf (T(":"), false, false).trim()); - const String headerValue ((*headers)[i].fromFirstOccurrenceOf (T(":"), false, false).trim()); - - [r setValue: juceStringToNS (headerValue) - forHTTPHeaderField: juceStringToNS (headerName)]; - } - } - - stop(); - [[webView mainFrame] loadRequest: r]; - } - - void goBack() - { - [webView goBack]; - } - - void goForward() - { - [webView goForward]; - } - - void stop() - { - [webView stopLoading: nil]; - } - - void refresh() - { - [webView reload: nil]; - } - -private: - WebView* webView; - DownloadClickDetector* clickListener; -}; - -WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) - : browser (0), - blankPageShown (false), - unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_) -{ - setOpaque (true); - - addAndMakeVisible (browser = new WebBrowserComponentInternal (this)); -} - -WebBrowserComponent::~WebBrowserComponent() -{ - deleteAndZero (browser); -} - -void WebBrowserComponent::goToURL (const String& url, - const StringArray* headers, - const MemoryBlock* postData) -{ - lastURL = url; - - lastHeaders.clear(); - if (headers != 0) - lastHeaders = *headers; - - lastPostData.setSize (0); - if (postData != 0) - lastPostData = *postData; - - blankPageShown = false; - - browser->goToURL (url, headers, postData); -} - -void WebBrowserComponent::stop() -{ - browser->stop(); -} - -void WebBrowserComponent::goBack() -{ - lastURL = String::empty; - blankPageShown = false; - browser->goBack(); -} - -void WebBrowserComponent::goForward() -{ - lastURL = String::empty; - browser->goForward(); -} - -void WebBrowserComponent::refresh() -{ - browser->refresh(); -} - -void WebBrowserComponent::paint (Graphics& g) -{ -} - -void WebBrowserComponent::checkWindowAssociation() -{ - if (isShowing()) - { - if (blankPageShown) - goBack(); - } - else - { - if (unloadPageWhenBrowserIsHidden && ! blankPageShown) - { - // when the component becomes invisible, some stuff like flash - // carries on playing audio, so we need to force it onto a blank - // page to avoid this, (and send it back when it's made visible again). - - blankPageShown = true; - browser->goToURL ("about:blank", 0, 0); - } - } -} - -void WebBrowserComponent::reloadLastURL() -{ - if (lastURL.isNotEmpty()) - { - goToURL (lastURL, &lastHeaders, &lastPostData); - lastURL = String::empty; - } -} - -void WebBrowserComponent::parentHierarchyChanged() -{ - checkWindowAssociation(); -} - -void WebBrowserComponent::resized() -{ - browser->setSize (getWidth(), getHeight()); -} - -void WebBrowserComponent::visibilityChanged() -{ - checkWindowAssociation(); -} - -bool WebBrowserComponent::pageAboutToLoad (const String& url) -{ - return true; -} - -#endif -/********* End of inlined file: juce_mac_WebBrowserComponent.mm *********/ - -/********* Start of inlined file: juce_mac_CoreAudio.cpp *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE - -#ifndef JUCE_COREAUDIO_ERROR_LOGGING_ENABLED - #define JUCE_COREAUDIO_ERROR_LOGGING_ENABLED 1 -#endif - -#undef log -#if JUCE_COREAUDIO_LOGGING_ENABLED - #define log(a) Logger::writeToLog (a) -#else - #define log(a) -#endif - -#undef OK -#if JUCE_COREAUDIO_ERROR_LOGGING_ENABLED - static bool logAnyErrors_CoreAudio (const OSStatus err, const int lineNum) - { - if (err == noErr) - return true; - - Logger::writeToLog (T("CoreAudio error: ") + String (lineNum) + T(" - ") + String::toHexString ((int)err)); - jassertfalse - return false; - } - - #define OK(a) logAnyErrors_CoreAudio (a, __LINE__) -#else - #define OK(a) (a == noErr) -#endif - -class CoreAudioInternal : public Timer -{ -public: - - CoreAudioInternal (AudioDeviceID id) - : inputLatency (0), - outputLatency (0), - callback (0), -#if ! MACOS_10_4_OR_EARLIER - audioProcID (0), -#endif - inputDevice (0), - isSlaveDevice (false), - deviceID (id), - started (false), - sampleRate (0), - bufferSize (512), - audioBuffer (0), - numInputChans (0), - numOutputChans (0), - callbacksAllowed (true), - numInputChannelInfos (0), - numOutputChannelInfos (0), - tempInputBuffers (0), - tempOutputBuffers (0), - inputChannelInfo (0), - outputChannelInfo (0) - { - jassert (deviceID != 0); - - updateDetailsFromDevice(); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectAddPropertyListener (deviceID, &pa, deviceListenerProc, this); - } - - ~CoreAudioInternal() - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectRemovePropertyListener (deviceID, &pa, deviceListenerProc, this); - - stop (false); - delete inputDevice; - - juce_free (audioBuffer); - juce_free (tempInputBuffers); - juce_free (tempOutputBuffers); - juce_free (inputChannelInfo); - juce_free (outputChannelInfo); - } - - void allocateTempBuffers() - { - const int tempBufSize = bufferSize + 4; - juce_free (audioBuffer); - audioBuffer = (float*) juce_calloc ((numInputChans + numOutputChans) * tempBufSize * sizeof (float)); - - juce_free (tempInputBuffers); - tempInputBuffers = (float**) juce_calloc (sizeof (float*) * (numInputChans + 2)); - juce_free (tempOutputBuffers); - tempOutputBuffers = (float**) juce_calloc (sizeof (float*) * (numOutputChans + 2)); - - int i, count = 0; - for (i = 0; i < numInputChans; ++i) - tempInputBuffers[i] = audioBuffer + count++ * tempBufSize; - - for (i = 0; i < numOutputChans; ++i) - tempOutputBuffers[i] = audioBuffer + count++ * tempBufSize; - } - - // returns the number of actual available channels - void fillInChannelInfo (const bool input) - { - int chanNum = 0; - UInt32 size; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyStreamConfiguration; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) - { - AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList))) - { - const int numStreams = bufList->mNumberBuffers; - - for (int i = 0; i < numStreams; ++i) - { - const AudioBuffer& b = bufList->mBuffers[i]; - - for (unsigned int j = 0; j < b.mNumberChannels; ++j) - { - String name; - - { - uint8 channelName [256]; - zerostruct (channelName); - UInt32 nameSize = sizeof (channelName); - UInt32 channelNum = chanNum + 1; - pa.mSelector = kAudioDevicePropertyChannelName; - - if (AudioObjectGetPropertyData (deviceID, &pa, sizeof (channelNum), &channelNum, &nameSize, channelName) == noErr) - name = String::fromUTF8 (channelName, nameSize); - } - - if (input) - { - if (activeInputChans[chanNum]) - { - inputChannelInfo [numInputChannelInfos].streamNum = i; - inputChannelInfo [numInputChannelInfos].dataOffsetSamples = j; - inputChannelInfo [numInputChannelInfos].dataStrideSamples = b.mNumberChannels; - ++numInputChannelInfos; - } - - if (name.isEmpty()) - name << "Input " << (chanNum + 1); - - inChanNames.add (name); - } - else - { - if (activeOutputChans[chanNum]) - { - outputChannelInfo [numOutputChannelInfos].streamNum = i; - outputChannelInfo [numOutputChannelInfos].dataOffsetSamples = j; - outputChannelInfo [numOutputChannelInfos].dataStrideSamples = b.mNumberChannels; - ++numOutputChannelInfos; - } - - if (name.isEmpty()) - name << "Output " << (chanNum + 1); - - outChanNames.add (name); - } - - ++chanNum; - } - } - } - - juce_free (bufList); - } - } - - void updateDetailsFromDevice() - { - stopTimer(); - - if (deviceID == 0) - return; - - const ScopedLock sl (callbackLock); - - Float64 sr; - UInt32 size = sizeof (Float64); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyNominalSampleRate; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &sr))) - sampleRate = sr; - - UInt32 framesPerBuf; - size = sizeof (framesPerBuf); - - pa.mSelector = kAudioDevicePropertyBufferFrameSize; - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &framesPerBuf))) - { - bufferSize = framesPerBuf; - allocateTempBuffers(); - } - - bufferSizes.clear(); - - pa.mSelector = kAudioDevicePropertyBufferFrameSizeRange; - - if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) - { - AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges))) - { - bufferSizes.add ((int) ranges[0].mMinimum); - - for (int i = 32; i < 8192; i += 32) - { - for (int j = size / sizeof (AudioValueRange); --j >= 0;) - { - if (i >= ranges[j].mMinimum && i <= ranges[j].mMaximum) - { - bufferSizes.addIfNotAlreadyThere (i); - break; - } - } - } - - if (bufferSize > 0) - bufferSizes.addIfNotAlreadyThere (bufferSize); - } - - juce_free (ranges); - } - - if (bufferSizes.size() == 0 && bufferSize > 0) - bufferSizes.add (bufferSize); - - sampleRates.clear(); - const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 }; - String rates; - - pa.mSelector = kAudioDevicePropertyAvailableNominalSampleRates; - - if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) - { - AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges))) - { - for (int i = 0; i < numElementsInArray (possibleRates); ++i) - { - bool ok = false; - - for (int j = size / sizeof (AudioValueRange); --j >= 0;) - if (possibleRates[i] >= ranges[j].mMinimum - 2 && possibleRates[i] <= ranges[j].mMaximum + 2) - ok = true; - - if (ok) - { - sampleRates.add (possibleRates[i]); - rates << possibleRates[i] << T(" "); - } - } - } - - juce_free (ranges); - } - - if (sampleRates.size() == 0 && sampleRate > 0) - { - sampleRates.add (sampleRate); - rates << sampleRate; - } - - log (T("sr: ") + rates); - - inputLatency = 0; - outputLatency = 0; - UInt32 lat; - size = sizeof (lat); - pa.mSelector = kAudioDevicePropertyLatency; - pa.mScope = kAudioDevicePropertyScopeInput; - //if (AudioDeviceGetProperty (deviceID, 0, true, kAudioDevicePropertyLatency, &size, &lat) == noErr) - if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &lat) == noErr) - inputLatency = (int) lat; - - pa.mScope = kAudioDevicePropertyScopeOutput; - size = sizeof (lat); - - if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &lat) == noErr) - outputLatency = (int) lat; - - log (T("lat: ") + String (inputLatency) + T(" ") + String (outputLatency)); - - inChanNames.clear(); - outChanNames.clear(); - - juce_free (inputChannelInfo); - inputChannelInfo = (CallbackDetailsForChannel*) juce_calloc (sizeof (CallbackDetailsForChannel) * (numInputChans + 2)); - numInputChannelInfos = 0; - - juce_free (outputChannelInfo); - outputChannelInfo = (CallbackDetailsForChannel*) juce_calloc (sizeof (CallbackDetailsForChannel) * (numOutputChans + 2)); - numOutputChannelInfos = 0; - - fillInChannelInfo (true); - fillInChannelInfo (false); - } - - const StringArray getSources (bool input) - { - StringArray s; - int num = 0; - OSType* types = getAllDataSourcesForDevice (deviceID, input, num); - - if (types != 0) - { - for (int i = 0; i < num; ++i) - { - AudioValueTranslation avt; - char buffer[256]; - - avt.mInputData = (void*) &(types[i]); - avt.mInputDataSize = sizeof (UInt32); - avt.mOutputData = buffer; - avt.mOutputDataSize = 256; - - UInt32 transSize = sizeof (avt); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSourceNameForID; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &transSize, &avt))) - { - DBG (buffer); - s.add (buffer); - } - } - - juce_free (types); - } - - return s; - } - - int getCurrentSourceIndex (bool input) const - { - OSType currentSourceID = 0; - UInt32 size = sizeof (currentSourceID); - int result = -1; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSource; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (deviceID != 0) - { - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ¤tSourceID))) - { - int num = 0; - OSType* const types = getAllDataSourcesForDevice (deviceID, input, num); - - if (types != 0) - { - for (int i = 0; i < num; ++i) - { - if (types[num] == currentSourceID) - { - result = i; - break; - } - } - - juce_free (types); - } - } - } - - return result; - } - - void setCurrentSourceIndex (int index, bool input) - { - if (deviceID != 0) - { - int num = 0; - OSType* types = getAllDataSourcesForDevice (deviceID, input, num); - - if (types != 0) - { - if (((unsigned int) index) < (unsigned int) num) - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSource; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - OSType typeId = types[index]; - - OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); - } - - juce_free (types); - } - } - } - - const String reopen (const BitArray& inputChannels, - const BitArray& outputChannels, - double newSampleRate, - int bufferSizeSamples) - { - String error; - log ("CoreAudio reopen"); - callbacksAllowed = false; - stopTimer(); - - stop (false); - - activeInputChans = inputChannels; - activeInputChans.setRange (inChanNames.size(), - activeInputChans.getHighestBit() + 1 - inChanNames.size(), - false); - - activeOutputChans = outputChannels; - activeOutputChans.setRange (outChanNames.size(), - activeOutputChans.getHighestBit() + 1 - outChanNames.size(), - false); - - numInputChans = activeInputChans.countNumberOfSetBits(); - numOutputChans = activeOutputChans.countNumberOfSetBits(); - - // set sample rate - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyNominalSampleRate; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - Float64 sr = newSampleRate; - - if (! OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (sr), &sr))) - { - error = "Couldn't change sample rate"; - } - else - { - // change buffer size - UInt32 framesPerBuf = bufferSizeSamples; - pa.mSelector = kAudioDevicePropertyBufferFrameSize; - - if (! OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (framesPerBuf), &framesPerBuf))) - { - error = "Couldn't change buffer size"; - } - else - { - // Annoyingly, after changing the rate and buffer size, some devices fail to - // correctly report their new settings until some random time in the future, so - // after calling updateDetailsFromDevice, we need to manually bodge these values - // to make sure we're using the correct numbers.. - updateDetailsFromDevice(); - sampleRate = newSampleRate; - bufferSize = bufferSizeSamples; - - if (sampleRates.size() == 0) - error = "Device has no available sample-rates"; - else if (bufferSizes.size() == 0) - error = "Device has no available buffer-sizes"; - else if (inputDevice != 0) - error = inputDevice->reopen (inputChannels, - outputChannels, - newSampleRate, - bufferSizeSamples); - } - } - - callbacksAllowed = true; - return error; - } - - bool start (AudioIODeviceCallback* cb) - { - if (! started) - { - callback = 0; - - if (deviceID != 0) - { -#if MACOS_10_4_OR_EARLIER - if (OK (AudioDeviceAddIOProc (deviceID, audioIOProc, (void*) this))) -#else - if (OK (AudioDeviceCreateIOProcID (deviceID, audioIOProc, (void*) this, &audioProcID))) -#endif - { - if (OK (AudioDeviceStart (deviceID, audioIOProc))) - { - started = true; - } - else - { -#if MACOS_10_4_OR_EARLIER - OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); -#else - OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); - audioProcID = 0; -#endif - } - } - } - } - - if (started) - { - const ScopedLock sl (callbackLock); - callback = cb; - } - - if (inputDevice != 0) - return started && inputDevice->start (cb); - else - return started; - } - - void stop (bool leaveInterruptRunning) - { - callbackLock.enter(); - callback = 0; - callbackLock.exit(); - - if (started - && (deviceID != 0) - && ! leaveInterruptRunning) - { - OK (AudioDeviceStop (deviceID, audioIOProc)); - -#if MACOS_10_4_OR_EARLIER - OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); -#else - OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); - audioProcID = 0; -#endif - started = false; - - callbackLock.enter(); - callbackLock.exit(); - - // wait until it's definately stopped calling back.. - for (int i = 40; --i >= 0;) - { - Thread::sleep (50); - - UInt32 running = 0; - UInt32 size = sizeof (running); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDeviceIsRunning; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &running)); - - if (running == 0) - break; - } - - callbackLock.enter(); - callbackLock.exit(); - } - - if (inputDevice != 0) - inputDevice->stop (leaveInterruptRunning); - } - - double getSampleRate() const - { - return sampleRate; - } - - int getBufferSize() const - { - return bufferSize; - } - - void audioCallback (const AudioBufferList* inInputData, - AudioBufferList* outOutputData) - { - int i; - const ScopedLock sl (callbackLock); - - if (callback != 0) - { - if (inputDevice == 0) - { - for (i = numInputChans; --i >= 0;) - { - const CallbackDetailsForChannel& info = inputChannelInfo[i]; - float* dest = tempInputBuffers [i]; - const float* src = ((const float*) inInputData->mBuffers[info.streamNum].mData) - + info.dataOffsetSamples; - const int stride = info.dataStrideSamples; - - if (stride != 0) // if this is zero, info is invalid - { - for (int j = bufferSize; --j >= 0;) - { - *dest++ = *src; - src += stride; - } - } - } - } - - if (! isSlaveDevice) - { - if (inputDevice == 0) - { - callback->audioDeviceIOCallback ((const float**) tempInputBuffers, - numInputChans, - tempOutputBuffers, - numOutputChans, - bufferSize); - } - else - { - jassert (inputDevice->bufferSize == bufferSize); - - // Sometimes the two linked devices seem to get their callbacks in - // parallel, so we need to lock both devices to stop the input data being - // changed while inside our callback.. - const ScopedLock sl (inputDevice->callbackLock); - - callback->audioDeviceIOCallback ((const float**) inputDevice->tempInputBuffers, - inputDevice->numInputChans, - tempOutputBuffers, - numOutputChans, - bufferSize); - } - - for (i = numOutputChans; --i >= 0;) - { - const CallbackDetailsForChannel& info = outputChannelInfo[i]; - const float* src = tempOutputBuffers [i]; - float* dest = ((float*) outOutputData->mBuffers[info.streamNum].mData) - + info.dataOffsetSamples; - const int stride = info.dataStrideSamples; - - if (stride != 0) // if this is zero, info is invalid - { - for (int j = bufferSize; --j >= 0;) - { - *dest = *src++; - dest += stride; - } - } - } - } - } - else - { - for (i = jmin (numOutputChans, numOutputChannelInfos); --i >= 0;) - { - const CallbackDetailsForChannel& info = outputChannelInfo[i]; - float* dest = ((float*) outOutputData->mBuffers[info.streamNum].mData) - + info.dataOffsetSamples; - const int stride = info.dataStrideSamples; - - if (stride != 0) // if this is zero, info is invalid - { - for (int j = bufferSize; --j >= 0;) - { - *dest = 0.0f; - dest += stride; - } - } - } - } - } - - // called by callbacks - void deviceDetailsChanged() - { - if (callbacksAllowed) - startTimer (100); - } - - void timerCallback() - { - stopTimer(); - log ("CoreAudio device changed callback"); - - const double oldSampleRate = sampleRate; - const int oldBufferSize = bufferSize; - updateDetailsFromDevice(); - - if (oldBufferSize != bufferSize || oldSampleRate != sampleRate) - { - callbacksAllowed = false; - stop (false); - updateDetailsFromDevice(); - callbacksAllowed = true; - } - } - - CoreAudioInternal* getRelatedDevice() const - { - UInt32 size = 0; - CoreAudioInternal* result = 0; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyRelatedDevices; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (deviceID != 0 - && AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size) == noErr - && size > 0) - { - AudioDeviceID* devs = (AudioDeviceID*) juce_calloc (size); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, devs))) - { - for (unsigned int i = 0; i < size / sizeof (AudioDeviceID); ++i) - { - if (devs[i] != deviceID && devs[i] != 0) - { - result = new CoreAudioInternal (devs[i]); - - const bool thisIsInput = inChanNames.size() > 0 && outChanNames.size() == 0; - const bool otherIsInput = result->inChanNames.size() > 0 && result->outChanNames.size() == 0; - - if (thisIsInput != otherIsInput - || (inChanNames.size() + outChanNames.size() == 0) - || (result->inChanNames.size() + result->outChanNames.size()) == 0) - break; - - deleteAndZero (result); - } - } - } - - juce_free (devs); - } - - return result; - } - - juce_UseDebuggingNewOperator - - int inputLatency, outputLatency; - BitArray activeInputChans, activeOutputChans; - StringArray inChanNames, outChanNames; - Array sampleRates; - Array bufferSizes; - AudioIODeviceCallback* callback; -#if ! MACOS_10_4_OR_EARLIER - AudioDeviceIOProcID audioProcID; -#endif - - CoreAudioInternal* inputDevice; - bool isSlaveDevice; - -private: - CriticalSection callbackLock; - AudioDeviceID deviceID; - bool started; - double sampleRate; - int bufferSize; - float* audioBuffer; - int numInputChans, numOutputChans; - bool callbacksAllowed; - - struct CallbackDetailsForChannel - { - int streamNum; - int dataOffsetSamples; - int dataStrideSamples; - }; - - int numInputChannelInfos, numOutputChannelInfos; - CallbackDetailsForChannel* inputChannelInfo; - CallbackDetailsForChannel* outputChannelInfo; - float** tempInputBuffers; - float** tempOutputBuffers; - - CoreAudioInternal (const CoreAudioInternal&); - const CoreAudioInternal& operator= (const CoreAudioInternal&); - - static OSStatus audioIOProc (AudioDeviceID inDevice, - const AudioTimeStamp* inNow, - const AudioBufferList* inInputData, - const AudioTimeStamp* inInputTime, - AudioBufferList* outOutputData, - const AudioTimeStamp* inOutputTime, - void* device) - { - ((CoreAudioInternal*) device)->audioCallback (inInputData, outOutputData); - return noErr; - } - - static OSStatus deviceListenerProc (AudioDeviceID /*inDevice*/, UInt32 /*inLine*/, const AudioObjectPropertyAddress* pa, void* inClientData) - { - CoreAudioInternal* const intern = (CoreAudioInternal*) inClientData; - - switch (pa->mSelector) - { - case kAudioDevicePropertyBufferSize: - case kAudioDevicePropertyBufferFrameSize: - case kAudioDevicePropertyNominalSampleRate: - case kAudioDevicePropertyStreamFormat: - case kAudioDevicePropertyDeviceIsAlive: - intern->deviceDetailsChanged(); - break; - - case kAudioDevicePropertyBufferSizeRange: - case kAudioDevicePropertyVolumeScalar: - case kAudioDevicePropertyMute: - case kAudioDevicePropertyPlayThru: - case kAudioDevicePropertyDataSource: - case kAudioDevicePropertyDeviceIsRunning: - break; - } - - return noErr; - } - - static OSType* getAllDataSourcesForDevice (AudioDeviceID deviceID, const bool input, int& num) - { - OSType* types = 0; - UInt32 size = 0; - num = 0; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSources; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (deviceID != 0 - && OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) - { - types = (OSType*) juce_calloc (size); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, types))) - { - num = size / sizeof (OSType); - } - else - { - juce_free (types); - types = 0; - } - } - - return types; - } -}; - -class CoreAudioIODevice : public AudioIODevice -{ -public: - CoreAudioIODevice (const String& deviceName, - AudioDeviceID inputDeviceId, - const int inputIndex_, - AudioDeviceID outputDeviceId, - const int outputIndex_) - : AudioIODevice (deviceName, "CoreAudio"), - inputIndex (inputIndex_), - outputIndex (outputIndex_), - isOpen_ (false), - isStarted (false) - { - internal = 0; - CoreAudioInternal* device = 0; - - if (outputDeviceId == 0 || outputDeviceId == inputDeviceId) - { - jassert (inputDeviceId != 0); - - device = new CoreAudioInternal (inputDeviceId); - } - else - { - device = new CoreAudioInternal (outputDeviceId); - - if (inputDeviceId != 0) - { - CoreAudioInternal* secondDevice = new CoreAudioInternal (inputDeviceId); - - device->inputDevice = secondDevice; - secondDevice->isSlaveDevice = true; - } - } - - internal = device; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectAddPropertyListener (kAudioObjectSystemObject, &pa, hardwareListenerProc, internal); - } - - ~CoreAudioIODevice() - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectRemovePropertyListener (kAudioObjectSystemObject, &pa, hardwareListenerProc, internal); - - delete internal; - } - - const StringArray getOutputChannelNames() - { - return internal->outChanNames; - } - - const StringArray getInputChannelNames() - { - if (internal->inputDevice != 0) - return internal->inputDevice->inChanNames; - else - return internal->inChanNames; - } - - int getNumSampleRates() - { - return internal->sampleRates.size(); - } - - double getSampleRate (int index) - { - return internal->sampleRates [index]; - } - - int getNumBufferSizesAvailable() - { - return internal->bufferSizes.size(); - } - - int getBufferSizeSamples (int index) - { - return internal->bufferSizes [index]; - } - - int getDefaultBufferSize() - { - for (int i = 0; i < getNumBufferSizesAvailable(); ++i) - if (getBufferSizeSamples(i) >= 512) - return getBufferSizeSamples(i); - - return 512; - } - - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, - double sampleRate, - int bufferSizeSamples) - { - isOpen_ = true; - - if (bufferSizeSamples <= 0) - bufferSizeSamples = getDefaultBufferSize(); - - lastError = internal->reopen (inputChannels, outputChannels, sampleRate, bufferSizeSamples); - isOpen_ = lastError.isEmpty(); - return lastError; - } - - void close() - { - isOpen_ = false; - internal->stop (false); - } - - bool isOpen() - { - return isOpen_; - } - - int getCurrentBufferSizeSamples() - { - return internal != 0 ? internal->getBufferSize() : 512; - } - - double getCurrentSampleRate() - { - return internal != 0 ? internal->getSampleRate() : 0; - } - - int getCurrentBitDepth() - { - return 32; // no way to find out, so just assume it's high.. - } - - const BitArray getActiveOutputChannels() const - { - return internal != 0 ? internal->activeOutputChans : BitArray(); - } - - const BitArray getActiveInputChannels() const - { - BitArray chans; - - if (internal != 0) - { - chans = internal->activeInputChans; - - if (internal->inputDevice != 0) - chans.orWith (internal->inputDevice->activeInputChans); - } - - return chans; - } - - int getOutputLatencyInSamples() - { - if (internal == 0) - return 0; - - // this seems like a good guess at getting the latency right - comparing - // this with a round-trip measurement, it gets it to within a few millisecs - // for the built-in mac soundcard - return internal->outputLatency + internal->getBufferSize() * 2; - } - - int getInputLatencyInSamples() - { - if (internal == 0) - return 0; - - return internal->inputLatency + internal->getBufferSize() * 2; - } - - void start (AudioIODeviceCallback* callback) - { - if (internal != 0 && ! isStarted) - { - if (callback != 0) - callback->audioDeviceAboutToStart (this); - - isStarted = true; - internal->start (callback); - } - } - - void stop() - { - if (isStarted && internal != 0) - { - AudioIODeviceCallback* const lastCallback = internal->callback; - - isStarted = false; - internal->stop (true); - - if (lastCallback != 0) - lastCallback->audioDeviceStopped(); - } - } - - bool isPlaying() - { - if (internal->callback == 0) - isStarted = false; - - return isStarted; - } - - const String getLastError() - { - return lastError; - } - - int inputIndex, outputIndex; - - juce_UseDebuggingNewOperator - -private: - CoreAudioInternal* internal; - bool isOpen_, isStarted; - String lastError; - - static OSStatus hardwareListenerProc (AudioDeviceID /*inDevice*/, UInt32 /*inLine*/, const AudioObjectPropertyAddress* pa, void* inClientData) - { - CoreAudioInternal* const intern = (CoreAudioInternal*) inClientData; - - switch (pa->mSelector) - { - case kAudioHardwarePropertyDevices: - intern->deviceDetailsChanged(); - break; - - case kAudioHardwarePropertyDefaultOutputDevice: - case kAudioHardwarePropertyDefaultInputDevice: - case kAudioHardwarePropertyDefaultSystemOutputDevice: - break; - } - - return noErr; - } - - CoreAudioIODevice (const CoreAudioIODevice&); - const CoreAudioIODevice& operator= (const CoreAudioIODevice&); -}; - -class CoreAudioIODeviceType : public AudioIODeviceType -{ -public: - - CoreAudioIODeviceType() - : AudioIODeviceType (T("CoreAudio")), - hasScanned (false) - { - } - - ~CoreAudioIODeviceType() - { - } - - void scanForDevices() - { - hasScanned = true; - - inputDeviceNames.clear(); - outputDeviceNames.clear(); - inputIds.clear(); - outputIds.clear(); - - UInt32 size; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioHardwarePropertyDevices; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyDataSize (kAudioObjectSystemObject, &pa, 0, 0, &size))) - { - AudioDeviceID* const devs = (AudioDeviceID*) juce_calloc (size); - - if (OK (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, 0, &size, devs))) - { - static bool alreadyLogged = false; - const int num = size / sizeof (AudioDeviceID); - for (int i = 0; i < num; ++i) - { - char name [1024]; - size = sizeof (name); - pa.mSelector = kAudioDevicePropertyDeviceName; - - if (OK (AudioObjectGetPropertyData (devs[i], &pa, 0, 0, &size, name))) - { - const String nameString (String::fromUTF8 ((const uint8*) name, strlen (name))); - - if (! alreadyLogged) - log (T("CoreAudio device: ") + nameString); - - const int numIns = getNumChannels (devs[i], true); - const int numOuts = getNumChannels (devs[i], false); - - if (numIns > 0) - { - inputDeviceNames.add (nameString); - inputIds.add (devs[i]); - } - - if (numOuts > 0) - { - outputDeviceNames.add (nameString); - outputIds.add (devs[i]); - } - } - } - - alreadyLogged = true; - } - - juce_free (devs); - } - - inputDeviceNames.appendNumbersToDuplicates (false, true); - outputDeviceNames.appendNumbersToDuplicates (false, true); - } - - const StringArray getDeviceNames (const bool wantInputNames) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - if (wantInputNames) - return inputDeviceNames; - else - return outputDeviceNames; - } - - int getDefaultDeviceIndex (const bool forInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - AudioDeviceID deviceID; - UInt32 size = sizeof (deviceID); - - // if they're asking for any input channels at all, use the default input, so we - // get the built-in mic rather than the built-in output with no inputs.. - - AudioObjectPropertyAddress pa; - pa.mSelector = forInput ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, 0, &size, &deviceID) == noErr) - { - if (forInput) - { - for (int i = inputIds.size(); --i >= 0;) - if (inputIds[i] == deviceID) - return i; - } - else - { - for (int i = outputIds.size(); --i >= 0;) - if (outputIds[i] == deviceID) - return i; - } - } - - return 0; - } - - int getIndexOfDevice (AudioIODevice* device, const bool asInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - CoreAudioIODevice* const d = dynamic_cast (device); - if (d == 0) - return -1; - - return asInput ? d->inputIndex - : d->outputIndex; - } - - bool hasSeparateInputsAndOutputs() const { return true; } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - const int inputIndex = inputDeviceNames.indexOf (inputDeviceName); - const int outputIndex = outputDeviceNames.indexOf (outputDeviceName); - - String deviceName (outputDeviceName); - if (deviceName.isEmpty()) - deviceName = inputDeviceName; - - if (index >= 0) - return new CoreAudioIODevice (deviceName, - inputIds [inputIndex], - inputIndex, - outputIds [outputIndex], - outputIndex); - - return 0; - } - - juce_UseDebuggingNewOperator - -private: - StringArray inputDeviceNames, outputDeviceNames; - Array inputIds, outputIds; - - bool hasScanned; - - static int getNumChannels (AudioDeviceID deviceID, bool input) - { - int total = 0; - UInt32 size; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyStreamConfiguration; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) - { - AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList))) - { - const int numStreams = bufList->mNumberBuffers; - - for (int i = 0; i < numStreams; ++i) - { - const AudioBuffer& b = bufList->mBuffers[i]; - total += b.mNumberChannels; - } - } - - juce_free (bufList); - } - - return total; - } - - CoreAudioIODeviceType (const CoreAudioIODeviceType&); - const CoreAudioIODeviceType& operator= (const CoreAudioIODeviceType&); -}; - -AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio() -{ - return new CoreAudioIODeviceType(); -} - -#undef log - -#endif -/********* End of inlined file: juce_mac_CoreAudio.cpp *********/ - -/********* Start of inlined file: juce_mac_CoreMidi.cpp *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE - -#undef log -#define log(a) Logger::writeToLog(a) - -static bool logAnyErrorsMidi (const OSStatus err, const int lineNum) -{ - if (err == noErr) - return true; - - log (T("CoreMidi error: ") + String (lineNum) + T(" - ") + String::toHexString ((int)err)); - jassertfalse - return false; -} - -#undef OK -#define OK(a) logAnyErrorsMidi(a, __LINE__) - -static const String getEndpointName (MIDIEndpointRef endpoint, bool isExternal) -{ - String result; - CFStringRef str = 0; - - MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str); - - if (str != 0) - { - result = PlatformUtilities::cfStringToJuceString (str); - CFRelease (str); - str = 0; - } - - MIDIEntityRef entity = 0; - MIDIEndpointGetEntity (endpoint, &entity); - - if (entity == 0) - return result; // probably virtual - - if (result.isEmpty()) - { - // endpoint name has zero length - try the entity - MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str); - - if (str != 0) - { - result += PlatformUtilities::cfStringToJuceString (str); - CFRelease (str); - str = 0; - } - } - - // now consider the device's name - MIDIDeviceRef device = 0; - MIDIEntityGetDevice (entity, &device); - if (device == 0) - return result; - - MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str); - - if (str != 0) - { - const String s (PlatformUtilities::cfStringToJuceString (str)); - CFRelease (str); - - // if an external device has only one entity, throw away - // the endpoint name and just use the device name - if (isExternal && MIDIDeviceGetNumberOfEntities (device) < 2) - { - result = s; - } - else if (! result.startsWithIgnoreCase (s)) - { - // prepend the device name to the entity name - result = (s + T(" ") + result).trimEnd(); - } - } - - return result; -} - -static const String getConnectedEndpointName (MIDIEndpointRef endpoint) -{ - String result; - - // Does the endpoint have connections? - CFDataRef connections = 0; - int numConnections = 0; - - MIDIObjectGetDataProperty (endpoint, kMIDIPropertyConnectionUniqueID, &connections); - - if (connections != 0) - { - numConnections = CFDataGetLength (connections) / sizeof (MIDIUniqueID); - - if (numConnections > 0) - { - const SInt32* pid = reinterpret_cast (CFDataGetBytePtr (connections)); - - for (int i = 0; i < numConnections; ++i, ++pid) - { - MIDIUniqueID uid = EndianS32_BtoN (*pid); - MIDIObjectRef connObject; - MIDIObjectType connObjectType; - OSStatus err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType); - - if (err == noErr) - { - String s; - - if (connObjectType == kMIDIObjectType_ExternalSource - || connObjectType == kMIDIObjectType_ExternalDestination) - { - // Connected to an external device's endpoint (10.3 and later). - s = getEndpointName (static_cast (connObject), true); - } - else - { - // Connected to an external device (10.2) (or something else, catch-all) - CFStringRef str = 0; - MIDIObjectGetStringProperty (connObject, kMIDIPropertyName, &str); - - if (str != 0) - { - s = PlatformUtilities::cfStringToJuceString (str); - CFRelease (str); - } - } - - if (s.isNotEmpty()) - { - if (result.isNotEmpty()) - result += (", "); - - result += s; - } - } - } - } - - CFRelease (connections); - } - - if (result.isNotEmpty()) - return result; - - // Here, either the endpoint had no connections, or we failed to obtain names for any of them. - return getEndpointName (endpoint, false); -} - -const StringArray MidiOutput::getDevices() -{ - StringArray s; - - const ItemCount num = MIDIGetNumberOfDestinations(); - for (ItemCount i = 0; i < num; ++i) - { - MIDIEndpointRef dest = MIDIGetDestination (i); - - if (dest != 0) - { - String name (getConnectedEndpointName (dest)); - - if (name.isEmpty()) - name = ""; - - s.add (name); - } - else - { - s.add (""); - } - } - - return s; -} - -int MidiOutput::getDefaultDeviceIndex() -{ - return 0; -} - -static MIDIClientRef globalMidiClient; -static bool hasGlobalClientBeenCreated = false; - -static bool makeSureClientExists() -{ - if (! hasGlobalClientBeenCreated) - { - String name (T("JUCE")); - - if (JUCEApplication::getInstance() != 0) - name = JUCEApplication::getInstance()->getApplicationName(); - - CFStringRef appName = PlatformUtilities::juceStringToCFString (name); - - hasGlobalClientBeenCreated = OK (MIDIClientCreate (appName, 0, 0, &globalMidiClient)); - CFRelease (appName); - } - - return hasGlobalClientBeenCreated; -} - -struct MidiPortAndEndpoint -{ - MIDIPortRef port; - MIDIEndpointRef endPoint; -}; - -MidiOutput* MidiOutput::openDevice (int index) -{ - MidiOutput* mo = 0; - - if (((unsigned int) index) < (unsigned int) MIDIGetNumberOfDestinations()) - { - MIDIEndpointRef endPoint = MIDIGetDestination (index); - - CFStringRef pname; - if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname))) - { - log (T("CoreMidi - opening out: ") + PlatformUtilities::cfStringToJuceString (pname)); - - if (makeSureClientExists()) - { - MIDIPortRef port; - - if (OK (MIDIOutputPortCreate (globalMidiClient, pname, &port))) - { - MidiPortAndEndpoint* mpe = new MidiPortAndEndpoint(); - mpe->port = port; - mpe->endPoint = endPoint; - - mo = new MidiOutput(); - mo->internal = (void*)mpe; - } - } - - CFRelease (pname); - } - } - - return mo; -} - -MidiOutput::~MidiOutput() -{ - MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal; - MIDIPortDispose (mpe->port); - delete mpe; -} - -void MidiOutput::reset() -{ -} - -bool MidiOutput::getVolume (float& leftVol, float& rightVol) -{ - return false; -} - -void MidiOutput::setVolume (float leftVol, float rightVol) -{ -} - -void MidiOutput::sendMessageNow (const MidiMessage& message) -{ - MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal; - - if (message.isSysEx()) - { - const int maxPacketSize = 256; - int pos = 0, bytesLeft = message.getRawDataSize(); - const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; - MIDIPacketList* const packets = (MIDIPacketList*) juce_malloc (32 * numPackets + message.getRawDataSize()); - packets->numPackets = numPackets; - - MIDIPacket* p = packets->packet; - - for (int i = 0; i < numPackets; ++i) - { - p->timeStamp = 0; - p->length = jmin (maxPacketSize, bytesLeft); - memcpy (p->data, message.getRawData() + pos, p->length); - pos += p->length; - bytesLeft -= p->length; - p = MIDIPacketNext (p); - } - - MIDISend (mpe->port, mpe->endPoint, packets); - juce_free (packets); - } - else - { - MIDIPacketList packets; - packets.numPackets = 1; - packets.packet[0].timeStamp = 0; - packets.packet[0].length = message.getRawDataSize(); - *(int*) (packets.packet[0].data) = *(const int*) message.getRawData(); - - MIDISend (mpe->port, mpe->endPoint, &packets); - } -} - -const StringArray MidiInput::getDevices() -{ - StringArray s; - - const ItemCount num = MIDIGetNumberOfSources(); - for (ItemCount i = 0; i < num; ++i) - { - MIDIEndpointRef source = MIDIGetSource (i); - - if (source != 0) - { - String name (getConnectedEndpointName (source)); - - if (name.isEmpty()) - name = ""; - - s.add (name); - } - else - { - s.add (""); - } - } - - return s; -} - -int MidiInput::getDefaultDeviceIndex() -{ - return 0; -} - -struct MidiPortAndCallback -{ - MidiInput* input; - MIDIPortRef port; - MIDIEndpointRef endPoint; - MidiInputCallback* callback; - MemoryBlock pendingData; - int pendingBytes; - double pendingDataTime; - bool active; -}; - -static CriticalSection callbackLock; -static VoidArray activeCallbacks; - -static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int& size, const double time) -{ - if (*d == 0xf0) - { - mpe->pendingBytes = 0; - mpe->pendingDataTime = time; - } - - mpe->pendingData.ensureSize (mpe->pendingBytes + size, false); - uint8* totalMessage = (uint8*) mpe->pendingData.getData(); - - uint8* dest = totalMessage + mpe->pendingBytes; - - while (size > 0) - { - if (mpe->pendingBytes > 0 && *d >= 0x80) - { - if (*d >= 0xfa || *d == 0xf8) - { - mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (*d, time)); - ++d; - --size; - } - else - { - if (*d == 0xf7) - { - *dest++ = *d++; - mpe->pendingBytes++; - --size; - } - - break; - } - } - else - { - *dest++ = *d++; - mpe->pendingBytes++; - --size; - } - } - - if (totalMessage [mpe->pendingBytes - 1] == 0xf7) - { - mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (totalMessage, - mpe->pendingBytes, - mpe->pendingDataTime)); - mpe->pendingBytes = 0; - } - else - { - mpe->callback->handlePartialSysexMessage (mpe->input, - totalMessage, - mpe->pendingBytes, - mpe->pendingDataTime); - } -} - -static void midiInputProc (const MIDIPacketList* pktlist, - void* readProcRefCon, - void* srcConnRefCon) -{ - double time = Time::getMillisecondCounterHiRes() * 0.001; - const double originalTime = time; - - MidiPortAndCallback* const mpe = (MidiPortAndCallback*) readProcRefCon; - const ScopedLock sl (callbackLock); - - if (activeCallbacks.contains (mpe) && mpe->active) - { - const MIDIPacket* packet = &pktlist->packet[0]; - - for (unsigned int i = 0; i < pktlist->numPackets; ++i) - { - const uint8* d = (const uint8*) (packet->data); - int size = packet->length; - - while (size > 0) - { - time = originalTime; - - if (mpe->pendingBytes > 0 || d[0] == 0xf0) - { - processSysex (mpe, d, size, time); - } - else - { - int used = 0; - const MidiMessage m (d, size, used, 0, time); - - if (used <= 0) - { - jassertfalse // malformed midi message - break; - } - else - { - mpe->callback->handleIncomingMidiMessage (mpe->input, m); - } - - size -= used; - d += used; - } - } - - packet = MIDIPacketNext (packet); - } - } -} - -MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) -{ - MidiInput* mi = 0; - - if (((unsigned int) index) < (unsigned int) MIDIGetNumberOfSources()) - { - MIDIEndpointRef endPoint = MIDIGetSource (index); - - if (endPoint != 0) - { - CFStringRef pname; - - if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname))) - { - log (T("CoreMidi - opening inp: ") + PlatformUtilities::cfStringToJuceString (pname)); - - if (makeSureClientExists()) - { - MIDIPortRef port; - - MidiPortAndCallback* const mpe = new MidiPortAndCallback(); - mpe->active = false; - - if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpe, &port))) - { - if (OK (MIDIPortConnectSource (port, endPoint, 0))) - { - mpe->port = port; - mpe->endPoint = endPoint; - mpe->callback = callback; - mpe->pendingBytes = 0; - mpe->pendingData.ensureSize (128); - - mi = new MidiInput (getDevices() [index]); - mpe->input = mi; - mi->internal = (void*) mpe; - - const ScopedLock sl (callbackLock); - activeCallbacks.add (mpe); - } - else - { - OK (MIDIPortDispose (port)); - delete mpe; - } - } - else - { - delete mpe; - } - } - } - - CFRelease (pname); - } - } - - return mi; -} - -MidiInput::MidiInput (const String& name_) - : name (name_) -{ -} - -MidiInput::~MidiInput() -{ - MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal; - mpe->active = false; - - callbackLock.enter(); - activeCallbacks.removeValue (mpe); - callbackLock.exit(); - - OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint)); - OK (MIDIPortDispose (mpe->port)); - delete mpe; -} - -void MidiInput::start() -{ - MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal; - const ScopedLock sl (callbackLock); - mpe->active = true; -} - -void MidiInput::stop() -{ - MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal; - const ScopedLock sl (callbackLock); - mpe->active = false; -} - -#undef log - -#endif -/********* End of inlined file: juce_mac_CoreMidi.cpp *********/ - -/********* Start of inlined file: juce_mac_CameraDevice.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE && JUCE_QUICKTIME && JUCE_USE_CAMERA - -#define QTCaptureCallbackDelegate MakeObjCClassName(QTCaptureCallbackDelegate) - -class QTCameraDeviceInteral; - -END_JUCE_NAMESPACE - -@interface QTCaptureCallbackDelegate : NSObject -{ -@public - CameraDevice* owner; - QTCameraDeviceInteral* internal; - Time* firstRecordedTime; -} - -- (QTCaptureCallbackDelegate*) initWithOwner: (CameraDevice*) owner internalDev: (QTCameraDeviceInteral*) d; -- (void) dealloc; - -- (void) captureOutput: (QTCaptureOutput*) captureOutput - didOutputVideoFrame: (CVImageBufferRef) videoFrame - withSampleBuffer: (QTSampleBuffer*) sampleBuffer - fromConnection: (QTCaptureConnection*) connection; - -- (void) captureOutput: (QTCaptureFileOutput*) captureOutput - didOutputSampleBuffer: (QTSampleBuffer*) sampleBuffer - fromConnection: (QTCaptureConnection*) connection; - -@end - -BEGIN_JUCE_NAMESPACE - -class QTCameraDeviceInteral -{ -public: - QTCameraDeviceInteral (CameraDevice* owner, int index) - { - const ScopedAutoReleasePool pool; - - session = [[QTCaptureSession alloc] init]; - - NSArray* devs = [QTCaptureDevice inputDevicesWithMediaType: QTMediaTypeVideo]; - device = (QTCaptureDevice*) [devs objectAtIndex: index]; - input = 0; - fileOutput = 0; - imageOutput = 0; - callbackDelegate = [[QTCaptureCallbackDelegate alloc] initWithOwner: owner - internalDev: this]; - - NSError* err = 0; - [device retain]; - [device open: &err]; - - if (err == 0) - { - input = [[QTCaptureDeviceInput alloc] initWithDevice: device]; - - [session addInput: input error: &err]; - - if (err == 0) - { - resetFile(); - - imageOutput = [[QTCaptureDecompressedVideoOutput alloc] init]; - [imageOutput setDelegate: callbackDelegate]; - - if (err == 0) - { - [session startRunning]; - return; - } - } - } - - openingError = nsStringToJuce ([err description]); - DBG (openingError); - } - - ~QTCameraDeviceInteral() - { - [session stopRunning]; - [session removeOutput: imageOutput]; - - [session release]; - [input release]; - [device release]; - [fileOutput release]; - [imageOutput release]; - [callbackDelegate release]; - } - - void resetFile() - { - [session removeOutput: fileOutput]; - [fileOutput release]; - fileOutput = [[QTCaptureMovieFileOutput alloc] init]; - [fileOutput setDelegate: callbackDelegate]; - } - - void addListener (CameraImageListener* listenerToAdd) - { - const ScopedLock sl (listenerLock); - - if (listeners.size() == 0) - [session addOutput: imageOutput error: nil]; - - listeners.addIfNotAlreadyThere (listenerToAdd); - } - - void removeListener (CameraImageListener* listenerToRemove) - { - const ScopedLock sl (listenerLock); - listeners.removeValue (listenerToRemove); - - if (listeners.size() == 0) - [session removeOutput: imageOutput]; - } - - static void drawNSBitmapIntoJuceImage (Image& dest, NSBitmapImageRep* source) - { - const ScopedAutoReleasePool pool; - int lineStride, pixelStride; - uint8* pixels = dest.lockPixelDataReadWrite (0, 0, dest.getWidth(), dest.getHeight(), - lineStride, pixelStride); - - NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes: &pixels - pixelsWide: dest.getWidth() - pixelsHigh: dest.getHeight() - bitsPerSample: 8 - samplesPerPixel: pixelStride - hasAlpha: dest.hasAlphaChannel() - isPlanar: NO - colorSpaceName: NSCalibratedRGBColorSpace - bitmapFormat: (NSBitmapFormat) 0 - bytesPerRow: lineStride - bitsPerPixel: pixelStride * 8]; - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithBitmapImageRep: rep]]; - - [source drawAtPoint: NSZeroPoint]; - - [[NSGraphicsContext currentContext] flushGraphics]; - [NSGraphicsContext restoreGraphicsState]; - - uint8* start = pixels; - for (int h = dest.getHeight(); --h >= 0;) - { - uint8* p = start; - start += lineStride; - - for (int i = dest.getWidth(); --i >= 0;) - { -#if JUCE_BIG_ENDIAN - const uint8 oldp3 = p[3]; - const uint8 oldp1 = p[1]; - p[3] = p[0]; - p[0] = oldp1; - p[1] = p[2]; - p[2] = oldp3; -#else - const uint8 oldp0 = p[0]; - p[0] = p[2]; - p[2] = oldp0; -#endif - - p += pixelStride; - } - } - - dest.releasePixelDataReadWrite (pixels); - } - - void callListeners (NSBitmapImageRep* bitmap) - { - Image image (Image::ARGB, [bitmap size].width, [bitmap size].height, false); - drawNSBitmapIntoJuceImage (image, bitmap); - - const ScopedLock sl (listenerLock); - - for (int i = listeners.size(); --i >= 0;) - { - CameraImageListener* l = (CameraImageListener*) listeners[i]; - - if (l != 0) - l->imageReceived (image); - } - } - - QTCaptureDevice* device; - QTCaptureDeviceInput* input; - QTCaptureSession* session; - QTCaptureMovieFileOutput* fileOutput; - QTCaptureDecompressedVideoOutput* imageOutput; - QTCaptureCallbackDelegate* callbackDelegate; - String openingError; - - VoidArray listeners; - CriticalSection listenerLock; -}; - -END_JUCE_NAMESPACE -@implementation QTCaptureCallbackDelegate - -- (QTCaptureCallbackDelegate*) initWithOwner: (CameraDevice*) owner_ - internalDev: (QTCameraDeviceInteral*) d -{ - [super init]; - owner = owner_; - internal = d; - firstRecordedTime = 0; - return self; -} - -- (void) dealloc -{ - delete firstRecordedTime; - [super dealloc]; -} - -- (void) captureOutput: (QTCaptureOutput*) captureOutput - didOutputVideoFrame: (CVImageBufferRef) videoFrame - withSampleBuffer: (QTSampleBuffer*) sampleBuffer - fromConnection: (QTCaptureConnection*) connection -{ - const ScopedAutoReleasePool pool; - CIImage* image = [CIImage imageWithCVImageBuffer: videoFrame]; - NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCIImage: image] autorelease]; - - internal->callListeners (bitmap); -} - -- (void) captureOutput: (QTCaptureFileOutput*) captureOutput - didOutputSampleBuffer: (QTSampleBuffer*) sampleBuffer - fromConnection: (QTCaptureConnection*) connection -{ - if (firstRecordedTime == 0) - firstRecordedTime = new Time (Time::getCurrentTime()); -} - -@end -BEGIN_JUCE_NAMESPACE - -class QTCaptureViewerComp : public NSViewComponent -{ -public: - QTCaptureViewerComp (CameraDevice* const cameraDevice, QTCameraDeviceInteral* const internal) - { - const ScopedAutoReleasePool pool; - captureView = [[QTCaptureView alloc] init]; - [captureView setCaptureSession: internal->session]; - - setSize (640, 480); // xxx need to somehow get the movie size - how? - setView (captureView); - } - - ~QTCaptureViewerComp() - { - setView (0); - [captureView setCaptureSession: nil]; - [captureView release]; - } - - QTCaptureView* captureView; -}; - -CameraDevice::CameraDevice (const String& name_, int index) - : name (name_) -{ - isRecording = false; - QTCameraDeviceInteral* d = new QTCameraDeviceInteral (this, index); - internal = d; -} - -CameraDevice::~CameraDevice() -{ - stopRecording(); - delete (QTCameraDeviceInteral*) internal; - internal = 0; -} - -Component* CameraDevice::createViewerComponent() -{ - return new QTCaptureViewerComp (this, (QTCameraDeviceInteral*) internal); -} - -const String CameraDevice::getFileExtension() -{ - return ".mov"; -} - -void CameraDevice::startRecordingToFile (const File& file) -{ - stopRecording(); - - QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal; - deleteAndZero (d->callbackDelegate->firstRecordedTime); - file.deleteFile(); - [d->fileOutput recordToOutputFileURL: [NSURL fileURLWithPath: juceStringToNS (file.getFullPathName())]]; - [d->session addOutput: d->fileOutput error: nil]; - isRecording = true; -} - -const Time CameraDevice::getTimeOfFirstRecordedFrame() const -{ - QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal; - if (d->callbackDelegate->firstRecordedTime != 0) - return *d->callbackDelegate->firstRecordedTime; - - return Time(); -} - -void CameraDevice::stopRecording() -{ - if (isRecording) - { - QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal; - d->resetFile(); - isRecording = false; - } -} - -void CameraDevice::addListener (CameraImageListener* listenerToAdd) -{ - QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal; - - if (listenerToAdd != 0) - d->addListener (listenerToAdd); -} - -void CameraDevice::removeListener (CameraImageListener* listenerToRemove) -{ - QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal; - - if (listenerToRemove != 0) - d->removeListener (listenerToRemove); -} - -const StringArray CameraDevice::getAvailableDevices() -{ - const ScopedAutoReleasePool pool; - - StringArray results; - NSArray* devs = [QTCaptureDevice inputDevicesWithMediaType: QTMediaTypeVideo]; - - for (int i = 0; i < [devs count]; ++i) - { - QTCaptureDevice* dev = (QTCaptureDevice*) [devs objectAtIndex: i]; - results.add (nsStringToJuce ([dev localizedDisplayName])); - } - - return results; -} - -CameraDevice* CameraDevice::openDevice (int index, - int minWidth, int minHeight, - int maxWidth, int maxHeight) -{ - CameraDevice* d = new CameraDevice (getAvailableDevices() [index], index); - - if (((QTCameraDeviceInteral*) (d->internal))->openingError.isEmpty()) - return d; - - delete d; - return 0; -} - -#endif -/********* End of inlined file: juce_mac_CameraDevice.mm *********/ - -#endif - -END_JUCE_NAMESPACE -/********* End of inlined file: juce_mac_NativeCode.mm *********/ - -#endif - -#if JUCE_IPHONE - -/********* Start of inlined file: juce_iphone_NativeCode.mm *********/ -/* - This file wraps together all the mac-specific code, so that - we can include all the native headers just once, and compile all our - platform-specific stuff in one big lump, keeping it out of the way of - the rest of the codebase. -*/ - -BEGIN_JUCE_NAMESPACE - -#undef Point - -#define JUCE_INCLUDED_FILE 1 - -// Now include the actual code files.. - -/********* Start of inlined file: juce_mac_ObjCSuffix.h *********/ -/** 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 - two DLLs are loaded into a host, each of which uses classes with the same names, and these get - cross-linked so that when you make a call to a class that you thought was private, it ends up - actually calling into a similarly named class in the other module's address space. - - By changing this macro to a unique value, you ensure that all the obj-C classes in your app - have unique names, and should avoid this problem. - - If you're using the amalgamated version, you can just set this macro to something unique before - you include juce_amalgamated.cpp. -*/ -#ifndef JUCE_ObjCExtraSuffix - #define JUCE_ObjCExtraSuffix 3 -#endif - -#define appendMacro1(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d -#define appendMacro2(a, b, c, d) appendMacro1(a, b, c, d) -#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_ObjCExtraSuffix) -/********* End of inlined file: juce_mac_ObjCSuffix.h *********/ - -/********* Start of inlined file: juce_mac_Strings.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE - -static const String nsStringToJuce (NSString* s) -{ - return String::fromUTF8 ((uint8*) [s UTF8String]); -} - -static NSString* juceStringToNS (const String& s) -{ - return [NSString stringWithUTF8String: (const char*) s.toUTF8()]; -} - -static const String convertUTF16ToString (const UniChar* utf16) -{ - String s; - - while (*utf16 != 0) - s += (juce_wchar) *utf16++; - - return s; -} - -const String PlatformUtilities::cfStringToJuceString (CFStringRef cfString) -{ - String result; - - if (cfString != 0) - { -#if JUCE_STRINGS_ARE_UNICODE - CFRange range = { 0, CFStringGetLength (cfString) }; - UniChar* const u = (UniChar*) juce_malloc (sizeof (UniChar) * (range.length + 1)); - - CFStringGetCharacters (cfString, range, u); - u[range.length] = 0; - - result = convertUTF16ToString (u); - - juce_free (u); -#else - const int len = CFStringGetLength (cfString); - char* buffer = (char*) juce_malloc (len + 1); - CFStringGetCString (cfString, buffer, len + 1, CFStringGetSystemEncoding()); - result = buffer; - juce_free (buffer); -#endif - } - - return result; -} - -CFStringRef PlatformUtilities::juceStringToCFString (const String& s) -{ -#if JUCE_STRINGS_ARE_UNICODE - const int len = s.length(); - const juce_wchar* t = (const juce_wchar*) s; - - UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4); - - for (int i = 0; i <= len; ++i) - temp[i] = t[i]; - - CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); - juce_free (temp); - - return result; - -#else - return CFStringCreateWithCString (kCFAllocatorDefault, - (const char*) s, - CFStringGetSystemEncoding()); -#endif -} - -const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) -{ -#if JUCE_IPHONE - const ScopedAutoReleasePool pool; - return nsStringToJuce ([juceStringToNS (s) precomposedStringWithCanonicalMapping]); -#else - UnicodeMapping map; - - map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault, - kUnicodeNoSubset, - kTextEncodingDefaultFormat); - - map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault, - kUnicodeCanonicalCompVariant, - kTextEncodingDefaultFormat); - - map.mappingVersion = kUnicodeUseLatestMapping; - - UnicodeToTextInfo conversionInfo = 0; - String result; - - if (CreateUnicodeToTextInfo (&map, &conversionInfo) == noErr) - { - const int len = s.length(); - - UniChar* const tempIn = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4); - UniChar* const tempOut = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4); - - for (int i = 0; i <= len; ++i) - tempIn[i] = s[i]; - - ByteCount bytesRead = 0; - ByteCount outputBufferSize = 0; - - if (ConvertFromUnicodeToText (conversionInfo, - len * sizeof (UniChar), tempIn, - kUnicodeDefaultDirectionMask, - 0, 0, 0, 0, - len * sizeof (UniChar), &bytesRead, - &outputBufferSize, tempOut) == noErr) - { - result.preallocateStorage (bytesRead / sizeof (UniChar) + 2); - - tchar* t = const_cast ((const tchar*) result); - - unsigned int i; - for (i = 0; i < bytesRead / sizeof (UniChar); ++i) - t[i] = (tchar) tempOut[i]; - - t[i] = 0; - } - - juce_free (tempIn); - juce_free (tempOut); - - DisposeUnicodeToTextInfo (&conversionInfo); - } - - return result; -#endif -} - -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY - -void SystemClipboard::copyTextToClipboard (const String& text) throw() -{ -#if JUCE_IPHONE - [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text) - forPasteboardType: (NSString*) kUTTypePlainText]; -#else - [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject: NSStringPboardType] - owner: nil]; - - [[NSPasteboard generalPasteboard] setString: juceStringToNS (text) - forType: NSStringPboardType]; -#endif -} - -const String SystemClipboard::getTextFromClipboard() throw() -{ -#if JUCE_IPHONE - NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: (NSString*) kUTTypePlainText]; -#else - NSString* text = [[NSPasteboard generalPasteboard] stringForType: NSStringPboardType]; -#endif - - return text == 0 ? String::empty - : nsStringToJuce (text); -} - -#endif - -#endif -/********* End of inlined file: juce_mac_Strings.mm *********/ - -/********* Start of inlined file: juce_mac_SystemStats.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE - -static int64 highResTimerFrequency = 0; -static double highResTimerToMillisecRatio = 0; - -#if JUCE_INTEL - -static void juce_getCpuVendor (char* const v) throw() -{ - int vendor[4]; - zerostruct (vendor); - int dummy = 0; - - asm ("mov %%ebx, %%esi \n\t" - "cpuid \n\t" - "xchg %%esi, %%ebx" - : "=a" (dummy), "=S" (vendor[0]), "=c" (vendor[2]), "=d" (vendor[1]) : "a" (0)); - - memcpy (v, vendor, 16); -} - -static unsigned int getCPUIDWord (unsigned int& familyModel, unsigned int& extFeatures) throw() -{ - unsigned int cpu = 0; - unsigned int ext = 0; - unsigned int family = 0; - unsigned int dummy = 0; - - asm ("mov %%ebx, %%esi \n\t" - "cpuid \n\t" - "xchg %%esi, %%ebx" - : "=a" (family), "=S" (ext), "=c" (dummy), "=d" (cpu) : "a" (1)); - - familyModel = family; - extFeatures = ext; - return cpu; -} - -struct CPUFlags -{ - bool hasMMX : 1; - bool hasSSE : 1; - bool hasSSE2 : 1; - bool has3DNow : 1; -}; - -static CPUFlags cpuFlags; - -#endif - -void SystemStats::initialiseStats() throw() -{ - static bool initialised = false; - - if (! initialised) - { - initialised = true; - -#if JUCE_MAC - // extremely annoying: adding this line stops the apple menu items from working. Of - // course, not adding it means that carbon windows (e.g. in plugins) won't get - // any events. - //NSApplicationLoad(); - [NSApplication sharedApplication]; -#endif - -#if JUCE_INTEL - { - unsigned int familyModel, extFeatures; - const unsigned int features = getCPUIDWord (familyModel, extFeatures); - - cpuFlags.hasMMX = ((features & (1 << 23)) != 0); - cpuFlags.hasSSE = ((features & (1 << 25)) != 0); - cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0); - cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0); - } -#endif - - mach_timebase_info_data_t timebase; - (void) mach_timebase_info (&timebase); - highResTimerFrequency = (int64) (1.0e9 * timebase.denom / timebase.numer); - highResTimerToMillisecRatio = timebase.numer / (1.0e6 * timebase.denom); - - String s (SystemStats::getJUCEVersion()); + // when the component becomes invisible, some stuff like flash + // carries on playing audio, so we need to force it onto a blank + // page to avoid this, (and send it back when it's made visible again). - rlimit lim; - getrlimit (RLIMIT_NOFILE, &lim); - lim.rlim_cur = lim.rlim_max = RLIM_INFINITY; - setrlimit (RLIMIT_NOFILE, &lim); + blankPageShown = true; + browser->goToURL ("about:blank", 0, 0); + } } } -SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() throw() +void WebBrowserComponent::reloadLastURL() { - return MacOSX; + if (lastURL.isNotEmpty()) + { + goToURL (lastURL, &lastHeaders, &lastPostData); + lastURL = String::empty; + } } -const String SystemStats::getOperatingSystemName() throw() +void WebBrowserComponent::parentHierarchyChanged() { - return T("Mac OS X"); + checkWindowAssociation(); } -bool SystemStats::isOperatingSystem64Bit() throw() +void WebBrowserComponent::resized() { -#if JUCE_64BIT - return true; -#else - //xxx not sure how to find this out?.. - return false; -#endif + browser->setSize (getWidth(), getHeight()); } -int SystemStats::getMemorySizeInMegabytes() throw() +void WebBrowserComponent::visibilityChanged() { - uint64 mem = 0; - size_t memSize = sizeof (mem); - int mib[] = { CTL_HW, HW_MEMSIZE }; - sysctl (mib, 2, &mem, &memSize, 0, 0); - return mem / (1024 * 1024); + checkWindowAssociation(); } -bool SystemStats::hasMMX() throw() +bool WebBrowserComponent::pageAboutToLoad (const String& url) { -#if JUCE_INTEL - return cpuFlags.hasMMX; -#else - return false; -#endif + return true; } -bool SystemStats::hasSSE() throw() -{ -#if JUCE_INTEL - return cpuFlags.hasSSE; #else - return false; -#endif -} -bool SystemStats::hasSSE2() throw() +WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) { -#if JUCE_INTEL - return cpuFlags.hasSSE2; -#else - return false; -#endif } -bool SystemStats::has3DNow() throw() +WebBrowserComponent::~WebBrowserComponent() { -#if JUCE_INTEL - return cpuFlags.has3DNow; -#else - return false; -#endif } -const String SystemStats::getCpuVendor() throw() +void WebBrowserComponent::goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) { -#if JUCE_INTEL - char v [16]; - juce_getCpuVendor (v); - return String (v, 16); -#else - return String::empty; -#endif } -int SystemStats::getCpuSpeedInMegaherz() throw() +void WebBrowserComponent::stop() { - uint64 speedHz = 0; - size_t speedSize = sizeof (speedHz); - int mib[] = { CTL_HW, HW_CPU_FREQ }; - sysctl (mib, 2, &speedHz, &speedSize, 0, 0); +} -#if JUCE_BIG_ENDIAN - if (speedSize == 4) - speedHz >>= 32; -#endif - return speedHz / 1000000; +void WebBrowserComponent::goBack() +{ } -int SystemStats::getNumCpus() throw() +void WebBrowserComponent::goForward() { -#if MACOS_10_4_OR_EARLIER - return MPProcessors(); -#else - return [[NSProcessInfo processInfo] activeProcessorCount]; -#endif } -uint32 juce_millisecondsSinceStartup() throw() +void WebBrowserComponent::refresh() { - return (uint32) (mach_absolute_time() * highResTimerToMillisecRatio); } -double Time::getMillisecondCounterHiRes() throw() +void WebBrowserComponent::paint (Graphics& g) { - return mach_absolute_time() * highResTimerToMillisecRatio; } -int64 Time::getHighResolutionTicks() throw() +void WebBrowserComponent::checkWindowAssociation() { - return (int64) mach_absolute_time(); } -int64 Time::getHighResolutionTicksPerSecond() throw() +void WebBrowserComponent::reloadLastURL() { - return highResTimerFrequency; } -int64 SystemStats::getClockCycleCounter() throw() +void WebBrowserComponent::parentHierarchyChanged() { - return (int64) mach_absolute_time(); } -bool Time::setSystemTimeToThisTime() const throw() +void WebBrowserComponent::resized() { - jassertfalse - return false; } -int SystemStats::getPageSize() throw() +void WebBrowserComponent::visibilityChanged() { - return NSPageSize(); } -void PlatformUtilities::fpuReset() +bool WebBrowserComponent::pageAboutToLoad (const String& url) { + return true; } #endif -/********* End of inlined file: juce_mac_SystemStats.mm *********/ -/********* Start of inlined file: juce_mac_Network.mm *********/ +#endif +/********* End of inlined file: juce_mac_WebBrowserComponent.mm *********/ + + //#include "mac/juce_mac_CoreAudio.cpp" + //#include "mac/juce_mac_CameraDevice.mm" + +/********* Start of inlined file: juce_mac_CoreMidi.cpp *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). -#if JUCE_INCLUDED_FILE +#ifdef JUCE_INCLUDED_FILE -int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw() +#if JUCE_MAC + +#undef log +#define log(a) Logger::writeToLog(a) + +static bool logAnyErrorsMidi (const OSStatus err, const int lineNum) { - #ifndef IFT_ETHER - #define IFT_ETHER 6 - #endif + if (err == noErr) + return true; - ifaddrs* addrs = 0; - int numResults = 0; + log (T("CoreMidi error: ") + String (lineNum) + T(" - ") + String::toHexString ((int)err)); + jassertfalse + return false; +} - if (getifaddrs (&addrs) == 0) +#undef OK +#define OK(a) logAnyErrorsMidi(a, __LINE__) + +static const String getEndpointName (MIDIEndpointRef endpoint, bool isExternal) +{ + String result; + CFStringRef str = 0; + + MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str); + + if (str != 0) { - const ifaddrs* cursor = addrs; + result = PlatformUtilities::cfStringToJuceString (str); + CFRelease (str); + str = 0; + } - while (cursor != 0 && numResults < maxNum) + MIDIEntityRef entity = 0; + MIDIEndpointGetEntity (endpoint, &entity); + + if (entity == 0) + return result; // probably virtual + + if (result.isEmpty()) + { + // endpoint name has zero length - try the entity + MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str); + + if (str != 0) { - if (cursor->ifa_addr->sa_family == AF_LINK) - { - const sockaddr_dl* const sadd = (const sockaddr_dl*) cursor->ifa_addr; + result += PlatformUtilities::cfStringToJuceString (str); + CFRelease (str); + str = 0; + } + } - if (sadd->sdl_type == IFT_ETHER) - { - const uint8* const addr = ((const uint8*) sadd->sdl_data) + sadd->sdl_nlen; + // now consider the device's name + MIDIDeviceRef device = 0; + MIDIEntityGetDevice (entity, &device); + if (device == 0) + return result; - uint64 a = 0; - for (int i = 6; --i >= 0;) - a = (a << 8) | addr [littleEndian ? i : (5 - i)]; + MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str); - *addresses++ = (int64) a; - ++numResults; - } - } + if (str != 0) + { + const String s (PlatformUtilities::cfStringToJuceString (str)); + CFRelease (str); - cursor = cursor->ifa_next; + // if an external device has only one entity, throw away + // the endpoint name and just use the device name + if (isExternal && MIDIDeviceGetNumberOfEntities (device) < 2) + { + result = s; + } + else if (! result.startsWithIgnoreCase (s)) + { + // prepend the device name to the entity name + result = (s + T(" ") + result).trimEnd(); } - - freeifaddrs (addrs); } - return numResults; + return result; } -bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress, - const String& emailSubject, - const String& bodyText, - const StringArray& filesToAttach) +static const String getConnectedEndpointName (MIDIEndpointRef endpoint) { -#if JUCE_IPHONE - //xxx probably need to use MFMailComposeViewController - jassertfalse - return false; -#else - const ScopedAutoReleasePool pool; + String result; - String script; - script << "tell application \"Mail\"\r\n" - "set newMessage to make new outgoing message with properties {subject:\"" - << emailSubject.replace (T("\""), T("\\\"")) - << "\", content:\"" - << bodyText.replace (T("\""), T("\\\"")) - << "\" & return & return}\r\n" - "tell newMessage\r\n" - "set visible to true\r\n" - "set sender to \"sdfsdfsdfewf\"\r\n" - "make new to recipient at end of to recipients with properties {address:\"" - << targetEmailAddress - << "\"}\r\n"; + // Does the endpoint have connections? + CFDataRef connections = 0; + int numConnections = 0; - for (int i = 0; i < filesToAttach.size(); ++i) + MIDIObjectGetDataProperty (endpoint, kMIDIPropertyConnectionUniqueID, &connections); + + if (connections != 0) { - script << "tell content\r\n" - "make new attachment with properties {file name:\"" - << filesToAttach[i].replace (T("\""), T("\\\"")) - << "\"} at after the last paragraph\r\n" - "end tell\r\n"; - } + numConnections = CFDataGetLength (connections) / sizeof (MIDIUniqueID); - script << "end tell\r\n" - "end tell\r\n"; + if (numConnections > 0) + { + const SInt32* pid = reinterpret_cast (CFDataGetBytePtr (connections)); - NSAppleScript* s = [[NSAppleScript alloc] - initWithSource: juceStringToNS (script)]; - NSDictionary* error = 0; - const bool ok = [s executeAndReturnError: &error] != nil; - [s release]; + for (int i = 0; i < numConnections; ++i, ++pid) + { + MIDIUniqueID uid = EndianS32_BtoN (*pid); + MIDIObjectRef connObject; + MIDIObjectType connObjectType; + OSStatus err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType); - return ok; -#endif -} + if (err == noErr) + { + String s; -END_JUCE_NAMESPACE + if (connObjectType == kMIDIObjectType_ExternalSource + || connObjectType == kMIDIObjectType_ExternalDestination) + { + // Connected to an external device's endpoint (10.3 and later). + s = getEndpointName (static_cast (connObject), true); + } + else + { + // Connected to an external device (10.2) (or something else, catch-all) + CFStringRef str = 0; + MIDIObjectGetStringProperty (connObject, kMIDIPropertyName, &str); -using namespace JUCE_NAMESPACE; + if (str != 0) + { + s = PlatformUtilities::cfStringToJuceString (str); + CFRelease (str); + } + } -#define JuceURLConnection MakeObjCClassName(JuceURLConnection) + if (s.isNotEmpty()) + { + if (result.isNotEmpty()) + result += (", "); -@interface JuceURLConnection : NSObject -{ -@public - NSURLRequest* request; - NSURLConnection* connection; - NSMutableData* data; - Thread* runLoopThread; - bool initialised, hasFailed, hasFinished; - int position; - int64 contentLength; - NSLock* dataLock; -} + result += s; + } + } + } + } -- (JuceURLConnection*) initWithRequest: (NSURLRequest*) req withCallback: (URL::OpenStreamProgressCallback*) callback withContext: (void*) context; -- (void) dealloc; -- (void) connection: (NSURLConnection*) connection didReceiveResponse: (NSURLResponse*) response; -- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error; -- (void) connection: (NSURLConnection*) connection didReceiveData: (NSData*) data; -- (void) connectionDidFinishLoading: (NSURLConnection*) connection; + CFRelease (connections); + } -- (BOOL) isOpen; -- (int) read: (char*) dest numBytes: (int) num; -- (int) readPosition; -- (void) stop; -- (void) createConnection; + if (result.isNotEmpty()) + return result; -@end + // Here, either the endpoint had no connections, or we failed to obtain names for any of them. + return getEndpointName (endpoint, false); +} -class JuceURLConnectionMessageThread : public Thread +const StringArray MidiOutput::getDevices() { - JuceURLConnection* owner; + StringArray s; -public: - JuceURLConnectionMessageThread (JuceURLConnection* owner_) - : Thread (T("http connection")), - owner (owner_) + const ItemCount num = MIDIGetNumberOfDestinations(); + for (ItemCount i = 0; i < num; ++i) { - } + MIDIEndpointRef dest = MIDIGetDestination (i); - ~JuceURLConnectionMessageThread() - { - stopThread (10000); - } + if (dest != 0) + { + String name (getConnectedEndpointName (dest)); - void run() - { - [owner createConnection]; + if (name.isEmpty()) + name = ""; - while (! threadShouldExit()) + s.add (name); + } + else { - const ScopedAutoReleasePool pool; - [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; + s.add (""); } } -}; -@implementation JuceURLConnection + return s; +} -- (JuceURLConnection*) initWithRequest: (NSURLRequest*) req - withCallback: (URL::OpenStreamProgressCallback*) callback - withContext: (void*) context; +int MidiOutput::getDefaultDeviceIndex() { - [super init]; - request = req; - [request retain]; - data = [[NSMutableData data] retain]; - dataLock = [[NSLock alloc] init]; - connection = 0; - initialised = false; - hasFailed = false; - hasFinished = false; - contentLength = -1; + return 0; +} - runLoopThread = new JuceURLConnectionMessageThread (self); - runLoopThread->startThread(); +static MIDIClientRef globalMidiClient; +static bool hasGlobalClientBeenCreated = false; - while (runLoopThread->isThreadRunning() && ! initialised) +static bool makeSureClientExists() +{ + if (! hasGlobalClientBeenCreated) { - if (callback != 0) - callback (context, -1, [[request HTTPBody] length]); + String name (T("JUCE")); - Thread::sleep (1); + if (JUCEApplication::getInstance() != 0) + name = JUCEApplication::getInstance()->getApplicationName(); + + CFStringRef appName = PlatformUtilities::juceStringToCFString (name); + + hasGlobalClientBeenCreated = OK (MIDIClientCreate (appName, 0, 0, &globalMidiClient)); + CFRelease (appName); } - return self; + return hasGlobalClientBeenCreated; } -- (void) dealloc +struct MidiPortAndEndpoint { - [self stop]; - - delete runLoopThread; - [connection release]; - [data release]; - [dataLock release]; - [request release]; - [super dealloc]; -} + MIDIPortRef port; + MIDIEndpointRef endPoint; +}; -- (void) createConnection +MidiOutput* MidiOutput::openDevice (int index) { - connection = [[NSURLConnection alloc] initWithRequest: request - delegate: [self retain]]; + MidiOutput* mo = 0; - if (connection == nil) - runLoopThread->signalThreadShouldExit(); -} + if (((unsigned int) index) < (unsigned int) MIDIGetNumberOfDestinations()) + { + MIDIEndpointRef endPoint = MIDIGetDestination (index); -- (void) connection: (NSURLConnection*) connection didReceiveResponse: (NSURLResponse*) response -{ - [dataLock lock]; - [data setLength: 0]; - [dataLock unlock]; - initialised = true; - contentLength = [response expectedContentLength]; + CFStringRef pname; + if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname))) + { + log (T("CoreMidi - opening out: ") + PlatformUtilities::cfStringToJuceString (pname)); + + if (makeSureClientExists()) + { + MIDIPortRef port; + + if (OK (MIDIOutputPortCreate (globalMidiClient, pname, &port))) + { + MidiPortAndEndpoint* mpe = new MidiPortAndEndpoint(); + mpe->port = port; + mpe->endPoint = endPoint; + + mo = new MidiOutput(); + mo->internal = (void*)mpe; + } + } + + CFRelease (pname); + } + } + + return mo; } -- (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error +MidiOutput::~MidiOutput() { - DBG (nsStringToJuce ([error description])); - hasFailed = true; - initialised = true; - runLoopThread->signalThreadShouldExit(); + MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal; + MIDIPortDispose (mpe->port); + delete mpe; } -- (void) connection: (NSURLConnection*) connection didReceiveData: (NSData*) newData +void MidiOutput::reset() { - [dataLock lock]; - [data appendData: newData]; - [dataLock unlock]; - initialised = true; } -- (void) connectionDidFinishLoading: (NSURLConnection*) connection +bool MidiOutput::getVolume (float& leftVol, float& rightVol) { - hasFinished = true; - initialised = true; - runLoopThread->signalThreadShouldExit(); + return false; } -- (BOOL) isOpen +void MidiOutput::setVolume (float leftVol, float rightVol) { - return connection != 0 && ! hasFailed; } -- (int) readPosition +void MidiOutput::sendMessageNow (const MidiMessage& message) { - return position; + MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal; + + if (message.isSysEx()) + { + const int maxPacketSize = 256; + int pos = 0, bytesLeft = message.getRawDataSize(); + const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; + MIDIPacketList* const packets = (MIDIPacketList*) juce_malloc (32 * numPackets + message.getRawDataSize()); + packets->numPackets = numPackets; + + MIDIPacket* p = packets->packet; + + for (int i = 0; i < numPackets; ++i) + { + p->timeStamp = 0; + p->length = jmin (maxPacketSize, bytesLeft); + memcpy (p->data, message.getRawData() + pos, p->length); + pos += p->length; + bytesLeft -= p->length; + p = MIDIPacketNext (p); + } + + MIDISend (mpe->port, mpe->endPoint, packets); + juce_free (packets); + } + else + { + MIDIPacketList packets; + packets.numPackets = 1; + packets.packet[0].timeStamp = 0; + packets.packet[0].length = message.getRawDataSize(); + *(int*) (packets.packet[0].data) = *(const int*) message.getRawData(); + + MIDISend (mpe->port, mpe->endPoint, &packets); + } } -- (int) read: (char*) dest numBytes: (int) numNeeded +const StringArray MidiInput::getDevices() { - int numDone = 0; + StringArray s; - while (numNeeded > 0) + const ItemCount num = MIDIGetNumberOfSources(); + for (ItemCount i = 0; i < num; ++i) { - int available = jmin (numNeeded, [data length]); + MIDIEndpointRef source = MIDIGetSource (i); - if (available > 0) + if (source != 0) { - [dataLock lock]; - [data getBytes: dest length: available]; - [data replaceBytesInRange: NSMakeRange (0, available) withBytes: nil length: 0]; - [dataLock unlock]; + String name (getConnectedEndpointName (source)); - numDone += available; - numNeeded -= available; - dest += available; + if (name.isEmpty()) + name = ""; + + s.add (name); } else { - if (hasFailed || hasFinished) - break; - - Thread::sleep (1); + s.add (""); } } - position += numDone; - return numDone; -} - -- (void) stop -{ - [connection cancel]; - runLoopThread->stopThread (10000); + return s; } -@end -BEGIN_JUCE_NAMESPACE - -bool juce_isOnLine() +int MidiInput::getDefaultDeviceIndex() { - return true; + return 0; } -void* juce_openInternetFile (const String& url, - const String& headers, - const MemoryBlock& postData, - const bool isPost, - URL::OpenStreamProgressCallback* callback, - void* callbackContext, - int timeOutMs) +struct MidiPortAndCallback { - const ScopedAutoReleasePool pool; + MidiInput* input; + MIDIPortRef port; + MIDIEndpointRef endPoint; + MidiInputCallback* callback; + MemoryBlock pendingData; + int pendingBytes; + double pendingDataTime; + bool active; +}; - NSMutableURLRequest* req = [NSMutableURLRequest - requestWithURL: [NSURL URLWithString: juceStringToNS (url)] - cachePolicy: NSURLRequestUseProtocolCachePolicy - timeoutInterval: timeOutMs <= 0 ? 60.0 : (timeOutMs / 1000.0)]; +static CriticalSection callbackLock; +static VoidArray activeCallbacks; - if (req == nil) - return 0; +static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int& size, const double time) +{ + if (*d == 0xf0) + { + mpe->pendingBytes = 0; + mpe->pendingDataTime = time; + } - [req setHTTPMethod: isPost ? @"POST" : @"GET"]; - //[req setCachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData]; + mpe->pendingData.ensureSize (mpe->pendingBytes + size, false); + uint8* totalMessage = (uint8*) mpe->pendingData.getData(); - StringArray headerLines; - headerLines.addLines (headers); - headerLines.removeEmptyStrings (true); + uint8* dest = totalMessage + mpe->pendingBytes; - for (int i = 0; i < headerLines.size(); ++i) + while (size > 0) { - const String key (headerLines[i].upToFirstOccurrenceOf (T(":"), false, false).trim()); - const String value (headerLines[i].fromFirstOccurrenceOf (T(":"), false, false).trim()); + if (mpe->pendingBytes > 0 && *d >= 0x80) + { + if (*d >= 0xfa || *d == 0xf8) + { + mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (*d, time)); + ++d; + --size; + } + else + { + if (*d == 0xf7) + { + *dest++ = *d++; + mpe->pendingBytes++; + --size; + } - if (key.isNotEmpty() && value.isNotEmpty()) - [req addValue: juceStringToNS (value) forHTTPHeaderField: juceStringToNS (key)]; + break; + } + } + else + { + *dest++ = *d++; + mpe->pendingBytes++; + --size; + } } - if (isPost && postData.getSize() > 0) + if (totalMessage [mpe->pendingBytes - 1] == 0xf7) { - [req setHTTPBody: [NSData dataWithBytes: postData.getData() - length: postData.getSize()]]; + mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (totalMessage, + mpe->pendingBytes, + mpe->pendingDataTime)); + mpe->pendingBytes = 0; + } + else + { + mpe->callback->handlePartialSysexMessage (mpe->input, + totalMessage, + mpe->pendingBytes, + mpe->pendingDataTime); } - - JuceURLConnection* const s = [[JuceURLConnection alloc] initWithRequest: req - withCallback: callback - withContext: callbackContext]; - - if ([s isOpen]) - return s; - - [s release]; - return 0; } -void juce_closeInternetFile (void* handle) +static void midiInputProc (const MIDIPacketList* pktlist, + void* readProcRefCon, + void* srcConnRefCon) { - JuceURLConnection* const s = (JuceURLConnection*) handle; + double time = Time::getMillisecondCounterHiRes() * 0.001; + const double originalTime = time; - if (s != 0) + MidiPortAndCallback* const mpe = (MidiPortAndCallback*) readProcRefCon; + const ScopedLock sl (callbackLock); + + if (activeCallbacks.contains (mpe) && mpe->active) { - const ScopedAutoReleasePool pool; - [s stop]; - [s release]; + const MIDIPacket* packet = &pktlist->packet[0]; + + for (unsigned int i = 0; i < pktlist->numPackets; ++i) + { + const uint8* d = (const uint8*) (packet->data); + int size = packet->length; + + while (size > 0) + { + time = originalTime; + + if (mpe->pendingBytes > 0 || d[0] == 0xf0) + { + processSysex (mpe, d, size, time); + } + else + { + int used = 0; + const MidiMessage m (d, size, used, 0, time); + + if (used <= 0) + { + jassertfalse // malformed midi message + break; + } + else + { + mpe->callback->handleIncomingMidiMessage (mpe->input, m); + } + + size -= used; + d += used; + } + } + + packet = MIDIPacketNext (packet); + } } } -int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead) +MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) { - JuceURLConnection* const s = (JuceURLConnection*) handle; + MidiInput* mi = 0; - if (s != 0) + if (((unsigned int) index) < (unsigned int) MIDIGetNumberOfSources()) { - const ScopedAutoReleasePool pool; - return [s read: (char*) buffer numBytes: bytesToRead]; - } + MIDIEndpointRef endPoint = MIDIGetSource (index); - return 0; -} + if (endPoint != 0) + { + CFStringRef pname; -int64 juce_getInternetFileContentLength (void* handle) -{ - JuceURLConnection* const s = (JuceURLConnection*) handle; + if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname))) + { + log (T("CoreMidi - opening inp: ") + PlatformUtilities::cfStringToJuceString (pname)); - if (s != 0) - return s->contentLength; + if (makeSureClientExists()) + { + MIDIPortRef port; - return -1; -} + MidiPortAndCallback* const mpe = new MidiPortAndCallback(); + mpe->active = false; -int juce_seekInInternetFile (void* handle, int newPosition) -{ - JuceURLConnection* const s = (JuceURLConnection*) handle; + if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpe, &port))) + { + if (OK (MIDIPortConnectSource (port, endPoint, 0))) + { + mpe->port = port; + mpe->endPoint = endPoint; + mpe->callback = callback; + mpe->pendingBytes = 0; + mpe->pendingData.ensureSize (128); - if (s != 0) - return [s readPosition]; + mi = new MidiInput (getDevices() [index]); + mpe->input = mi; + mi->internal = (void*) mpe; - return 0; -} + const ScopedLock sl (callbackLock); + activeCallbacks.add (mpe); + } + else + { + OK (MIDIPortDispose (port)); + delete mpe; + } + } + else + { + delete mpe; + } + } + } -#endif -/********* End of inlined file: juce_mac_Network.mm *********/ + CFRelease (pname); + } + } -/********* Start of inlined file: juce_posix_NamedPipe.cpp *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE + return mi; +} -struct NamedPipeInternal +MidiInput::MidiInput (const String& name_) + : name (name_) { - String pipeInName, pipeOutName; - int pipeIn, pipeOut; +} - bool volatile createdPipe, blocked, stopReadOperation; +MidiInput::~MidiInput() +{ + MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal; + mpe->active = false; - static void signalHandler (int) {} -}; + callbackLock.enter(); + activeCallbacks.removeValue (mpe); + callbackLock.exit(); -void NamedPipe::cancelPendingReads() + OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint)); + OK (MIDIPortDispose (mpe->port)); + delete mpe; +} + +void MidiInput::start() { - while (internal != 0 && ((NamedPipeInternal*) internal)->blocked) - { - NamedPipeInternal* const intern = (NamedPipeInternal*) internal; + MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal; + const ScopedLock sl (callbackLock); + mpe->active = true; +} - intern->stopReadOperation = true; +void MidiInput::stop() +{ + MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal; + const ScopedLock sl (callbackLock); + mpe->active = false; +} - char buffer [1] = { 0 }; - int bytesWritten = ::write (intern->pipeIn, buffer, 1); - (void) bytesWritten; +#undef log - int timeout = 2000; - while (intern->blocked && --timeout >= 0) - Thread::sleep (2); +#else - intern->stopReadOperation = false; - } +MidiOutput::~MidiOutput() +{ } -void NamedPipe::close() +void MidiOutput::reset() { - NamedPipeInternal* const intern = (NamedPipeInternal*) internal; +} - if (intern != 0) - { - internal = 0; +bool MidiOutput::getVolume (float& leftVol, float& rightVol) +{ + return false; +} - if (intern->pipeIn != -1) - ::close (intern->pipeIn); +void MidiOutput::setVolume (float leftVol, float rightVol) +{ +} - if (intern->pipeOut != -1) - ::close (intern->pipeOut); +void MidiOutput::sendMessageNow (const MidiMessage& message) +{ +} - if (intern->createdPipe) - { - unlink (intern->pipeInName); - unlink (intern->pipeOutName); - } +const StringArray MidiOutput::getDevices() +{ + return StringArray(); +} - delete intern; - } +MidiOutput* MidiOutput::openDevice (int index) +{ + return 0; } -bool NamedPipe::openInternal (const String& pipeName, const bool createPipe) +const StringArray MidiInput::getDevices() { - close(); + return StringArray(); +} - NamedPipeInternal* const intern = new NamedPipeInternal(); - internal = intern; - intern->createdPipe = createPipe; - intern->blocked = false; - intern->stopReadOperation = false; +MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) +{ + return 0; +} - signal (SIGPIPE, NamedPipeInternal::signalHandler); - siginterrupt (SIGPIPE, 1); +#endif - const String pipePath (T("/tmp/") + File::createLegalFileName (pipeName)); +#endif +/********* End of inlined file: juce_mac_CoreMidi.cpp *********/ - intern->pipeInName = pipePath + T("_in"); - intern->pipeOutName = pipePath + T("_out"); - intern->pipeIn = -1; - intern->pipeOut = -1; + #else - if (createPipe) - { - if ((mkfifo (intern->pipeInName, 0666) && errno != EEXIST) - || (mkfifo (intern->pipeOutName, 0666) && errno != EEXIST)) - { - delete intern; - internal = 0; +/********* Start of inlined file: juce_mac_NSViewComponentPeer.mm *********/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#ifdef JUCE_INCLUDED_FILE - return false; - } - } +class NSViewComponentPeer; - return true; -} +END_JUCE_NAMESPACE -int NamedPipe::read (void* destBuffer, int maxBytesToRead, int /*timeOutMilliseconds*/) +#define JuceNSView MakeObjCClassName(JuceNSView) + +@interface JuceNSView : NSView { - int bytesRead = -1; - NamedPipeInternal* const intern = (NamedPipeInternal*) internal; +@public + NSViewComponentPeer* owner; + NSNotificationCenter* notificationCenter; +} - if (intern != 0) - { - intern->blocked = true; +- (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner withFrame: (NSRect) frame; +- (void) dealloc; - if (intern->pipeIn == -1) - { - if (intern->createdPipe) - intern->pipeIn = ::open (intern->pipeInName, O_RDWR); - else - intern->pipeIn = ::open (intern->pipeOutName, O_RDWR); +- (BOOL) isOpaque; +- (void) drawRect: (NSRect) r; - if (intern->pipeIn == -1) - { - intern->blocked = false; - return -1; - } - } +- (void) mouseDown: (NSEvent*) ev; +- (void) asyncMouseDown: (NSEvent*) ev; +- (void) mouseUp: (NSEvent*) ev; +- (void) asyncMouseUp: (NSEvent*) ev; +- (void) mouseDragged: (NSEvent*) ev; +- (void) mouseMoved: (NSEvent*) ev; +- (void) mouseEntered: (NSEvent*) ev; +- (void) mouseExited: (NSEvent*) ev; +- (void) rightMouseDown: (NSEvent*) ev; +- (void) rightMouseDragged: (NSEvent*) ev; +- (void) rightMouseUp: (NSEvent*) ev; +- (void) otherMouseDown: (NSEvent*) ev; +- (void) otherMouseDragged: (NSEvent*) ev; +- (void) otherMouseUp: (NSEvent*) ev; +- (void) scrollWheel: (NSEvent*) ev; +- (BOOL) acceptsFirstMouse: (NSEvent*) ev; +- (void) frameChanged: (NSNotification*) n; - bytesRead = 0; +- (void) keyDown: (NSEvent*) ev; +- (void) keyUp: (NSEvent*) ev; +- (void) flagsChanged: (NSEvent*) ev; +#if MACOS_10_4_OR_EARLIER +- (BOOL) performKeyEquivalent: (NSEvent*) ev; +#endif - char* p = (char*) destBuffer; +- (BOOL) becomeFirstResponder; +- (BOOL) resignFirstResponder; +- (BOOL) acceptsFirstResponder; - while (bytesRead < maxBytesToRead) - { - const int bytesThisTime = maxBytesToRead - bytesRead; - const int numRead = ::read (intern->pipeIn, p, bytesThisTime); +- (NSArray*) getSupportedDragTypes; +- (BOOL) sendDragCallback: (int) type sender: (id ) sender; +- (NSDragOperation) draggingEntered: (id ) sender; +- (NSDragOperation) draggingUpdated: (id ) sender; +- (void) draggingEnded: (id ) sender; +- (void) draggingExited: (id ) sender; +- (BOOL) prepareForDragOperation: (id ) sender; +- (BOOL) performDragOperation: (id ) sender; +- (void) concludeDragOperation: (id ) sender; + +@end + +#define JuceNSWindow MakeObjCClassName(JuceNSWindow) + +#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +@interface JuceNSWindow : NSWindow +#else +@interface JuceNSWindow : NSWindow +#endif +{ +@private + NSViewComponentPeer* owner; + bool isZooming; +} + +- (void) setOwner: (NSViewComponentPeer*) owner; +- (BOOL) canBecomeKeyWindow; +- (void) becomeKeyWindow; +- (BOOL) windowShouldClose: (id) window; +- (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; +- (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; +- (void) zoom: (id) sender; +@end - if (numRead <= 0 || intern->stopReadOperation) - { - bytesRead = -1; - break; - } +BEGIN_JUCE_NAMESPACE - bytesRead += numRead; - p += bytesRead; - } +class NSViewComponentPeer : public ComponentPeer +{ +public: + NSViewComponentPeer (Component* const component, + const int windowStyleFlags, + NSView* viewToAttachTo); - intern->blocked = false; - } + ~NSViewComponentPeer(); - return bytesRead; -} + void* getNativeHandle() const; + void setVisible (bool shouldBeVisible); + void setTitle (const String& title); + void setPosition (int x, int y); + void setSize (int w, int h); + void setBounds (int x, int y, int w, int h, const bool isNowFullScreen); + void getBounds (int& x, int& y, int& w, int& h, const bool global) const; + void getBounds (int& x, int& y, int& w, int& h) const; + int getScreenX() const; + int getScreenY() const; + void relativePositionToGlobal (int& x, int& y); + void globalPositionToRelative (int& x, int& y); + void setMinimised (bool shouldBeMinimised); + bool isMinimised() const; + void setFullScreen (bool shouldBeFullScreen); + bool isFullScreen() const; + bool contains (int x, int y, bool trueIfInAChildWindow) const; + const BorderSize getFrameSize() const; + bool setAlwaysOnTop (bool alwaysOnTop); + void toFront (bool makeActiveWindow); + void toBehind (ComponentPeer* other); + void setIcon (const Image& newIcon); -int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds) -{ - int bytesWritten = -1; - NamedPipeInternal* const intern = (NamedPipeInternal*) internal; + /* 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. - if (intern != 0) - { - if (intern->pipeOut == -1) - { - if (intern->createdPipe) - intern->pipeOut = ::open (intern->pipeOutName, O_WRONLY); - else - intern->pipeOut = ::open (intern->pipeInName, O_WRONLY); + 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. + */ + virtual void redirectMouseDown (NSEvent* ev); + virtual void redirectMouseUp (NSEvent* ev); + virtual void redirectMouseDrag (NSEvent* ev); + virtual void redirectMouseMove (NSEvent* ev); + virtual void redirectMouseEnter (NSEvent* ev); + virtual void redirectMouseExit (NSEvent* ev); + virtual void redirectMouseWheel (NSEvent* ev); - if (intern->pipeOut == -1) - { - return -1; - } - } + bool handleKeyEvent (NSEvent* ev, bool isKeyDown); + virtual bool redirectKeyDown (NSEvent* ev); + virtual bool redirectKeyUp (NSEvent* ev); + virtual void redirectModKeyChange (NSEvent* ev); +#if MACOS_10_4_OR_EARLIER + virtual bool redirectPerformKeyEquivalent (NSEvent* ev); +#endif - const char* p = (const char*) sourceBuffer; - bytesWritten = 0; + virtual BOOL sendDragCallback (int type, id sender); - const uint32 timeOutTime = Time::getMillisecondCounter() + timeOutMilliseconds; + virtual bool isOpaque(); + virtual void drawRect (NSRect r); - while (bytesWritten < numBytesToWrite - && (timeOutMilliseconds < 0 || Time::getMillisecondCounter() < timeOutTime)) - { - const int bytesThisTime = numBytesToWrite - bytesWritten; - const int numWritten = ::write (intern->pipeOut, p, bytesThisTime); + virtual bool canBecomeKeyWindow(); + virtual bool windowShouldClose(); - if (numWritten <= 0) - { - bytesWritten = -1; - break; - } + virtual void redirectMovedOrResized(); + virtual NSRect constrainRect (NSRect r); - bytesWritten += numWritten; - p += bytesWritten; - } - } + static void showArrowCursorIfNeeded(); - return bytesWritten; -} + virtual void viewFocusGain(); + virtual void viewFocusLoss(); + bool isFocused() const; + void grabFocus(); + void textInputRequired (int x, int y); -#endif -/********* End of inlined file: juce_posix_NamedPipe.cpp *********/ + void repaint (int x, int y, int w, int h); + void performAnyPendingRepaintsNow(); -/********* Start of inlined file: juce_mac_Threads.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE + juce_UseDebuggingNewOperator -/* - Note that a lot of methods that you'd expect to find in this file actually - live in juce_posix_SharedCode.h! -*/ + NSWindow* window; + JuceNSView* view; + bool isSharedWindow, fullScreen; +}; -void JUCE_API juce_threadEntryPoint (void*); +END_JUCE_NAMESPACE -void* threadEntryProc (void* userData) throw() -{ - const ScopedAutoReleasePool pool; - juce_threadEntryPoint (userData); - return 0; -} +@implementation JuceNSView -void* juce_createThread (void* userData) throw() +- (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner_ + withFrame: (NSRect) frame { - pthread_t handle = 0; + [super initWithFrame: frame]; + owner = owner_; - if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) + notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter addObserver: self + selector: @selector (frameChanged:) + name: NSViewFrameDidChangeNotification + object: self]; + + if (! owner_->isSharedWindow) { - pthread_detach (handle); - return (void*) handle; + [notificationCenter addObserver: self + selector: @selector (frameChanged:) + name: NSWindowDidMoveNotification + object: owner_->window]; } - return 0; -} + [self registerForDraggedTypes: [self getSupportedDragTypes]]; -void juce_killThread (void* handle) throw() -{ - if (handle != 0) - pthread_cancel ((pthread_t) handle); + return self; } -void juce_setCurrentThreadName (const String& /*name*/) throw() +- (void) dealloc { + [notificationCenter removeObserver: self]; + [super dealloc]; } -Thread::ThreadID Thread::getCurrentThreadId() throw() +- (void) drawRect: (NSRect) r { - return (ThreadID) pthread_self(); + if (owner != 0) + owner->drawRect (r); } -bool juce_setThreadPriority (void* handle, int priority) throw() +- (BOOL) isOpaque { - if (handle == 0) - handle = (void*) pthread_self(); - - struct sched_param param; - int policy; - pthread_getschedparam ((pthread_t) handle, &policy, ¶m); - param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11); - return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; + return owner == 0 || owner->isOpaque(); } -void Thread::yield() throw() +- (void) mouseDown: (NSEvent*) ev { - sched_yield(); + // In some host situations, the host will stop modal loops from working + // correctly if they're called from a mouse event, so we'll trigger + // the event asynchronously.. + if (JUCEApplication::getInstance() == 0) + [self performSelectorOnMainThread: @selector (asyncMouseDown:) + withObject: ev + waitUntilDone: NO]; + else + [self asyncMouseDown: ev]; } -void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw() +- (void) asyncMouseDown: (NSEvent*) ev { - // xxx - jassertfalse + if (owner != 0) + owner->redirectMouseDown (ev); } -bool Process::isForegroundProcess() throw() +- (void) mouseUp: (NSEvent*) ev { -#if JUCE_MAC - return [NSApp isActive]; -#else - return true; // xxx change this if more than one app is ever possible on the iPhone! -#endif + // In some host situations, the host will stop modal loops from working + // correctly if they're called from a mouse event, so we'll trigger + // the event asynchronously.. + if (JUCEApplication::getInstance() == 0) + [self performSelectorOnMainThread: @selector (asyncMouseUp:) + withObject: ev + waitUntilDone: NO]; + else + [self asyncMouseUp: ev]; } -void Process::raisePrivilege() +- (void) asyncMouseUp: (NSEvent*) ev { - jassertfalse + if (owner != 0) + owner->redirectMouseUp (ev); } -void Process::lowerPrivilege() +- (void) mouseDragged: (NSEvent*) ev { - jassertfalse + if (owner != 0) + owner->redirectMouseDrag (ev); } -void Process::terminate() +- (void) mouseMoved: (NSEvent*) ev { - exit (0); + if (owner != 0) + owner->redirectMouseMove (ev); } -void Process::setPriority (ProcessPriority p) +- (void) mouseEntered: (NSEvent*) ev { - // xxx + if (owner != 0) + owner->redirectMouseEnter (ev); } -#endif -/********* End of inlined file: juce_mac_Threads.mm *********/ - -/********* Start of inlined file: juce_posix_SharedCode.h *********/ -/* - This file contains posix routines that are common to both the Linux and Mac builds. - - It gets included directly in the cpp files for these platforms. -*/ - -CriticalSection::CriticalSection() throw() +- (void) mouseExited: (NSEvent*) ev { - pthread_mutexattr_t atts; - pthread_mutexattr_init (&atts); - pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init (&internal, &atts); + if (owner != 0) + owner->redirectMouseExit (ev); } -CriticalSection::~CriticalSection() throw() +- (void) rightMouseDown: (NSEvent*) ev { - pthread_mutex_destroy (&internal); + [self mouseDown: ev]; } -void CriticalSection::enter() const throw() +- (void) rightMouseDragged: (NSEvent*) ev { - pthread_mutex_lock (&internal); + [self mouseDragged: ev]; } -bool CriticalSection::tryEnter() const throw() +- (void) rightMouseUp: (NSEvent*) ev { - return pthread_mutex_trylock (&internal) == 0; + [self mouseUp: ev]; } -void CriticalSection::exit() const throw() +- (void) otherMouseDown: (NSEvent*) ev { - pthread_mutex_unlock (&internal); + [self mouseDown: ev]; } -struct EventStruct +- (void) otherMouseDragged: (NSEvent*) ev { - pthread_cond_t condition; - pthread_mutex_t mutex; - bool triggered; -}; + [self mouseDragged: ev]; +} -WaitableEvent::WaitableEvent() throw() +- (void) otherMouseUp: (NSEvent*) ev { - EventStruct* const es = new EventStruct(); - es->triggered = false; - - pthread_cond_init (&es->condition, 0); - pthread_mutex_init (&es->mutex, 0); - - internal = es; + [self mouseUp: ev]; } -WaitableEvent::~WaitableEvent() throw() +- (void) scrollWheel: (NSEvent*) ev { - EventStruct* const es = (EventStruct*) internal; - - pthread_cond_destroy (&es->condition); - pthread_mutex_destroy (&es->mutex); - - delete es; + if (owner != 0) + owner->redirectMouseWheel (ev); } -bool WaitableEvent::wait (const int timeOutMillisecs) const throw() +- (BOOL) acceptsFirstMouse: (NSEvent*) ev { - EventStruct* const es = (EventStruct*) internal; - - bool ok = true; - pthread_mutex_lock (&es->mutex); - - if (timeOutMillisecs < 0) - { - while (! es->triggered) - pthread_cond_wait (&es->condition, &es->mutex); - } - else - { - while (! es->triggered) - { - struct timeval t; - gettimeofday (&t, 0); - - struct timespec time; - time.tv_sec = t.tv_sec + (timeOutMillisecs / 1000); - time.tv_nsec = (t.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000; - - if (time.tv_nsec >= 1000000000) - { - time.tv_nsec -= 1000000000; - time.tv_sec++; - } - - if (pthread_cond_timedwait (&es->condition, &es->mutex, &time) == ETIMEDOUT) - { - ok = false; - break; - } - } - } - - es->triggered = false; - - pthread_mutex_unlock (&es->mutex); - return ok; + return YES; } -void WaitableEvent::signal() const throw() +- (void) frameChanged: (NSNotification*) n { - EventStruct* const es = (EventStruct*) internal; - - pthread_mutex_lock (&es->mutex); - es->triggered = true; - pthread_cond_broadcast (&es->condition); - pthread_mutex_unlock (&es->mutex); + if (owner != 0) + owner->redirectMovedOrResized(); } -void WaitableEvent::reset() const throw() +- (void) keyDown: (NSEvent*) ev { - EventStruct* const es = (EventStruct*) internal; - - pthread_mutex_lock (&es->mutex); - es->triggered = false; - pthread_mutex_unlock (&es->mutex); + if (owner == 0 || ! owner->redirectKeyDown (ev)) + [super keyDown: ev]; } -void JUCE_CALLTYPE Thread::sleep (int millisecs) throw() +- (void) keyUp: (NSEvent*) ev { - struct timespec time; - time.tv_sec = millisecs / 1000; - time.tv_nsec = (millisecs % 1000) * 1000000; - nanosleep (&time, 0); + if (owner == 0 || ! owner->redirectKeyUp (ev)) + [super keyUp: ev]; } -const tchar File::separator = T('/'); -const tchar* File::separatorString = T("/"); - -bool juce_copyFile (const String& s, const String& d) throw(); - -static bool juce_stat (const String& fileName, struct stat& info) throw() +- (void) flagsChanged: (NSEvent*) ev { - return fileName.isNotEmpty() - && (stat (fileName.toUTF8(), &info) == 0); + if (owner != 0) + owner->redirectModKeyChange (ev); } -bool juce_isDirectory (const String& fileName) throw() +#if MACOS_10_4_OR_EARLIER +- (BOOL) performKeyEquivalent: (NSEvent*) ev { - struct stat info; + if (owner != 0 && owner->redirectPerformKeyEquivalent (ev)) + return true; - return fileName.isEmpty() - || (juce_stat (fileName, info) - && ((info.st_mode & S_IFDIR) != 0)); + return [super performKeyEquivalent: ev]; } +#endif -bool juce_fileExists (const String& fileName, const bool dontCountDirectories) throw() +- (BOOL) becomeFirstResponder { - if (fileName.isEmpty()) - return false; + if (owner != 0) + owner->viewFocusGain(); - const char* const fileNameUTF8 = fileName.toUTF8(); - bool exists = access (fileNameUTF8, F_OK) == 0; + return true; +} - if (exists && dontCountDirectories) - { - struct stat info; - const int res = stat (fileNameUTF8, &info); +- (BOOL) resignFirstResponder +{ + if (owner != 0) + owner->viewFocusLoss(); - if (res == 0 && (info.st_mode & S_IFDIR) != 0) - exists = false; - } + return true; +} - return exists; +- (BOOL) acceptsFirstResponder +{ + return owner != 0 && owner->canBecomeKeyWindow(); } -int64 juce_getFileSize (const String& fileName) throw() +- (NSArray*) getSupportedDragTypes { - struct stat info; - return juce_stat (fileName, info) ? info.st_size : 0; + return [NSArray arrayWithObjects: NSFilenamesPboardType, /*NSFilesPromisePboardType, NSStringPboardType,*/ nil]; } -bool juce_canWriteToFile (const String& fileName) throw() +- (BOOL) sendDragCallback: (int) type sender: (id ) sender { - return access (fileName.toUTF8(), W_OK) == 0; + return owner != 0 && owner->sendDragCallback (type, sender); } -bool juce_deleteFile (const String& fileName) throw() +- (NSDragOperation) draggingEntered: (id ) sender { - if (juce_isDirectory (fileName)) - return rmdir ((const char*) fileName.toUTF8()) == 0; + if ([self sendDragCallback: 0 sender: sender]) + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric; else - return remove ((const char*) fileName.toUTF8()) == 0; + return NSDragOperationNone; } -bool juce_moveFile (const String& source, const String& dest) throw() +- (NSDragOperation) draggingUpdated: (id ) sender { - if (rename (source.toUTF8(), dest.toUTF8()) == 0) - return true; - - if (juce_canWriteToFile (source) - && juce_copyFile (source, dest)) - { - if (juce_deleteFile (source)) - return true; - - juce_deleteFile (dest); - } - - return false; + if ([self sendDragCallback: 0 sender: sender]) + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric; + else + return NSDragOperationNone; } -void juce_createDirectory (const String& fileName) throw() +- (void) draggingEnded: (id ) sender { - mkdir (fileName.toUTF8(), 0777); + [self sendDragCallback: 1 sender: sender]; } -void* juce_fileOpen (const String& fileName, bool forWriting) throw() +- (void) draggingExited: (id ) sender { - int flags = O_RDONLY; - - if (forWriting) - { - if (juce_fileExists (fileName, false)) - { - const int f = open ((const char*) fileName.toUTF8(), O_RDWR, 00644); - - if (f != -1) - lseek (f, 0, SEEK_END); - - return (void*) f; - } - else - { - flags = O_RDWR + O_CREAT; - } - } - - return (void*) open ((const char*) fileName.toUTF8(), flags, 00644); + [self sendDragCallback: 1 sender: sender]; } -void juce_fileClose (void* handle) throw() +- (BOOL) prepareForDragOperation: (id ) sender { - if (handle != 0) - close ((int) (pointer_sized_int) handle); + return YES; } -int juce_fileRead (void* handle, void* buffer, int size) throw() +- (BOOL) performDragOperation: (id ) sender { - if (handle != 0) - return read ((int) (pointer_sized_int) handle, buffer, size); - - return 0; + return [self sendDragCallback: 2 sender: sender]; } -int juce_fileWrite (void* handle, const void* buffer, int size) throw() +- (void) concludeDragOperation: (id ) sender { - if (handle != 0) - return write ((int) (pointer_sized_int) handle, buffer, size); - - return 0; } -int64 juce_fileSetPosition (void* handle, int64 pos) throw() +@end + +@implementation JuceNSWindow + +- (void) setOwner: (NSViewComponentPeer*) owner_ { - if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos) - return pos; + owner = owner_; + isZooming = false; +} - return -1; +- (BOOL) canBecomeKeyWindow +{ + return owner != 0 && owner->canBecomeKeyWindow(); } -int64 juce_fileGetPosition (void* handle) throw() +- (void) becomeKeyWindow { - if (handle != 0) - return lseek ((int) (pointer_sized_int) handle, 0, SEEK_CUR); - else - return -1; + [super becomeKeyWindow]; + + if (owner != 0) + owner->grabFocus(); } -void juce_fileFlush (void* handle) throw() +- (BOOL) windowShouldClose: (id) window { - if (handle != 0) - fsync ((int) (pointer_sized_int) handle); + return owner == 0 || owner->windowShouldClose(); } -const File juce_getExecutableFile() +- (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen { - Dl_info exeInfo; - dladdr ((const void*) juce_getExecutableFile, &exeInfo); - return File (exeInfo.dli_fname); + if (owner != 0) + frameRect = owner->constrainRect (frameRect); + + return frameRect; } -// if this file doesn't exist, find a parent of it that does.. -static bool doStatFS (const File* file, struct statfs& result) throw() +- (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize { - File f (*file); + if (isZooming) + return proposedFrameSize; - for (int i = 5; --i >= 0;) - { - if (f.exists()) - break; + NSRect frameRect = [self frame]; + frameRect.origin.y -= proposedFrameSize.height - frameRect.size.height; + frameRect.size = proposedFrameSize; - f = f.getParentDirectory(); - } + if (owner != 0) + frameRect = owner->constrainRect (frameRect); - return statfs (f.getFullPathName().toUTF8(), &result) == 0; + return frameRect.size; } -int64 File::getBytesFreeOnVolume() const throw() +- (void) zoom: (id) sender { - struct statfs buf; - if (doStatFS (this, buf)) - return (int64) buf.f_bsize * (int64) buf.f_bavail; // Note: this returns space available to non-super user - - return 0; + isZooming = true; + [super zoom: sender]; + isZooming = false; } -int64 File::getVolumeTotalSize() const throw() +- (void) windowWillMove: (NSNotification*) notification { - struct statfs buf; - if (doStatFS (this, buf)) - return (int64) buf.f_bsize * (int64) buf.f_blocks; - - return 0; + if (juce::Component::getCurrentlyModalComponent() != 0 + && owner->getComponent()->isCurrentlyBlockedByAnotherModalComponent() + && (owner->getStyleFlags() & juce::ComponentPeer::windowHasTitleBar) != 0) + juce::Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); } -const String juce_getVolumeLabel (const String& filenameOnVolume, - int& volumeSerialNumber) throw() -{ - volumeSerialNumber = 0; +@end -#if JUCE_MAC - struct VolAttrBuf +BEGIN_JUCE_NAMESPACE + +class JuceNSImage +{ +public: + JuceNSImage (const int width, const int height, const bool hasAlpha) + : juceImage (hasAlpha ? Image::ARGB : Image::RGB, + width, height, hasAlpha) { - u_int32_t length; - attrreference_t mountPointRef; - char mountPointSpace [MAXPATHLEN]; - } attrBuf; + lineStride = 0; + pixelStride = 0; + imageData = juceImage.lockPixelDataReadWrite (0, 0, width, height, + lineStride, pixelStride); - struct attrlist attrList; - zerostruct (attrList); - attrList.bitmapcount = ATTR_BIT_MAP_COUNT; - attrList.volattr = ATTR_VOL_INFO | ATTR_VOL_NAME; + imageRep = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes: &imageData + pixelsWide: width + pixelsHigh: height + bitsPerSample: 8 + samplesPerPixel: pixelStride + hasAlpha: hasAlpha + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bitmapFormat: /*NSAlphaFirstBitmapFormat*/ (NSBitmapFormat) 0 + bytesPerRow: lineStride + bitsPerPixel: 8 * pixelStride ]; - File f (filenameOnVolume); + juceImage.releasePixelDataReadWrite (imageData); + } - for (;;) + ~JuceNSImage() { - if (getattrlist ((const char*) f.getFullPathName().toUTF8(), - &attrList, &attrBuf, sizeof(attrBuf), 0) == 0) - { - return String::fromUTF8 (((const uint8*) &attrBuf.mountPointRef) + attrBuf.mountPointRef.attr_dataoffset, - (int) attrBuf.mountPointRef.attr_length); - } + [imageRep release]; + } - const File parent (f.getParentDirectory()); + Image& getJuceImage() throw() { return juceImage; } - if (f == parent) - break; + void draw (const float x, const float y, + const RectangleList& clip, + const int originX, const int originY) const + { + // Our data is BGRA and the damned image rep only takes RGBA, so + // we need to byte-swap the active areas if there's an alpha channel... + if (juceImage.hasAlphaChannel()) + { + RectangleList::Iterator iter (clip); + while (iter.next()) + { + const Rectangle* const r = iter.getRectangle(); - f = parent; + swapRGBOrder (r->getX() + originX, + r->getY() + originY, + r->getWidth(), + r->getHeight()); + } + } + + NSPoint p; + p.x = x; + p.y = y; + [imageRep drawAtPoint: p]; } -#endif - return String::empty; -} + void drawNSImage (NSImage* imageToDraw) + { + const ScopedAutoReleasePool pool; -void juce_runSystemCommand (const String& command) -{ - int result = system ((const char*) command.toUTF8()); - (void) result; -} + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext: + [NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]]; -const String juce_getOutputFromCommand (const String& command) -{ - // slight bodge here, as we just pipe the output into a temp file and read it... - const File tempFile (File::getSpecialLocation (File::tempDirectory) - .getNonexistentChildFile (String::toHexString (Random::getSystemRandom().nextInt()), ".tmp", false)); + [imageToDraw drawAtPoint: NSZeroPoint + fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height) + operation: NSCompositeSourceOver + fraction: 1.0f]; - juce_runSystemCommand (command + " > " + tempFile.getFullPathName()); + [[NSGraphicsContext currentContext] flushGraphics]; + [NSGraphicsContext restoreGraphicsState]; - String result (tempFile.loadFileAsString()); - tempFile.deleteFile(); - return result; -} + if (juceImage.hasAlphaChannel()) + swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight()); + } -#if JUCE_64BIT - #define filedesc ((long long) internal) -#else - #define filedesc ((int) internal) -#endif +private: + Image juceImage; + NSBitmapImageRep* imageRep; + uint8* imageData; + int pixelStride, lineStride; -InterProcessLock::InterProcessLock (const String& name_) throw() - : internal (0), - name (name_), - reentrancyLevel (0) -{ -#if JUCE_MAC - // (don't use getSpecialLocation() to avoid the temp folder being different for each app) - const File temp (File (T("~/Library/Caches/Juce")).getChildFile (name)); -#else - const File temp (File::getSpecialLocation (File::tempDirectory).getChildFile (name)); + void swapRGBOrder (const int x, const int y, const int w, int h) const + { +#if JUCE_BIG_ENDIAN + jassert (pixelStride == 4); #endif + jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight()) + .contains (Rectangle (x, y, w, h))); - temp.create(); + uint8* start = imageData + x * pixelStride + y * lineStride; - internal = (void*) open (temp.getFullPathName().toUTF8(), O_RDWR); -} + while (--h >= 0) + { + uint8* p = start; + start += lineStride; -InterProcessLock::~InterProcessLock() throw() -{ - while (reentrancyLevel > 0) - this->exit(); + for (int i = w; --i >= 0;) + { +#if JUCE_BIG_ENDIAN + const uint8 oldp3 = p[3]; + const uint8 oldp1 = p[1]; + p[3] = p[0]; + p[0] = oldp1; + p[1] = p[2]; + p[2] = oldp3; +#else + const uint8 oldp0 = p[0]; + p[0] = p[2]; + p[2] = oldp0; +#endif - close (filedesc); -} + p += pixelStride; + } + } + } +}; -bool InterProcessLock::enter (const int timeOutMillisecs) throw() -{ - if (internal == 0) - return false; +static ComponentPeer* currentlyFocusedPeer = 0; +static VoidArray keysCurrentlyDown; - if (reentrancyLevel != 0) +bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() +{ + if (keysCurrentlyDown.contains ((void*) keyCode)) return true; - const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs; - - struct flock fl; - zerostruct (fl); - fl.l_whence = SEEK_SET; - fl.l_type = F_WRLCK; + if (keyCode >= 'A' && keyCode <= 'Z' + && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode))) + return true; - for (;;) - { - const int result = fcntl (filedesc, F_SETLK, &fl); + if (keyCode >= 'a' && keyCode <= 'z' + && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toUpperCase ((tchar) keyCode))) + return true; - if (result >= 0) - { - ++reentrancyLevel; - return true; - } + return false; +} - if (errno != EINTR) - { - if (timeOutMillisecs == 0 - || (timeOutMillisecs > 0 && Time::currentTimeMillis() >= endTime)) - break; +static int getKeyCodeFromEvent (NSEvent* ev) +{ + const String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); + int keyCode = unmodified[0]; - Thread::sleep (10); - } - } + if (keyCode == 0x19) // (backwards-tab) + keyCode = '\t'; + else if (keyCode == 0x03) // (enter) + keyCode = '\r'; - return false; + return keyCode; } -void InterProcessLock::exit() throw() +static int currentModifiers = 0; + +static void updateModifiers (NSEvent* e) { - if (reentrancyLevel > 0 && internal != 0) - { - --reentrancyLevel; + int m = currentModifiers & ~(ModifierKeys::shiftModifier | ModifierKeys::ctrlModifier + | ModifierKeys::altModifier | ModifierKeys::commandModifier); - struct flock fl; - zerostruct (fl); - fl.l_whence = SEEK_SET; - fl.l_type = F_UNLCK; + if (([e modifierFlags] & NSShiftKeyMask) != 0) + m |= ModifierKeys::shiftModifier; - for (;;) - { - const int result = fcntl (filedesc, F_SETLKW, &fl); + if (([e modifierFlags] & NSControlKeyMask) != 0) + m |= ModifierKeys::ctrlModifier; - if (result >= 0 || errno != EINTR) - break; - } - } -} -/********* End of inlined file: juce_posix_SharedCode.h *********/ + if (([e modifierFlags] & NSAlternateKeyMask) != 0) + m |= ModifierKeys::altModifier; -/********* Start of inlined file: juce_mac_Files.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE + if (([e modifierFlags] & NSCommandKeyMask) != 0) + m |= ModifierKeys::commandModifier; -/* - Note that a lot of methods that you'd expect to find in this file actually - live in juce_posix_SharedCode.h! -*/ + currentModifiers = m; +} -void juce_getFileTimes (const String& fileName, - int64& modificationTime, - int64& accessTime, - int64& creationTime) throw() +static void updateKeysDown (NSEvent* ev, bool isKeyDown) { - modificationTime = 0; - accessTime = 0; - creationTime = 0; + updateModifiers (ev); + int keyCode = getKeyCodeFromEvent (ev); - struct stat info; - const int res = stat (fileName.toUTF8(), &info); - if (res == 0) + if (keyCode != 0) { - modificationTime = (int64) info.st_mtime * 1000; - accessTime = (int64) info.st_atime * 1000; - creationTime = (int64) info.st_ctime * 1000; + if (isKeyDown) + keysCurrentlyDown.addIfNotAlreadyThere ((void*) keyCode); + else + keysCurrentlyDown.removeValue ((void*) keyCode); } } -bool juce_setFileTimes (const String& fileName, - int64 modificationTime, - int64 accessTime, - int64 creationTime) throw() +const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() { - struct utimbuf times; - times.actime = (time_t) (accessTime / 1000); - times.modtime = (time_t) (modificationTime / 1000); - - return utime (fileName.toUTF8(), ×) == 0; + return ModifierKeys (currentModifiers); } -bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw() +void ModifierKeys::updateCurrentModifiers() throw() { - struct stat info; - const int res = stat (fileName.toUTF8(), &info); - if (res != 0) - return false; - - info.st_mode &= 0777; // Just permissions - - if (isReadOnly) - info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - else - // Give everybody write permission? - info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; - - return chmod (fileName.toUTF8(), info.st_mode) == 0; + currentModifierFlags = currentModifiers; } -bool juce_copyFile (const String& src, const String& dst) throw() -{ - const ScopedAutoReleasePool pool; - NSFileManager* fm = [NSFileManager defaultManager]; +static int64 getMouseTime (NSEvent* e) { return (int64) [e timestamp] * 1000.0; } - return [fm fileExistsAtPath: juceStringToNS (src)] -#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - && [fm copyItemAtPath: juceStringToNS (src) - toPath: juceStringToNS (dst) - error: nil]; -#else - && [fm copyPath: juceStringToNS (src) - toPath: juceStringToNS (dst) - handler: nil]; -#endif +static void getMousePos (NSEvent* e, NSView* view, int& x, int& y) +{ + NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil]; + x = roundFloatToInt (p.x); + y = roundFloatToInt ([view frame].size.height - p.y); } -const StringArray juce_getFileSystemRoots() throw() +static int getModifierForButtonNumber (const int num) throw() { - StringArray s; - s.add (T("/")); - return s; + return num == 0 ? ModifierKeys::leftButtonModifier + : (num == 1 ? ModifierKeys::rightButtonModifier + : (num == 2 ? ModifierKeys::middleButtonModifier : 0)); } -static bool isFileOnDriveType (const File* const f, const char** types) throw() +NSViewComponentPeer::NSViewComponentPeer (Component* const component, + const int windowStyleFlags, + NSView* viewToAttachTo) + : ComponentPeer (component, windowStyleFlags), + window (0), + view (0), + isSharedWindow (viewToAttachTo != 0), + fullScreen (false) { - struct statfs buf; + NSRect r; + r.origin.x = 0; + r.origin.y = 0; + r.size.width = (float) component->getWidth(); + r.size.height = (float) component->getHeight(); - if (doStatFS (f, buf)) + view = [[JuceNSView alloc] initWithOwner: this withFrame: r]; + [view setPostsFrameChangedNotifications: YES]; + + if (isSharedWindow) { - const String type (buf.f_fstypename); + window = [viewToAttachTo window]; + [viewToAttachTo addSubview: view]; - while (*types != 0) - if (type.equalsIgnoreCase (*types++)) - return true; + setVisible (component->isVisible()); } + else + { + r.origin.x = (float) component->getX(); + r.origin.y = (float) component->getY(); + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); - return false; + unsigned int style = 0; + if ((windowStyleFlags & windowHasTitleBar) == 0) + style = NSBorderlessWindowMask; + else + style = NSTitledWindowMask; + + if ((windowStyleFlags & windowHasMinimiseButton) != 0) + style |= NSMiniaturizableWindowMask; + + if ((windowStyleFlags & windowHasCloseButton) != 0) + style |= NSClosableWindowMask; + + if ((windowStyleFlags & windowIsResizable) != 0) + style |= NSResizableWindowMask; + + window = [[JuceNSWindow alloc] initWithContentRect: r + styleMask: style + backing: NSBackingStoreBuffered + defer: YES]; + + [((JuceNSWindow*) window) setOwner: this]; + [window orderOut: nil]; + [window setDelegate: (JuceNSWindow*) window]; + [window setOpaque: component->isOpaque()]; + [window setHasShadow: ((windowStyleFlags & windowHasDropShadow) != 0)]; + + if (component->isAlwaysOnTop()) + [window setLevel: NSFloatingWindowLevel]; + + [window setContentView: view]; + [window setAutodisplay: YES]; + [window setAcceptsMouseMovedEvents: YES]; + + // We'll both retain and also release this on closing because plugin hosts can unexpectedly + // close the window for us, and also tend to get cause trouble if setReleasedWhenClosed is NO. + [window setReleasedWhenClosed: YES]; + [window retain]; + + [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0]; + [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0]; + } + + setTitle (component->getName()); } -bool File::isOnCDRomDrive() const throw() +NSViewComponentPeer::~NSViewComponentPeer() { - static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 }; + view->owner = 0; + [view removeFromSuperview]; + [view release]; - return isFileOnDriveType (this, (const char**) cdTypes); + if (! isSharedWindow) + { + [((JuceNSWindow*) window) setOwner: 0]; + [window close]; + [window release]; + } } -bool File::isOnHardDisk() const throw() +void* NSViewComponentPeer::getNativeHandle() const { - static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 }; + return view; +} - return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes)); +void NSViewComponentPeer::setVisible (bool shouldBeVisible) +{ + if (isSharedWindow) + { + [view setHidden: ! shouldBeVisible]; + } + else + { + if (shouldBeVisible) + [window orderFront: nil]; + else + [window orderOut: nil]; + } } -bool File::isOnRemovableDrive() const throw() +void NSViewComponentPeer::setTitle (const String& title) { -#if JUCE_IPHONE - return false; // xxx is this possible? -#else const ScopedAutoReleasePool pool; - BOOL removable = false; - - [[NSWorkspace sharedWorkspace] - getFileSystemInfoForPath: juceStringToNS (getFullPathName()) - isRemovable: &removable - isWritable: nil - isUnmountable: nil - description: nil - type: nil]; - return removable; -#endif + if (! isSharedWindow) + [window setTitle: juceStringToNS (title)]; } -static bool juce_isHiddenFile (const String& path) throw() +void NSViewComponentPeer::setPosition (int x, int y) { -#if JUCE_IPHONE - return File (path).getFileName().startsWithChar (T('.')); -#else - FSRef ref; - if (! PlatformUtilities::makeFSRefFromPath (&ref, path)) - return false; - - FSCatalogInfo info; - FSGetCatalogInfo (&ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &info, 0, 0, 0); - - if ((info.nodeFlags & kFSNodeIsDirectoryBit) != 0) - return (((FolderInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; - - return (((FileInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0; -#endif + setBounds (x, y, component->getWidth(), component->getHeight(), false); } -bool File::isHidden() const throw() +void NSViewComponentPeer::setSize (int w, int h) { - return juce_isHiddenFile (getFullPathName()); + setBounds (component->getX(), component->getY(), w, h, false); } -const File File::getSpecialLocation (const SpecialLocationType type) +void NSViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNowFullScreen) { - const ScopedAutoReleasePool pool; + fullScreen = isNowFullScreen; + w = jmax (0, w); + h = jmax (0, h); - String resultPath; + NSRect r; + r.origin.x = (float) x; + r.origin.y = (float) y; + r.size.width = (float) w; + r.size.height = (float) h; - switch (type) + if (isSharedWindow) { - case userHomeDirectory: - resultPath = nsStringToJuce (NSHomeDirectory()); - break; - - case userDocumentsDirectory: - resultPath = "~/Documents"; - break; - - case userDesktopDirectory: - resultPath = "~/Desktop"; - break; - - case userApplicationDataDirectory: - resultPath = "~/Library"; - break; - - case commonApplicationDataDirectory: - resultPath = "/Library"; - break; - - case globalApplicationsDirectory: - resultPath = "/Applications"; - break; - - case userMusicDirectory: - resultPath = "~/Music"; - break; + r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); - case userMoviesDirectory: - resultPath = "~/Movies"; - break; + if ([view frame].size.width != r.size.width + || [view frame].size.height != r.size.height) + [view setNeedsDisplay: true]; - case tempDirectory: + [view setFrame: r]; + } + else { - File tmp (T("~/Library/Caches/") + juce_getExecutableFile().getFileNameWithoutExtension()); + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); - tmp.createDirectory(); - return tmp.getFullPathName(); + [window setFrame: [window frameRectForContentRect: r] + display: true]; } +} - case currentExecutableFile: - return juce_getExecutableFile(); +void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool global) const +{ + NSRect r = [view frame]; - case currentApplicationFile: + if (global && [view window] != 0) { - const File exe (juce_getExecutableFile()); - const File parent (exe.getParentDirectory()); + r = [view convertRect: r toView: nil]; + NSRect wr = [[view window] frame]; + r.origin.x += wr.origin.x; + r.origin.y += wr.origin.y; - return parent.getFullPathName().endsWithIgnoreCase (T("Contents/MacOS")) - ? parent.getParentDirectory().getParentDirectory() - : exe; + y = (int) ([[[NSScreen screens] objectAtIndex:0] frame].size.height - r.origin.y - r.size.height); } - - default: - jassertfalse // unknown type? - break; + else + { + y = (int) ([[view superview] frame].size.height - r.origin.y - r.size.height); } - if (resultPath != 0) - return File (PlatformUtilities::convertToPrecomposedUnicode (resultPath)); - - return File::nonexistent; + x = (int) r.origin.x; + w = (int) r.size.width; + h = (int) r.size.height; } -const File File::getCurrentWorkingDirectory() throw() +void NSViewComponentPeer::getBounds (int& x, int& y, int& w, int& h) const { - char buf [2048]; - getcwd (buf, sizeof(buf)); + getBounds (x, y, w, h, ! isSharedWindow); +} - return File (PlatformUtilities::convertToPrecomposedUnicode (buf)); +int NSViewComponentPeer::getScreenX() const +{ + int x, y, w, h; + getBounds (x, y, w, h, true); + return x; } -bool File::setAsCurrentWorkingDirectory() const throw() +int NSViewComponentPeer::getScreenY() const { - return chdir (getFullPathName().toUTF8()) == 0; + int x, y, w, h; + getBounds (x, y, w, h, true); + return y; } -const String File::getVersion() const throw() +void NSViewComponentPeer::relativePositionToGlobal (int& x, int& y) { - const ScopedAutoReleasePool pool; - String result; + int wx, wy, ww, wh; + getBounds (wx, wy, ww, wh, true); + x += wx; + y += wy; +} - NSBundle* bundle = [NSBundle bundleWithPath: juceStringToNS (getFullPathName())]; +void NSViewComponentPeer::globalPositionToRelative (int& x, int& y) +{ + int wx, wy, ww, wh; + getBounds (wx, wy, ww, wh, true); + x -= wx; + y -= wy; +} - if (bundle != 0) +NSRect NSViewComponentPeer::constrainRect (NSRect r) +{ + if (constrainer != 0) { - NSDictionary* info = [bundle infoDictionary]; + NSRect current = [window frame]; + current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; - if (info != 0) - { - NSString* name = [info valueForKey: @"CFBundleShortVersionString"]; + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; - if (name != nil) - result = nsStringToJuce (name); - } - } + int x = (int) r.origin.x; + int y = (int) r.origin.y; + int w = (int) r.size.width; + int h = (int) r.size.height; - return result; -} + Rectangle original ((int) current.origin.x, (int) current.origin.y, + (int) current.size.width, (int) current.size.height); -const File File::getLinkedTarget() const throw() -{ - NSString* dest = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath: juceStringToNS (getFullPathName()) error: nil]; + constrainer->checkBounds (x, y, w, h, + original, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + y != original.getY() && y + h == original.getBottom(), + x != original.getX() && x + w == original.getRight(), + y == original.getY() && y + h != original.getBottom(), + x == original.getX() && x + w != original.getRight()); - if (dest != nil) - return File (nsStringToJuce (dest)); + r.origin.x = x; + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - y; + r.size.width = w; + r.size.height = h; + } - return *this; + return r; } -bool File::moveToTrash() const throw() +void NSViewComponentPeer::setMinimised (bool shouldBeMinimised) { - if (! exists()) - return true; - -#if JUCE_IPHONE - return deleteFile(); //xxx is there a trashcan on the iPhone? -#else - const ScopedAutoReleasePool pool; - - NSString* p = juceStringToNS (getFullPathName()); - - return [[NSWorkspace sharedWorkspace] - performFileOperation: NSWorkspaceRecycleOperation - source: [p stringByDeletingLastPathComponent] - destination: @"" - files: [NSArray arrayWithObject: [p lastPathComponent]] - tag: nil ]; -#endif + if (! isSharedWindow) + { + if (shouldBeMinimised) + [window miniaturize: nil]; + else + [window deminiaturize: nil]; + } } -struct FindFileStruct +bool NSViewComponentPeer::isMinimised() const { - NSDirectoryEnumerator* enumerator; - String parentDir; -}; + return window != 0 && [window isMiniaturized]; +} -void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile, - bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, - Time* creationTime, bool* isReadOnly) throw() +void NSViewComponentPeer::setFullScreen (bool shouldBeFullScreen) { - NSDirectoryEnumerator* e = [[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory)]; - - if (e != 0) + if (! isSharedWindow) { - FindFileStruct* ff = new FindFileStruct(); - ff->enumerator = [e retain]; - ff->parentDir = directory; + Rectangle r (lastNonFullscreenBounds); - if (! ff->parentDir.endsWithChar (File::separator)) - ff->parentDir += File::separator; + setMinimised (false); - if (juce_findFileNext (ff, firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly)) - return ff; + if (fullScreen != shouldBeFullScreen) + { + if (shouldBeFullScreen) + r = Desktop::getInstance().getMainMonitorArea(); - [e release]; - delete ff; + // (can't call the component's setBounds method because that'll reset our fullscreen flag) + if (r != getComponent()->getBounds() && ! r.isEmpty()) + setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen); + } } - - return 0; } -bool juce_findFileNext (void* handle, String& resultFile, - bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw() +bool NSViewComponentPeer::isFullScreen() const { - FindFileStruct* ff = (FindFileStruct*) handle; - NSString* file; + return fullScreen; +} - if (ff == 0 || (file = [ff->enumerator nextObject]) == 0) +bool NSViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const +{ + if (((unsigned int) x) >= (unsigned int) component->getWidth() + || ((unsigned int) y) >= (unsigned int) component->getHeight()) return false; - [ff->enumerator skipDescendents]; - resultFile = nsStringToJuce (file); - - const String path (ff->parentDir + resultFile); + NSPoint p; + p.x = (float) x; + p.y = (float) y; - if (isDir != 0 || fileSize != 0) - { - struct stat info; - const bool statOk = juce_stat (path, info); + NSView* v = [view hitTest: p]; - if (isDir != 0) - *isDir = statOk && ((info.st_mode & S_IFDIR) != 0); + if (trueIfInAChildWindow) + return v != nil; - if (isHidden != 0) - *isHidden = juce_isHiddenFile (path); + return v == view; +} - if (fileSize != 0) - *fileSize = statOk ? info.st_size : 0; - } +const BorderSize NSViewComponentPeer::getFrameSize() const +{ + BorderSize b; - if (modTime != 0 || creationTime != 0) + if (! isSharedWindow) { - int64 m, a, c; - juce_getFileTimes (path, m, a, c); - - if (modTime != 0) - *modTime = m; + NSRect v = [view convertRect: [view frame] toView: nil]; + NSRect w = [window frame]; - if (creationTime != 0) - *creationTime = c; + b.setTop ((int) (w.size.height - (v.origin.y + v.size.height))); + b.setBottom ((int) v.origin.y); + b.setLeft ((int) v.origin.x); + b.setRight ((int) (w.size.width - (v.origin.x + v.size.width))); } - if (isReadOnly != 0) - *isReadOnly = ! juce_canWriteToFile (path); + return b; +} + +bool NSViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) +{ + if (! isSharedWindow) + { + [window setLevel: alwaysOnTop ? NSFloatingWindowLevel + : NSNormalWindowLevel]; + } return true; } -void juce_findFileClose (void* handle) throw() +void NSViewComponentPeer::toFront (bool makeActiveWindow) { - FindFileStruct* ff = (FindFileStruct*) handle; - [ff->enumerator release]; - delete ff; + if (isSharedWindow) + { + [[view superview] addSubview: view + positioned: NSWindowAbove + relativeTo: nil]; + } + + if (window != 0 && component->isVisible()) + { + if (makeActiveWindow) + [window makeKeyAndOrderFront: nil]; + else + [window orderFront: nil]; + } } -bool juce_launchExecutable (const String& pathAndArguments) throw() +void NSViewComponentPeer::toBehind (ComponentPeer* other) { - const char* const argv[4] = { "/bin/sh", "-c", (const char*) pathAndArguments, 0 }; - - const int cpid = fork(); + NSViewComponentPeer* o = (NSViewComponentPeer*) other; - if (cpid == 0) + if (isSharedWindow) { - // Child process - if (execve (argv[0], (char**) argv, 0) < 0) - exit (0); + [[view superview] addSubview: view + positioned: NSWindowBelow + relativeTo: o->view]; } else { - if (cpid < 0) - return false; + [window orderWindow: NSWindowBelow + relativeTo: o->window != 0 ? [o->window windowNumber] + : nil ]; } +} - return true; +void NSViewComponentPeer::setIcon (const Image& /*newIcon*/) +{ + // to do.. } -bool juce_launchFile (const String& fileName, - const String& parameters) throw() +void NSViewComponentPeer::viewFocusGain() { -#if JUCE_IPHONE - return false; // is this possible? -#else - const ScopedAutoReleasePool pool; + if (currentlyFocusedPeer != this) + { + if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) + currentlyFocusedPeer->handleFocusLoss(); - if (parameters.isEmpty()) + currentlyFocusedPeer = this; + + handleFocusGain(); + } +} + +void NSViewComponentPeer::viewFocusLoss() +{ + if (currentlyFocusedPeer == this) { - return [[NSWorkspace sharedWorkspace] openFile: juceStringToNS (fileName)] - || [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: juceStringToNS (fileName)]]; + currentlyFocusedPeer = 0; + handleFocusLoss(); } +} - bool ok = false; +void juce_HandleProcessFocusChange() +{ + keysCurrentlyDown.clear(); - FSRef ref; - if (PlatformUtilities::makeFSRefFromPath (&ref, fileName)) + if (NSViewComponentPeer::isValidPeer (currentlyFocusedPeer)) { - if (PlatformUtilities::isBundle (fileName)) + if (Process::isForegroundProcess()) { - NSMutableArray* urls = [NSMutableArray array]; - - StringArray docs; - docs.addTokens (parameters, true); - for (int i = 0; i < docs.size(); ++i) - [urls addObject: juceStringToNS (docs[i])]; + currentlyFocusedPeer->handleFocusGain(); - ok = [[NSWorkspace sharedWorkspace] openURLs: urls - withAppBundleIdentifier: [[NSBundle bundleWithPath: juceStringToNS (fileName)] bundleIdentifier] - options: nil - additionalEventParamDescriptor: nil - launchIdentifiers: nil]; + ComponentPeer::bringModalComponentToFront(); } else { - ok = juce_launchExecutable (T("\"") + fileName + T("\" ") + parameters); + currentlyFocusedPeer->handleFocusLoss(); + + // turn kiosk mode off if we lose focus.. + Desktop::getInstance().setKioskModeComponent (0); } } - - return ok; -#endif } -#if ! JUCE_IPHONE -bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path) +bool NSViewComponentPeer::isFocused() const { - return FSPathMakeRef ((const UInt8*) path.toUTF8(), destFSRef, 0) == noErr; + return isSharedWindow ? this == currentlyFocusedPeer + : (window != 0 && [window isKeyWindow]); } -const String PlatformUtilities::makePathFromFSRef (FSRef* file) +void NSViewComponentPeer::grabFocus() { - uint8 path [2048]; - zeromem (path, sizeof (path)); - - String result; - - if (FSRefMakePath (file, (UInt8*) path, sizeof (path) - 1) == noErr) - result = String::fromUTF8 (path); + if (window != 0) + { + [window makeKeyWindow]; + [window makeFirstResponder: view]; - return PlatformUtilities::convertToPrecomposedUnicode (result); + viewFocusGain(); + } } -#endif -OSType PlatformUtilities::getTypeOfFile (const String& filename) +void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) { - const ScopedAutoReleasePool pool; - NSDictionary* fileDict = [[NSFileManager defaultManager] fileAttributesAtPath: juceStringToNS (filename) traverseLink: NO]; - return (OSType) [fileDict objectForKey: NSFileHFSTypeCode]; } -bool PlatformUtilities::isBundle (const String& filename) +bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) { -#if JUCE_IPHONE - return false; // xxx can't find a sensible way to do this without trying to open the bundle.. -#else - const ScopedAutoReleasePool pool; - return [[NSWorkspace sharedWorkspace] isFilePackageAtPath: juceStringToNS (filename)]; -#endif -} + String unicode (nsStringToJuce ([ev characters])); + String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); + int keyCode = getKeyCodeFromEvent (ev); -#endif -/********* End of inlined file: juce_mac_Files.mm *********/ + //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0])); + //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0])); -/********* Start of inlined file: juce_iphone_MiscUtilities.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE + if (unicode.isNotEmpty() || keyCode != 0) + { + if (isKeyDown) + { + bool used = false; -ScopedAutoReleasePool::ScopedAutoReleasePool() + while (unicode.length() > 0) + { + juce_wchar textCharacter = unicode[0]; + unicode = unicode.substring (1); + + if (([ev modifierFlags] & NSCommandKeyMask) != 0) + textCharacter = 0; + + used = handleKeyUpOrDown (true) || used; + used = handleKeyPress (keyCode, textCharacter) || used; + } + + return used; + } + else + { + if (handleKeyUpOrDown (false)) + return true; + } + } + + return false; +} + +bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) { - pool = [[NSAutoreleasePool alloc] init]; + updateKeysDown (ev, true); + bool used = handleKeyEvent (ev, true); + + if (([ev modifierFlags] & NSCommandKeyMask) != 0) + { + // for command keys, the key-up event is thrown away, so simulate one.. + updateKeysDown (ev, false); + used = (isValidPeer (this) && handleKeyEvent (ev, false)) || used; + } + + // (If we're running modally, don't allow unused keystrokes to be passed + // along to other blocked views..) + if (Component::getCurrentlyModalComponent() != 0) + used = true; + + return used; } -ScopedAutoReleasePool::~ScopedAutoReleasePool() +bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) { - [((NSAutoreleasePool*) pool) release]; + updateKeysDown (ev, false); + return handleKeyEvent (ev, false) + || Component::getCurrentlyModalComponent() != 0; } -void PlatformUtilities::beep() +void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) { - //xxx - //AudioServicesPlaySystemSound (); + updateModifiers (ev); + handleModifierKeysChange(); } -void PlatformUtilities::addItemToDock (const File& file) +#if MACOS_10_4_OR_EARLIER +bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) { + if ([ev type] == NSKeyDown) + return redirectKeyDown (ev); + else if ([ev type] == NSKeyUp) + return redirectKeyUp (ev); + + return false; } +#endif -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY +void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) +{ + updateModifiers (ev); + currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); + int x, y; + getMousePos (ev, view, x, y); -bool AlertWindow::showNativeDialogBox (const String& title, - const String& bodyText, - bool isOkCancel) + handleMouseDown (x, y, getMouseTime (ev)); +} + +void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) { - const ScopedAutoReleasePool pool; + const int oldMods = currentModifiers; + updateModifiers (ev); + currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); + int x, y; + getMousePos (ev, view, x, y); - UIAlertView *alert = [[[UIAlertView alloc] initWithTitle: juceStringToNS (title) - message: juceStringToNS (title) - delegate: nil - cancelButtonTitle: @"OK" - otherButtonTitles: (isOkCancel ? @"Cancel" : nil), nil] autorelease]; - alert.cancelButtonIndex = alert.firstOtherButtonIndex; - [alert show]; + handleMouseUp (oldMods, x, y, getMouseTime (ev)); + showArrowCursorIfNeeded(); +} - // xxx need to use a delegate to find which button was clicked - return false; +void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) +{ + updateModifiers (ev); + currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); + int x, y; + getMousePos (ev, view, x, y); + + handleMouseDrag (x, y, getMouseTime (ev)); } -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) +void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) { - jassertfalse // not implemented! - return false; + updateModifiers (ev); + int x, y; + getMousePos (ev, view, x, y); + + handleMouseMove (x, y, getMouseTime (ev)); + showArrowCursorIfNeeded(); } -bool DragAndDropContainer::performExternalDragDropOfText (const String& text) +void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) { - jassertfalse // not implemented! - return false; + updateModifiers (ev); + int x, y; + getMousePos (ev, view, x, y); + + handleMouseEnter (x, y, getMouseTime (ev)); } -bool Desktop::canUseSemiTransparentWindows() throw() +void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) { - return true; + updateModifiers (ev); + int x, y; + getMousePos (ev, view, x, y); + + handleMouseExit (x, y, getMouseTime (ev)); } -void Desktop::getMousePosition (int& x, int& y) throw() +void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) { - x = 0; - y = 0; + updateModifiers (ev); + + handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), + roundFloatToInt ([ev deltaY] * 10.0f), + getMouseTime (ev)); } -void Desktop::setMousePosition (int x, int y) throw() +void NSViewComponentPeer::showArrowCursorIfNeeded() { + if (Component::getComponentUnderMouse() == 0) + { + int mx, my; + Desktop::getInstance().getMousePosition (mx, my); + + if (Desktop::getInstance().findComponentAt (mx, my) == 0) + [[NSCursor arrowCursor] set]; + } } -void Desktop::setScreenSaverEnabled (const bool isEnabled) throw() +BOOL NSViewComponentPeer::sendDragCallback (int type, id sender) { - [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled]; + NSString* bestType + = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; + + if (bestType == nil) + return false; + + NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; + int x = (int) p.x; + int y = (int) ([view frame].size.height - p.y); + + StringArray files; + + id list = [[sender draggingPasteboard] propertyListForType: bestType]; + if (list == nil) + return false; + + if ([list isKindOfClass: [NSArray class]]) + { + NSArray* items = (NSArray*) list; + + for (unsigned int i = 0; i < [items count]; ++i) + files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); + } + + if (files.size() == 0) + return false; + + if (type == 0) + handleFileDragMove (files, x, y); + else if (type == 1) + handleFileDragExit (files); + else if (type == 2) + handleFileDragDrop (files, x, y); + + return true; } -bool Desktop::isScreenSaverEnabled() throw() +bool NSViewComponentPeer::isOpaque() { - return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; + if (! getComponent()->isValidComponent()) + return true; + + return getComponent()->isOpaque(); } -void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool clipToWorkArea) throw() +void NSViewComponentPeer::drawRect (NSRect r) { - const ScopedAutoReleasePool pool; - monitorCoords.clear(); + if (r.size.width < 1.0f || r.size.height < 1.0f) + return; - CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame] - : [[UIScreen mainScreen] bounds]; + const float y = [view frame].size.height - (r.origin.y + r.size.height); - monitorCoords.add (Rectangle ((int) r.origin.x, - (int) r.origin.y, - (int) r.size.width, - (int) r.size.height)); -} + JuceNSImage temp ((int) (r.size.width + 0.5f), + (int) (r.size.height + 0.5f), + ! getComponent()->isOpaque()); -#endif + LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage()); + const int originX = -roundFloatToInt (r.origin.x); + const int originY = -roundFloatToInt (y); + context.setOrigin (originX, originY); -#endif -/********* End of inlined file: juce_iphone_MiscUtilities.mm *********/ + const NSRect* rects = 0; + NSInteger numRects = 0; + [view getRectsBeingDrawn: &rects count: &numRects]; -/********* Start of inlined file: juce_mac_Debugging.mm *********/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#ifdef JUCE_INCLUDED_FILE + RectangleList clip; + for (int i = 0; i < numRects; ++i) + { + clip.addWithoutMerging (Rectangle (roundFloatToInt (rects[i].origin.x), + roundFloatToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)), + roundFloatToInt (rects[i].size.width), + roundFloatToInt (rects[i].size.height))); + } -void Logger::outputDebugString (const String& text) throw() + if (context.reduceClipRegion (clip)) + { + handlePaint (context); + temp.draw (r.origin.x, r.origin.y, clip, originX, originY); + } +} + +bool NSViewComponentPeer::canBecomeKeyWindow() { - fputs (text.toUTF8(), stderr); - fputs ("\n", stderr); + return (getStyleFlags() & juce::ComponentPeer::windowIgnoresKeyPresses) == 0; } -void Logger::outputDebugPrintf (const tchar* format, ...) throw() +bool NSViewComponentPeer::windowShouldClose() { - String text; - va_list args; - va_start (args, format); - text.vprintf (format, args); - outputDebugString (text); + if (! isValidPeer (this)) + return YES; + + handleUserClosingWindow(); + return NO; } -bool JUCE_CALLTYPE juce_isRunningUnderDebugger() throw() +void NSViewComponentPeer::redirectMovedOrResized() { - static char testResult = 0; + handleMovedOrResized(); +} - if (testResult == 0) +void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) +{ + // Very annoyingly, this function has to use the old SetSystemUIMode function, + // which is in Carbon.framework. But, because there's no Cocoa equivalent, it + // is apparently still available in 64-bit apps.. + if (enableOrDisable) { - struct kinfo_proc info; - int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; - size_t sz = sizeof (info); - sysctl (m, 4, &info, &sz, 0, 0); - testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1; + SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0); + kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); + } + else + { + SetSystemUIMode (kUIModeNormal, 0); } +} - return testResult > 0; +void NSViewComponentPeer::repaint (int x, int y, int w, int h) +{ + [view setNeedsDisplayInRect: + NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)), + (float) w, (float) h)]; } -bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw() +void NSViewComponentPeer::performAnyPendingRepaintsNow() { - return juce_isRunningUnderDebugger(); + [view displayIfNeeded]; } -#endif -/********* End of inlined file: juce_mac_Debugging.mm *********/ +ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) +{ + return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo); +} -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY - /*#include "mac/juce_mac_NSViewComponentPeer.mm" +static Image* NSImageToJuceImage (NSImage* image) +{ + JuceNSImage juceIm ((int) [image size].width, + (int) [image size].height, + true); + + juceIm.drawNSImage (image); + return juceIm.getJuceImage().createCopy(); +} + +Image* juce_createIconForFile (const File& file) +{ + const ScopedAutoReleasePool pool; + + NSImage* im = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())]; + return NSImageToJuceImage (im); +} + +const int KeyPress::spaceKey = ' '; +const int KeyPress::returnKey = 0x0d; +const int KeyPress::escapeKey = 0x1b; +const int KeyPress::backspaceKey = 0x7f; +const int KeyPress::leftKey = NSLeftArrowFunctionKey; +const int KeyPress::rightKey = NSRightArrowFunctionKey; +const int KeyPress::upKey = NSUpArrowFunctionKey; +const int KeyPress::downKey = NSDownArrowFunctionKey; +const int KeyPress::pageUpKey = NSPageUpFunctionKey; +const int KeyPress::pageDownKey = NSPageDownFunctionKey; +const int KeyPress::endKey = NSEndFunctionKey; +const int KeyPress::homeKey = NSHomeFunctionKey; +const int KeyPress::deleteKey = NSDeleteFunctionKey; +const int KeyPress::insertKey = -1; +const int KeyPress::tabKey = 9; +const int KeyPress::F1Key = NSF1FunctionKey; +const int KeyPress::F2Key = NSF2FunctionKey; +const int KeyPress::F3Key = NSF3FunctionKey; +const int KeyPress::F4Key = NSF4FunctionKey; +const int KeyPress::F5Key = NSF5FunctionKey; +const int KeyPress::F6Key = NSF6FunctionKey; +const int KeyPress::F7Key = NSF7FunctionKey; +const int KeyPress::F8Key = NSF8FunctionKey; +const int KeyPress::F9Key = NSF9FunctionKey; +const int KeyPress::F10Key = NSF10FunctionKey; +const int KeyPress::F11Key = NSF1FunctionKey; +const int KeyPress::F12Key = NSF12FunctionKey; +const int KeyPress::F13Key = NSF13FunctionKey; +const int KeyPress::F14Key = NSF14FunctionKey; +const int KeyPress::F15Key = NSF15FunctionKey; +const int KeyPress::F16Key = NSF16FunctionKey; +const int KeyPress::numberPad0 = 0x30020; +const int KeyPress::numberPad1 = 0x30021; +const int KeyPress::numberPad2 = 0x30022; +const int KeyPress::numberPad3 = 0x30023; +const int KeyPress::numberPad4 = 0x30024; +const int KeyPress::numberPad5 = 0x30025; +const int KeyPress::numberPad6 = 0x30026; +const int KeyPress::numberPad7 = 0x30027; +const int KeyPress::numberPad8 = 0x30028; +const int KeyPress::numberPad9 = 0x30029; +const int KeyPress::numberPadAdd = 0x3002a; +const int KeyPress::numberPadSubtract = 0x3002b; +const int KeyPress::numberPadMultiply = 0x3002c; +const int KeyPress::numberPadDivide = 0x3002d; +const int KeyPress::numberPadSeparator = 0x3002e; +const int KeyPress::numberPadDecimalPoint = 0x3002f; +const int KeyPress::numberPadEquals = 0x30030; +const int KeyPress::numberPadDelete = 0x30031; +const int KeyPress::playKey = 0x30000; +const int KeyPress::stopKey = 0x30001; +const int KeyPress::fastForwardKey = 0x30002; +const int KeyPress::rewindKey = 0x30003; + +#endif +/********* End of inlined file: juce_mac_NSViewComponentPeer.mm *********/ /********* Start of inlined file: juce_mac_MouseCursor.mm *********/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). #ifdef JUCE_INCLUDED_FILE +#if JUCE_MAC + static NSImage* juceImageToNSImage (const Image& image) { const ScopedAutoReleasePool pool; @@ -267737,6 +263440,16 @@ void MouseCursor::showInWindow (ComponentPeer*) const throw() [c set]; } +#else + +void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw() { return 0; } +void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw() { return 0; } +void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw() {} +void MouseCursor::showInAllWindows() const throw() {} +void MouseCursor::showInWindow (ComponentPeer*) const throw() {} + +#endif + #endif /********* End of inlined file: juce_mac_MouseCursor.mm *********/ @@ -268119,6 +263832,8 @@ void AppleRemoteDevice::handleCallbackInternal() // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_OPENGL +#if JUCE_MAC + END_JUCE_NAMESPACE #define ThreadSafeNSOpenGLView MakeObjCClassName(ThreadSafeNSOpenGLView) @@ -268402,6 +264117,22 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/, //jassertfalse //xxx can't see how you do this in cocoa! } +#else + +OpenGLContext* OpenGLContext::createContextForWindow (Component* const component, + const OpenGLPixelFormat& pixelFormat, + const OpenGLContext* const contextToShareWith) +{ + return 0; +} + +void juce_glViewport (const int w, const int h) +{ + //glViewport (0, 0, w, h); +} + +#endif + #endif /********* End of inlined file: juce_mac_OpenGLComponent.mm *********/ @@ -268893,6 +264624,8 @@ void initialiseMainMenu() // compiled on its own). #ifdef JUCE_INCLUDED_FILE +#if JUCE_MAC + END_JUCE_NAMESPACE using namespace JUCE_NAMESPACE; @@ -269011,6 +264744,25 @@ void FileChooser::showPlatformDialog (OwnedArray& results, [panel setDelegate: nil]; } +#else + +void FileChooser::showPlatformDialog (OwnedArray& results, + const String& title, + const File& currentFileOrDirectory, + const String& filter, + bool selectsDirectory, + bool isSaveDialogue, + bool warnAboutOverwritingExistingFiles, + bool selectMultipleFiles, + FilePreviewComponent* extraInfoComponent) +{ + const ScopedAutoReleasePool pool; + + jassertfalse //xxx to do +} + +#endif + #endif /********* End of inlined file: juce_mac_FileChooser.mm *********/ @@ -270461,6 +266213,8 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER +#if JUCE_MAC + END_JUCE_NAMESPACE #define DownloadClickDetector MakeObjCClassName(DownloadClickDetector) @@ -270693,6 +266447,69 @@ bool WebBrowserComponent::pageAboutToLoad (const String& url) return true; } +#else + +WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) +{ +} + +WebBrowserComponent::~WebBrowserComponent() +{ +} + +void WebBrowserComponent::goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) +{ +} + +void WebBrowserComponent::stop() +{ +} + +void WebBrowserComponent::goBack() +{ +} + +void WebBrowserComponent::goForward() +{ +} + +void WebBrowserComponent::refresh() +{ +} + +void WebBrowserComponent::paint (Graphics& g) +{ +} + +void WebBrowserComponent::checkWindowAssociation() +{ +} + +void WebBrowserComponent::reloadLastURL() +{ +} + +void WebBrowserComponent::parentHierarchyChanged() +{ +} + +void WebBrowserComponent::resized() +{ +} + +void WebBrowserComponent::visibilityChanged() +{ +} + +bool WebBrowserComponent::pageAboutToLoad (const String& url) +{ + return true; +} + +#endif + #endif /********* End of inlined file: juce_mac_WebBrowserComponent.mm *********/ @@ -272037,6 +267854,8 @@ AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio() // compiled on its own). #ifdef JUCE_INCLUDED_FILE +#if JUCE_MAC + #undef log #define log(a) Logger::writeToLog(a) @@ -272590,6 +268409,51 @@ void MidiInput::stop() #undef log +#else + +MidiOutput::~MidiOutput() +{ +} + +void MidiOutput::reset() +{ +} + +bool MidiOutput::getVolume (float& leftVol, float& rightVol) +{ + return false; +} + +void MidiOutput::setVolume (float leftVol, float rightVol) +{ +} + +void MidiOutput::sendMessageNow (const MidiMessage& message) +{ +} + +const StringArray MidiOutput::getDevices() +{ + return StringArray(); +} + +MidiOutput* MidiOutput::openDevice (int index) +{ + return 0; +} + +const StringArray MidiInput::getDevices() +{ + return StringArray(); +} + +MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) +{ + return 0; +} + +#endif + #endif /********* End of inlined file: juce_mac_CoreMidi.cpp *********/ @@ -272967,10 +268831,10 @@ CameraDevice* CameraDevice::openDevice (int index, #endif /********* End of inlined file: juce_mac_CameraDevice.mm *********/ -*/ + #endif #endif END_JUCE_NAMESPACE -/********* End of inlined file: juce_iphone_NativeCode.mm *********/ +/********* End of inlined file: juce_mac_NativeCode.mm *********/ #endif diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 5600a8ab5f..b4cbb90cf5 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -72,6 +72,147 @@ */ #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8)) +/********* Start of inlined file: juce_TargetPlatform.h *********/ +#ifndef __JUCE_TARGETPLATFORM_JUCEHEADER__ +#define __JUCE_TARGETPLATFORM_JUCEHEADER__ + +/* This file figures out which platform is being built, and defines some macros + that the rest of the code can use for OS-specific compilation. + + Macros that will be set here are: + + - One of JUCE_WINDOWS, JUCE_MAC or JUCE_LINUX. + - Either JUCE_32BIT or JUCE_64BIT, depending on the architecture. + - Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN. + - Either JUCE_INTEL or JUCE_PPC + - Either JUCE_GCC or JUCE_MSVC +*/ + +#if (defined (_WIN32) || defined (_WIN64)) + #define JUCE_WIN32 1 + #define JUCE_WINDOWS 1 +#elif defined (LINUX) || defined (__linux__) + #define JUCE_LINUX 1 +#elif defined(__APPLE_CPP__) || defined(__APPLE_CC__) + #include // (needed to find out what platform we're using) + + #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + #define JUCE_IPHONE 1 + #else + #define JUCE_MAC 1 + #endif +#else + #error "Unknown platform!" +#endif + +#if JUCE_WINDOWS + #ifdef _MSC_VER + #ifdef _WIN64 + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + #endif + + #ifdef _DEBUG + #define JUCE_DEBUG 1 + #endif + + /** If defined, this indicates that the processor is little-endian. */ + #define JUCE_LITTLE_ENDIAN 1 + + #define JUCE_INTEL 1 +#endif + +#if JUCE_MAC + + #ifndef NDEBUG + #define JUCE_DEBUG 1 + #endif + + #ifdef __LITTLE_ENDIAN__ + #define JUCE_LITTLE_ENDIAN 1 + #else + #define JUCE_BIG_ENDIAN 1 + #endif + + #if defined (__ppc__) || defined (__ppc64__) + #define JUCE_PPC 1 + #else + #define JUCE_INTEL 1 + #endif + + #ifdef __LP64__ + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + + #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3) + #error "Building for OSX 10.2 is no longer supported!" + #endif + + #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) + #define MACOS_10_3_OR_EARLIER 1 + #endif + + #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) + #define MACOS_10_4_OR_EARLIER 1 + #endif +#endif + +#if JUCE_IPHONE + + #ifndef NDEBUG + #define JUCE_DEBUG 1 + #endif + + #ifdef __LITTLE_ENDIAN__ + #define JUCE_LITTLE_ENDIAN 1 + #else + #define JUCE_BIG_ENDIAN 1 + #endif +#endif + +#if JUCE_LINUX + + #ifdef _DEBUG + #define JUCE_DEBUG 1 + #endif + + // Allow override for big-endian Linux platforms + #ifndef JUCE_BIG_ENDIAN + #define JUCE_LITTLE_ENDIAN 1 + #endif + + #if defined (__LP64__) || defined (_LP64) + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + + #define JUCE_INTEL 1 +#endif + +// Compiler type macros. + +#ifdef __GNUC__ + #define JUCE_GCC 1 +#elif defined (_MSC_VER) + #define JUCE_MSVC 1 + + #if _MSC_VER >= 1400 + #define JUCE_USE_INTRINSICS 1 + #endif +#else + #error unknown compiler +#endif + +#endif // __JUCE_PLATFORMDEFS_JUCEHEADER__ +/********* End of inlined file: juce_TargetPlatform.h *********/ + + // (sets up the various JUCE_WINDOWS, JUCE_MAC, etc flags) + /********* Start of inlined file: juce_Config.h *********/ #ifndef __JUCE_CONFIG_JUCEHEADER__ #define __JUCE_CONFIG_JUCEHEADER__ @@ -145,7 +286,7 @@ On Windows, if you enable this, you'll need to have the QuickTime SDK installed, and its header files will need to be on your include path. */ -#if ! (defined (JUCE_QUICKTIME) || defined (LINUX) || defined (TARGET_OS_IPHONE) || defined (TARGET_IPHONE_SIMULATOR) || (defined (_WIN32) && ! defined (_MSC_VER))) +#if ! (defined (JUCE_QUICKTIME) || JUCE_LINUX || JUCE_IPHONE || (JUCE_WINDOWS && ! JUCE_MSVC)) #define JUCE_QUICKTIME 1 #endif @@ -173,7 +314,7 @@ /** This flag lets you enable support for CD-burning. You might want to disable it to build without the MS SDK under windows. */ -#if (! defined (JUCE_USE_CDBURNER)) && ! (defined (_WIN32) && ! defined (_MSC_VER)) +#if (! defined (JUCE_USE_CDBURNER)) && ! (JUCE_WINDOWS && ! JUCE_MSVC) #define JUCE_USE_CDBURNER 1 #endif @@ -300,131 +441,13 @@ #define END_JUCE_NAMESPACE #endif -// This sets up the JUCE_WIN32, JUCE_MAC, or JUCE_LINUX macros - /********* Start of inlined file: juce_PlatformDefs.h *********/ #ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__ #define __JUCE_PLATFORMDEFS_JUCEHEADER__ -/* This file figures out which platform is being built, and defines some macros - that the rest of the code can use for OS-specific compilation. - - Macros that will be set here are: - - - One of JUCE_WIN32, JUCE_MAC or JUCE_LINUX. - - Either JUCE_32BIT or JUCE_64BIT, depending on the architecture. - - Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN. - - Either JUCE_INTEL or JUCE_PPC - - Either JUCE_GCC or JUCE_MSVC - - It also includes a set of macros for debug console output and assertions. - +/* This file defines miscellaneous macros for debugging, assertions, etc. */ -#if (defined (_WIN32) || defined (_WIN64)) - #define JUCE_WIN32 1 -#else - #if defined (LINUX) || defined (__linux__) - #define JUCE_LINUX 1 - #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - #define JUCE_IPHONE 1 - #else - #define JUCE_MAC 1 - #endif -#endif - -#if JUCE_WIN32 - #ifdef _MSC_VER - #ifdef _WIN64 - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - #endif - - #ifdef _DEBUG - #define JUCE_DEBUG 1 - #endif - - /** If defined, this indicates that the processor is little-endian. */ - #define JUCE_LITTLE_ENDIAN 1 - - #define JUCE_INTEL 1 -#endif - -#if JUCE_MAC - - #include - - #ifndef NDEBUG - #define JUCE_DEBUG 1 - #endif - - #ifdef __LITTLE_ENDIAN__ - #define JUCE_LITTLE_ENDIAN 1 - #else - #define JUCE_BIG_ENDIAN 1 - #endif - - #if defined (__ppc__) || defined (__ppc64__) - #define JUCE_PPC 1 - #else - #define JUCE_INTEL 1 - #endif - - #ifdef __LP64__ - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - - #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3) - #error "Building for OSX 10.2 is no longer supported!" - #endif - - #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) - #define MACOS_10_3_OR_EARLIER 1 - #endif - - #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - #define MACOS_10_4_OR_EARLIER 1 - #endif -#endif - -#if JUCE_IPHONE - #include - - #ifndef NDEBUG - #define JUCE_DEBUG 1 - #endif - - #ifdef __LITTLE_ENDIAN__ - #define JUCE_LITTLE_ENDIAN 1 - #else - #define JUCE_BIG_ENDIAN 1 - #endif -#endif - -#if JUCE_LINUX - - #ifdef _DEBUG - #define JUCE_DEBUG 1 - #endif - - // Allow override for big-endian Linux platforms - #ifndef JUCE_BIG_ENDIAN - #define JUCE_LITTLE_ENDIAN 1 - #endif - - #if defined (__LP64__) || defined (_LP64) - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - - #define JUCE_INTEL 1 -#endif - #ifdef JUCE_FORCE_DEBUG #undef JUCE_DEBUG @@ -433,20 +456,6 @@ #endif #endif -// Compiler type macros. - -#ifdef __GNUC__ - #define JUCE_GCC 1 -#elif defined (_MSC_VER) - #define JUCE_MSVC 1 - - #if _MSC_VER >= 1400 - #define JUCE_USE_INTRINSICS 1 - #endif -#else - #error unknown compiler -#endif - /** This macro defines the C calling convention used as the standard for Juce calls. */ #if JUCE_MSVC #define JUCE_CALLTYPE __stdcall @@ -487,7 +496,7 @@ // Assertions.. - #if JUCE_WIN32 || DOXYGEN + #if JUCE_WINDOWS || DOXYGEN #if JUCE_USE_INTRINSICS #pragma intrinsic (__debugbreak) @@ -511,7 +520,7 @@ #elif JUCE_MAC #define juce_breakDebugger Debugger(); #elif JUCE_IPHONE - #define juce_breakDebugger assert (false); + #define juce_breakDebugger kill (0, SIGTRAP); #elif JUCE_LINUX #define juce_breakDebugger kill (0, SIGTRAP); #endif @@ -1027,7 +1036,7 @@ inline void swapVariables (Type& variable1, Type& variable2) throw() // Some useful maths functions that aren't always present with all compilers and build settings. -#if JUCE_WIN32 || defined (DOXYGEN) +#if JUCE_WINDOWS || defined (DOXYGEN) /** Using juce_hypot and juce_hypotf is easier than dealing with all the different versions of these functions of various platforms and compilers. */ forcedinline double juce_hypot (double a, double b) { return _hypot (a, b); } @@ -1075,7 +1084,7 @@ const float float_Pi = 3.14159265358979323846f; #else #define juce_isfinite(v) std::isfinite(v) #endif -#elif JUCE_WIN32 && ! defined (isfinite) +#elif JUCE_WINDOWS && ! defined (isfinite) #define juce_isfinite(v) _finite(v) #else #define juce_isfinite(v) isfinite(v) @@ -1094,12 +1103,20 @@ const float float_Pi = 3.14159265358979323846f; // Endianness conversions.. +#if JUCE_IPHONE +// a gcc compiler error seems to mean that these functions only work properly +// on the iPhone if they are declared static.. +static forcedinline uint32 swapByteOrder (uint32 n) throw(); +static inline uint16 swapByteOrder (const uint16 n) throw(); +static inline uint64 swapByteOrder (const uint64 value) throw(); +#endif + /** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */ forcedinline uint32 swapByteOrder (uint32 n) throw() { #if JUCE_MAC || JUCE_IPHONE // Mac version - return CFSwapInt32 (n); + return OSSwapInt32 (n); #elif JUCE_GCC // Inpenetrable GCC version.. asm("bswap %%eax" : "=a"(n) : "a"(n)); @@ -1132,7 +1149,7 @@ inline uint16 swapByteOrder (const uint16 n) throw() inline uint64 swapByteOrder (const uint64 value) throw() { #if JUCE_MAC || JUCE_IPHONE - return CFSwapInt64 (value); + return OSSwapInt64 (value); #elif JUCE_USE_INTRINSICS return _byteswap_uint64 (value); #else @@ -2534,7 +2551,7 @@ BEGIN_JUCE_NAMESPACE #pragma warning (disable: 4786) // (old vc6 warning about long class names) #endif -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE #pragma align=natural #endif @@ -2558,10 +2575,11 @@ BEGIN_JUCE_NAMESPACE #if ! MACOS_10_3_OR_EARLIER - forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); } - forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); } - forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); } - forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); } + #include + static forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); } + static forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); } + static forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); } + static forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); } #else forcedinline void atomicIncrement (int& variable) throw() { OTAtomicAdd32 (1, (SInt32*) &variable); } @@ -7194,7 +7212,7 @@ public: static void addItemToDock (const File& file); #endif -#if JUCE_WIN32 || DOXYGEN +#if JUCE_WINDOWS || DOXYGEN // Some registry helper functions: @@ -7272,7 +7290,7 @@ public: */ static void fpuReset(); -#if JUCE_LINUX || JUCE_WIN32 +#if JUCE_LINUX || JUCE_WINDOWS /** Loads a dynamically-linked library into the process's address space. @@ -23872,7 +23890,12 @@ private: String commandLineParameters; int appReturnValue; bool stillInitialising; + InterProcessLock* appLock; +public: + /** @internal */ + bool initialiseApp (String& commandLine); + /** @internal */ static int shutdownAppAndClearUp(); }; @@ -37075,7 +37098,7 @@ public: static int compareElements (const File* const, const File* const) throw(); private: -#elif JUCE_WIN32 +#elif JUCE_WINDOWS int numTracks; int trackStarts[100]; bool audioTracks [100]; @@ -51964,7 +51987,7 @@ private: #ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__ #define __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__ -#if JUCE_WIN32 || DOXYGEN +#if JUCE_WINDOWS || DOXYGEN /** A Windows-specific class that can create and embed an ActiveX control inside @@ -53629,7 +53652,7 @@ private: // this is used to disable QuickTime, and is defined in juce_Config.h #if JUCE_QUICKTIME || DOXYGEN -#if JUCE_WIN32 +#if JUCE_WINDOWS typedef ActiveXControlComponent QTCompBaseClass; #else @@ -53773,7 +53796,7 @@ private: File movieFile; bool movieLoaded, controllerVisible, looping; -#if JUCE_WIN32 +#if JUCE_WINDOWS /** @internal */ void parentHierarchyChanged(); /** @internal */ @@ -53801,7 +53824,7 @@ private: #ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ #define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -#if JUCE_WIN32 || JUCE_LINUX || DOXYGEN +#if JUCE_WINDOWS || JUCE_LINUX || DOXYGEN /** On Windows only, this component sits in the taskbar tray as a small icon. @@ -55028,7 +55051,7 @@ public: #pragma pack (pop) #endif -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE #pragma align=reset #endif @@ -55063,7 +55086,7 @@ END_JUCE_NAMESPACE files, you may need to use the juce_WithoutMacros.h file - see the comments in that file for more information. */ - #if JUCE_WIN32 && ! JUCE_DONT_DEFINE_MACROS + #if JUCE_WINDOWS && ! JUCE_DONT_DEFINE_MACROS #define Rectangle JUCE_NAMESPACE::Rectangle #endif #endif @@ -55164,7 +55187,7 @@ END_JUCE_NAMESPACE return JUCE_NAMESPACE::JUCEApplication::main (argc, argv, new AppClass()); \ } -#elif JUCE_WIN32 +#elif JUCE_WINDOWS #ifdef _CONSOLE #define START_JUCE_APPLICATION(AppClass) \ diff --git a/src/application/juce_Application.cpp b/src/application/juce_Application.cpp index 5e832a6417..d8dc039cbf 100644 --- a/src/application/juce_Application.cpp +++ b/src/application/juce_Application.cpp @@ -44,7 +44,6 @@ BEGIN_JUCE_NAMESPACE #include "../core/juce_Time.h" #include "../core/juce_Initialisation.h" #include "../threads/juce_Process.h" -#include "../threads/juce_InterProcessLock.h" #include "../core/juce_PlatformUtilities.h" void juce_setCurrentThreadName (const String& name) throw(); @@ -55,12 +54,18 @@ static JUCEApplication* appInstance = 0; //============================================================================== JUCEApplication::JUCEApplication() : appReturnValue (0), - stillInitialising (true) + stillInitialising (true), + appLock (0) { } JUCEApplication::~JUCEApplication() { + if (appLock != 0) + { + appLock->exit(); + delete appLock; + } } JUCEApplication* JUCEApplication::getInstance() throw() @@ -156,68 +161,65 @@ bool JUCEApplication::perform (const InvocationInfo& info) //============================================================================== int JUCEApplication::main (String& commandLine, JUCEApplication* const app) +{ + if (! app->initialiseApp (commandLine)) + return 0; + + // now loop until a quit message is received.. + JUCE_TRY + { + MessageManager::getInstance()->runDispatchLoop(); + } +#if JUCE_CATCH_UNHANDLED_EXCEPTIONS + catch (const std::exception& e) + { + app->unhandledException (&e, __FILE__, __LINE__); + } + catch (...) + { + app->unhandledException (0, __FILE__, __LINE__); + } +#endif + + return shutdownAppAndClearUp(); +} + +bool JUCEApplication::initialiseApp (String& commandLine) { jassert (appInstance == 0); - appInstance = app; + appInstance = this; - app->commandLineParameters = commandLine.trim(); + commandLineParameters = commandLine.trim(); commandLine = String::empty; initialiseJuce_GUI(); InterProcessLock* appLock = 0; - if (! app->moreThanOneInstanceAllowed()) + if (! moreThanOneInstanceAllowed()) { - appLock = new InterProcessLock ("juceAppLock_" + app->getApplicationName()); + appLock = new InterProcessLock ("juceAppLock_" + getApplicationName()); if (! appLock->enter(0)) { - MessageManager::broadcastMessage (app->getApplicationName() + "/" + app->commandLineParameters); + MessageManager::broadcastMessage (getApplicationName() + "/" + commandLineParameters); delete appInstance; appInstance = 0; DBG ("Another instance is running - quitting..."); - return 0; + return false; } } - JUCE_TRY - { - juce_setCurrentThreadName ("Juce Message Thread"); - - // let the app do its setting-up.. - app->initialise (app->commandLineParameters); - - // register for broadcast new app messages - MessageManager::getInstance()->registerBroadcastListener (app); + // let the app do its setting-up.. + initialise (commandLineParameters); - app->stillInitialising = false; + // register for broadcast new app messages + MessageManager::getInstance()->registerBroadcastListener (this); - // now loop until a quit message is received.. - MessageManager::getInstance()->runDispatchLoop(); - - MessageManager::getInstance()->deregisterBroadcastListener (app); - - if (appLock != 0) - { - appLock->exit(); - delete appLock; - } - } -#if JUCE_CATCH_UNHANDLED_EXCEPTIONS - catch (const std::exception& e) - { - app->unhandledException (&e, __FILE__, __LINE__); - } - catch (...) - { - app->unhandledException (0, __FILE__, __LINE__); - } -#endif - - return shutdownAppAndClearUp(); + stillInitialising = false; + return true; } int JUCEApplication::shutdownAppAndClearUp() @@ -226,6 +228,8 @@ int JUCEApplication::shutdownAppAndClearUp() JUCEApplication* const app = appInstance; int returnValue = 0; + MessageManager::getInstance()->deregisterBroadcastListener (app); + static bool reentrancyCheck = false; if (! reentrancyCheck) @@ -265,9 +269,18 @@ int JUCEApplication::shutdownAppAndClearUp() return returnValue; } +#if JUCE_IPHONE + extern int juce_IPhoneMain (int argc, char* argv[], JUCEApplication* app); +#endif + int JUCEApplication::main (int argc, char* argv[], JUCEApplication* const newApp) { +#if JUCE_IPHONE + const ScopedAutoReleasePool pool; + return juce_IPhoneMain (argc, argv, newApp); +#else + #if JUCE_MAC const ScopedAutoReleasePool pool; #endif @@ -277,6 +290,7 @@ int JUCEApplication::main (int argc, char* argv[], cmd << String::fromUTF8 ((const uint8*) argv[i]) << T(' '); return JUCEApplication::main (cmd, newApp); +#endif } void JUCEApplication::actionListenerCallback (const String& message) @@ -293,7 +307,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI() { if (! juceInitialisedGUI) { -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE const ScopedAutoReleasePool pool; #endif juceInitialisedGUI = true; @@ -301,8 +315,9 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI() initialiseJuce_NonGUI(); MessageManager::getInstance(); LookAndFeel::setDefaultLookAndFeel (0); + juce_setCurrentThreadName ("Juce Message Thread"); -#if JUCE_WIN32 && JUCE_DEBUG +#if JUCE_WINDOWS && JUCE_DEBUG // This section is just for catching people who mess up their project settings and // turn RTTI off.. try diff --git a/src/application/juce_Application.h b/src/application/juce_Application.h index ad02605c01..db113d5d28 100644 --- a/src/application/juce_Application.h +++ b/src/application/juce_Application.h @@ -28,6 +28,7 @@ #include "juce_ApplicationCommandTarget.h" #include "../events/juce_ActionListener.h" +#include "../threads/juce_InterProcessLock.h" //============================================================================== @@ -288,7 +289,12 @@ private: String commandLineParameters; int appReturnValue; bool stillInitialising; + InterProcessLock* appLock; +public: + /** @internal */ + bool initialiseApp (String& commandLine); + /** @internal */ static int shutdownAppAndClearUp(); }; diff --git a/src/audio/audio_file_formats/flac/libFLAC/juce_FlacHeader.h b/src/audio/audio_file_formats/flac/libFLAC/juce_FlacHeader.h index c95ba14db2..206af683bd 100644 --- a/src/audio/audio_file_formats/flac/libFLAC/juce_FlacHeader.h +++ b/src/audio/audio_file_formats/flac/libFLAC/juce_FlacHeader.h @@ -26,17 +26,17 @@ // This file is included at the start of each FLAC .c file, just to do a few housekeeping // tasks.. - +#include "../../../../core/juce_TargetPlatform.h" #include "../../../../../juce_Config.h" #define VERSION "1.2.1" #define FLAC__NO_DLL 1 -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312) #endif -#if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX)) +#if JUCE_MAC #define FLAC__SYS_DARWIN 1 #endif diff --git a/src/audio/audio_file_formats/juce_AudioCDReader.h b/src/audio/audio_file_formats/juce_AudioCDReader.h index 78301ca5bd..581e2da461 100644 --- a/src/audio/audio_file_formats/juce_AudioCDReader.h +++ b/src/audio/audio_file_formats/juce_AudioCDReader.h @@ -158,7 +158,7 @@ public: static int compareElements (const File* const, const File* const) throw(); private: -#elif JUCE_WIN32 +#elif JUCE_WINDOWS int numTracks; int trackStarts[100]; bool audioTracks [100]; diff --git a/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp b/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp index 9c8dd6c005..f80aa01a46 100644 --- a/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp @@ -23,13 +23,15 @@ ============================================================================== */ +#include "../../core/juce_TargetPlatform.h" #include "../../../juce_Config.h" -#ifdef _MSC_VER - #include -#endif #if JUCE_USE_FLAC +#if JUCE_WINDOWS + #include +#endif + #include "../../core/juce_StandardHeader.h" #ifdef _MSC_VER diff --git a/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp b/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp index 3b3edaa319..d6ded62867 100644 --- a/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp @@ -23,6 +23,7 @@ ============================================================================== */ +#include "../../core/juce_TargetPlatform.h" #include "../../../juce_Config.h" #if JUCE_USE_OGGVORBIS diff --git a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp index c9f6eaf059..6a141b2de9 100644 --- a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp @@ -23,18 +23,19 @@ ============================================================================== */ +#include "../../core/juce_TargetPlatform.h" #include "../../../juce_Config.h" -#if JUCE_QUICKTIME +#if JUCE_QUICKTIME && ! (JUCE_64BIT || JUCE_IPHONE) -#if ! defined (_WIN32) +#if ! JUCE_WINDOWS #include #include #include #include #include #else - #ifdef _MSC_VER + #if JUCE_MSVC #pragma warning (push) #pragma warning (disable : 4100) #endif @@ -51,15 +52,13 @@ #include #include - #ifdef _MSC_VER + #if JUCE_MSVC #pragma warning (pop) #endif #endif #include "../../core/juce_StandardHeader.h" -#if ! (JUCE_MAC && JUCE_64BIT) - BEGIN_JUCE_NAMESPACE #include "juce_QuickTimeAudioFormat.h" @@ -404,4 +403,3 @@ AudioFormatWriter* QuickTimeAudioFormat::createWriterFor (OutputStream* /*stream END_JUCE_NAMESPACE #endif -#endif diff --git a/src/audio/audio_file_formats/oggvorbis/juce_OggVorbisHeader.h b/src/audio/audio_file_formats/oggvorbis/juce_OggVorbisHeader.h index d5cbe9870d..7de1d908fc 100644 --- a/src/audio/audio_file_formats/oggvorbis/juce_OggVorbisHeader.h +++ b/src/audio/audio_file_formats/oggvorbis/juce_OggVorbisHeader.h @@ -27,8 +27,9 @@ // tasks.. +#include "../../../../src/core/juce_TargetPlatform.h" #include "../../../../juce_Config.h" -#ifdef _MSC_VER +#if JUCE_MSVC #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706) #endif diff --git a/src/audio/devices/juce_AudioDeviceManager.cpp b/src/audio/devices/juce_AudioDeviceManager.cpp index 19739b8e4f..4d105a343b 100644 --- a/src/audio/devices/juce_AudioDeviceManager.cpp +++ b/src/audio/devices/juce_AudioDeviceManager.cpp @@ -115,10 +115,10 @@ AudioIODeviceType* juce_createAudioIODeviceType_ALSA(); void AudioDeviceManager::createAudioDeviceTypes (OwnedArray & list) { - #if JUCE_WIN32 + #if JUCE_WINDOWS #if JUCE_WASAPI if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) - list.add (juce_createAudioIODeviceType_WASAPI()); + list.add (juce_createAudioIODeviceType_WASAPI()); #endif #if JUCE_DIRECTSOUND diff --git a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm index 0879c622c3..7cff3a7488 100644 --- a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm +++ b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm @@ -23,6 +23,7 @@ ============================================================================== */ +#include "../../../core/juce_TargetPlatform.h" #include "../../../../juce_Config.h" #if JUCE_PLUGINHOST_AU && (! (defined (LINUX) || defined (_WIN32))) diff --git a/src/audio/plugins/formats/juce_VSTPluginFormat.cpp b/src/audio/plugins/formats/juce_VSTPluginFormat.cpp index 9cdd923058..fecf0a5dd6 100644 --- a/src/audio/plugins/formats/juce_VSTPluginFormat.cpp +++ b/src/audio/plugins/formats/juce_VSTPluginFormat.cpp @@ -23,6 +23,7 @@ ============================================================================== */ +#include "../../../core/juce_TargetPlatform.h" #include "../../../../juce_Config.h" #if JUCE_PLUGINHOST_VST diff --git a/src/core/juce_Atomic.h b/src/core/juce_Atomic.h index 00d0be9c4f..a4d1c7f03e 100644 --- a/src/core/juce_Atomic.h +++ b/src/core/juce_Atomic.h @@ -35,10 +35,11 @@ #if ! MACOS_10_3_OR_EARLIER //============================================================================== - forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); } - forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); } - forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); } - forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); } + #include + static forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); } + static forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); } + static forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); } + static forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); } #else //============================================================================== forcedinline void atomicIncrement (int& variable) throw() { OTAtomicAdd32 (1, (SInt32*) &variable); } diff --git a/src/core/juce_DataConversions.h b/src/core/juce_DataConversions.h index 877b8eb158..5f53fb8417 100644 --- a/src/core/juce_DataConversions.h +++ b/src/core/juce_DataConversions.h @@ -26,8 +26,6 @@ #ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ #define __JUCE_DATACONVERSIONS_JUCEHEADER__ -#include "juce_PlatformDefs.h" - #if JUCE_USE_INTRINSICS #pragma intrinsic (_byteswap_ulong) #endif @@ -35,12 +33,20 @@ //============================================================================== // Endianness conversions.. +#if JUCE_IPHONE +// a gcc compiler error seems to mean that these functions only work properly +// on the iPhone if they are declared static.. +static forcedinline uint32 swapByteOrder (uint32 n) throw(); +static inline uint16 swapByteOrder (const uint16 n) throw(); +static inline uint64 swapByteOrder (const uint64 value) throw(); +#endif + /** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */ forcedinline uint32 swapByteOrder (uint32 n) throw() { #if JUCE_MAC || JUCE_IPHONE // Mac version - return CFSwapInt32 (n); + return OSSwapInt32 (n); #elif JUCE_GCC // Inpenetrable GCC version.. asm("bswap %%eax" : "=a"(n) : "a"(n)); @@ -73,7 +79,7 @@ inline uint16 swapByteOrder (const uint16 n) throw() inline uint64 swapByteOrder (const uint64 value) throw() { #if JUCE_MAC || JUCE_IPHONE - return CFSwapInt64 (value); + return OSSwapInt64 (value); #elif JUCE_USE_INTRINSICS return _byteswap_uint64 (value); #else diff --git a/src/core/juce_MathsFunctions.h b/src/core/juce_MathsFunctions.h index 3c0bd63a49..06561de1b5 100644 --- a/src/core/juce_MathsFunctions.h +++ b/src/core/juce_MathsFunctions.h @@ -207,7 +207,7 @@ inline void swapVariables (Type& variable1, Type& variable2) throw() //============================================================================== // Some useful maths functions that aren't always present with all compilers and build settings. -#if JUCE_WIN32 || defined (DOXYGEN) +#if JUCE_WINDOWS || defined (DOXYGEN) /** Using juce_hypot and juce_hypotf is easier than dealing with all the different versions of these functions of various platforms and compilers. */ forcedinline double juce_hypot (double a, double b) { return _hypot (a, b); } @@ -259,7 +259,7 @@ const float float_Pi = 3.14159265358979323846f; #else #define juce_isfinite(v) std::isfinite(v) #endif -#elif JUCE_WIN32 && ! defined (isfinite) +#elif JUCE_WINDOWS && ! defined (isfinite) #define juce_isfinite(v) _finite(v) #else #define juce_isfinite(v) isfinite(v) diff --git a/src/core/juce_PlatformDefs.h b/src/core/juce_PlatformDefs.h index 32f1a9978a..97714b8d1e 100644 --- a/src/core/juce_PlatformDefs.h +++ b/src/core/juce_PlatformDefs.h @@ -27,130 +27,9 @@ #define __JUCE_PLATFORMDEFS_JUCEHEADER__ //============================================================================== -/* This file figures out which platform is being built, and defines some macros - that the rest of the code can use for OS-specific compilation. - - Macros that will be set here are: - - - One of JUCE_WIN32, JUCE_MAC or JUCE_LINUX. - - Either JUCE_32BIT or JUCE_64BIT, depending on the architecture. - - Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN. - - Either JUCE_INTEL or JUCE_PPC - - Either JUCE_GCC or JUCE_MSVC - - It also includes a set of macros for debug console output and assertions. - +/* This file defines miscellaneous macros for debugging, assertions, etc. */ -//============================================================================== -#if (defined (_WIN32) || defined (_WIN64)) - #define JUCE_WIN32 1 -#else - #if defined (LINUX) || defined (__linux__) - #define JUCE_LINUX 1 - #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - #define JUCE_IPHONE 1 - #else - #define JUCE_MAC 1 - #endif -#endif - -//============================================================================== -#if JUCE_WIN32 - #ifdef _MSC_VER - #ifdef _WIN64 - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - #endif - - #ifdef _DEBUG - #define JUCE_DEBUG 1 - #endif - - /** If defined, this indicates that the processor is little-endian. */ - #define JUCE_LITTLE_ENDIAN 1 - - #define JUCE_INTEL 1 -#endif - -//============================================================================== -#if JUCE_MAC - - #include - - #ifndef NDEBUG - #define JUCE_DEBUG 1 - #endif - - #ifdef __LITTLE_ENDIAN__ - #define JUCE_LITTLE_ENDIAN 1 - #else - #define JUCE_BIG_ENDIAN 1 - #endif - - #if defined (__ppc__) || defined (__ppc64__) - #define JUCE_PPC 1 - #else - #define JUCE_INTEL 1 - #endif - - #ifdef __LP64__ - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - - #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3) - #error "Building for OSX 10.2 is no longer supported!" - #endif - - #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) - #define MACOS_10_3_OR_EARLIER 1 - #endif - - #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - #define MACOS_10_4_OR_EARLIER 1 - #endif -#endif - -//============================================================================== -#if JUCE_IPHONE - #include - - #ifndef NDEBUG - #define JUCE_DEBUG 1 - #endif - - #ifdef __LITTLE_ENDIAN__ - #define JUCE_LITTLE_ENDIAN 1 - #else - #define JUCE_BIG_ENDIAN 1 - #endif -#endif - -//============================================================================== -#if JUCE_LINUX - - #ifdef _DEBUG - #define JUCE_DEBUG 1 - #endif - - // Allow override for big-endian Linux platforms - #ifndef JUCE_BIG_ENDIAN - #define JUCE_LITTLE_ENDIAN 1 - #endif - - #if defined (__LP64__) || defined (_LP64) - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - - #define JUCE_INTEL 1 -#endif - //============================================================================== #ifdef JUCE_FORCE_DEBUG #undef JUCE_DEBUG @@ -160,21 +39,6 @@ #endif #endif -//============================================================================== -// Compiler type macros. - -#ifdef __GNUC__ - #define JUCE_GCC 1 -#elif defined (_MSC_VER) - #define JUCE_MSVC 1 - - #if _MSC_VER >= 1400 - #define JUCE_USE_INTRINSICS 1 - #endif -#else - #error unknown compiler -#endif - /** This macro defines the C calling convention used as the standard for Juce calls. */ #if JUCE_MSVC #define JUCE_CALLTYPE __stdcall @@ -217,7 +81,7 @@ //============================================================================== // Assertions.. - #if JUCE_WIN32 || DOXYGEN + #if JUCE_WINDOWS || DOXYGEN #if JUCE_USE_INTRINSICS #pragma intrinsic (__debugbreak) @@ -241,7 +105,7 @@ #elif JUCE_MAC #define juce_breakDebugger Debugger(); #elif JUCE_IPHONE - #define juce_breakDebugger assert (false); + #define juce_breakDebugger kill (0, SIGTRAP); #elif JUCE_LINUX #define juce_breakDebugger kill (0, SIGTRAP); #endif diff --git a/src/core/juce_PlatformUtilities.h b/src/core/juce_PlatformUtilities.h index d58763c44f..06caddd577 100644 --- a/src/core/juce_PlatformUtilities.h +++ b/src/core/juce_PlatformUtilities.h @@ -76,7 +76,7 @@ public: #endif -#if JUCE_WIN32 || DOXYGEN +#if JUCE_WINDOWS || DOXYGEN //============================================================================== // Some registry helper functions: @@ -155,7 +155,7 @@ public: static void fpuReset(); -#if JUCE_LINUX || JUCE_WIN32 +#if JUCE_LINUX || JUCE_WINDOWS //============================================================================== /** Loads a dynamically-linked library into the process's address space. diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index f15723276b..fd8b11cc07 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -46,6 +46,8 @@ //============================================================================== +#include "juce_TargetPlatform.h" // (sets up the various JUCE_WINDOWS, JUCE_MAC, etc flags) + #include "../../juce_Config.h" //============================================================================== @@ -58,7 +60,6 @@ #endif //============================================================================== -// This sets up the JUCE_WIN32, JUCE_MAC, or JUCE_LINUX macros #include "juce_PlatformDefs.h" // Now we'll include any OS headers we need.. (at this point we are outside the Juce namespace). diff --git a/src/core/juce_SystemStats.cpp b/src/core/juce_SystemStats.cpp index 142674067d..d57898064a 100644 --- a/src/core/juce_SystemStats.cpp +++ b/src/core/juce_SystemStats.cpp @@ -52,7 +52,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() { if (! juceInitialisedNonGUI) { -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE const ScopedAutoReleasePool pool; #endif @@ -84,7 +84,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() } } -#if JUCE_WIN32 +#if JUCE_WINDOWS // This is imported from the sockets code.. typedef int (__stdcall juce_CloseWin32SocketLibCall) (void); extern juce_CloseWin32SocketLibCall* juce_CloseWin32SocketLib; @@ -98,11 +98,11 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI() { if (juceInitialisedNonGUI) { -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE const ScopedAutoReleasePool pool; #endif -#if JUCE_WIN32 +#if JUCE_WINDOWS // need to shut down sockets if they were used.. if (juce_CloseWin32SocketLib != 0) (*juce_CloseWin32SocketLib)(); diff --git a/src/core/juce_TargetPlatform.h b/src/core/juce_TargetPlatform.h new file mode 100644 index 0000000000..ed57c58f7e --- /dev/null +++ b/src/core/juce_TargetPlatform.h @@ -0,0 +1,169 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 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_TARGETPLATFORM_JUCEHEADER__ +#define __JUCE_TARGETPLATFORM_JUCEHEADER__ + +//============================================================================== +/* This file figures out which platform is being built, and defines some macros + that the rest of the code can use for OS-specific compilation. + + Macros that will be set here are: + + - One of JUCE_WINDOWS, JUCE_MAC or JUCE_LINUX. + - Either JUCE_32BIT or JUCE_64BIT, depending on the architecture. + - Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN. + - Either JUCE_INTEL or JUCE_PPC + - Either JUCE_GCC or JUCE_MSVC +*/ + +//============================================================================== +#if (defined (_WIN32) || defined (_WIN64)) + #define JUCE_WIN32 1 + #define JUCE_WINDOWS 1 +#elif defined (LINUX) || defined (__linux__) + #define JUCE_LINUX 1 +#elif defined(__APPLE_CPP__) || defined(__APPLE_CC__) + #include // (needed to find out what platform we're using) + + #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + #define JUCE_IPHONE 1 + #else + #define JUCE_MAC 1 + #endif +#else + #error "Unknown platform!" +#endif + +//============================================================================== +#if JUCE_WINDOWS + #ifdef _MSC_VER + #ifdef _WIN64 + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + #endif + + #ifdef _DEBUG + #define JUCE_DEBUG 1 + #endif + + /** If defined, this indicates that the processor is little-endian. */ + #define JUCE_LITTLE_ENDIAN 1 + + #define JUCE_INTEL 1 +#endif + +//============================================================================== +#if JUCE_MAC + + #ifndef NDEBUG + #define JUCE_DEBUG 1 + #endif + + #ifdef __LITTLE_ENDIAN__ + #define JUCE_LITTLE_ENDIAN 1 + #else + #define JUCE_BIG_ENDIAN 1 + #endif + + #if defined (__ppc__) || defined (__ppc64__) + #define JUCE_PPC 1 + #else + #define JUCE_INTEL 1 + #endif + + #ifdef __LP64__ + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + + #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3) + #error "Building for OSX 10.2 is no longer supported!" + #endif + + #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) + #define MACOS_10_3_OR_EARLIER 1 + #endif + + #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) + #define MACOS_10_4_OR_EARLIER 1 + #endif +#endif + +//============================================================================== +#if JUCE_IPHONE + + #ifndef NDEBUG + #define JUCE_DEBUG 1 + #endif + + #ifdef __LITTLE_ENDIAN__ + #define JUCE_LITTLE_ENDIAN 1 + #else + #define JUCE_BIG_ENDIAN 1 + #endif +#endif + +//============================================================================== +#if JUCE_LINUX + + #ifdef _DEBUG + #define JUCE_DEBUG 1 + #endif + + // Allow override for big-endian Linux platforms + #ifndef JUCE_BIG_ENDIAN + #define JUCE_LITTLE_ENDIAN 1 + #endif + + #if defined (__LP64__) || defined (_LP64) + #define JUCE_64BIT 1 + #else + #define JUCE_32BIT 1 + #endif + + #define JUCE_INTEL 1 +#endif + +//============================================================================== +// Compiler type macros. + +#ifdef __GNUC__ + #define JUCE_GCC 1 +#elif defined (_MSC_VER) + #define JUCE_MSVC 1 + + #if _MSC_VER >= 1400 + #define JUCE_USE_INTRINSICS 1 + #endif +#else + #error unknown compiler +#endif + + +#endif // __JUCE_PLATFORMDEFS_JUCEHEADER__ diff --git a/src/core/juce_Time.cpp b/src/core/juce_Time.cpp index ba232b5eb9..ee57f62f1b 100644 --- a/src/core/juce_Time.cpp +++ b/src/core/juce_Time.cpp @@ -30,7 +30,7 @@ #include "juce_StandardHeader.h" -#ifndef JUCE_WIN32 +#ifndef JUCE_WINDOWS #include #else #include @@ -90,7 +90,7 @@ static void millisToLocal (const int64 millis, struct tm& result) throw() { time_t now = (time_t) (seconds); -#if JUCE_WIN32 +#if JUCE_WINDOWS #ifdef USE_NEW_SECURE_TIME_FNS if (now >= 0 && now <= 0x793406fff) localtime_s (&result, &now); @@ -195,7 +195,7 @@ int64 Time::currentTimeMillis() throw() { // get the time once using normal library calls, and store the difference needed to // turn the millisecond counter into a real time. -#if JUCE_WIN32 +#if JUCE_WINDOWS struct _timeb t; #ifdef USE_NEW_SECURE_TIME_FNS _ftime_s (&t); @@ -446,7 +446,7 @@ const String Time::getTimeZone() const throw() { String zone[2]; -#if JUCE_WIN32 +#if JUCE_WINDOWS _tzset(); #ifdef USE_NEW_SECURE_TIME_FNS diff --git a/src/events/juce_MessageManager.cpp b/src/events/juce_MessageManager.cpp index e4f639e8ab..9cd7ca16a5 100644 --- a/src/events/juce_MessageManager.cpp +++ b/src/events/juce_MessageManager.cpp @@ -129,7 +129,7 @@ void MessageManager::deliverMessage (void* message) } //============================================================================== -#if ! JUCE_MAC +#if ! (JUCE_MAC || JUCE_IPHONE) void MessageManager::runDispatchLoop() { jassert (isThisTheMessageThread()); // must only be called by the message thread diff --git a/src/gui/components/filebrowser/juce_DirectoryContentsList.cpp b/src/gui/components/filebrowser/juce_DirectoryContentsList.cpp index e1df3f7a72..1f568dd388 100644 --- a/src/gui/components/filebrowser/juce_DirectoryContentsList.cpp +++ b/src/gui/components/filebrowser/juce_DirectoryContentsList.cpp @@ -249,7 +249,7 @@ bool DirectoryContentsList::checkNextFile (bool& hasChanged) int DirectoryContentsList::compareElements (const DirectoryContentsList::FileInfo* const first, const DirectoryContentsList::FileInfo* const second) throw() { -#if JUCE_WIN32 +#if JUCE_WINDOWS if (first->isDirectory != second->isDirectory) return first->isDirectory ? -1 : 1; #endif diff --git a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp index 79669843cd..e44045ae40 100644 --- a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp +++ b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp @@ -342,7 +342,7 @@ void FileBrowserComponent::fileDoubleClicked (const File& f) bool FileBrowserComponent::keyPressed (const KeyPress& key) { -#if JUCE_LINUX || JUCE_WIN32 +#if JUCE_LINUX || JUCE_WINDOWS if (key.getModifiers().isCommandDown() && (key.getKeyCode() == 'H' || key.getKeyCode() == 'h')) { @@ -441,7 +441,7 @@ const BitArray FileBrowserComponent::getRoots (StringArray& rootNames, StringArr { BitArray separators; -#if JUCE_WIN32 +#if JUCE_WINDOWS OwnedArray roots; File::findFileSystemRoots (roots); rootPaths.clear(); diff --git a/src/gui/components/filebrowser/juce_FileChooser.cpp b/src/gui/components/filebrowser/juce_FileChooser.cpp index ca318523d0..25a70c8693 100644 --- a/src/gui/components/filebrowser/juce_FileChooser.cpp +++ b/src/gui/components/filebrowser/juce_FileChooser.cpp @@ -113,7 +113,7 @@ bool FileChooser::showDialog (const bool isDirectory, jassert (previewComponent == 0 || (previewComponent->getWidth() > 10 && previewComponent->getHeight() > 10)); -#if JUCE_WIN32 +#if JUCE_WINDOWS if (useNativeDialogBox) #else if (useNativeDialogBox && (previewComponent == 0)) diff --git a/src/gui/components/special/juce_ActiveXControlComponent.h b/src/gui/components/special/juce_ActiveXControlComponent.h index be49ae6849..c7614eec64 100644 --- a/src/gui/components/special/juce_ActiveXControlComponent.h +++ b/src/gui/components/special/juce_ActiveXControlComponent.h @@ -28,7 +28,7 @@ #include "../juce_Component.h" -#if JUCE_WIN32 || DOXYGEN +#if JUCE_WINDOWS || DOXYGEN //============================================================================== /** diff --git a/src/gui/components/special/juce_QuickTimeMovieComponent.h b/src/gui/components/special/juce_QuickTimeMovieComponent.h index 28dc7dacbe..dbb0d6168e 100644 --- a/src/gui/components/special/juce_QuickTimeMovieComponent.h +++ b/src/gui/components/special/juce_QuickTimeMovieComponent.h @@ -31,7 +31,7 @@ // this is used to disable QuickTime, and is defined in juce_Config.h #if JUCE_QUICKTIME || DOXYGEN -#if JUCE_WIN32 +#if JUCE_WINDOWS #include "juce_ActiveXControlComponent.h" typedef ActiveXControlComponent QTCompBaseClass; #else @@ -179,7 +179,7 @@ private: File movieFile; bool movieLoaded, controllerVisible, looping; -#if JUCE_WIN32 +#if JUCE_WINDOWS /** @internal */ void parentHierarchyChanged(); /** @internal */ diff --git a/src/gui/components/special/juce_SystemTrayIconComponent.cpp b/src/gui/components/special/juce_SystemTrayIconComponent.cpp index 0b7a7d0943..837d713543 100644 --- a/src/gui/components/special/juce_SystemTrayIconComponent.cpp +++ b/src/gui/components/special/juce_SystemTrayIconComponent.cpp @@ -25,7 +25,7 @@ #include "../../../core/juce_StandardHeader.h" -#if JUCE_WIN32 || JUCE_LINUX +#if JUCE_WINDOWS || JUCE_LINUX BEGIN_JUCE_NAMESPACE diff --git a/src/gui/components/special/juce_SystemTrayIconComponent.h b/src/gui/components/special/juce_SystemTrayIconComponent.h index 780d124d51..1b065a88e7 100644 --- a/src/gui/components/special/juce_SystemTrayIconComponent.h +++ b/src/gui/components/special/juce_SystemTrayIconComponent.h @@ -26,7 +26,7 @@ #ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ #define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -#if JUCE_WIN32 || JUCE_LINUX || DOXYGEN +#if JUCE_WINDOWS || JUCE_LINUX || DOXYGEN #include "../juce_Component.h" diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index 2166e33620..869a9f5826 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -35,11 +35,11 @@ BEGIN_JUCE_NAMESPACE #include "../geometry/juce_Rectangle.h" #include "../../../core/juce_SystemStats.h" -#if ! (defined (JUCE_MAC) || (defined (JUCE_WIN32) && defined (JUCE_64BIT))) +#if (JUCE_WINDOWS || JUCE_LINUX) && ! JUCE_64BIT #define JUCE_USE_SSE_INSTRUCTIONS 1 #endif -#if defined (JUCE_DEBUG) && JUCE_MSVC +#if JUCE_DEBUG && JUCE_MSVC #pragma warning (disable: 4714) #endif @@ -163,7 +163,7 @@ static void blendRectRGB (uint8* pixels, const int w, int h, const int stride, c if (alpha <= 0) return; -#if defined (JUCE_USE_SSE_INSTRUCTIONS) && ! JUCE_64BIT +#if JUCE_USE_SSE_INSTRUCTIONS if (SystemStats::hasSSE()) { int64 rgb0 = (((int64) blendColour.getRed()) << 32) diff --git a/src/io/files/juce_File.cpp b/src/io/files/juce_File.cpp index 05a60910e4..4dc428a995 100644 --- a/src/io/files/juce_File.cpp +++ b/src/io/files/juce_File.cpp @@ -30,7 +30,7 @@ #include "../../core/juce_StandardHeader.h" -#ifndef JUCE_WIN32 +#if ! JUCE_WINDOWS #include #endif @@ -103,7 +103,7 @@ static const String parseAbsolutePath (String path) throw() if (path.isEmpty()) return String::empty; -#if JUCE_WIN32 +#if JUCE_WINDOWS // Windows.. path = path.replaceCharacter (T('/'), T('\\')); @@ -271,7 +271,7 @@ bool File::hasWriteAccess() const throw() if (exists()) return juce_canWriteToFile (fullPath); -#ifndef JUCE_WIN32 +#if ! JUCE_WINDOWS else if ((! isDirectory()) && fullPath.containsChar (separator)) return getParentDirectory().hasWriteAccess(); else @@ -444,7 +444,7 @@ bool File::isAChildOf (const File& potentialParent) const throw() bool File::isAbsolutePath (const String& path) throw() { return path.startsWithChar (T('/')) || path.startsWithChar (T('\\')) -#if JUCE_WIN32 +#if JUCE_WINDOWS || (path.isNotEmpty() && ((const String&) path)[1] == T(':')); #else || path.startsWithChar (T('~')); @@ -465,7 +465,7 @@ const File File::getChildFile (String relativePath) const throw() if (relativePath[0] == T('.')) { -#if JUCE_WIN32 +#if JUCE_WINDOWS relativePath = relativePath.replaceCharacter (T('/'), T('\\')).trimStart(); #else relativePath = relativePath.replaceCharacter (T('\\'), T('/')).trimStart(); @@ -1100,7 +1100,7 @@ const String File::getRelativePathFrom (const File& dir) const throw() while (dirPath.isNotEmpty()) { -#if JUCE_WIN32 +#if JUCE_WINDOWS thisPath = T("..\\") + thisPath; #else thisPath = T("../") + thisPath; diff --git a/src/io/network/juce_Socket.cpp b/src/io/network/juce_Socket.cpp index cfc0401dd1..b4fe4f3547 100644 --- a/src/io/network/juce_Socket.cpp +++ b/src/io/network/juce_Socket.cpp @@ -23,7 +23,9 @@ ============================================================================== */ -#ifdef _WIN32 +#include "../../core/juce_TargetPlatform.h" + +#if JUCE_WINDOWS #include #ifdef _MSC_VER @@ -31,16 +33,14 @@ #endif #else - #if defined (LINUX) || defined (__linux__) + #if JUCE_LINUX #include #include #include #include #include - #else - #if (MACOSX_DEPLOYMENT_TARGET <= MAC_OS_X_VERSION_10_4) && ! (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) - #include - #endif + #elif (MACOSX_DEPLOYMENT_TARGET <= MAC_OS_X_VERSION_10_4) && ! JUCE_IPHONE + #include #endif #include @@ -65,7 +65,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -#if JUCE_WIN32 +#if JUCE_WINDOWS typedef int (__stdcall juce_CloseWin32SocketLibCall) (void); juce_CloseWin32SocketLibCall* juce_CloseWin32SocketLib = 0; @@ -126,7 +126,7 @@ static int readSocket (const int handle, { int bytesThisTime; -#if JUCE_WIN32 +#if JUCE_WINDOWS bytesThisTime = recv (handle, ((char*) destBuffer) + bytesRead, maxBytesToRead - bytesRead, 0); #else while ((bytesThisTime = ::read (handle, ((char*) destBuffer) + bytesRead, maxBytesToRead - bytesRead)) < 0 @@ -179,7 +179,7 @@ static int waitForReadiness (const int handle, const bool forReading, fd_set* const prset = forReading ? &rset : 0; fd_set* const pwset = forReading ? 0 : &wset; -#if JUCE_WIN32 +#if JUCE_WINDOWS if (select (handle + 1, prset, pwset, 0, timeoutp) < 0) return -1; #else @@ -213,7 +213,7 @@ static int waitForReadiness (const int handle, const bool forReading, static bool setSocketBlockingState (const int handle, const bool shouldBlock) throw() { -#if JUCE_WIN32 +#if JUCE_WINDOWS u_long nonBlocking = shouldBlock ? 0 : 1; if (ioctlsocket (handle, FIONBIO, &nonBlocking) != 0) @@ -279,7 +279,7 @@ static bool connectSocket (int volatile& handle, if (result < 0) { -#if JUCE_WIN32 +#if JUCE_WINDOWS if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EINPROGRESS) @@ -306,7 +306,7 @@ StreamingSocket::StreamingSocket() connected (false), isListener (false) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif } @@ -320,7 +320,7 @@ StreamingSocket::StreamingSocket (const String& hostName_, connected (true), isListener (false) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif @@ -344,7 +344,7 @@ int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite) if (isListener || ! connected) return -1; -#if JUCE_WIN32 +#if JUCE_WINDOWS return send (handle, (const char*) sourceBuffer, numBytesToWrite, 0); #else int result; @@ -403,7 +403,7 @@ bool StreamingSocket::connect (const String& remoteHostName, void StreamingSocket::close() { -#if JUCE_WIN32 +#if JUCE_WINDOWS closesocket (handle); connected = false; #else @@ -497,7 +497,7 @@ DatagramSocket::DatagramSocket (const int localPortNumber, const bool allowBroad allowBroadcast (allowBroadcast_), serverAddress (0) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif @@ -514,7 +514,7 @@ DatagramSocket::DatagramSocket (const String& hostName_, const int portNumber_, allowBroadcast (false), serverAddress (0) { -#if JUCE_WIN32 +#if JUCE_WINDOWS initWin32Sockets(); #endif @@ -532,7 +532,7 @@ DatagramSocket::~DatagramSocket() void DatagramSocket::close() { -#if JUCE_WIN32 +#if JUCE_WINDOWS closesocket (handle); connected = false; #else diff --git a/src/juce_amalgamated_template.cpp b/src/juce_amalgamated_template.cpp index 3fcfb22f22..5b5a7cb8e8 100644 --- a/src/juce_amalgamated_template.cpp +++ b/src/juce_amalgamated_template.cpp @@ -38,17 +38,18 @@ #error #endif +#include "core/juce_TargetPlatform.h" // FORCE_AMALGAMATOR_INCLUDE #include "../juce_Config.h" // FORCE_AMALGAMATOR_INCLUDE //============================================================================== -#ifdef _WIN32 +#if JUCE_WINDOWS #include "native/windows/juce_win32_NativeIncludes.h" -#elif defined (LINUX) +#elif JUCE_LINUX #include "native/linux/juce_linux_NativeIncludes.h" -#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - #include "native/mac/juce_iphone_NativeIncludes.h" -#else +#elif JUCE_MAC || JUCE_IPHONE #include "native/mac/juce_mac_NativeIncludes.h" +#else + #error "Unknown platform!" #endif //============================================================================== @@ -338,7 +339,7 @@ #endif //============================================================================== -#if JUCE_WIN32 +#if JUCE_WINDOWS #include "native/juce_win32_NativeCode.cpp" #endif @@ -346,10 +347,6 @@ #include "native/juce_linux_NativeCode.cpp" #endif -#if JUCE_MAC +#if JUCE_MAC || JUCE_IPHONE #include "native/juce_mac_NativeCode.mm" #endif - -#if JUCE_IPHONE - #include "native/juce_iphone_NativeCode.mm" -#endif diff --git a/src/native/juce_iphone_NativeCode.mm b/src/native/juce_iphone_NativeCode.mm deleted file mode 100644 index 79b1c8ea87..0000000000 --- a/src/native/juce_iphone_NativeCode.mm +++ /dev/null @@ -1,111 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-9 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. - - ============================================================================== -*/ - -/* - This file wraps together all the mac-specific code, so that - we can include all the native headers just once, and compile all our - platform-specific stuff in one big lump, keeping it out of the way of - the rest of the codebase. -*/ - -#include "mac/juce_iphone_NativeIncludes.h" - -BEGIN_JUCE_NAMESPACE - -//============================================================================== -#include "../core/juce_Singleton.h" -#include "../core/juce_Random.h" -#include "../core/juce_SystemStats.h" -#include "../threads/juce_Process.h" -#include "../threads/juce_Thread.h" -#include "../threads/juce_InterProcessLock.h" -#include "../io/files/juce_FileInputStream.h" -#include "../io/files/juce_NamedPipe.h" -#include "../io/network/juce_URL.h" -#include "../core/juce_PlatformUtilities.h" -#include "../text/juce_LocalisedStrings.h" -#include "../utilities/juce_DeletedAtShutdown.h" -#include "../application/juce_Application.h" -#include "../utilities/juce_SystemClipboard.h" -#include "../events/juce_MessageManager.h" -#include "../gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h" -#include "../gui/graphics/imaging/juce_ImageFileFormat.h" -#include "../gui/graphics/imaging/juce_CameraDevice.h" -#include "../gui/components/windows/juce_AlertWindow.h" -#include "../gui/components/juce_Desktop.h" -#include "../gui/components/menus/juce_MenuBarModel.h" -#include "../gui/components/special/juce_OpenGLComponent.h" -#include "../gui/components/special/juce_QuickTimeMovieComponent.h" -#include "../gui/components/mouse/juce_DragAndDropContainer.h" -#include "../gui/components/keyboard/juce_KeyPressMappingSet.h" -#include "../gui/components/special/juce_NSViewComponent.h" -#include "../gui/components/layout/juce_ComponentMovementWatcher.h" -#include "../gui/components/special/juce_WebBrowserComponent.h" -#include "../gui/components/filebrowser/juce_FileChooser.h" -#include "../audio/audio_file_formats/juce_AudioCDBurner.h" -#include "../audio/audio_file_formats/juce_AudioCDReader.h" -#include "../audio/audio_sources/juce_AudioSource.h" -#include "../audio/dsp/juce_AudioDataConverters.h" -#include "../audio/devices/juce_AudioIODeviceType.h" -#include "../audio/devices/juce_MidiOutput.h" -#include "../audio/devices/juce_MidiInput.h" -#undef Point - - -//============================================================================== -#define JUCE_INCLUDED_FILE 1 - -// Now include the actual code files.. - -#include "mac/juce_mac_ObjCSuffix.h" -#include "mac/juce_mac_Strings.mm" -#include "mac/juce_mac_SystemStats.mm" -#include "mac/juce_mac_Network.mm" -#include "common/juce_posix_NamedPipe.cpp" -#include "mac/juce_mac_Threads.mm" -#include "common/juce_posix_SharedCode.h" -#include "mac/juce_mac_Files.mm" -#include "mac/juce_iphone_MiscUtilities.mm" -#include "mac/juce_mac_Debugging.mm" - -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY - /*#include "mac/juce_mac_NSViewComponentPeer.mm" - #include "mac/juce_mac_MouseCursor.mm" - #include "mac/juce_mac_NSViewComponent.mm" - #include "mac/juce_mac_AppleRemote.mm" - #include "mac/juce_mac_OpenGLComponent.mm" - #include "mac/juce_mac_MainMenu.mm" - #include "mac/juce_mac_FileChooser.mm" - #include "mac/juce_mac_QuickTimeMovieComponent.mm" - #include "mac/juce_mac_AudioCDBurner.mm" - #include "mac/juce_mac_Fonts.mm" - #include "mac/juce_mac_MessageManager.mm" - #include "mac/juce_mac_WebBrowserComponent.mm" - #include "mac/juce_mac_CoreAudio.cpp" - #include "mac/juce_mac_CoreMidi.cpp" - #include "mac/juce_mac_CameraDevice.mm"*/ -#endif - -END_JUCE_NAMESPACE diff --git a/src/native/juce_mac_NativeCode.mm b/src/native/juce_mac_NativeCode.mm index 7c3e7a68c7..7f3e7e3583 100644 --- a/src/native/juce_mac_NativeCode.mm +++ b/src/native/juce_mac_NativeCode.mm @@ -86,25 +86,44 @@ BEGIN_JUCE_NAMESPACE #include "mac/juce_mac_Threads.mm" #include "common/juce_posix_SharedCode.h" #include "mac/juce_mac_Files.mm" -#include "mac/juce_mac_MiscUtilities.mm" + +#if JUCE_IPHONE + #include "mac/juce_iphone_MiscUtilities.mm" +#else + #include "mac/juce_mac_MiscUtilities.mm" +#endif + #include "mac/juce_mac_Debugging.mm" #if ! JUCE_ONLY_BUILD_CORE_LIBRARY - #include "mac/juce_mac_NSViewComponentPeer.mm" - #include "mac/juce_mac_MouseCursor.mm" - #include "mac/juce_mac_NSViewComponent.mm" - #include "mac/juce_mac_AppleRemote.mm" - #include "mac/juce_mac_OpenGLComponent.mm" - #include "mac/juce_mac_MainMenu.mm" - #include "mac/juce_mac_FileChooser.mm" - #include "mac/juce_mac_QuickTimeMovieComponent.mm" - #include "mac/juce_mac_AudioCDBurner.mm" - #include "mac/juce_mac_Fonts.mm" - #include "mac/juce_mac_MessageManager.mm" - #include "mac/juce_mac_WebBrowserComponent.mm" - #include "mac/juce_mac_CoreAudio.cpp" - #include "mac/juce_mac_CoreMidi.cpp" - #include "mac/juce_mac_CameraDevice.mm" + #if JUCE_IPHONE + #include "mac/juce_iphone_UIViewComponentPeer.mm" + #include "mac/juce_iphone_Fonts.mm" + #include "mac/juce_iphone_MessageManager.mm" + #include "mac/juce_mac_FileChooser.mm" + #include "mac/juce_mac_OpenGLComponent.mm" + #include "mac/juce_mac_MouseCursor.mm" + #include "mac/juce_mac_WebBrowserComponent.mm" + //#include "mac/juce_mac_CoreAudio.cpp" + //#include "mac/juce_mac_CameraDevice.mm" + #include "mac/juce_mac_CoreMidi.cpp" + #else + #include "mac/juce_mac_NSViewComponentPeer.mm" + #include "mac/juce_mac_MouseCursor.mm" + #include "mac/juce_mac_NSViewComponent.mm" + #include "mac/juce_mac_AppleRemote.mm" + #include "mac/juce_mac_OpenGLComponent.mm" + #include "mac/juce_mac_MainMenu.mm" + #include "mac/juce_mac_FileChooser.mm" + #include "mac/juce_mac_QuickTimeMovieComponent.mm" + #include "mac/juce_mac_AudioCDBurner.mm" + #include "mac/juce_mac_Fonts.mm" + #include "mac/juce_mac_MessageManager.mm" + #include "mac/juce_mac_WebBrowserComponent.mm" + #include "mac/juce_mac_CoreAudio.cpp" + #include "mac/juce_mac_CoreMidi.cpp" + #include "mac/juce_mac_CameraDevice.mm" + #endif #endif END_JUCE_NAMESPACE diff --git a/src/native/mac/juce_iphone_Audio.cpp b/src/native/mac/juce_iphone_Audio.cpp new file mode 100644 index 0000000000..382a622929 --- /dev/null +++ b/src/native/mac/juce_iphone_Audio.cpp @@ -0,0 +1,449 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 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. + + ============================================================================== +*/ + +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#ifdef JUCE_INCLUDED_FILE + + +@interface UIKitAUIOHost : UIViewController +{ +@public + /** READONLY The audio format of the data stream. */ + AudioStreamBasicDescription format; + AURenderCallbackStruct inputProc; + Float64 hwSampleRate; + AudioUnit rioUnit; + UGen rawInput; + UGen postFadeOutput; + UGen preFadeOutput; + int bufferSize; + float *floatBuffer; + UInt32 audioInputIsAvailable; + UInt32 numInputChannels; + UInt32 numOutputChannels; + bool isRunning; + float fadeInTime; + UGenArray others; + NSLock* nsLock; +} + +/** Initialises the AudioUnit framework and structures. + Do not call this method, it is called automatically when the application launches. */ +- (void)initAudio; + +/** Construct a UGen graph. + You must implement this in your subclass. You should return a UGen which will be the UGen graph which is + performed and rendered to the host. The input parameter may be ignored if only signal generation is required + or may be used if a processing algorithm is being implemented (e.g., filtering incoming audio data). + + @param input The input UGen which will contain audio data from the host. + @return the UGen graph which will be performed */ +- (UGen)constructGraph:(UGen)input; + +- (void)addOther:(UGen)ugen; + +- (void)lock; +- (void)unlock; +- (BOOL)tryLock; + +@end + +#define NUM_CHANNELS 2 + +void SetFormat(AudioStreamBasicDescription& format) +{ + memset(&format, 0, sizeof(AudioStreamBasicDescription)); + format.mFormatID = kAudioFormatLinearPCM; + int sampleSize = sizeof(AudioSampleType); + format.mFormatFlags = kAudioFormatFlagsCanonical; + format.mBitsPerChannel = 8 * sampleSize; + format.mChannelsPerFrame = NUM_CHANNELS; + format.mFramesPerPacket = 1; + format.mBytesPerPacket = format.mBytesPerFrame = sampleSize; + format.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; +} + +int SetupRemoteIO (AudioUnit& inRemoteIOUnit, AURenderCallbackStruct inRenderProc, AudioStreamBasicDescription& outFormat) +{ + // Open the output unit + AudioComponentDescription desc; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_RemoteIO; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + AudioComponent comp = AudioComponentFindNext (NULL, &desc); + AudioComponentInstanceNew (comp, &inRemoteIOUnit); + + const UInt32 one = 1; + AudioUnitSetProperty(inRemoteIOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &one, sizeof(one)); + AudioUnitSetProperty(inRemoteIOUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &inRenderProc, sizeof(inRenderProc)); + + AudioUnitSetProperty(inRemoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outFormat, sizeof(outFormat)); + AudioUnitSetProperty(inRemoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &outFormat, sizeof(outFormat)); + + AudioUnitInitialize(inRemoteIOUnit); + + return 0; +} + +static const float FloatToFixed824_Factor = 16777216.f; +static const float Fixed824ToFloat_Factor = 5.960464477539e-08f; + +static const float FloatToPCM16Bit_Factor = 32767.f; +static const float PCM16BitToFloat_Factor = 3.051850947600e-05f; + +static OSStatus PerformThru(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData) +{ + OSStatus err = 0; + UIKitAUIOHost *x = (UIKitAUIOHost *)inRefCon; + + [x lock]; + + if(x->audioInputIsAvailable) + { + err = AudioUnitRender(x->rioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData); + if (err) { printf("PerformThru: error %d\n", (int)err); return err; } + } + + if(inNumberFrames > x->bufferSize) + { + delete [] x->floatBuffer; + x->bufferSize = inNumberFrames; + + x->floatBuffer = new float[inNumberFrames * NUM_CHANNELS]; + } + + long blockID = UGen::getNextBlockID(inNumberFrames); + + float *floatBufferData[2]; + floatBufferData[0] = x->floatBuffer; + floatBufferData[1] = floatBufferData[0] + inNumberFrames; + + if(x->audioInputIsAvailable) + { + for (UInt32 channel = 0; channel < x->numInputChannels; channel++) + { + AudioSampleType *audioUnitBuffer = (AudioSampleType*)ioData->mBuffers[0].mData; + float *floatBuffer = floatBufferData[channel]; + + for(int sample = 0; sample < inNumberFrames; sample++) + { + floatBuffer[sample] = (float)audioUnitBuffer[sample] * PCM16BitToFloat_Factor; + } + } + + x->rawInput.getSource().setInputs((const float**)floatBufferData, inNumberFrames, x->numInputChannels); + } + else + { + memset(x->floatBuffer, 0, x->numInputChannels * inNumberFrames * sizeof(float)); + } + + x->postFadeOutput.setOutputs(floatBufferData, inNumberFrames, 2); + x->postFadeOutput.prepareAndProcessBlock(inNumberFrames, blockID); + + for (UInt32 channel = 0; channel < ioData->mNumberBuffers; channel++) + { + AudioSampleType *audioUnitBuffer = (AudioSampleType*)ioData->mBuffers[channel].mData; + float *floatBuffer = floatBufferData[channel]; + + for(int sample = 0; sample < inNumberFrames; sample++) + { + audioUnitBuffer[sample] = (AudioSampleType)(floatBuffer[sample] * FloatToPCM16Bit_Factor); + } + } + + for(int i = 0; i < x->others.size(); i++) + { + x->others[i].prepareAndProcessBlock(inNumberFrames, blockID); + } + + [x unlock]; + + return err; +} + +void propListener(void * inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void * inPropertyValue) +{ + printf("Property changed!\n"); + + UIKitAUIOHost *x = (UIKitAUIOHost *)inClientData; + + if(!x->isRunning) return; + + if(inPropertyValue) + { + CFDictionaryRef routeChangeDictionary = (CFDictionaryRef)inPropertyValue; + CFNumberRef routeChangeReasonRef = + (CFNumberRef)CFDictionaryGetValue (routeChangeDictionary, + CFSTR (kAudioSession_AudioRouteChangeKey_Reason)); + + SInt32 routeChangeReason; + CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); + + CFStringRef newAudioRoute; + UInt32 propertySize = sizeof (CFStringRef); + AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &newAudioRoute); + + printf("route=%s\n", CFStringGetCStringPtr(newAudioRoute, CFStringGetSystemEncoding())); + + } + + UInt32 size = sizeof(UInt32); + AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &size, &x->numInputChannels); + AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &size, &x->numOutputChannels); + AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &x->audioInputIsAvailable); + + printf("inputs=%d outputs=%d audioInputIsAvailable=%d\n", x->numInputChannels, x->numOutputChannels, x->audioInputIsAvailable); + + if(x->rioUnit) + { + AudioComponentInstanceDispose(x->rioUnit); + } + + SetFormat(x->format); + SetupRemoteIO(x->rioUnit, x->inputProc, x->format); + + x->rawInput.setSource(AudioIn::AR(x->numInputChannels), true); + x->postFadeOutput = Plug::AR(UGen::emptyChannels(x->preFadeOutput.getNumChannels())); + x->postFadeOutput.fadeSourceAndRelease(x->preFadeOutput, x->fadeInTime); + + AudioSessionSetActive(true); + AudioOutputUnitStart(x->rioUnit); +} + +void rioInterruptionListener(void *inClientData, UInt32 inInterruption) +{ + printf("Session interrupted! --- %s ---\n", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); + + UIKitAUIOHost *x = (UIKitAUIOHost *)inClientData; + + if (inInterruption == kAudioSessionEndInterruption) { + // make sure we are again the active session + //AudioSessionSetActive(false); + AudioSessionSetActive(true); + x->isRunning = true; + AudioOutputUnitStart(x->rioUnit); + } + + if (inInterruption == kAudioSessionBeginInterruption) { + x->isRunning = false; + AudioOutputUnitStop(x->rioUnit); + + printf("rioInterruptionListener audioInputIsAvailable=%d\n", x->audioInputIsAvailable); + + UIAlertView *baseAlert = [[UIAlertView alloc] initWithTitle:@"Audio interrupted" + message:@"This could have been interrupted by another application or due to unplugging a headset:" + delegate:x + cancelButtonTitle:nil + otherButtonTitles:@"Resume", @"Cancel", nil]; + [baseAlert show]; + } + +} + +@implementation UIKitAUIOHost + +- (id)init +{ + if (self = [super init]) + { + nsLock = [[NSLock alloc] init]; + fadeInTime = 1.0; + [self performSelector:@selector(initAudio) withObject:nil afterDelay:1.0]; + } + return self; +} + +- (void)initAudio +{ + // render proc + inputProc.inputProc = PerformThru; + inputProc.inputProcRefCon = self; + + // session + AudioSessionInitialize (NULL, NULL, rioInterruptionListener, self); + AudioSessionSetActive (true); + + UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; + AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); + AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self); + + UInt32 size = sizeof(hwSampleRate); + AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &hwSampleRate); + + Float32 bufferDuration = 512 / hwSampleRate; + AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(bufferDuration), &bufferDuration); + + UGen::initialise(); + UGen::prepareToPlay(hwSampleRate, 512); + + rawInput = Plug::AR(UGen::emptyChannels(2)); + preFadeOutput = [self constructGraph: rawInput]; + + rioUnit = NULL; + isRunning = true; + propListener((void*)self, 0,0,0); + + size = sizeof(format); + AudioUnitGetProperty(rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, &size); + + //Float32 bufferDuration; + size = sizeof(bufferDuration); + AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &size, &bufferDuration); + + bufferSize = (int)(hwSampleRate*bufferDuration+0.5); + floatBuffer = new float[bufferSize * NUM_CHANNELS]; +} + +- (UGen)constructGraph:(UGen)input +{ + return UGen::emptyChannels(NUM_CHANNELS); +} + +- (void)addOther:(UGen)ugen +{ + [self lock]; + others <<= ugen; + [self unlock]; +} + +- (void)lock +{ + [nsLock lock]; +} + +- (void)unlock +{ + [nsLock unlock]; +} + +- (BOOL)tryLock +{ + return [nsLock tryLock]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + printf("buttonIndex=%d\n", buttonIndex); + + if(buttonIndex == 0) + { + // resume + isRunning = true; + propListener((void*)self, 0,0,0); + } + + [alertView release]; +} + + +-(void) dealloc +{ + UGen::shutdown(); + delete [] floatBuffer; + [nsLock release]; + [super dealloc]; +} +@end + + +//============================================================================== +class IPhoneAudioIODeviceType : public AudioIODeviceType +{ +public: + //============================================================================== + IPhoneAudioIODeviceType() + : AudioIODeviceType (T("iPhone Audio")), + hasScanned (false) + { + } + + ~IPhoneAudioIODeviceType() + { + } + + //============================================================================== + void scanForDevices() + { + } + + const StringArray getDeviceNames (const bool wantInputNames) const + { + StringArray s; + return s; + } + + int getDefaultDeviceIndex (const bool forInput) const + { + return 0; + } + + int getIndexOfDevice (AudioIODevice* device, const bool asInput) const + { + return 0; + } + + bool hasSeparateInputsAndOutputs() const { return true; } + + AudioIODevice* createDevice (const String& outputDeviceName, + const String& inputDeviceName) + { + if (outputDeviceName.isNotEmpty() && inputDeviceName.isNotEmpty()) + return new CoreAudioIODevice (deviceName, + inputIds [inputIndex], + inputIndex, + outputIds [outputIndex], + outputIndex); + + return 0; + } + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + IPhoneAudioIODeviceType (const IPhoneAudioIODeviceType&); + const IPhoneAudioIODeviceType& operator= (const IPhoneAudioIODeviceType&); +}; + +//============================================================================== +AudioIODeviceType* juce_createAudioIODeviceType_iPhoneAudio() +{ + return new IPhoneAudioIODeviceType(); +} + +#endif diff --git a/src/native/mac/juce_iphone_Fonts.mm b/src/native/mac/juce_iphone_Fonts.mm new file mode 100644 index 0000000000..c734523f19 --- /dev/null +++ b/src/native/mac/juce_iphone_Fonts.mm @@ -0,0 +1,352 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 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. + + ============================================================================== +*/ + +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#ifdef JUCE_INCLUDED_FILE + + +//============================================================================== +class FontHelper +{ + UIFont* font; + +public: + String name; + bool isBold, isItalic, needsItalicTransform; + float fontSize, totalSize, ascent; + int refCount; + + FontHelper (const String& name_, + const bool bold_, + const bool italic_, + const float size_) + : font (0), + name (name_), + isBold (bold_), + isItalic (italic_), + needsItalicTransform (false), + fontSize (size_), + refCount (1) + { + //attributes = [[NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] + // forKey: NSLigatureAttributeName] retain]; + + font = [UIFont fontWithName: juceStringToNS (name_) size: size_]; + + if (italic_) + { +/* NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; + + if (newFont == font) + needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform.. + + font = newFont;*/ + } + +// if (bold_) + // font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; + + [font retain]; + + ascent = fabsf (font.ascender); + totalSize = ascent + fabsf (font.descender); + } + + ~FontHelper() + { + [font release]; + } + + bool getPathAndKerning (const juce_wchar char1, + const juce_wchar char2, + Path* path, + float& kerning, + float* ascent, + float* descent) + { + const ScopedAutoReleasePool pool; + + return false; +/* if (font == 0 + || ! [[font coveredCharacterSet] longCharacterIsMember: (UTF32Char) char1]) + return false; + + String chars; + chars << ' ' << char1 << char2; + + NSTextStorage* textStorage = [[[NSTextStorage alloc] initWithString: juceStringToNS (chars) + attributes: attributes] autorelease]; + NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; + NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; + [layoutManager addTextContainer: textContainer]; + [textStorage addLayoutManager: layoutManager]; + [textStorage setFont: font]; + + unsigned int glyphIndex = [layoutManager glyphRangeForCharacterRange: NSMakeRange (1, 1) + actualCharacterRange: 0].location; + NSPoint p1 = [layoutManager locationForGlyphAtIndex: glyphIndex]; + NSPoint p2 = [layoutManager locationForGlyphAtIndex: glyphIndex + 1]; + kerning = p2.x - p1.x; + + if (ascent != 0) + *ascent = this->ascent; + + if (descent != 0) + *descent = fabsf ([font descender]); + + if (path != 0) + { + NSBezierPath* bez = [NSBezierPath bezierPath]; + [bez moveToPoint: NSMakePoint (0, 0)]; + [bez appendBezierPathWithGlyph: [layoutManager glyphAtIndex: glyphIndex] + inFont: font]; + + for (int i = 0; i < [bez elementCount]; ++i) + { + NSPoint p[3]; + switch ([bez elementAtIndex: i associatedPoints: p]) + { + case NSMoveToBezierPathElement: + path->startNewSubPath (p[0].x, -p[0].y); + break; + case NSLineToBezierPathElement: + path->lineTo (p[0].x, -p[0].y); + break; + case NSCurveToBezierPathElement: + path->cubicTo (p[0].x, -p[0].y, p[1].x, -p[1].y, p[2].x, -p[2].y); + break; + case NSClosePathBezierPathElement: + path->closeSubPath(); + break; + default: + jassertfalse + break; + } + } + + if (needsItalicTransform) + path->applyTransform (AffineTransform::identity.sheared (-0.15, 0)); + } + + return kerning != 0;*/ + } + + juce_wchar getDefaultChar() + { + return 0; + } +}; + +//============================================================================== +class FontHelperCache : public Timer, + public DeletedAtShutdown +{ + VoidArray cache; + +public: + FontHelperCache() + { + } + + ~FontHelperCache() + { + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); + delete f; + } + + clearSingletonInstance(); + } + + FontHelper* getFont (const String& name, + const bool bold, + const bool italic, + const float size = 1024) + { + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); + + if (f->name == name + && f->isBold == bold + && f->isItalic == italic + && f->fontSize == size) + { + f->refCount++; + return f; + } + } + + FontHelper* const f = new FontHelper (name, bold, italic, size); + cache.add (f); + return f; + } + + void releaseFont (FontHelper* f) + { + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f2 = (FontHelper*) cache.getUnchecked(i); + + if (f == f2) + { + f->refCount--; + + if (f->refCount == 0) + startTimer (5000); + + break; + } + } + } + + void timerCallback() + { + stopTimer(); + + for (int i = cache.size(); --i >= 0;) + { + FontHelper* const f = (FontHelper*) cache.getUnchecked(i); + + if (f->refCount == 0) + { + cache.remove (i); + delete f; + } + } + + if (cache.size() == 0) + delete this; + } + + juce_DeclareSingleton_SingleThreaded_Minimal (FontHelperCache) +}; + +juce_ImplementSingleton_SingleThreaded (FontHelperCache) + +//============================================================================== +void Typeface::initialiseTypefaceCharacteristics (const String& fontName, + bool bold, + bool italic, + bool addAllGlyphsToFont) throw() +{ + // This method is only safe to be called from the normal UI thread.. + jassert (MessageManager::getInstance()->isThisTheMessageThread()); + + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (fontName, bold, italic); + + clear(); + setAscent (helper->ascent / helper->totalSize); + setName (fontName); + setDefaultCharacter (helper->getDefaultChar()); + setBold (bold); + setItalic (italic); + + if (addAllGlyphsToFont) + { + //xxx + jassertfalse + } + + FontHelperCache::getInstance()->releaseFont (helper); +} + +bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() +{ + // This method is only safe to be called from the normal UI thread.. + jassert (MessageManager::getInstance()->isThisTheMessageThread()); + + if (character == 0) + return false; + + FontHelper* const helper = FontHelperCache::getInstance() + ->getFont (getName(), isBold(), isItalic()); + + Path path; + float width; + bool foundOne = false; + + if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) + { + path.applyTransform (AffineTransform::scale (1.0f / helper->totalSize, + 1.0f / helper->totalSize)); + + addGlyph (character, path, width / helper->totalSize); + + for (int i = 0; i < glyphs.size(); ++i) + { + const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i); + + float kerning; + if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0)) + { + kerning = (kerning - width) / helper->totalSize; + + if (kerning != 0) + addKerningPair (character, g->getCharacter(), kerning); + } + + if (helper->getPathAndKerning (g->getCharacter(), character, 0, kerning, 0, 0)) + { + kerning = kerning / helper->totalSize - g->width; + + if (kerning != 0) + addKerningPair (g->getCharacter(), character, kerning); + } + } + + foundOne = true; + } + + FontHelperCache::getInstance()->releaseFont (helper); + return foundOne; +} + +//============================================================================== +const StringArray Font::findAllTypefaceNames() throw() +{ + StringArray names; + + const ScopedAutoReleasePool pool; + NSArray* fonts = [UIFont familyNames]; + + for (unsigned int i = 0; i < [fonts count]; ++i) + names.add (nsStringToJuce ((NSString*) [fonts objectAtIndex: i])); + + names.sort (true); + return names; +} + +void Typeface::getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw() +{ + defaultSans = "Lucida Grande"; + defaultSerif = "Times New Roman"; + defaultFixed = "Monaco"; +} + +#endif diff --git a/src/native/mac/juce_iphone_MessageManager.mm b/src/native/mac/juce_iphone_MessageManager.mm new file mode 100644 index 0000000000..af83f0c7fa --- /dev/null +++ b/src/native/mac/juce_iphone_MessageManager.mm @@ -0,0 +1,325 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 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. + + ============================================================================== +*/ + +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#ifdef JUCE_INCLUDED_FILE + +struct CallbackMessagePayload +{ + MessageCallbackFunction* function; + void* parameter; + void* volatile result; + bool volatile hasBeenExecuted; +}; + +/* 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 BOOL openFile (const NSString* filename) + { + if (JUCEApplication::getInstance() != 0) + { + JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); + return YES; + } + + return NO; + } + + virtual void openFiles (NSArray* filenames) + { + StringArray files; + for (unsigned int i = 0; i < [filenames count]; ++i) + files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); + + if (files.size() > 0 && JUCEApplication::getInstance() != 0) + { + JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); + } + } + + virtual void focusChanged() + { + juce_HandleProcessFocusChange(); + } + + virtual void deliverMessage (void* message) + { + // no need for an mm lock here - deliverMessage locks it + MessageManager::getInstance()->deliverMessage (message); + } + + virtual void performCallback (CallbackMessagePayload* pl) + { + pl->result = (*pl->function) (pl->parameter); + pl->hasBeenExecuted = true; + } + + virtual void deleteSelf() + { + delete this; + } +}; + +END_JUCE_NAMESPACE +using namespace JUCE_NAMESPACE; + +#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate) + +static int numPendingMessages = 0; + +@interface JuceAppDelegate : NSObject +{ +@private + id oldDelegate; + AppDelegateRedirector* redirector; + +@public + bool flushingMessages; +} + +- (JuceAppDelegate*) init; +- (void) dealloc; +- (BOOL) application: (UIApplication*) application handleOpenURL: (NSURL*) url; +- (void) applicationDidBecomeActive: (NSNotification*) aNotification; +- (void) applicationDidResignActive: (NSNotification*) aNotification; +- (void) applicationWillUnhide: (NSNotification*) aNotification; +- (void) customEvent: (id) data; +- (void) performCallback: (id) info; +- (void) dummyMethod; +@end + +@implementation JuceAppDelegate + +- (JuceAppDelegate*) init +{ + [super init]; + + redirector = new AppDelegateRedirector(); + numPendingMessages = 0; + flushingMessages = false; + + oldDelegate = [[UIApplication sharedApplication] delegate]; + [[UIApplication sharedApplication] setDelegate: self]; + + return self; +} + +- (void) dealloc +{ + if (oldDelegate != 0) + [[UIApplication sharedApplication] setDelegate: oldDelegate]; + + redirector->deleteSelf(); + [super dealloc]; +} + +- (BOOL) application: (UIApplication*) application handleOpenURL: (NSURL*) url +{ + return redirector->openFile ([url absoluteString]); +} + +- (void) applicationDidBecomeActive: (NSNotification*) aNotification +{ + redirector->focusChanged(); +} + +- (void) applicationDidResignActive: (NSNotification*) aNotification +{ + redirector->focusChanged(); +} + +- (void) applicationWillUnhide: (NSNotification*) aNotification +{ + redirector->focusChanged(); +} + +- (void) customEvent: (id) n +{ + atomicDecrement (numPendingMessages); + + NSData* data = (NSData*) n; + void* message = 0; + [data getBytes: &message length: sizeof (message)]; + [data release]; + + if (message != 0 && ! flushingMessages) + redirector->deliverMessage (message); +} + +- (void) performCallback: (id) info +{ + if ([info isKindOfClass: [NSData class]]) + { + CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; + + if (pl != 0) + redirector->performCallback (pl); + } + else + { + jassertfalse // should never get here! + } +} + +- (void) dummyMethod {} // (used as a way of running a dummy thread) + +@end + +BEGIN_JUCE_NAMESPACE + +static JuceAppDelegate* juceAppDelegate = 0; + +void MessageManager::runDispatchLoop() +{ + jassert (isThisTheMessageThread()); // must only be called by the message thread + + runDispatchLoopUntil (-1); +} + +static const int quitMessageId = 0xfffff321; + +void MessageManager::stopDispatchLoop() +{ + Message* const m = new Message (quitMessageId, 0, 0, 0); + m->messageRecipient = 0; + postMessageToQueue (m); + + quitMessagePosted = true; +} + +bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) +{ + const ScopedAutoReleasePool pool; + jassert (isThisTheMessageThread()); // must only be called by the message thread + + uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor; + NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001]; + + while (! quitMessagePosted) + { + const ScopedAutoReleasePool pool; + + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode + beforeDate: endDate]; + + if (millisecondsToRunFor >= 0 && Time::getMillisecondCounter() >= endTime) + break; + } + + return ! quitMessagePosted; +} + +//============================================================================== +void MessageManager::doPlatformSpecificInitialisation() +{ + if (juceAppDelegate == 0) + juceAppDelegate = [[JuceAppDelegate alloc] init]; +} + +void MessageManager::doPlatformSpecificShutdown() +{ + if (juceAppDelegate != 0) + { + [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate]; + [[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate]; + + // Annoyingly, cancelPerformSelectorsWithTarget can't actually cancel the messages + // sent by performSelectorOnMainThread, so need to manually flush these before quitting.. + juceAppDelegate->flushingMessages = true; + + for (int i = 100; --i >= 0 && numPendingMessages > 0;) + { + const ScopedAutoReleasePool pool; + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode + beforeDate: [NSDate dateWithTimeIntervalSinceNow: 5 * 0.001]]; + } + + [juceAppDelegate release]; + juceAppDelegate = 0; + } +} + +bool juce_postMessageToSystemQueue (void* message) +{ + atomicIncrement (numPendingMessages); + + [juceAppDelegate performSelectorOnMainThread: @selector (customEvent:) + withObject: (id) [[NSData alloc] initWithBytes: &message length: (int) sizeof (message)] + waitUntilDone: NO]; + return true; +} + +void MessageManager::broadcastMessage (const String& value) throw() +{ +} + +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()); + + const ScopedAutoReleasePool pool; + + 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 diff --git a/src/native/mac/juce_iphone_MiscUtilities.mm b/src/native/mac/juce_iphone_MiscUtilities.mm index 0da5e8b18c..1b7cb0204b 100644 --- a/src/native/mac/juce_iphone_MiscUtilities.mm +++ b/src/native/mac/juce_iphone_MiscUtilities.mm @@ -28,6 +28,46 @@ #ifdef JUCE_INCLUDED_FILE +//============================================================================== +static JUCEApplication* juce_intialisingApp; + +END_JUCE_NAMESPACE + +@interface JuceAppStartupDelegate : NSObject +{ +} + +- (void) applicationDidFinishLaunching: (UIApplication*) application; +- (void) applicationWillResignActive: (UIApplication*) application; + +@end + +@implementation JuceAppStartupDelegate + +- (void) applicationDidFinishLaunching: (UIApplication*) application +{ + String dummy; + if (! juce_intialisingApp->initialiseApp (dummy)) + { + // (should quit) + } +} + +- (void) applicationWillResignActive: (UIApplication*) application +{ + JUCEApplication::shutdownAppAndClearUp(); +} + +@end + +BEGIN_JUCE_NAMESPACE + +int juce_IPhoneMain (int argc, char* argv[], JUCEApplication* app) +{ + juce_intialisingApp = app; + return UIApplicationMain (argc, argv, nil, @"JuceAppStartupDelegate"); +} + //============================================================================== ScopedAutoReleasePool::ScopedAutoReleasePool() { diff --git a/src/native/mac/juce_iphone_NativeIncludes.h b/src/native/mac/juce_iphone_NativeIncludes.h deleted file mode 100644 index 481125738f..0000000000 --- a/src/native/mac/juce_iphone_NativeIncludes.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-9 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_MAC_NATIVEINCLUDES_JUCEHEADER__ -#define __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ - -/* - This file wraps together all the mac-specific code, so that - we can include all the native headers just once, and compile all our - platform-specific stuff in one big lump, keeping it out of the way of - the rest of the codebase. -*/ - -#include "../../core/juce_StandardHeader.h" - -#import -#import -#import -#import -#import -#import -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#endif // __JUCE_MAC_NATIVEINCLUDES_JUCEHEADER__ diff --git a/src/native/mac/juce_iphone_UIViewComponentPeer.mm b/src/native/mac/juce_iphone_UIViewComponentPeer.mm new file mode 100644 index 0000000000..593ba27957 --- /dev/null +++ b/src/native/mac/juce_iphone_UIViewComponentPeer.mm @@ -0,0 +1,926 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 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. + + ============================================================================== +*/ + +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#ifdef JUCE_INCLUDED_FILE + +class UIViewComponentPeer; + +//============================================================================== +END_JUCE_NAMESPACE + +#define JuceUIView MakeObjCClassName(JuceUIView) + +@interface JuceUIView : UIView +{ +@public + UIViewComponentPeer* owner; +} + +- (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner withFrame: (CGRect) frame; +- (void) dealloc; + +- (void) drawRect: (CGRect) r; + +- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event; +- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event; +- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event; +- (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event; + +- (BOOL) becomeFirstResponder; +- (BOOL) resignFirstResponder; +- (BOOL) canBecomeFirstResponder; + +@end + +//============================================================================== +#define JuceUIWindow MakeObjCClassName(JuceUIWindow) + +@interface JuceUIWindow : UIWindow +{ +@private + UIViewComponentPeer* owner; + bool isZooming; +} + +- (void) setOwner: (UIViewComponentPeer*) owner; +- (void) becomeKeyWindow; +@end + +BEGIN_JUCE_NAMESPACE + +//============================================================================== +class UIViewComponentPeer : public ComponentPeer +{ +public: + UIViewComponentPeer (Component* const component, + const int windowStyleFlags, + UIView* viewToAttachTo); + + ~UIViewComponentPeer(); + + //============================================================================== + void* getNativeHandle() const; + void setVisible (bool shouldBeVisible); + void setTitle (const String& title); + void setPosition (int x, int y); + void setSize (int w, int h); + void setBounds (int x, int y, int w, int h, const bool isNowFullScreen); + void getBounds (int& x, int& y, int& w, int& h, const bool global) const; + void getBounds (int& x, int& y, int& w, int& h) const; + int getScreenX() const; + int getScreenY() const; + void relativePositionToGlobal (int& x, int& y); + void globalPositionToRelative (int& x, int& y); + void setMinimised (bool shouldBeMinimised); + bool isMinimised() const; + void setFullScreen (bool shouldBeFullScreen); + bool isFullScreen() const; + bool contains (int x, int y, bool trueIfInAChildWindow) const; + const BorderSize getFrameSize() const; + bool setAlwaysOnTop (bool alwaysOnTop); + void toFront (bool makeActiveWindow); + void toBehind (ComponentPeer* other); + void setIcon (const Image& newIcon); + + virtual void drawRect (CGRect r); + + virtual bool canBecomeKeyWindow(); + virtual bool windowShouldClose(); + + virtual void redirectMovedOrResized(); + virtual CGRect constrainRect (CGRect r); + + //============================================================================== + virtual void viewFocusGain(); + virtual void viewFocusLoss(); + bool isFocused() const; + void grabFocus(); + void textInputRequired (int x, int y); + + //============================================================================== + void repaint (int x, int y, int w, int h); + void performAnyPendingRepaintsNow(); + + //============================================================================== + juce_UseDebuggingNewOperator + + UIWindow* window; + JuceUIView* view; + bool isSharedWindow, fullScreen; +}; + +//============================================================================== +END_JUCE_NAMESPACE + +@implementation JuceUIView + +- (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner_ + withFrame: (CGRect) frame +{ + [super initWithFrame: frame]; + owner = owner_; + + return self; +} + +- (void) dealloc +{ + [super dealloc]; +} + +//============================================================================== +- (void) drawRect: (CGRect) r +{ + if (owner != 0) + owner->drawRect (r); +} + +//============================================================================== +bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() +{ + return false; +} + +static int currentModifiers = 0; + +const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() +{ + return ModifierKeys (currentModifiers); +} + +void ModifierKeys::updateCurrentModifiers() throw() +{ + currentModifierFlags = currentModifiers; +} + +static int getModifierForButtonNumber (const int num) throw() +{ + return num == 0 ? ModifierKeys::leftButtonModifier + : (num == 1 ? ModifierKeys::rightButtonModifier + : (num == 2 ? ModifierKeys::middleButtonModifier : 0)); +} + +static int64 getMouseTime (UIEvent* e) { return (int64) [e timestamp] * 1000.0; } + +//============================================================================== +- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event +{ + NSArray* const t = [[event touchesForView: self] allObjects]; + + switch ([t count]) + { + case 1: // One finger.. + { + CGPoint p = [[t objectAtIndex: 0] locationInView: self]; + currentModifiers |= getModifierForButtonNumber (0); + + owner->handleMouseDown (p.x, p.y, getMouseTime (event)); + } + + default: + //xxx multi-touch.. + break; + } +} + +- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event +{ + NSArray* const t = [[event touchesForView: self] allObjects]; + + switch ([t count]) + { + case 1: // One finger.. + { + CGPoint p = [[t objectAtIndex: 0] locationInView: self]; + owner->handleMouseDrag (p.x, p.y, getMouseTime (event)); + } + + default: + //xxx multi-touch.. + break; + } +} + +- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event +{ + NSArray* const t = [[event touchesForView: self] allObjects]; + + switch ([t count]) + { + case 1: // One finger.. + { + CGPoint p = [[t objectAtIndex: 0] locationInView: self]; + const int oldMods = currentModifiers; + currentModifiers &= ~getModifierForButtonNumber (0); + owner->handleMouseUp (oldMods, p.x, p.y, getMouseTime (event)); + } + + default: + //xxx multi-touch.. + break; + } +} + +- (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event +{ + [self touchesEnded: touches withEvent: event]; +} + +//============================================================================== +- (BOOL) becomeFirstResponder +{ + if (owner != 0) + owner->viewFocusGain(); + + return true; +} + +- (BOOL) resignFirstResponder +{ + if (owner != 0) + owner->viewFocusLoss(); + + return true; +} + +- (BOOL) canBecomeFirstResponder +{ + return owner != 0 && owner->canBecomeKeyWindow(); +} + + +@end + +//============================================================================== +@implementation JuceUIWindow + +- (void) setOwner: (UIViewComponentPeer*) owner_ +{ + owner = owner_; + isZooming = false; +} + +- (void) becomeKeyWindow +{ + [super becomeKeyWindow]; + + if (owner != 0) + owner->grabFocus(); +} + +@end + +//============================================================================== +//============================================================================== +BEGIN_JUCE_NAMESPACE + +//============================================================================== +class JuceUIImage +{ +public: + JuceUIImage (const int width, const int height, const bool hasAlpha) + : juceImage (hasAlpha ? Image::ARGB : Image::RGB, + width, height, hasAlpha) + { + lineStride = 0; + pixelStride = 0; + imageData = juceImage.lockPixelDataReadWrite (0, 0, width, height, + lineStride, pixelStride); + + CGDataProviderRef provider = CGDataProviderCreateWithData (0, imageData, lineStride * pixelStride, 0); + + imageRef = CGImageCreate (width, height, + 8, pixelStride * 8, lineStride, + CGColorSpaceCreateDeviceRGB(), + hasAlpha ? (kCGImageAlphaFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault, + provider, + 0, + true, kCGRenderingIntentDefault); + + juceImage.releasePixelDataReadWrite (imageData); + + uiImage = [[UIImage imageWithCGImage: imageRef] retain]; + } + + ~JuceUIImage() + { + [uiImage release]; + CFRelease (imageRef); + } + + Image& getJuceImage() throw() { return juceImage; } + + void draw (const float x, const float y) const + { + [uiImage drawAtPoint: CGPointMake (x, y) + blendMode: kCGBlendModeCopy + alpha: 1.0f]; + } + + void drawUIImage (UIImage* imageToDraw) + { + const ScopedAutoReleasePool pool; + + jassertfalse + /*[NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext: + [NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]]; + + [imageToDraw drawAtPoint: NSZeroPoint + fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height) + operation: NSCompositeSourceOver + fraction: 1.0f]; + + [[NSGraphicsContext currentContext] flushGraphics]; + [NSGraphicsContext restoreGraphicsState]; + + if (juceImage.hasAlphaChannel()) + swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());*/ + + } + +private: + Image juceImage; + CGImageRef imageRef; + CGDataProviderRef provider; + UIImage* uiImage; + uint8* imageData; + int pixelStride, lineStride; + +/* void swapRGBOrder (const int x, const int y, const int w, int h) const + { +#if JUCE_BIG_ENDIAN + jassert (pixelStride == 4); +#endif + jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight()) + .contains (Rectangle (x, y, w, h))); + + uint8* start = imageData + x * pixelStride + y * lineStride; + + while (--h >= 0) + { + uint8* p = start; + start += lineStride; + + for (int i = w; --i >= 0;) + { +#if JUCE_BIG_ENDIAN + const uint8 oldp3 = p[3]; + const uint8 oldp1 = p[1]; + p[3] = p[0]; + p[0] = oldp1; + p[1] = p[2]; + p[2] = oldp3; +#else + const uint8 oldp0 = p[0]; + p[0] = p[2]; + p[2] = oldp0; +#endif + + p += pixelStride; + } + } + }*/ +}; + +//============================================================================== +UIViewComponentPeer::UIViewComponentPeer (Component* const component, + const int windowStyleFlags, + UIView* viewToAttachTo) + : ComponentPeer (component, windowStyleFlags), + window (0), + view (0), + isSharedWindow (viewToAttachTo != 0), + fullScreen (false) +{ + CGRect r; + r.origin.x = 0; + r.origin.y = 0; + r.size.width = (float) component->getWidth(); + r.size.height = (float) component->getHeight(); + + view = [[JuceUIView alloc] initWithOwner: this withFrame: r]; + + if (isSharedWindow) + { + window = [viewToAttachTo window]; + [viewToAttachTo addSubview: view]; + + setVisible (component->isVisible()); + } + else + { + r.origin.x = (float) component->getX(); + r.origin.y = (float) component->getY(); + r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height); + + window = [[JuceUIWindow alloc] init]; + window.frame = r; + [((JuceUIWindow*) window) setOwner: this]; + + if (component->isAlwaysOnTop()) + window.windowLevel = UIWindowLevelAlert; + + [window addSubview: view]; + view.frame = CGRectMake (0, 0, r.size.width, r.size.height); + } + + setTitle (component->getName()); +} + +UIViewComponentPeer::~UIViewComponentPeer() +{ + view->owner = 0; + [view removeFromSuperview]; + [view release]; + + if (! isSharedWindow) + { + [((JuceUIWindow*) window) setOwner: 0]; + [window release]; + } +} + +//============================================================================== +void* UIViewComponentPeer::getNativeHandle() const +{ + return view; +} + +void UIViewComponentPeer::setVisible (bool shouldBeVisible) +{ + view.hidden = ! shouldBeVisible; +} + +void UIViewComponentPeer::setTitle (const String& title) +{ + // xxx is this possible? +} + +void UIViewComponentPeer::setPosition (int x, int y) +{ + setBounds (x, y, component->getWidth(), component->getHeight(), false); +} + +void UIViewComponentPeer::setSize (int w, int h) +{ + setBounds (component->getX(), component->getY(), w, h, false); +} + +void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNowFullScreen) +{ + fullScreen = isNowFullScreen; + w = jmax (0, w); + h = jmax (0, h); + + CGRect r; + r.origin.x = (float) x; + r.origin.y = (float) y; + r.size.width = (float) w; + r.size.height = (float) h; + + if (isSharedWindow) + { + //r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); + + if ([view frame].size.width != r.size.width + || [view frame].size.height != r.size.height) + [view setNeedsDisplay]; + + view.frame = r; + } + else + { + //r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height); + + window.frame = r; + view.frame = CGRectMake (0, 0, r.size.width, r.size.height); + } +} + +void UIViewComponentPeer::getBounds (int& x, int& y, int& w, int& h, const bool global) const +{ + CGRect r = [view frame]; + + if (global && [view window] != 0) + { + r = [view convertRect: r toView: nil]; + CGRect wr = [[view window] frame]; + r.origin.x += wr.origin.x; + r.origin.y += wr.origin.y; + + y = (int) ([[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height); + } + else + { + y = (int) ([[view superview] frame].size.height - r.origin.y - r.size.height); + } + + x = (int) r.origin.x; + w = (int) r.size.width; + h = (int) r.size.height; +} + +void UIViewComponentPeer::getBounds (int& x, int& y, int& w, int& h) const +{ + getBounds (x, y, w, h, ! isSharedWindow); +} + +int UIViewComponentPeer::getScreenX() const +{ + int x, y, w, h; + getBounds (x, y, w, h, true); + return x; +} + +int UIViewComponentPeer::getScreenY() const +{ + int x, y, w, h; + getBounds (x, y, w, h, true); + return y; +} + +void UIViewComponentPeer::relativePositionToGlobal (int& x, int& y) +{ + int wx, wy, ww, wh; + getBounds (wx, wy, ww, wh, true); + x += wx; + y += wy; +} + +void UIViewComponentPeer::globalPositionToRelative (int& x, int& y) +{ + int wx, wy, ww, wh; + getBounds (wx, wy, ww, wh, true); + x -= wx; + y -= wy; +} + +CGRect UIViewComponentPeer::constrainRect (CGRect r) +{ + if (constrainer != 0) + { + CGRect current = [window frame]; + current.origin.y = [[UIScreen mainScreen] bounds].size.height - current.origin.y - current.size.height; + + r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height; + + int x = (int) r.origin.x; + int y = (int) r.origin.y; + int w = (int) r.size.width; + int h = (int) r.size.height; + + Rectangle original ((int) current.origin.x, (int) current.origin.y, + (int) current.size.width, (int) current.size.height); + + constrainer->checkBounds (x, y, w, h, + original, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + y != original.getY() && y + h == original.getBottom(), + x != original.getX() && x + w == original.getRight(), + y == original.getY() && y + h != original.getBottom(), + x == original.getX() && x + w != original.getRight()); + + r.origin.x = x; + r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.size.height - y; + r.size.width = w; + r.size.height = h; + } + + return r; +} + +void UIViewComponentPeer::setMinimised (bool shouldBeMinimised) +{ + // xxx +} + +bool UIViewComponentPeer::isMinimised() const +{ + return false; +} + +void UIViewComponentPeer::setFullScreen (bool shouldBeFullScreen) +{ + if (! isSharedWindow) + { + Rectangle r (lastNonFullscreenBounds); + + setMinimised (false); + + if (fullScreen != shouldBeFullScreen) + { + if (shouldBeFullScreen) + r = Desktop::getInstance().getMainMonitorArea(); + + // (can't call the component's setBounds method because that'll reset our fullscreen flag) + if (r != getComponent()->getBounds() && ! r.isEmpty()) + setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen); + } + } +} + +bool UIViewComponentPeer::isFullScreen() const +{ + return fullScreen; +} + +bool UIViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const +{ + if (((unsigned int) x) >= (unsigned int) component->getWidth() + || ((unsigned int) y) >= (unsigned int) component->getHeight()) + return false; + + CGPoint p; + p.x = (float) x; + p.y = (float) y; + + UIView* v = [view hitTest: p withEvent: nil]; + + if (trueIfInAChildWindow) + return v != nil; + + return v == view; +} + +const BorderSize UIViewComponentPeer::getFrameSize() const +{ + BorderSize b; + + if (! isSharedWindow) + { + CGRect v = [view convertRect: [view frame] toView: nil]; + CGRect w = [window frame]; + + b.setTop ((int) (w.size.height - (v.origin.y + v.size.height))); + b.setBottom ((int) v.origin.y); + b.setLeft ((int) v.origin.x); + b.setRight ((int) (w.size.width - (v.origin.x + v.size.width))); + } + + return b; +} + +bool UIViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) +{ + if (! isSharedWindow) + window.windowLevel = alwaysOnTop ? UIWindowLevelAlert : UIWindowLevelNormal; + + return true; +} + +void UIViewComponentPeer::toFront (bool makeActiveWindow) +{ + if (isSharedWindow) + [[view superview] bringSubviewToFront: view]; + + if (window != 0 && component->isVisible()) + [window makeKeyAndVisible]; +} + +void UIViewComponentPeer::toBehind (ComponentPeer* other) +{ + UIViewComponentPeer* o = (UIViewComponentPeer*) other; + + if (isSharedWindow) + { + [[view superview] insertSubview: view belowSubview: o->view]; + } + else + { + jassertfalse // don't know how to do this + } +} + +void UIViewComponentPeer::setIcon (const Image& /*newIcon*/) +{ + // to do.. +} + +//============================================================================== +static UIViewComponentPeer* currentlyFocusedPeer = 0; + +void UIViewComponentPeer::viewFocusGain() +{ + if (currentlyFocusedPeer != this) + { + if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) + currentlyFocusedPeer->handleFocusLoss(); + + currentlyFocusedPeer = this; + + handleFocusGain(); + } +} + +void UIViewComponentPeer::viewFocusLoss() +{ + if (currentlyFocusedPeer == this) + { + currentlyFocusedPeer = 0; + handleFocusLoss(); + } +} + +void juce_HandleProcessFocusChange() +{ + if (UIViewComponentPeer::isValidPeer (currentlyFocusedPeer)) + { + if (Process::isForegroundProcess()) + { + currentlyFocusedPeer->handleFocusGain(); + + ComponentPeer::bringModalComponentToFront(); + } + else + { + currentlyFocusedPeer->handleFocusLoss(); + + // turn kiosk mode off if we lose focus.. + Desktop::getInstance().setKioskModeComponent (0); + } + } +} + +bool UIViewComponentPeer::isFocused() const +{ + return isSharedWindow ? this == currentlyFocusedPeer + : (window != 0 && [window isKeyWindow]); +} + +void UIViewComponentPeer::grabFocus() +{ + if (window != 0) + { + [window makeKeyWindow]; + viewFocusGain(); + } +} + +void UIViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) +{ +} + + +//============================================================================== +void UIViewComponentPeer::drawRect (CGRect r) +{ + if (r.size.width < 1.0f || r.size.height < 1.0f) + return; + + DBG (Rectangle (r.origin.x, r.origin.y, r.size.width, r.size.height).toString()); + + const float y = r.origin.y;//[view frame].size.height - (r.origin.y + r.size.height); + + JuceUIImage temp ((int) (r.size.width + 0.5f), + (int) (r.size.height + 0.5f), + true);//! getComponent()->isOpaque()); + + LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage()); + const int originX = -roundFloatToInt (r.origin.x); + const int originY = -roundFloatToInt (y); + context.setOrigin (originX, originY); + + handlePaint (context); + + //CGContextClipToRect (UIGraphicsGetCurrentContext(), r); + temp.draw (r.origin.x, r.origin.y); +} + +bool UIViewComponentPeer::canBecomeKeyWindow() +{ + return (getStyleFlags() & juce::ComponentPeer::windowIgnoresKeyPresses) == 0; +} + +bool UIViewComponentPeer::windowShouldClose() +{ + if (! isValidPeer (this)) + return YES; + + handleUserClosingWindow(); + return NO; +} + +void UIViewComponentPeer::redirectMovedOrResized() +{ + handleMovedOrResized(); +} + +//============================================================================== +void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) +{ +} + +//============================================================================== +void UIViewComponentPeer::repaint (int x, int y, int w, int h) +{ + [view setNeedsDisplayInRect: + CGRectMake ((float) x, (float) y,//([view frame].size.height - (y + h)), + (float) w, (float) h)]; +} + +void UIViewComponentPeer::performAnyPendingRepaintsNow() +{ +} + +ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) +{ + return new UIViewComponentPeer (this, styleFlags, (UIView*) windowToAttachTo); +} + +//============================================================================== +static Image* UIImageToJuceImage (UIImage* image) +{ + JuceUIImage juceIm ((int) [image size].width, + (int) [image size].height, + true); + + juceIm.drawUIImage (image); + return juceIm.getJuceImage().createCopy(); +} + +Image* juce_createIconForFile (const File& file) +{ + return 0; +} + +//============================================================================== +const int KeyPress::spaceKey = ' '; +const int KeyPress::returnKey = 0x0d; +const int KeyPress::escapeKey = 0x1b; +const int KeyPress::backspaceKey = 0x7f; +const int KeyPress::leftKey = 0x1000; +const int KeyPress::rightKey = 0x1001; +const int KeyPress::upKey = 0x1002; +const int KeyPress::downKey = 0x1003; +const int KeyPress::pageUpKey = 0x1004; +const int KeyPress::pageDownKey = 0x1005; +const int KeyPress::endKey = 0x1006; +const int KeyPress::homeKey = 0x1007; +const int KeyPress::deleteKey = 0x1008; +const int KeyPress::insertKey = -1; +const int KeyPress::tabKey = 9; +const int KeyPress::F1Key = 0x2001; +const int KeyPress::F2Key = 0x2002; +const int KeyPress::F3Key = 0x2003; +const int KeyPress::F4Key = 0x2004; +const int KeyPress::F5Key = 0x2005; +const int KeyPress::F6Key = 0x2006; +const int KeyPress::F7Key = 0x2007; +const int KeyPress::F8Key = 0x2008; +const int KeyPress::F9Key = 0x2009; +const int KeyPress::F10Key = 0x200a; +const int KeyPress::F11Key = 0x200b; +const int KeyPress::F12Key = 0x200c; +const int KeyPress::F13Key = 0x200d; +const int KeyPress::F14Key = 0x200e; +const int KeyPress::F15Key = 0x200f; +const int KeyPress::F16Key = 0x2010; +const int KeyPress::numberPad0 = 0x30020; +const int KeyPress::numberPad1 = 0x30021; +const int KeyPress::numberPad2 = 0x30022; +const int KeyPress::numberPad3 = 0x30023; +const int KeyPress::numberPad4 = 0x30024; +const int KeyPress::numberPad5 = 0x30025; +const int KeyPress::numberPad6 = 0x30026; +const int KeyPress::numberPad7 = 0x30027; +const int KeyPress::numberPad8 = 0x30028; +const int KeyPress::numberPad9 = 0x30029; +const int KeyPress::numberPadAdd = 0x3002a; +const int KeyPress::numberPadSubtract = 0x3002b; +const int KeyPress::numberPadMultiply = 0x3002c; +const int KeyPress::numberPadDivide = 0x3002d; +const int KeyPress::numberPadSeparator = 0x3002e; +const int KeyPress::numberPadDecimalPoint = 0x3002f; +const int KeyPress::numberPadEquals = 0x30030; +const int KeyPress::numberPadDelete = 0x30031; +const int KeyPress::playKey = 0x30000; +const int KeyPress::stopKey = 0x30001; +const int KeyPress::fastForwardKey = 0x30002; +const int KeyPress::rewindKey = 0x30003; + +#endif diff --git a/src/native/mac/juce_mac_CameraDevice.mm b/src/native/mac/juce_mac_CameraDevice.mm index 5dd8a9be7a..628448ff44 100644 --- a/src/native/mac/juce_mac_CameraDevice.mm +++ b/src/native/mac/juce_mac_CameraDevice.mm @@ -27,7 +27,6 @@ // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_QUICKTIME && JUCE_USE_CAMERA - //============================================================================== #define QTCaptureCallbackDelegate MakeObjCClassName(QTCaptureCallbackDelegate) @@ -399,5 +398,4 @@ CameraDevice* CameraDevice::openDevice (int index, return 0; } - #endif diff --git a/src/native/mac/juce_mac_CoreMidi.cpp b/src/native/mac/juce_mac_CoreMidi.cpp index 311325f6b8..a7a68ebd29 100644 --- a/src/native/mac/juce_mac_CoreMidi.cpp +++ b/src/native/mac/juce_mac_CoreMidi.cpp @@ -27,6 +27,8 @@ // compiled on its own). #ifdef JUCE_INCLUDED_FILE +#if JUCE_MAC + //============================================================================== #undef log #define log(a) Logger::writeToLog(a) @@ -586,4 +588,50 @@ void MidiInput::stop() #undef log +#else + +MidiOutput::~MidiOutput() +{ +} + +void MidiOutput::reset() +{ +} + +bool MidiOutput::getVolume (float& leftVol, float& rightVol) +{ + return false; +} + +void MidiOutput::setVolume (float leftVol, float rightVol) +{ +} + +void MidiOutput::sendMessageNow (const MidiMessage& message) +{ +} + +const StringArray MidiOutput::getDevices() +{ + return StringArray(); +} + +MidiOutput* MidiOutput::openDevice (int index) +{ + return 0; +} + +const StringArray MidiInput::getDevices() +{ + return StringArray(); +} + +MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) +{ + return 0; +} + + +#endif + #endif diff --git a/src/native/mac/juce_mac_FileChooser.mm b/src/native/mac/juce_mac_FileChooser.mm index d22f6668ee..d4de6b4db6 100644 --- a/src/native/mac/juce_mac_FileChooser.mm +++ b/src/native/mac/juce_mac_FileChooser.mm @@ -27,6 +27,8 @@ // compiled on its own). #ifdef JUCE_INCLUDED_FILE +#if JUCE_MAC + //============================================================================== END_JUCE_NAMESPACE using namespace JUCE_NAMESPACE; @@ -147,4 +149,24 @@ void FileChooser::showPlatformDialog (OwnedArray& results, [panel setDelegate: nil]; } +#else + +//============================================================================== +void FileChooser::showPlatformDialog (OwnedArray& results, + const String& title, + const File& currentFileOrDirectory, + const String& filter, + bool selectsDirectory, + bool isSaveDialogue, + bool warnAboutOverwritingExistingFiles, + bool selectMultipleFiles, + FilePreviewComponent* extraInfoComponent) +{ + const ScopedAutoReleasePool pool; + + jassertfalse //xxx to do +} + +#endif + #endif diff --git a/src/native/mac/juce_mac_Files.mm b/src/native/mac/juce_mac_Files.mm index c60aed8bdc..606ac878e7 100644 --- a/src/native/mac/juce_mac_Files.mm +++ b/src/native/mac/juce_mac_Files.mm @@ -295,8 +295,13 @@ const String File::getVersion() const throw() //============================================================================== const File File::getLinkedTarget() const throw() { +#if JUCE_IPHONE || (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) NSString* dest = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath: juceStringToNS (getFullPathName()) error: nil]; +#else + NSString* dest = [[NSFileManager defaultManager] pathContentOfSymbolicLinkAtPath: juceStringToNS (getFullPathName())]; +#endif + if (dest != nil) return File (nsStringToJuce (dest)); @@ -332,31 +337,6 @@ struct FindFileStruct String parentDir; }; -void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile, - bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, - Time* creationTime, bool* isReadOnly) throw() -{ - NSDirectoryEnumerator* e = [[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory)]; - - if (e != 0) - { - FindFileStruct* ff = new FindFileStruct(); - ff->enumerator = [e retain]; - ff->parentDir = directory; - - if (! ff->parentDir.endsWithChar (File::separator)) - ff->parentDir += File::separator; - - if (juce_findFileNext (ff, firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly)) - return ff; - - [e release]; - delete ff; - } - - return 0; -} - bool juce_findFileNext (void* handle, String& resultFile, bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw() { @@ -404,6 +384,31 @@ bool juce_findFileNext (void* handle, String& resultFile, return true; } +void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile, + bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, + Time* creationTime, bool* isReadOnly) throw() +{ + NSDirectoryEnumerator* e = [[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory)]; + + if (e != 0) + { + FindFileStruct* ff = new FindFileStruct(); + ff->enumerator = [e retain]; + ff->parentDir = directory; + + if (! ff->parentDir.endsWithChar (File::separator)) + ff->parentDir += File::separator; + + if (juce_findFileNext (ff, firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly)) + return ff; + + [e release]; + delete ff; + } + + return 0; +} + void juce_findFileClose (void* handle) throw() { FindFileStruct* ff = (FindFileStruct*) handle; @@ -437,7 +442,7 @@ bool juce_launchFile (const String& fileName, const String& parameters) throw() { #if JUCE_IPHONE - return false; // is this possible? + return [[UIApplication sharedApplication] openURL: [NSURL fileURLWithPath: juceStringToNS (fileName)]]; #else const ScopedAutoReleasePool pool; @@ -502,7 +507,12 @@ const String PlatformUtilities::makePathFromFSRef (FSRef* file) OSType PlatformUtilities::getTypeOfFile (const String& filename) { const ScopedAutoReleasePool pool; + +#if JUCE_IPHONE || (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + NSDictionary* fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath: juceStringToNS (filename) error: nil]; +#else NSDictionary* fileDict = [[NSFileManager defaultManager] fileAttributesAtPath: juceStringToNS (filename) traverseLink: NO]; +#endif return (OSType) [fileDict objectForKey: NSFileHFSTypeCode]; } diff --git a/src/native/mac/juce_mac_MouseCursor.mm b/src/native/mac/juce_mac_MouseCursor.mm index b9e91279a3..108efac618 100644 --- a/src/native/mac/juce_mac_MouseCursor.mm +++ b/src/native/mac/juce_mac_MouseCursor.mm @@ -27,6 +27,8 @@ // compiled on its own). #ifdef JUCE_INCLUDED_FILE +#if JUCE_MAC + //============================================================================== static NSImage* juceImageToNSImage (const Image& image) { @@ -187,4 +189,14 @@ void MouseCursor::showInWindow (ComponentPeer*) const throw() [c set]; } +#else + +void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw() { return 0; } +void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw() { return 0; } +void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw() {} +void MouseCursor::showInAllWindows() const throw() {} +void MouseCursor::showInWindow (ComponentPeer*) const throw() {} + +#endif + #endif diff --git a/src/native/mac/juce_mac_NativeIncludes.h b/src/native/mac/juce_mac_NativeIncludes.h index 381f4a6982..340dcf66b4 100644 --- a/src/native/mac/juce_mac_NativeIncludes.h +++ b/src/native/mac/juce_mac_NativeIncludes.h @@ -35,22 +35,33 @@ #include "../../core/juce_StandardHeader.h" -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import +#if JUCE_IPHONE + #import + #import + #import + #import + #import + #import + #include +#else + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #include + #include +#endif #include #include -#include #include #include #include diff --git a/src/native/mac/juce_mac_OpenGLComponent.mm b/src/native/mac/juce_mac_OpenGLComponent.mm index 108423922c..8e22c62105 100644 --- a/src/native/mac/juce_mac_OpenGLComponent.mm +++ b/src/native/mac/juce_mac_OpenGLComponent.mm @@ -27,6 +27,8 @@ // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_OPENGL +#if JUCE_MAC + END_JUCE_NAMESPACE #define ThreadSafeNSOpenGLView MakeObjCClassName(ThreadSafeNSOpenGLView) @@ -315,4 +317,21 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/, //jassertfalse //xxx can't see how you do this in cocoa! } +#else +//============================================================================== + +OpenGLContext* OpenGLContext::createContextForWindow (Component* const component, + const OpenGLPixelFormat& pixelFormat, + const OpenGLContext* const contextToShareWith) +{ + return 0; +} + +void juce_glViewport (const int w, const int h) +{ + //glViewport (0, 0, w, h); +} + +#endif + #endif diff --git a/src/native/mac/juce_mac_Strings.mm b/src/native/mac/juce_mac_Strings.mm index cd11998e44..8114cd3162 100644 --- a/src/native/mac/juce_mac_Strings.mm +++ b/src/native/mac/juce_mac_Strings.mm @@ -170,7 +170,7 @@ void SystemClipboard::copyTextToClipboard (const String& text) throw() { #if JUCE_IPHONE [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text) - forPasteboardType: (NSString*) kUTTypePlainText]; + forPasteboardType: @"public.text"]; #else [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: nil]; @@ -183,7 +183,7 @@ void SystemClipboard::copyTextToClipboard (const String& text) throw() const String SystemClipboard::getTextFromClipboard() throw() { #if JUCE_IPHONE - NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: (NSString*) kUTTypePlainText]; + NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"]; #else NSString* text = [[NSPasteboard generalPasteboard] stringForType: NSStringPboardType]; #endif diff --git a/src/native/mac/juce_mac_WebBrowserComponent.mm b/src/native/mac/juce_mac_WebBrowserComponent.mm index 66119716f0..a1d2ebaeab 100644 --- a/src/native/mac/juce_mac_WebBrowserComponent.mm +++ b/src/native/mac/juce_mac_WebBrowserComponent.mm @@ -27,6 +27,8 @@ // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER +#if JUCE_MAC + //============================================================================== END_JUCE_NAMESPACE @@ -266,4 +268,70 @@ bool WebBrowserComponent::pageAboutToLoad (const String& url) return true; } +#else + +//============================================================================== +WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) +{ +} + +WebBrowserComponent::~WebBrowserComponent() +{ +} + +//============================================================================== +void WebBrowserComponent::goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) +{ +} + +void WebBrowserComponent::stop() +{ +} + +void WebBrowserComponent::goBack() +{ +} + +void WebBrowserComponent::goForward() +{ +} + +void WebBrowserComponent::refresh() +{ +} + +//============================================================================== +void WebBrowserComponent::paint (Graphics& g) +{ +} + +void WebBrowserComponent::checkWindowAssociation() +{ +} + +void WebBrowserComponent::reloadLastURL() +{ +} + +void WebBrowserComponent::parentHierarchyChanged() +{ +} + +void WebBrowserComponent::resized() +{ +} + +void WebBrowserComponent::visibilityChanged() +{ +} + +bool WebBrowserComponent::pageAboutToLoad (const String& url) +{ + return true; +} + +#endif + #endif diff --git a/src/native/windows/juce_win32_NativeIncludes.h b/src/native/windows/juce_win32_NativeIncludes.h index 4c43ee53d8..eb6be77d67 100644 --- a/src/native/windows/juce_win32_NativeIncludes.h +++ b/src/native/windows/juce_win32_NativeIncludes.h @@ -28,6 +28,7 @@ #define __JUCE_WIN32_NATIVEINCLUDES_JUCEHEADER__ +#include "../../core/juce_TargetPlatform.h" #include "../../../juce_Config.h" #ifndef STRICT