From 2343dcdceeeb13cb0f0d39ed24e9be50b1a1e007 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Mon, 11 Jan 2010 22:25:43 +0000 Subject: [PATCH] Added Linux contributions for headless messaging, clipboard and better shm support. --- build/linux/JUCE.make | 478 +++++++------ juce_amalgamated.cpp | 751 ++++++++++++++------ src/native/juce_linux_NativeCode.cpp | 2 + src/native/linux/juce_linux_Clipboard.cpp | 266 +++++++ src/native/linux/juce_linux_FileChooser.cpp | 56 ++ src/native/linux/juce_linux_Messaging.cpp | 335 +++++---- src/native/linux/juce_linux_Windowing.cpp | 108 +-- src/native/mac/juce_mac_CameraDevice.mm | 18 +- 8 files changed, 1344 insertions(+), 670 deletions(-) create mode 100644 src/native/linux/juce_linux_Clipboard.cpp diff --git a/build/linux/JUCE.make b/build/linux/JUCE.make index f1ec774ae4..deafdb9500 100644 --- a/build/linux/JUCE.make +++ b/build/linux/JUCE.make @@ -41,68 +41,69 @@ endif OBJECTS := \ $(OBJDIR)/juce_FileLogger.o \ $(OBJDIR)/juce_PerformanceCounter.o \ + $(OBJDIR)/juce_Time.o \ $(OBJDIR)/juce_Random.o \ $(OBJDIR)/juce_RelativeTime.o \ - $(OBJDIR)/juce_Time.o \ - $(OBJDIR)/juce_Uuid.o \ $(OBJDIR)/juce_SystemStats.o \ + $(OBJDIR)/juce_Uuid.o \ $(OBJDIR)/juce_Logger.o \ $(OBJDIR)/juce_BlowFish.o \ $(OBJDIR)/juce_Primes.o \ $(OBJDIR)/juce_RSAKey.o \ $(OBJDIR)/juce_MD5.o \ - $(OBJDIR)/juce_ValueTree.o \ $(OBJDIR)/juce_PropertySet.o \ + $(OBJDIR)/juce_Variant.o \ $(OBJDIR)/juce_BitArray.o \ $(OBJDIR)/juce_MemoryBlock.o \ - $(OBJDIR)/juce_Variant.o \ + $(OBJDIR)/juce_ValueTree.o \ + $(OBJDIR)/juce_Value.o \ $(OBJDIR)/juce_FileInputStream.o \ $(OBJDIR)/juce_File.o \ - $(OBJDIR)/juce_FileOutputStream.o \ $(OBJDIR)/juce_FileSearchPath.o \ $(OBJDIR)/juce_NamedPipe.o \ - $(OBJDIR)/juce_ZipFile.o \ + $(OBJDIR)/juce_FileOutputStream.o \ $(OBJDIR)/juce_DirectoryIterator.o \ + $(OBJDIR)/juce_ZipFile.o \ $(OBJDIR)/juce_Socket.o \ $(OBJDIR)/juce_URL.o \ - $(OBJDIR)/juce_FileInputSource.o \ - $(OBJDIR)/juce_OutputStream.o \ $(OBJDIR)/juce_MemoryInputStream.o \ - $(OBJDIR)/juce_MemoryOutputStream.o \ - $(OBJDIR)/juce_SubregionStream.o \ $(OBJDIR)/juce_InputStream.o \ - $(OBJDIR)/juce_GZIPCompressorOutputStream.o \ + $(OBJDIR)/juce_FileInputSource.o \ + $(OBJDIR)/juce_MemoryOutputStream.o \ $(OBJDIR)/juce_BufferedInputStream.o \ + $(OBJDIR)/juce_SubregionStream.o \ $(OBJDIR)/juce_GZIPDecompressorInputStream.o \ - $(OBJDIR)/juce_LocalisedStrings.o \ + $(OBJDIR)/juce_GZIPCompressorOutputStream.o \ + $(OBJDIR)/juce_OutputStream.o \ $(OBJDIR)/juce_String.o \ $(OBJDIR)/juce_StringPairArray.o \ $(OBJDIR)/juce_XmlDocument.o \ $(OBJDIR)/juce_CharacterFunctions.o \ $(OBJDIR)/juce_StringArray.o \ + $(OBJDIR)/juce_LocalisedStrings.o \ $(OBJDIR)/juce_XmlElement.o \ $(OBJDIR)/juce_InterProcessLock.o \ $(OBJDIR)/juce_ReadWriteLock.o \ $(OBJDIR)/juce_Thread.o \ $(OBJDIR)/juce_ThreadPool.o \ $(OBJDIR)/juce_TimeSliceThread.o \ - $(OBJDIR)/juce_Application.o \ $(OBJDIR)/juce_ApplicationCommandInfo.o \ - $(OBJDIR)/juce_ApplicationCommandTarget.o \ $(OBJDIR)/juce_ApplicationProperties.o \ $(OBJDIR)/juce_ApplicationCommandManager.o \ - $(OBJDIR)/juce_AudioDataConverters.o \ + $(OBJDIR)/juce_ApplicationCommandTarget.o \ + $(OBJDIR)/juce_Application.o \ $(OBJDIR)/juce_IIRFilter.o \ $(OBJDIR)/juce_AudioSampleBuffer.o \ + $(OBJDIR)/juce_AudioDataConverters.o \ $(OBJDIR)/juce_MidiKeyboardState.o \ $(OBJDIR)/juce_MidiMessageCollector.o \ $(OBJDIR)/juce_MidiMessageSequence.o \ $(OBJDIR)/juce_MidiMessage.o \ $(OBJDIR)/juce_MidiBuffer.o \ $(OBJDIR)/juce_MidiFile.o \ - $(OBJDIR)/juce_AudioProcessor.o \ $(OBJDIR)/juce_AudioProcessorEditor.o \ $(OBJDIR)/juce_AudioProcessorPlayer.o \ + $(OBJDIR)/juce_AudioProcessor.o \ $(OBJDIR)/juce_GenericAudioProcessorEditor.o \ $(OBJDIR)/juce_AudioProcessorGraph.o \ $(OBJDIR)/juce_AudioPluginFormat.o \ @@ -113,17 +114,17 @@ OBJECTS := \ $(OBJDIR)/juce_PluginDirectoryScanner.o \ $(OBJDIR)/juce_PluginListComponent.o \ $(OBJDIR)/juce_VSTPluginFormat.o \ - $(OBJDIR)/juce_AiffAudioFormat.o \ $(OBJDIR)/juce_AudioCDReader.o \ - $(OBJDIR)/juce_AudioFormatManager.o \ $(OBJDIR)/juce_AudioSubsectionReader.o \ $(OBJDIR)/juce_AudioThumbnailCache.o \ $(OBJDIR)/juce_AudioFormat.o \ - $(OBJDIR)/juce_QuickTimeAudioFormat.o \ - $(OBJDIR)/juce_WavAudioFormat.o \ - $(OBJDIR)/juce_OggVorbisAudioFormat.o \ $(OBJDIR)/juce_AudioThumbnail.o \ + $(OBJDIR)/juce_AudioFormatManager.o \ + $(OBJDIR)/juce_QuickTimeAudioFormat.o \ + $(OBJDIR)/juce_AiffAudioFormat.o \ + $(OBJDIR)/juce_WavAudioFormat.o \ $(OBJDIR)/juce_FlacAudioFormat.o \ + $(OBJDIR)/juce_OggVorbisAudioFormat.o \ $(OBJDIR)/juce_AudioFormatReaderSource.o \ $(OBJDIR)/juce_AudioSourcePlayer.o \ $(OBJDIR)/juce_AudioTransportSource.o \ @@ -144,63 +145,62 @@ OBJECTS := \ $(OBJDIR)/juce_AsyncUpdater.o \ $(OBJDIR)/juce_ChangeBroadcaster.o \ $(OBJDIR)/juce_ChangeListenerList.o \ - $(OBJDIR)/juce_InterprocessConnection.o \ - $(OBJDIR)/juce_InterprocessConnectionServer.o \ $(OBJDIR)/juce_Message.o \ $(OBJDIR)/juce_MessageListener.o \ - $(OBJDIR)/juce_MultiTimer.o \ $(OBJDIR)/juce_Timer.o \ $(OBJDIR)/juce_MessageManager.o \ - $(OBJDIR)/juce_DeletedAtShutdown.o \ + $(OBJDIR)/juce_InterprocessConnectionServer.o \ + $(OBJDIR)/juce_InterprocessConnection.o \ + $(OBJDIR)/juce_MultiTimer.o \ $(OBJDIR)/juce_FileBasedDocument.o \ - $(OBJDIR)/juce_PropertiesFile.o \ $(OBJDIR)/juce_UndoManager.o \ $(OBJDIR)/juce_RecentlyOpenedFilesList.o \ + $(OBJDIR)/juce_DeletedAtShutdown.o \ + $(OBJDIR)/juce_PropertiesFile.o \ $(OBJDIR)/juce_Colours.o \ $(OBJDIR)/juce_Colour.o \ $(OBJDIR)/juce_ColourGradient.o \ $(OBJDIR)/juce_Justification.o \ $(OBJDIR)/juce_RectanglePlacement.o \ - $(OBJDIR)/juce_Graphics.o \ $(OBJDIR)/juce_LowLevelGraphicsSoftwareRenderer.o \ $(OBJDIR)/juce_LowLevelGraphicsPostScriptRenderer.o \ $(OBJDIR)/juce_EdgeTable.o \ $(OBJDIR)/juce_FillType.o \ + $(OBJDIR)/juce_Graphics.o \ $(OBJDIR)/juce_DrawableComposite.o \ $(OBJDIR)/juce_Drawable.o \ $(OBJDIR)/juce_DrawablePath.o \ $(OBJDIR)/juce_DrawableText.o \ - $(OBJDIR)/juce_DrawableImage.o \ $(OBJDIR)/juce_SVGParser.o \ + $(OBJDIR)/juce_DrawableImage.o \ $(OBJDIR)/juce_GlowEffect.o \ $(OBJDIR)/juce_ReduceOpacityEffect.o \ $(OBJDIR)/juce_DropShadowEffect.o \ + $(OBJDIR)/juce_TextLayout.o \ $(OBJDIR)/juce_Font.o \ $(OBJDIR)/juce_Typeface.o \ $(OBJDIR)/juce_GlyphArrangement.o \ - $(OBJDIR)/juce_TextLayout.o \ $(OBJDIR)/juce_Path.o \ $(OBJDIR)/juce_BorderSize.o \ $(OBJDIR)/juce_Line.o \ - $(OBJDIR)/juce_PathStrokeType.o \ $(OBJDIR)/juce_AffineTransform.o \ $(OBJDIR)/juce_Point.o \ $(OBJDIR)/juce_PositionedRectangle.o \ $(OBJDIR)/juce_RectangleList.o \ $(OBJDIR)/juce_Rectangle.o \ $(OBJDIR)/juce_PathIterator.o \ + $(OBJDIR)/juce_PathStrokeType.o \ $(OBJDIR)/juce_ImageCache.o \ - $(OBJDIR)/juce_Image.o \ $(OBJDIR)/juce_ImageFileFormat.o \ $(OBJDIR)/juce_ImageConvolutionKernel.o \ - $(OBJDIR)/juce_GIFLoader.o \ + $(OBJDIR)/juce_Image.o \ $(OBJDIR)/juce_JPEGLoader.o \ $(OBJDIR)/juce_PNGLoader.o \ + $(OBJDIR)/juce_GIFLoader.o \ $(OBJDIR)/juce_ComponentListener.o \ $(OBJDIR)/juce_Desktop.o \ $(OBJDIR)/juce_Component.o \ $(OBJDIR)/juce_ArrowButton.o \ - $(OBJDIR)/juce_Button.o \ $(OBJDIR)/juce_HyperlinkButton.o \ $(OBJDIR)/juce_ImageButton.o \ $(OBJDIR)/juce_TextButton.o \ @@ -208,33 +208,34 @@ OBJECTS := \ $(OBJDIR)/juce_ShapeButton.o \ $(OBJDIR)/juce_ToolbarButton.o \ $(OBJDIR)/juce_DrawableButton.o \ - $(OBJDIR)/juce_TableListBox.o \ + $(OBJDIR)/juce_Button.o \ $(OBJDIR)/juce_TextEditor.o \ + $(OBJDIR)/juce_Label.o \ $(OBJDIR)/juce_ProgressBar.o \ $(OBJDIR)/juce_ToolbarItemPalette.o \ - $(OBJDIR)/juce_Slider.o \ $(OBJDIR)/juce_Toolbar.o \ $(OBJDIR)/juce_ListBox.o \ - $(OBJDIR)/juce_TreeView.o \ $(OBJDIR)/juce_ToolbarItemComponent.o \ $(OBJDIR)/juce_ComboBox.o \ + $(OBJDIR)/juce_TableListBox.o \ $(OBJDIR)/juce_TableHeaderComponent.o \ - $(OBJDIR)/juce_Label.o \ - $(OBJDIR)/juce_CodeDocument.o \ + $(OBJDIR)/juce_Slider.o \ + $(OBJDIR)/juce_TreeView.o \ $(OBJDIR)/juce_CPlusPlusCodeTokeniser.o \ $(OBJDIR)/juce_CodeEditorComponent.o \ + $(OBJDIR)/juce_CodeDocument.o \ $(OBJDIR)/juce_DirectoryContentsDisplayComponent.o \ $(OBJDIR)/juce_FileFilter.o \ $(OBJDIR)/juce_FileListComponent.o \ $(OBJDIR)/juce_FilenameComponent.o \ + $(OBJDIR)/juce_FileTreeComponent.o \ $(OBJDIR)/juce_FileChooserDialogBox.o \ $(OBJDIR)/juce_FileSearchPathListComponent.o \ $(OBJDIR)/juce_WildcardFileFilter.o \ $(OBJDIR)/juce_ImagePreviewComponent.o \ - $(OBJDIR)/juce_FileTreeComponent.o \ $(OBJDIR)/juce_FileChooser.o \ - $(OBJDIR)/juce_DirectoryContentsList.o \ $(OBJDIR)/juce_FileBrowserComponent.o \ + $(OBJDIR)/juce_DirectoryContentsList.o \ $(OBJDIR)/juce_KeyListener.o \ $(OBJDIR)/juce_KeyPress.o \ $(OBJDIR)/juce_KeyboardFocusTraverser.o \ @@ -255,33 +256,33 @@ OBJECTS := \ $(OBJDIR)/juce_TabbedComponent.o \ $(OBJDIR)/juce_Viewport.o \ $(OBJDIR)/juce_ComponentMovementWatcher.o \ - $(OBJDIR)/juce_LookAndFeel.o \ $(OBJDIR)/juce_OldSchoolLookAndFeel.o \ - $(OBJDIR)/juce_MenuBarModel.o \ + $(OBJDIR)/juce_LookAndFeel.o \ $(OBJDIR)/juce_PopupMenu.o \ + $(OBJDIR)/juce_MenuBarModel.o \ $(OBJDIR)/juce_MenuBarComponent.o \ $(OBJDIR)/juce_ComponentDragger.o \ - $(OBJDIR)/juce_DragAndDropContainer.o \ + $(OBJDIR)/juce_MouseCursor.o \ $(OBJDIR)/juce_MouseEvent.o \ $(OBJDIR)/juce_MouseHoverDetector.o \ $(OBJDIR)/juce_MouseListener.o \ - $(OBJDIR)/juce_MouseCursor.o \ + $(OBJDIR)/juce_DragAndDropContainer.o \ $(OBJDIR)/juce_BooleanPropertyComponent.o \ $(OBJDIR)/juce_ButtonPropertyComponent.o \ - $(OBJDIR)/juce_ChoicePropertyComponent.o \ $(OBJDIR)/juce_PropertyComponent.o \ - $(OBJDIR)/juce_PropertyPanel.o \ $(OBJDIR)/juce_SliderPropertyComponent.o \ $(OBJDIR)/juce_TextPropertyComponent.o \ - $(OBJDIR)/juce_AudioDeviceSelectorComponent.o \ + $(OBJDIR)/juce_PropertyPanel.o \ + $(OBJDIR)/juce_ChoicePropertyComponent.o \ $(OBJDIR)/juce_BubbleMessageComponent.o \ - $(OBJDIR)/juce_DropShadower.o \ $(OBJDIR)/juce_OpenGLComponent.o \ - $(OBJDIR)/juce_PreferencesPanel.o \ $(OBJDIR)/juce_SystemTrayIconComponent.o \ $(OBJDIR)/juce_BubbleComponent.o \ $(OBJDIR)/juce_MidiKeyboardComponent.o \ + $(OBJDIR)/juce_PreferencesPanel.o \ + $(OBJDIR)/juce_DropShadower.o \ $(OBJDIR)/juce_MagnifierComponent.o \ + $(OBJDIR)/juce_AudioDeviceSelectorComponent.o \ $(OBJDIR)/juce_ColourSelector.o \ $(OBJDIR)/juce_AlertWindow.o \ $(OBJDIR)/juce_DialogWindow.o \ @@ -295,16 +296,17 @@ OBJECTS := \ $(OBJDIR)/juce_linux_Midi.o \ $(OBJDIR)/juce_linux_Network.o \ $(OBJDIR)/juce_linux_FileChooser.o \ - $(OBJDIR)/juce_linux_Threads.o \ - $(OBJDIR)/juce_linux_Messaging.o \ $(OBJDIR)/juce_linux_Fonts.o \ - $(OBJDIR)/juce_linux_SystemStats.o \ + $(OBJDIR)/juce_linux_Windowing.o \ $(OBJDIR)/juce_linux_WebBrowserComponent.o \ $(OBJDIR)/juce_linux_JackAudio.o \ $(OBJDIR)/juce_linux_Audio.o \ $(OBJDIR)/juce_linux_AudioCDReader.o \ $(OBJDIR)/juce_linux_Files.o \ - $(OBJDIR)/juce_linux_Windowing.o \ + $(OBJDIR)/juce_linux_Threads.o \ + $(OBJDIR)/juce_linux_SystemStats.o \ + $(OBJDIR)/juce_linux_Clipboard.o \ + $(OBJDIR)/juce_linux_Messaging.o \ $(OBJDIR)/juce_linux_NativeCode.o \ MKDIR_TYPE := msdos @@ -357,6 +359,11 @@ $(OBJDIR)/juce_PerformanceCounter.o: ../../src/core/juce_PerformanceCounter.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_Time.o: ../../src/core/juce_Time.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_Random.o: ../../src/core/juce_Random.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -367,7 +374,7 @@ $(OBJDIR)/juce_RelativeTime.o: ../../src/core/juce_RelativeTime.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Time.o: ../../src/core/juce_Time.cpp +$(OBJDIR)/juce_SystemStats.o: ../../src/core/juce_SystemStats.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -377,11 +384,6 @@ $(OBJDIR)/juce_Uuid.o: ../../src/core/juce_Uuid.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_SystemStats.o: ../../src/core/juce_SystemStats.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_Logger.o: ../../src/core/juce_Logger.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -407,12 +409,12 @@ $(OBJDIR)/juce_MD5.o: ../../src/cryptography/juce_MD5.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_ValueTree.o: ../../src/containers/juce_ValueTree.cpp +$(OBJDIR)/juce_PropertySet.o: ../../src/containers/juce_PropertySet.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_PropertySet.o: ../../src/containers/juce_PropertySet.cpp +$(OBJDIR)/juce_Variant.o: ../../src/containers/juce_Variant.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -427,7 +429,12 @@ $(OBJDIR)/juce_MemoryBlock.o: ../../src/containers/juce_MemoryBlock.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Variant.o: ../../src/containers/juce_Variant.cpp +$(OBJDIR)/juce_ValueTree.o: ../../src/containers/juce_ValueTree.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_Value.o: ../../src/containers/juce_Value.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -442,11 +449,6 @@ $(OBJDIR)/juce_File.o: ../../src/io/files/juce_File.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_FileOutputStream.o: ../../src/io/files/juce_FileOutputStream.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_FileSearchPath.o: ../../src/io/files/juce_FileSearchPath.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -457,7 +459,7 @@ $(OBJDIR)/juce_NamedPipe.o: ../../src/io/files/juce_NamedPipe.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_ZipFile.o: ../../src/io/files/juce_ZipFile.cpp +$(OBJDIR)/juce_FileOutputStream.o: ../../src/io/files/juce_FileOutputStream.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -467,6 +469,11 @@ $(OBJDIR)/juce_DirectoryIterator.o: ../../src/io/files/juce_DirectoryIterator.cp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_ZipFile.o: ../../src/io/files/juce_ZipFile.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_Socket.o: ../../src/io/network/juce_Socket.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -477,37 +484,22 @@ $(OBJDIR)/juce_URL.o: ../../src/io/network/juce_URL.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_FileInputSource.o: ../../src/io/streams/juce_FileInputSource.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/juce_OutputStream.o: ../../src/io/streams/juce_OutputStream.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_MemoryInputStream.o: ../../src/io/streams/juce_MemoryInputStream.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_MemoryOutputStream.o: ../../src/io/streams/juce_MemoryOutputStream.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/juce_SubregionStream.o: ../../src/io/streams/juce_SubregionStream.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_InputStream.o: ../../src/io/streams/juce_InputStream.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_GZIPCompressorOutputStream.o: ../../src/io/streams/juce_GZIPCompressorOutputStream.cpp +$(OBJDIR)/juce_FileInputSource.o: ../../src/io/streams/juce_FileInputSource.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_MemoryOutputStream.o: ../../src/io/streams/juce_MemoryOutputStream.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -517,12 +509,22 @@ $(OBJDIR)/juce_BufferedInputStream.o: ../../src/io/streams/juce_BufferedInputStr @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_SubregionStream.o: ../../src/io/streams/juce_SubregionStream.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_GZIPDecompressorInputStream.o: ../../src/io/streams/juce_GZIPDecompressorInputStream.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_LocalisedStrings.o: ../../src/text/juce_LocalisedStrings.cpp +$(OBJDIR)/juce_GZIPCompressorOutputStream.o: ../../src/io/streams/juce_GZIPCompressorOutputStream.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_OutputStream.o: ../../src/io/streams/juce_OutputStream.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -552,6 +554,11 @@ $(OBJDIR)/juce_StringArray.o: ../../src/text/juce_StringArray.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_LocalisedStrings.o: ../../src/text/juce_LocalisedStrings.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_XmlElement.o: ../../src/text/juce_XmlElement.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -582,21 +589,11 @@ $(OBJDIR)/juce_TimeSliceThread.o: ../../src/threads/juce_TimeSliceThread.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Application.o: ../../src/application/juce_Application.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_ApplicationCommandInfo.o: ../../src/application/juce_ApplicationCommandInfo.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_ApplicationCommandTarget.o: ../../src/application/juce_ApplicationCommandTarget.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_ApplicationProperties.o: ../../src/application/juce_ApplicationProperties.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -607,7 +604,12 @@ $(OBJDIR)/juce_ApplicationCommandManager.o: ../../src/application/juce_Applicati @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_AudioDataConverters.o: ../../src/audio/dsp/juce_AudioDataConverters.cpp +$(OBJDIR)/juce_ApplicationCommandTarget.o: ../../src/application/juce_ApplicationCommandTarget.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_Application.o: ../../src/application/juce_Application.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -622,6 +624,11 @@ $(OBJDIR)/juce_AudioSampleBuffer.o: ../../src/audio/dsp/juce_AudioSampleBuffer.c @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_AudioDataConverters.o: ../../src/audio/dsp/juce_AudioDataConverters.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_MidiKeyboardState.o: ../../src/audio/midi/juce_MidiKeyboardState.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -652,11 +659,6 @@ $(OBJDIR)/juce_MidiFile.o: ../../src/audio/midi/juce_MidiFile.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_AudioProcessor.o: ../../src/audio/processors/juce_AudioProcessor.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_AudioProcessorEditor.o: ../../src/audio/processors/juce_AudioProcessorEditor.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -667,6 +669,11 @@ $(OBJDIR)/juce_AudioProcessorPlayer.o: ../../src/audio/processors/juce_AudioProc @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_AudioProcessor.o: ../../src/audio/processors/juce_AudioProcessor.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_GenericAudioProcessorEditor.o: ../../src/audio/processors/juce_GenericAudioProcessorEditor.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -717,21 +724,11 @@ $(OBJDIR)/juce_VSTPluginFormat.o: ../../src/audio/plugins/formats/juce_VSTPlugin @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_AiffAudioFormat.o: ../../src/audio/audio_file_formats/juce_AiffAudioFormat.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_AudioCDReader.o: ../../src/audio/audio_file_formats/juce_AudioCDReader.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_AudioFormatManager.o: ../../src/audio/audio_file_formats/juce_AudioFormatManager.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_AudioSubsectionReader.o: ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -747,31 +744,41 @@ $(OBJDIR)/juce_AudioFormat.o: ../../src/audio/audio_file_formats/juce_AudioForma @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_AudioThumbnail.o: ../../src/audio/audio_file_formats/juce_AudioThumbnail.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_AudioFormatManager.o: ../../src/audio/audio_file_formats/juce_AudioFormatManager.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_QuickTimeAudioFormat.o: ../../src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_AiffAudioFormat.o: ../../src/audio/audio_file_formats/juce_AiffAudioFormat.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_WavAudioFormat.o: ../../src/audio/audio_file_formats/juce_WavAudioFormat.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_OggVorbisAudioFormat.o: ../../src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/juce_AudioThumbnail.o: ../../src/audio/audio_file_formats/juce_AudioThumbnail.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_FlacAudioFormat.o: ../../src/audio/audio_file_formats/juce_FlacAudioFormat.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_OggVorbisAudioFormat.o: ../../src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_AudioFormatReaderSource.o: ../../src/audio/audio_sources/juce_AudioFormatReaderSource.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -872,16 +879,6 @@ $(OBJDIR)/juce_ChangeListenerList.o: ../../src/events/juce_ChangeListenerList.cp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_InterprocessConnection.o: ../../src/events/juce_InterprocessConnection.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/juce_InterprocessConnectionServer.o: ../../src/events/juce_InterprocessConnectionServer.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_Message.o: ../../src/events/juce_Message.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -892,11 +889,6 @@ $(OBJDIR)/juce_MessageListener.o: ../../src/events/juce_MessageListener.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_MultiTimer.o: ../../src/events/juce_MultiTimer.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_Timer.o: ../../src/events/juce_Timer.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -907,7 +899,17 @@ $(OBJDIR)/juce_MessageManager.o: ../../src/events/juce_MessageManager.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_DeletedAtShutdown.o: ../../src/utilities/juce_DeletedAtShutdown.cpp +$(OBJDIR)/juce_InterprocessConnectionServer.o: ../../src/events/juce_InterprocessConnectionServer.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_InterprocessConnection.o: ../../src/events/juce_InterprocessConnection.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_MultiTimer.o: ../../src/events/juce_MultiTimer.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -917,11 +919,6 @@ $(OBJDIR)/juce_FileBasedDocument.o: ../../src/utilities/juce_FileBasedDocument.c @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_PropertiesFile.o: ../../src/utilities/juce_PropertiesFile.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_UndoManager.o: ../../src/utilities/juce_UndoManager.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -932,6 +929,16 @@ $(OBJDIR)/juce_RecentlyOpenedFilesList.o: ../../src/utilities/juce_RecentlyOpene @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_DeletedAtShutdown.o: ../../src/utilities/juce_DeletedAtShutdown.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_PropertiesFile.o: ../../src/utilities/juce_PropertiesFile.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_Colours.o: ../../src/gui/graphics/colour/juce_Colours.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -957,11 +964,6 @@ $(OBJDIR)/juce_RectanglePlacement.o: ../../src/gui/graphics/contexts/juce_Rectan @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Graphics.o: ../../src/gui/graphics/contexts/juce_Graphics.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_LowLevelGraphicsSoftwareRenderer.o: ../../src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -982,6 +984,11 @@ $(OBJDIR)/juce_FillType.o: ../../src/gui/graphics/contexts/juce_FillType.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_Graphics.o: ../../src/gui/graphics/contexts/juce_Graphics.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_DrawableComposite.o: ../../src/gui/graphics/drawables/juce_DrawableComposite.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1002,12 +1009,12 @@ $(OBJDIR)/juce_DrawableText.o: ../../src/gui/graphics/drawables/juce_DrawableTex @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_DrawableImage.o: ../../src/gui/graphics/drawables/juce_DrawableImage.cpp +$(OBJDIR)/juce_SVGParser.o: ../../src/gui/graphics/drawables/juce_SVGParser.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_SVGParser.o: ../../src/gui/graphics/drawables/juce_SVGParser.cpp +$(OBJDIR)/juce_DrawableImage.o: ../../src/gui/graphics/drawables/juce_DrawableImage.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1027,6 +1034,11 @@ $(OBJDIR)/juce_DropShadowEffect.o: ../../src/gui/graphics/effects/juce_DropShado @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_TextLayout.o: ../../src/gui/graphics/fonts/juce_TextLayout.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_Font.o: ../../src/gui/graphics/fonts/juce_Font.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1042,11 +1054,6 @@ $(OBJDIR)/juce_GlyphArrangement.o: ../../src/gui/graphics/fonts/juce_GlyphArrang @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_TextLayout.o: ../../src/gui/graphics/fonts/juce_TextLayout.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_Path.o: ../../src/gui/graphics/geometry/juce_Path.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1062,11 +1069,6 @@ $(OBJDIR)/juce_Line.o: ../../src/gui/graphics/geometry/juce_Line.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_PathStrokeType.o: ../../src/gui/graphics/geometry/juce_PathStrokeType.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_AffineTransform.o: ../../src/gui/graphics/geometry/juce_AffineTransform.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1097,12 +1099,12 @@ $(OBJDIR)/juce_PathIterator.o: ../../src/gui/graphics/geometry/juce_PathIterator @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_ImageCache.o: ../../src/gui/graphics/imaging/juce_ImageCache.cpp +$(OBJDIR)/juce_PathStrokeType.o: ../../src/gui/graphics/geometry/juce_PathStrokeType.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Image.o: ../../src/gui/graphics/imaging/juce_Image.cpp +$(OBJDIR)/juce_ImageCache.o: ../../src/gui/graphics/imaging/juce_ImageCache.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1117,7 +1119,7 @@ $(OBJDIR)/juce_ImageConvolutionKernel.o: ../../src/gui/graphics/imaging/juce_Ima @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_GIFLoader.o: ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp +$(OBJDIR)/juce_Image.o: ../../src/gui/graphics/imaging/juce_Image.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1132,6 +1134,11 @@ $(OBJDIR)/juce_PNGLoader.o: ../../src/gui/graphics/imaging/image_file_formats/ju @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_GIFLoader.o: ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_ComponentListener.o: ../../src/gui/components/juce_ComponentListener.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1152,11 +1159,6 @@ $(OBJDIR)/juce_ArrowButton.o: ../../src/gui/components/buttons/juce_ArrowButton. @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Button.o: ../../src/gui/components/buttons/juce_Button.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_HyperlinkButton.o: ../../src/gui/components/buttons/juce_HyperlinkButton.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1192,7 +1194,7 @@ $(OBJDIR)/juce_DrawableButton.o: ../../src/gui/components/buttons/juce_DrawableB @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_TableListBox.o: ../../src/gui/components/controls/juce_TableListBox.cpp +$(OBJDIR)/juce_Button.o: ../../src/gui/components/buttons/juce_Button.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1202,6 +1204,11 @@ $(OBJDIR)/juce_TextEditor.o: ../../src/gui/components/controls/juce_TextEditor.c @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_Label.o: ../../src/gui/components/controls/juce_Label.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_ProgressBar.o: ../../src/gui/components/controls/juce_ProgressBar.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1212,11 +1219,6 @@ $(OBJDIR)/juce_ToolbarItemPalette.o: ../../src/gui/components/controls/juce_Tool @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Slider.o: ../../src/gui/components/controls/juce_Slider.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_Toolbar.o: ../../src/gui/components/controls/juce_Toolbar.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1227,11 +1229,6 @@ $(OBJDIR)/juce_ListBox.o: ../../src/gui/components/controls/juce_ListBox.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_TreeView.o: ../../src/gui/components/controls/juce_TreeView.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_ToolbarItemComponent.o: ../../src/gui/components/controls/juce_ToolbarItemComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1242,17 +1239,22 @@ $(OBJDIR)/juce_ComboBox.o: ../../src/gui/components/controls/juce_ComboBox.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_TableListBox.o: ../../src/gui/components/controls/juce_TableListBox.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_TableHeaderComponent.o: ../../src/gui/components/controls/juce_TableHeaderComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_Label.o: ../../src/gui/components/controls/juce_Label.cpp +$(OBJDIR)/juce_Slider.o: ../../src/gui/components/controls/juce_Slider.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_CodeDocument.o: ../../src/gui/components/code_editor/juce_CodeDocument.cpp +$(OBJDIR)/juce_TreeView.o: ../../src/gui/components/controls/juce_TreeView.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1267,6 +1269,11 @@ $(OBJDIR)/juce_CodeEditorComponent.o: ../../src/gui/components/code_editor/juce_ @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_CodeDocument.o: ../../src/gui/components/code_editor/juce_CodeDocument.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_DirectoryContentsDisplayComponent.o: ../../src/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1287,6 +1294,11 @@ $(OBJDIR)/juce_FilenameComponent.o: ../../src/gui/components/filebrowser/juce_Fi @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_FileTreeComponent.o: ../../src/gui/components/filebrowser/juce_FileTreeComponent.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_FileChooserDialogBox.o: ../../src/gui/components/filebrowser/juce_FileChooserDialogBox.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1307,22 +1319,17 @@ $(OBJDIR)/juce_ImagePreviewComponent.o: ../../src/gui/components/filebrowser/juc @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_FileTreeComponent.o: ../../src/gui/components/filebrowser/juce_FileTreeComponent.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_FileChooser.o: ../../src/gui/components/filebrowser/juce_FileChooser.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_DirectoryContentsList.o: ../../src/gui/components/filebrowser/juce_DirectoryContentsList.cpp +$(OBJDIR)/juce_FileBrowserComponent.o: ../../src/gui/components/filebrowser/juce_FileBrowserComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_FileBrowserComponent.o: ../../src/gui/components/filebrowser/juce_FileBrowserComponent.cpp +$(OBJDIR)/juce_DirectoryContentsList.o: ../../src/gui/components/filebrowser/juce_DirectoryContentsList.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1427,17 +1434,12 @@ $(OBJDIR)/juce_ComponentMovementWatcher.o: ../../src/gui/components/layout/juce_ @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_LookAndFeel.o: ../../src/gui/components/lookandfeel/juce_LookAndFeel.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_OldSchoolLookAndFeel.o: ../../src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_MenuBarModel.o: ../../src/gui/components/menus/juce_MenuBarModel.cpp +$(OBJDIR)/juce_LookAndFeel.o: ../../src/gui/components/lookandfeel/juce_LookAndFeel.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1447,6 +1449,11 @@ $(OBJDIR)/juce_PopupMenu.o: ../../src/gui/components/menus/juce_PopupMenu.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_MenuBarModel.o: ../../src/gui/components/menus/juce_MenuBarModel.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_MenuBarComponent.o: ../../src/gui/components/menus/juce_MenuBarComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1457,7 +1464,7 @@ $(OBJDIR)/juce_ComponentDragger.o: ../../src/gui/components/mouse/juce_Component @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_DragAndDropContainer.o: ../../src/gui/components/mouse/juce_DragAndDropContainer.cpp +$(OBJDIR)/juce_MouseCursor.o: ../../src/gui/components/mouse/juce_MouseCursor.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1477,7 +1484,7 @@ $(OBJDIR)/juce_MouseListener.o: ../../src/gui/components/mouse/juce_MouseListene @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_MouseCursor.o: ../../src/gui/components/mouse/juce_MouseCursor.cpp +$(OBJDIR)/juce_DragAndDropContainer.o: ../../src/gui/components/mouse/juce_DragAndDropContainer.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1492,21 +1499,11 @@ $(OBJDIR)/juce_ButtonPropertyComponent.o: ../../src/gui/components/properties/ju @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_ChoicePropertyComponent.o: ../../src/gui/components/properties/juce_ChoicePropertyComponent.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_PropertyComponent.o: ../../src/gui/components/properties/juce_PropertyComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_PropertyPanel.o: ../../src/gui/components/properties/juce_PropertyPanel.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_SliderPropertyComponent.o: ../../src/gui/components/properties/juce_SliderPropertyComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1517,7 +1514,12 @@ $(OBJDIR)/juce_TextPropertyComponent.o: ../../src/gui/components/properties/juce @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_AudioDeviceSelectorComponent.o: ../../src/gui/components/special/juce_AudioDeviceSelectorComponent.cpp +$(OBJDIR)/juce_PropertyPanel.o: ../../src/gui/components/properties/juce_PropertyPanel.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_ChoicePropertyComponent.o: ../../src/gui/components/properties/juce_ChoicePropertyComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1527,21 +1529,11 @@ $(OBJDIR)/juce_BubbleMessageComponent.o: ../../src/gui/components/special/juce_B @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_DropShadower.o: ../../src/gui/components/special/juce_DropShadower.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_OpenGLComponent.o: ../../src/gui/components/special/juce_OpenGLComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_PreferencesPanel.o: ../../src/gui/components/special/juce_PreferencesPanel.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_SystemTrayIconComponent.o: ../../src/gui/components/special/juce_SystemTrayIconComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1557,11 +1549,26 @@ $(OBJDIR)/juce_MidiKeyboardComponent.o: ../../src/gui/components/special/juce_Mi @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_PreferencesPanel.o: ../../src/gui/components/special/juce_PreferencesPanel.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_DropShadower.o: ../../src/gui/components/special/juce_DropShadower.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_MagnifierComponent.o: ../../src/gui/components/special/juce_MagnifierComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_AudioDeviceSelectorComponent.o: ../../src/gui/components/special/juce_AudioDeviceSelectorComponent.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_ColourSelector.o: ../../src/gui/components/special/juce_ColourSelector.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1627,22 +1634,12 @@ $(OBJDIR)/juce_linux_FileChooser.o: ../../src/native/linux/juce_linux_FileChoose @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_linux_Threads.o: ../../src/native/linux/juce_linux_Threads.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/juce_linux_Messaging.o: ../../src/native/linux/juce_linux_Messaging.cpp - -@$(CMD_MKOBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/juce_linux_Fonts.o: ../../src/native/linux/juce_linux_Fonts.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_linux_SystemStats.o: ../../src/native/linux/juce_linux_SystemStats.cpp +$(OBJDIR)/juce_linux_Windowing.o: ../../src/native/linux/juce_linux_Windowing.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @@ -1672,7 +1669,22 @@ $(OBJDIR)/juce_linux_Files.o: ../../src/native/linux/juce_linux_Files.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/juce_linux_Windowing.o: ../../src/native/linux/juce_linux_Windowing.cpp +$(OBJDIR)/juce_linux_Threads.o: ../../src/native/linux/juce_linux_Threads.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_linux_SystemStats.o: ../../src/native/linux/juce_linux_SystemStats.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_linux_Clipboard.o: ../../src/native/linux/juce_linux_Clipboard.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_linux_Messaging.o: ../../src/native/linux/juce_linux_Messaging.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index a258846eda..0e1b2cb086 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -252666,7 +252666,7 @@ void* PlatformUtilities::getProcedureEntryPoint (void* libraryHandle, const Stri #if ! JUCE_ONLY_BUILD_CORE_LIBRARY -/********* Start of inlined file: juce_linux_Messaging.cpp *********/ +/********* Start of inlined file: juce_linux_Clipboard.cpp *********/ // (This file gets included by juce_linux_NativeCode.cpp, rather than being // compiled on its own). #if JUCE_INCLUDED_FILE @@ -252675,8 +252675,246 @@ void* PlatformUtilities::getProcedureEntryPoint (void* libraryHandle, const Stri #define JUCE_DEBUG_XERRORS 1 #endif +extern Display* display; +extern Window juce_messageWindowHandle; + +static String localClipboardContent; +static Atom atom_UTF8_STRING; +static Atom atom_CLIPBOARD; +static Atom atom_TARGETS; + +static void initSelectionAtoms() +{ + static bool isInitialised = false; + if (! isInitialised) + { + atom_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); + atom_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False); + atom_TARGETS = XInternAtom (display, "TARGETS", False); + } +} + +// Read the content of a window property as either a locale-dependent string or an utf8 string +// works only for strings shorter than 1000000 bytes +static String juce_readWindowProperty (Window window, Atom prop, + Atom fmt, // XA_STRING or UTF8_STRING + bool deleteAfterReading) +{ + String returnData; + uint8 *clipData; + Atom actualType; + int actualFormat; + unsigned long numItems, bytesLeft; + + if (XGetWindowProperty (display, window, prop, + 0L /* offset */, 1000000 /* length (max) */, False, + AnyPropertyType /* format */, + &actualType, &actualFormat, &numItems, &bytesLeft, + &clipData) == Success) + { + if (actualType == atom_UTF8_STRING && actualFormat == 8) + { + returnData = String::fromUTF8 (clipData, numItems); + } + else if (actualType == XA_STRING && actualFormat == 8) + { + returnData = String ((const char*) clipData, numItems); + } + + if (clipData != 0) + XFree (clipData); + + jassert (bytesLeft == 0 || numItems == 1000000); + } + + if (deleteAfterReading) + XDeleteProperty (display, window, prop); + + return returnData; +} + +// Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */ +static bool juce_requestSelectionContent (String &selection_content, Atom selection, Atom requested_format) +{ + Atom property_name = XInternAtom (display, "JUCE_SEL", false); + + // The selection owner will be asked to set the JUCE_SEL property on the + // juce_messageWindowHandle with the selection content + XConvertSelection (display, selection, requested_format, property_name, + juce_messageWindowHandle, CurrentTime); + + int timeoutMs = 200; // will wait at most for 200 ms + + do + { + XEvent event; + + if (XCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event)) + { + if (event.xselection.property == property_name) + { + jassert (event.xselection.requestor == juce_messageWindowHandle); + + selection_content = juce_readWindowProperty (event.xselection.requestor, + event.xselection.property, + requested_format, true); + return true; + } + else + { + return false; // the format we asked for was denied.. (event.xselection.property == None) + } + } + + // not very elegant.. we could do a select() or something like that... + // however clipboard content requesting is inherently slow on x11, it + // often takes 50ms or more so... + Thread::sleep (4); + timeoutMs -= 4; + } + while (timeoutMs > 0); + + DBG("timeout for juce_requestSelectionContent"); + return false; +} + +// Called from the event loop in juce_linux_Messaging in response to SelectionRequest events +void juce_handleSelectionRequest (XSelectionRequestEvent &evt) +{ + initSelectionAtoms(); + + // the selection content is sent to the target window as a window property + XSelectionEvent reply; + reply.type = SelectionNotify; + reply.display = evt.display; + reply.requestor = evt.requestor; + reply.selection = evt.selection; + reply.target = evt.target; + reply.property = None; // == "fail" + reply.time = evt.time; + + HeapBlock data; + int propertyFormat = 0, numDataItems = 0; + + if (evt.selection == XA_PRIMARY || evt.selection == atom_CLIPBOARD) + { + if (evt.target == XA_STRING) + { + // format data according to system locale + numDataItems = localClipboardContent.length(); + data.calloc (numDataItems + 2); + localClipboardContent.copyToBuffer ((char*) data, numDataItems + 1); + propertyFormat = 8; // bits/item + } + else if (evt.target == atom_UTF8_STRING) + { + // translate to utf8 + numDataItems = localClipboardContent.copyToUTF8 (0); + data.calloc (numDataItems + 2); + localClipboardContent.copyToUTF8 (data, numDataItems + 1); + propertyFormat = 8; // bits/item + } + else if (evt.target == atom_TARGETS) + { + // another application wants to know what we are able to send + numDataItems = 2; + propertyFormat = 32; // atoms are 32-bit + data.calloc (numDataItems * 4); + ((Atom*) data)[0] = atom_UTF8_STRING; + ((Atom*) data)[1] = XA_STRING; + } + } + else + { + DBG ("requested unsupported clipboard"); + } + + if (data != 0) + { + const int maxReasonableSelectionSize = 1000000; + + // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss + if (evt.property != None && numDataItems < maxReasonableSelectionSize) + { + XChangeProperty (evt.display, evt.requestor, + evt.property, evt.target, + propertyFormat /* 8 or 32 */, PropModeReplace, + (const unsigned char*) data, numDataItems); + reply.property = evt.property; // " == success" + } + } + + XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); +} + +void SystemClipboard::copyTextToClipboard (const String& clipText) throw() +{ + initSelectionAtoms(); + localClipboardContent = clipText; + + XSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime); + XSetSelectionOwner (display, atom_CLIPBOARD, juce_messageWindowHandle, CurrentTime); +} + +const String SystemClipboard::getTextFromClipboard() throw() +{ + initSelectionAtoms(); + + /* 1) try to read from the "CLIPBOARD" selection first (the "high + level" clipboard that is supposed to be filled by ctrl-C + etc). When a clipboard manager is running, the content of this + selection is preserved even when the original selection owner + exits. + + 2) and then try to read from "PRIMARY" selection (the "legacy" selection + filled by good old x11 apps such as xterm) + */ + String content; + Atom selection = XA_PRIMARY; + Window selectionOwner = None; + + if ((selectionOwner = XGetSelectionOwner (display, selection)) == None) + { + selection = atom_CLIPBOARD; + selectionOwner = XGetSelectionOwner (display, selection); + } + + if (selectionOwner != None) + { + if (selectionOwner == juce_messageWindowHandle) + { + content = localClipboardContent; + } + else + { + // first try: we want an utf8 string + bool ok = juce_requestSelectionContent (content, selection, atom_UTF8_STRING); + + if (! ok) + { + // second chance, ask for a good old locale-dependent string .. + ok = juce_requestSelectionContent (content, selection, XA_STRING); + } + } + } + + return content; +} + +#endif +/********* End of inlined file: juce_linux_Clipboard.cpp *********/ + +/********* Start of inlined file: juce_linux_Messaging.cpp *********/ +// (This file gets included by juce_linux_NativeCode.cpp, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE + +#ifdef JUCE_DEBUG + #define JUCE_DEBUG_XERRORS 1 +#endif + Display* display = 0; // This is also referenced from WindowDriver.cpp -static Window juce_messageWindowHandle = None; +Window juce_messageWindowHandle = None; #define SpecialAtom "JUCESpecialAtom" #define BroadcastAtom "JUCEBroadcastAtom" @@ -252692,8 +252930,68 @@ XContext improbableNumber; // Defined in WindowDriver.cpp extern void juce_windowMessageReceive (XEvent* event); +// Defined in ClipboardDriver.cpp +extern void juce_handleSelectionRequest (XSelectionRequestEvent &evt); + +class InternalMessageQueue +{ +public: + InternalMessageQueue() + { + int ret = ::socketpair (AF_LOCAL, SOCK_STREAM, 0, fd); + (void) ret; jassert (ret == 0); + } + + ~InternalMessageQueue() + { + close (fd[0]); + close (fd[1]); + } + + void postMessage (Message* msg) + { + ScopedLock sl (lock); + queue.add (msg); + + const unsigned char x = 0xff; + write (fd[0], &x, 1); + } + + bool isEmpty() const + { + ScopedLock sl (lock); + return queue.size() == 0; + } + + Message* popMessage() + { + Message* m = 0; + ScopedLock sl (lock); + + if (queue.size() != 0) + { + unsigned char x; + read (fd[1], &x, 1); + + m = queue.getUnchecked(0); + queue.remove (0, false /* deleteObject */); + } + + return m; + } + + int getWaitHandle() const { return fd[1]; } + +private: + CriticalSection lock; + OwnedArray queue; + int fd[2]; +}; + struct MessageThreadFuncCall { + enum { uniqueID = 0x73774623 }; + MessageCallbackFunction* func; void* parameter; void* result; @@ -252701,21 +252999,22 @@ struct MessageThreadFuncCall WaitableEvent event; }; -static bool errorCondition = false; +static InternalMessageQueue* juce_internalMessageQueue = 0; + +// error handling in X11 +static bool errorOccurred = false; +static bool keyboardBreakOccurred = false; static XErrorHandler oldErrorHandler = (XErrorHandler) 0; static XIOErrorHandler oldIOErrorHandler = (XIOErrorHandler) 0; -// (defined in another file to avoid problems including certain headers in this one) -extern bool juce_isRunningAsApplication(); - // Usually happens when client-server connection is broken static int ioErrorHandler (Display* display) { DBG (T("ERROR: connection to X server broken.. terminating.")); - errorCondition = true; + errorOccurred = true; - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) Process::terminate(); return 0; @@ -252743,20 +253042,18 @@ static int errorHandler (Display* display, XErrorEvent* event) return 0; } -static bool breakIn = false; - // Breakin from keyboard -static void sig_handler (int sig) +static void signalHandler (int sig) { if (sig == SIGINT) { - breakIn = true; + keyboardBreakOccurred = true; return; } static bool reentrant = false; - if (reentrant == false) + if (! reentrant) { reentrant = true; @@ -252764,14 +253061,14 @@ static void sig_handler (int sig) fflush (stdout); Logger::outputDebugString ("ERROR: Program executed illegal instruction.. terminating"); - errorCondition = true; + errorOccurred = true; - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) Process::terminate(); } else { - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) exit(0); } } @@ -252788,7 +253085,7 @@ void MessageManager::doPlatformSpecificInitialisation() // This is fatal! Print error and closedown Logger::outputDebugString ("Failed to initialise xlib thread support."); - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) Process::terminate(); return; @@ -252807,7 +253104,7 @@ void MessageManager::doPlatformSpecificInitialisation() struct sigaction saction; sigset_t maskSet; sigemptyset (&maskSet); - saction.sa_handler = sig_handler; + saction.sa_handler = signalHandler; saction.sa_mask = maskSet; saction.sa_flags = 0; sigaction (SIGINT, &saction, NULL); @@ -252821,6 +253118,10 @@ void MessageManager::doPlatformSpecificInitialisation() sigaction (SIGSYS, &saction, NULL); #endif + // Create the internal message queue + juce_internalMessageQueue = new InternalMessageQueue(); + + // Try to connect to a display String displayName (getenv ("DISPLAY")); if (displayName.isEmpty()) displayName = T(":0.0"); @@ -252829,12 +253130,7 @@ void MessageManager::doPlatformSpecificInitialisation() if (display == 0) { - // This is fatal! Print error and closedown - Logger::outputDebugString ("Failed to open the X display."); - - if (juce_isRunningAsApplication()) - Process::terminate(); - + // This is not fatal! we can run headless. return; } @@ -252865,7 +253161,9 @@ void MessageManager::doPlatformSpecificInitialisation() void MessageManager::doPlatformSpecificShutdown() { - if (errorCondition == false) + deleteAndZero (juce_internalMessageQueue); + + if (display != 0 && ! errorOccurred) { XDestroyWindow (display, juce_messageWindowHandle); XCloseDisplay (display); @@ -252884,9 +253182,15 @@ void MessageManager::doPlatformSpecificShutdown() bool juce_postMessageToSystemQueue (void* message) { - if (errorCondition) + if (errorOccurred) return false; + juce_internalMessageQueue->postMessage ((Message*) message); + return true; +} + +/*bool juce_postMessageToX11Queue (void *message) +{ XClientMessageEvent clientMsg; clientMsg.display = display; clientMsg.window = juce_messageWindowHandle; @@ -252906,131 +253210,79 @@ bool juce_postMessageToSystemQueue (void* message) XFlush (display); // This is necessary to ensure the event is delivered return true; -} +}*/ void MessageManager::broadcastMessage (const String& value) throw() { + /* TODO */ } void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func, void* parameter) { - void* retVal = 0; + if (errorOccurred) + return 0; - if (! errorCondition) + if (! isThisTheMessageThread()) { - if (! isThisTheMessageThread()) - { - static MessageThreadFuncCall messageFuncCallContext; + MessageThreadFuncCall messageCallContext; + messageCallContext.func = func; + messageCallContext.parameter = parameter; - const ScopedLock sl (messageFuncCallContext.lock); + juce_internalMessageQueue->postMessage (new Message (MessageThreadFuncCall::uniqueID, + 0, 0, &messageCallContext)); - XClientMessageEvent clientMsg; - clientMsg.display = display; - clientMsg.window = juce_messageWindowHandle; - clientMsg.type = ClientMessage; - clientMsg.format = 32; - clientMsg.message_type = specialCallbackId; -#if JUCE_64BIT - clientMsg.data.l[0] = (long) (0x00000000ffffffff & (((uint64) &messageFuncCallContext) >> 32)); - clientMsg.data.l[1] = (long) (0x00000000ffffffff & (uint64) &messageFuncCallContext); -#else - clientMsg.data.l[0] = (long) &messageFuncCallContext; -#endif + // Wait for it to complete before continuing + messageCallContext.event.wait(); - messageFuncCallContext.func = func; - messageFuncCallContext.parameter = parameter; - - if (XSendEvent (display, juce_messageWindowHandle, false, NoEventMask, (XEvent*) &clientMsg) == 0) - return 0; - - XFlush (display); // This is necessary to ensure the event is delivered - - // Wait for it to complete before continuing - messageFuncCallContext.event.wait(); - - retVal = messageFuncCallContext.result; - } - else - { - // Just call the function directly - retVal = func (parameter); - } + return messageCallContext.result; + } + else + { + // Just call the function directly + return func (parameter); } - - return retVal; } -bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) +// Wait for an event (either XEvent, or an internal Message) +static bool juce_sleepUntilEvent (const int timeoutMs) { - if (errorCondition) - return false; + if ((display != 0 && XPending (display)) || ! juce_internalMessageQueue->isEmpty()) + return true; - if (breakIn) + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeoutMs * 1000; + int fd0 = juce_internalMessageQueue->getWaitHandle(); + int fdmax = fd0; + + fd_set readset; + FD_ZERO (&readset); + FD_SET (fd0, &readset); + + if (display != 0) { - errorCondition = true; - - if (juce_isRunningAsApplication()) - Process::terminate(); - - return false; + int fd1 = XConnectionNumber (display); + FD_SET (fd1, &readset); + fdmax = jmax (fd0, fd1); } - if (returnIfNoPendingMessages && ! XPending (display)) + int ret = select (fdmax + 1, &readset, 0, 0, &tv); + return (ret > 0); // ret <= 0 if error or timeout +} + +// Handle next XEvent (if any) +static bool juce_dispatchNextXEvent() +{ + if (display == 0 || ! XPending (display)) return false; XEvent evt; XNextEvent (display, &evt); - if (evt.type == ClientMessage && evt.xany.window == juce_messageWindowHandle) + if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle) { - XClientMessageEvent* const clientMsg = (XClientMessageEvent*) &evt; - - if (clientMsg->format != 32) - { - jassertfalse - DBG ("Error: juce_dispatchNextMessageOnSystemQueue received malformed client message."); - } - else - { - JUCE_TRY - { -#if JUCE_64BIT - void* const messagePtr - = (void*) ((0xffffffff00000000 & (((uint64) clientMsg->data.l[0]) << 32)) - | (clientMsg->data.l[1] & 0x00000000ffffffff)); -#else - void* const messagePtr = (void*) (clientMsg->data.l[0]); -#endif - - if (clientMsg->message_type == specialId) - { - MessageManager::getInstance()->deliverMessage (messagePtr); - } - else if (clientMsg->message_type == specialCallbackId) - { - MessageThreadFuncCall* const call = (MessageThreadFuncCall*) messagePtr; - MessageCallbackFunction* func = call->func; - call->result = (*func) (call->parameter); - call->event.signal(); - } - else if (clientMsg->message_type == broadcastId) - { -#if 0 - TCHAR buffer[8192]; - zeromem (buffer, sizeof (buffer)); - - if (GlobalGetAtomName ((ATOM) lParam, buffer, 8192) != 0) - mq->deliverBroadcastMessage (String (buffer)); -#endif - } - else - { - DBG ("Error: juce_dispatchNextMessageOnSystemQueue received unknown client message."); - } - } - JUCE_CATCH_ALL - } + juce_handleSelectionRequest (evt.xselectionrequest); } else if (evt.xany.window != juce_messageWindowHandle) { @@ -253040,6 +253292,76 @@ bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) return true; } +// Handle next internal Message (if any) +static bool juce_dispatchNextInternalMessage() +{ + if (juce_internalMessageQueue->isEmpty()) + return false; + + ScopedPointer msg (juce_internalMessageQueue->popMessage()); + + if (msg->intParameter1 == MessageThreadFuncCall::uniqueID) + { + // Handle callback message + MessageThreadFuncCall* const call = (MessageThreadFuncCall*) msg->pointerParameter; + + call->result = (*(call->func)) (call->parameter); + call->event.signal(); + } + else + { + // Handle "normal" messages + MessageManager::getInstance()->deliverMessage (msg.release()); + } + + return true; +} + +// this function expects that it will NEVER be called simultaneously for two concurrent threads +bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) +{ + for (;;) + { + if (errorOccurred) + break; + + if (keyboardBreakOccurred) + { + errorOccurred = true; + + if (JUCEApplication::getInstance() != 0) + Process::terminate(); + + break; + } + + static int totalEventCount = 0; + ++totalEventCount; + + // The purpose here is to give either priority to XEvents or + // to internal messages This is necessary to keep a "good" + // behaviour when the cpu is overloaded + if (totalEventCount & 1) + { + if (juce_dispatchNextXEvent() || juce_dispatchNextInternalMessage()) + return true; + } + else + { + if (juce_dispatchNextInternalMessage() || juce_dispatchNextXEvent()) + return true; + } + + if (returnIfNoPendingMessages) // early exit + break; + + // the timeout is to be on the safe side, but it does not seem to be useful + juce_sleepUntilEvent (2000); + } + + return false; +} + #endif /********* End of inlined file: juce_linux_Messaging.cpp *********/ @@ -253667,12 +253989,6 @@ bool Process::isForegroundProcess() return isActiveApplication; } -// (used in the messaging code, declared here for build reasons) -bool juce_isRunningAsApplication() -{ - return JUCEApplication::getInstance() != 0; -} - // These are defined in juce_linux_Messaging.cpp extern Display* display; extern XContext improbableNumber; @@ -254170,7 +254486,7 @@ public: // blit results to screen. #if JUCE_USE_XSHM if (usingXShm) - XShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, False); + XShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, True); else #endif XPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh); @@ -255182,6 +255498,10 @@ public: break; default: +#if JUCE_USE_XSHM + if (event->xany.type == XShmGetEventBase (display)) + repainter->notifyPaintCompleted(); +#endif break; } } @@ -255269,6 +255589,8 @@ private: lastTimeImageUsed (0) { #if JUCE_USE_XSHM + shmCompletedDrawing = true; + useARGBImagesForRendering = isShmAvailable(); if (useARGBImagesForRendering) @@ -255291,7 +255613,7 @@ private: void timerCallback() { - if (! regionsNeedingRepaint.isEmpty()) + if (! regionsNeedingRepaint.isEmpty() && shmCompletedDrawing) { stopTimer(); performAnyPendingRepaintsNow(); @@ -255319,6 +255641,8 @@ private: if (! totalArea.isEmpty()) { + shmCompletedDrawing = false; + if (image == 0 || image->getWidth() < totalArea.getWidth() || image->getHeight() < totalArea.getHeight()) { @@ -255362,6 +255686,13 @@ private: startTimer (repaintTimerPeriod); } +#if JUCE_USE_XSHM + void notifyPaintCompleted() + { + shmCompletedDrawing = true; + } +#endif + private: LinuxComponentPeer* const peer; ScopedPointer image; @@ -255370,6 +255701,7 @@ private: #if JUCE_USE_XSHM bool useARGBImagesForRendering; + bool shmCompletedDrawing; #endif LinuxRepaintManager (const LinuxRepaintManager&); const LinuxRepaintManager& operator= (const LinuxRepaintManager&); @@ -256101,6 +256433,9 @@ void juce_windowMessageReceive (XEvent* event) void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool /*clipToWorkArea*/) throw() { + if (display == 0) + return; + #if JUCE_USE_XINERAMA int major_opcode, first_event, first_error; @@ -256629,84 +256964,6 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* component, #endif -static void initClipboard (Window root, Atom* cutBuffers) throw() -{ - static bool init = false; - - if (! init) - { - init = true; - - // Make sure all cut buffers exist before use - for (int i = 0; i < 8; i++) - { - XChangeProperty (display, root, cutBuffers[i], - XA_STRING, 8, PropModeAppend, NULL, 0); - } - } -} - -// Clipboard implemented currently using cut buffers -// rather than the more powerful selection method -void SystemClipboard::copyTextToClipboard (const String& clipText) throw() -{ - Window root = RootWindow (display, DefaultScreen (display)); - Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3, - XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 }; - - initClipboard (root, cutBuffers); - - XRotateWindowProperties (display, root, cutBuffers, 8, 1); - XChangeProperty (display, root, cutBuffers[0], - XA_STRING, 8, PropModeReplace, (const unsigned char*) (const char*) clipText, - clipText.length()); -} - -const String SystemClipboard::getTextFromClipboard() throw() -{ - const int bufSize = 64; // in words - String returnData; - int byteOffset = 0; - - Window root = RootWindow (display, DefaultScreen (display)); - - Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3, - XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 }; - - initClipboard (root, cutBuffers); - - for (;;) - { - unsigned long bytesLeft = 0, nitems = 0; - unsigned char* clipData = 0; - int actualFormat = 0; - Atom actualType; - - if (XGetWindowProperty (display, root, cutBuffers[0], byteOffset >> 2, bufSize, - False, XA_STRING, &actualType, &actualFormat, &nitems, &bytesLeft, - &clipData) == Success) - { - if (actualType == XA_STRING && actualFormat == 8) - { - byteOffset += nitems; - returnData += String ((const char*) clipData, nitems); - } - else - { - bytesLeft = 0; - } - - if (clipData != 0) - XFree (clipData); - } - - if (bytesLeft == 0) - break; - } - - return returnData; -} - bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) { jassertfalse // not implemented! @@ -258888,6 +259145,62 @@ void FileChooser::showPlatformDialog (OwnedArray& results, bool selectMultipleFiles, FilePreviewComponent* previewComponent) { + const tchar* const separator = T(":"); + String command ("zenity --file-selection"); + + if (title.isNotEmpty()) + command << " --title=\"" << title << "\""; + + if (file != File::nonexistent) + command << " --filename=\"" << file.getFullPathName () << "\""; + + if (isDirectory) + command << " --directory"; + + if (isSave) + command << " --save"; + + if (selectMultipleFiles) + command << " --multiple --separator=\"" << separator << "\""; + + command << " 2>&1"; + + MemoryOutputStream result; + int status = -1; + FILE* stream = popen ((const char*) command.toUTF8(), "r"); + + if (stream != 0) + { + for (;;) + { + char buffer [1024]; + const int bytesRead = fread (buffer, 1, sizeof (buffer), stream); + + if (bytesRead <= 0) + break; + + result.write (buffer, bytesRead); + } + + status = pclose (stream); + } + + if (status == 0) + { + String resultString (String::fromUTF8 ((const uint8*) result.getData(), result.getDataSize())); + StringArray tokens; + + if (selectMultipleFiles) + tokens.addTokens (resultString, separator, 0); + else + tokens.add (resultString); + + for (int i = 0; i < tokens.size(); i++) + results.add (new File (tokens[i])); + + return; + } + //xxx ain't got one! jassertfalse } @@ -273681,7 +273994,6 @@ END_JUCE_NAMESPACE - (void) captureOutput: (QTCaptureFileOutput*) captureOutput didOutputSampleBuffer: (QTSampleBuffer*) sampleBuffer fromConnection: (QTCaptureConnection*) connection; - @end BEGIN_JUCE_NAMESPACE @@ -273747,6 +274059,7 @@ public: void resetFile() { + [fileOutput recordToOutputFileURL: nil]; [session removeOutput: fileOutput]; [fileOutput release]; fileOutput = [[QTCaptureMovieFileOutput alloc] init]; @@ -273826,11 +274139,14 @@ END_JUCE_NAMESPACE withSampleBuffer: (QTSampleBuffer*) sampleBuffer fromConnection: (QTCaptureConnection*) connection { - const ScopedAutoReleasePool pool; + if (internal->listeners.size() > 0) + { + const ScopedAutoReleasePool pool; - internal->callListeners ([CIImage imageWithCVImageBuffer: videoFrame], - CVPixelBufferGetWidth (videoFrame), - CVPixelBufferGetHeight (videoFrame)); + internal->callListeners ([CIImage imageWithCVImageBuffer: videoFrame], + CVPixelBufferGetWidth (videoFrame), + CVPixelBufferGetHeight (videoFrame)); + } } - (void) captureOutput: (QTCaptureFileOutput*) captureOutput @@ -273962,12 +274278,11 @@ CameraDevice* CameraDevice::openDevice (int index, int minWidth, int minHeight, int maxWidth, int maxHeight) { - CameraDevice* d = new CameraDevice (getAvailableDevices() [index], index); + ScopedPointer d (new CameraDevice (getAvailableDevices() [index], index)); if (((QTCameraDeviceInteral*) (d->internal))->openingError.isEmpty()) - return d; + return d.release(); - delete d; return 0; } diff --git a/src/native/juce_linux_NativeCode.cpp b/src/native/juce_linux_NativeCode.cpp index 35d9e84ef8..0606fd57ce 100644 --- a/src/native/juce_linux_NativeCode.cpp +++ b/src/native/juce_linux_NativeCode.cpp @@ -41,6 +41,7 @@ BEGIN_JUCE_NAMESPACE #include "../core/juce_Random.h" #include "../io/network/juce_URL.h" #include "../io/files/juce_NamedPipe.h" +#include "../io/streams/juce_MemoryOutputStream.h" #include "../threads/juce_InterProcessLock.h" #include "../audio/devices/juce_AudioIODeviceType.h" #include "../threads/juce_Thread.h" @@ -100,6 +101,7 @@ BEGIN_JUCE_NAMESPACE #include "linux/juce_linux_Threads.cpp" #if ! JUCE_ONLY_BUILD_CORE_LIBRARY + #include "linux/juce_linux_Clipboard.cpp" #include "linux/juce_linux_Messaging.cpp" #include "linux/juce_linux_Fonts.cpp" #include "linux/juce_linux_Windowing.cpp" diff --git a/src/native/linux/juce_linux_Clipboard.cpp b/src/native/linux/juce_linux_Clipboard.cpp new file mode 100644 index 0000000000..6a513a0a99 --- /dev/null +++ b/src/native/linux/juce_linux_Clipboard.cpp @@ -0,0 +1,266 @@ +/* + ============================================================================== + + 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_linux_NativeCode.cpp, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE + +//============================================================================== +#ifdef JUCE_DEBUG + #define JUCE_DEBUG_XERRORS 1 +#endif + +extern Display* display; +extern Window juce_messageWindowHandle; + +static String localClipboardContent; +static Atom atom_UTF8_STRING; +static Atom atom_CLIPBOARD; +static Atom atom_TARGETS; + +//============================================================================== +static void initSelectionAtoms() +{ + static bool isInitialised = false; + if (! isInitialised) + { + atom_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); + atom_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False); + atom_TARGETS = XInternAtom (display, "TARGETS", False); + } +} + +//============================================================================== +// Read the content of a window property as either a locale-dependent string or an utf8 string +// works only for strings shorter than 1000000 bytes +static String juce_readWindowProperty (Window window, Atom prop, + Atom fmt, // XA_STRING or UTF8_STRING + bool deleteAfterReading) +{ + String returnData; + uint8 *clipData; + Atom actualType; + int actualFormat; + unsigned long numItems, bytesLeft; + + if (XGetWindowProperty (display, window, prop, + 0L /* offset */, 1000000 /* length (max) */, False, + AnyPropertyType /* format */, + &actualType, &actualFormat, &numItems, &bytesLeft, + &clipData) == Success) + { + if (actualType == atom_UTF8_STRING && actualFormat == 8) + { + returnData = String::fromUTF8 (clipData, numItems); + } + else if (actualType == XA_STRING && actualFormat == 8) + { + returnData = String ((const char*) clipData, numItems); + } + + if (clipData != 0) + XFree (clipData); + + jassert (bytesLeft == 0 || numItems == 1000000); + } + + if (deleteAfterReading) + XDeleteProperty (display, window, prop); + + return returnData; +} + +//============================================================================== +// Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */ +static bool juce_requestSelectionContent (String &selection_content, Atom selection, Atom requested_format) +{ + Atom property_name = XInternAtom (display, "JUCE_SEL", false); + + // The selection owner will be asked to set the JUCE_SEL property on the + // juce_messageWindowHandle with the selection content + XConvertSelection (display, selection, requested_format, property_name, + juce_messageWindowHandle, CurrentTime); + + int timeoutMs = 200; // will wait at most for 200 ms + + do + { + XEvent event; + + if (XCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event)) + { + if (event.xselection.property == property_name) + { + jassert (event.xselection.requestor == juce_messageWindowHandle); + + selection_content = juce_readWindowProperty (event.xselection.requestor, + event.xselection.property, + requested_format, true); + return true; + } + else + { + return false; // the format we asked for was denied.. (event.xselection.property == None) + } + } + + // not very elegant.. we could do a select() or something like that... + // however clipboard content requesting is inherently slow on x11, it + // often takes 50ms or more so... + Thread::sleep (4); + timeoutMs -= 4; + } + while (timeoutMs > 0); + + DBG("timeout for juce_requestSelectionContent"); + return false; +} + +//============================================================================== +// Called from the event loop in juce_linux_Messaging in response to SelectionRequest events +void juce_handleSelectionRequest (XSelectionRequestEvent &evt) +{ + initSelectionAtoms(); + + // the selection content is sent to the target window as a window property + XSelectionEvent reply; + reply.type = SelectionNotify; + reply.display = evt.display; + reply.requestor = evt.requestor; + reply.selection = evt.selection; + reply.target = evt.target; + reply.property = None; // == "fail" + reply.time = evt.time; + + HeapBlock data; + int propertyFormat = 0, numDataItems = 0; + + if (evt.selection == XA_PRIMARY || evt.selection == atom_CLIPBOARD) + { + if (evt.target == XA_STRING) + { + // format data according to system locale + numDataItems = localClipboardContent.length(); + data.calloc (numDataItems + 2); + localClipboardContent.copyToBuffer ((char*) data, numDataItems + 1); + propertyFormat = 8; // bits/item + } + else if (evt.target == atom_UTF8_STRING) + { + // translate to utf8 + numDataItems = localClipboardContent.copyToUTF8 (0); + data.calloc (numDataItems + 2); + localClipboardContent.copyToUTF8 (data, numDataItems + 1); + propertyFormat = 8; // bits/item + } + else if (evt.target == atom_TARGETS) + { + // another application wants to know what we are able to send + numDataItems = 2; + propertyFormat = 32; // atoms are 32-bit + data.calloc (numDataItems * 4); + ((Atom*) data)[0] = atom_UTF8_STRING; + ((Atom*) data)[1] = XA_STRING; + } + } + else + { + DBG ("requested unsupported clipboard"); + } + + if (data != 0) + { + const int maxReasonableSelectionSize = 1000000; + + // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss + if (evt.property != None && numDataItems < maxReasonableSelectionSize) + { + XChangeProperty (evt.display, evt.requestor, + evt.property, evt.target, + propertyFormat /* 8 or 32 */, PropModeReplace, + (const unsigned char*) data, numDataItems); + reply.property = evt.property; // " == success" + } + } + + XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); +} + +//============================================================================== +void SystemClipboard::copyTextToClipboard (const String& clipText) throw() +{ + initSelectionAtoms(); + localClipboardContent = clipText; + + XSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime); + XSetSelectionOwner (display, atom_CLIPBOARD, juce_messageWindowHandle, CurrentTime); +} + +const String SystemClipboard::getTextFromClipboard() throw() +{ + initSelectionAtoms(); + + /* 1) try to read from the "CLIPBOARD" selection first (the "high + level" clipboard that is supposed to be filled by ctrl-C + etc). When a clipboard manager is running, the content of this + selection is preserved even when the original selection owner + exits. + + 2) and then try to read from "PRIMARY" selection (the "legacy" selection + filled by good old x11 apps such as xterm) + */ + String content; + Atom selection = XA_PRIMARY; + Window selectionOwner = None; + + if ((selectionOwner = XGetSelectionOwner (display, selection)) == None) + { + selection = atom_CLIPBOARD; + selectionOwner = XGetSelectionOwner (display, selection); + } + + if (selectionOwner != None) + { + if (selectionOwner == juce_messageWindowHandle) + { + content = localClipboardContent; + } + else + { + // first try: we want an utf8 string + bool ok = juce_requestSelectionContent (content, selection, atom_UTF8_STRING); + + if (! ok) + { + // second chance, ask for a good old locale-dependent string .. + ok = juce_requestSelectionContent (content, selection, XA_STRING); + } + } + } + + return content; +} + +#endif diff --git a/src/native/linux/juce_linux_FileChooser.cpp b/src/native/linux/juce_linux_FileChooser.cpp index d786fdf23e..24fb7e0a66 100644 --- a/src/native/linux/juce_linux_FileChooser.cpp +++ b/src/native/linux/juce_linux_FileChooser.cpp @@ -39,6 +39,62 @@ void FileChooser::showPlatformDialog (OwnedArray& results, bool selectMultipleFiles, FilePreviewComponent* previewComponent) { + const tchar* const separator = T(":"); + String command ("zenity --file-selection"); + + if (title.isNotEmpty()) + command << " --title=\"" << title << "\""; + + if (file != File::nonexistent) + command << " --filename=\"" << file.getFullPathName () << "\""; + + if (isDirectory) + command << " --directory"; + + if (isSave) + command << " --save"; + + if (selectMultipleFiles) + command << " --multiple --separator=\"" << separator << "\""; + + command << " 2>&1"; + + MemoryOutputStream result; + int status = -1; + FILE* stream = popen ((const char*) command.toUTF8(), "r"); + + if (stream != 0) + { + for (;;) + { + char buffer [1024]; + const int bytesRead = fread (buffer, 1, sizeof (buffer), stream); + + if (bytesRead <= 0) + break; + + result.write (buffer, bytesRead); + } + + status = pclose (stream); + } + + if (status == 0) + { + String resultString (String::fromUTF8 ((const uint8*) result.getData(), result.getDataSize())); + StringArray tokens; + + if (selectMultipleFiles) + tokens.addTokens (resultString, separator, 0); + else + tokens.add (resultString); + + for (int i = 0; i < tokens.size(); i++) + results.add (new File (tokens[i])); + + return; + } + //xxx ain't got one! jassertfalse } diff --git a/src/native/linux/juce_linux_Messaging.cpp b/src/native/linux/juce_linux_Messaging.cpp index 753e2e8266..34c39dacda 100644 --- a/src/native/linux/juce_linux_Messaging.cpp +++ b/src/native/linux/juce_linux_Messaging.cpp @@ -29,11 +29,11 @@ //============================================================================== #ifdef JUCE_DEBUG - #define JUCE_DEBUG_XERRORS 1 + #define JUCE_DEBUG_XERRORS 1 #endif Display* display = 0; // This is also referenced from WindowDriver.cpp -static Window juce_messageWindowHandle = None; +Window juce_messageWindowHandle = None; #define SpecialAtom "JUCESpecialAtom" #define BroadcastAtom "JUCEBroadcastAtom" @@ -49,8 +49,70 @@ XContext improbableNumber; // Defined in WindowDriver.cpp extern void juce_windowMessageReceive (XEvent* event); +// Defined in ClipboardDriver.cpp +extern void juce_handleSelectionRequest (XSelectionRequestEvent &evt); + +//============================================================================== +class InternalMessageQueue +{ +public: + InternalMessageQueue() + { + int ret = ::socketpair (AF_LOCAL, SOCK_STREAM, 0, fd); + (void) ret; jassert (ret == 0); + } + + ~InternalMessageQueue() + { + close (fd[0]); + close (fd[1]); + } + + void postMessage (Message* msg) + { + ScopedLock sl (lock); + queue.add (msg); + + const unsigned char x = 0xff; + write (fd[0], &x, 1); + } + + bool isEmpty() const + { + ScopedLock sl (lock); + return queue.size() == 0; + } + + Message* popMessage() + { + Message* m = 0; + ScopedLock sl (lock); + + if (queue.size() != 0) + { + unsigned char x; + read (fd[1], &x, 1); + + m = queue.getUnchecked(0); + queue.remove (0, false /* deleteObject */); + } + + return m; + } + + int getWaitHandle() const { return fd[1]; } + +private: + CriticalSection lock; + OwnedArray queue; + int fd[2]; +}; + +//============================================================================== struct MessageThreadFuncCall { + enum { uniqueID = 0x73774623 }; + MessageCallbackFunction* func; void* parameter; void* result; @@ -58,21 +120,23 @@ struct MessageThreadFuncCall WaitableEvent event; }; -static bool errorCondition = false; +//============================================================================== +static InternalMessageQueue* juce_internalMessageQueue = 0; + +// error handling in X11 +static bool errorOccurred = false; +static bool keyboardBreakOccurred = false; static XErrorHandler oldErrorHandler = (XErrorHandler) 0; static XIOErrorHandler oldIOErrorHandler = (XIOErrorHandler) 0; -// (defined in another file to avoid problems including certain headers in this one) -extern bool juce_isRunningAsApplication(); - // Usually happens when client-server connection is broken static int ioErrorHandler (Display* display) { DBG (T("ERROR: connection to X server broken.. terminating.")); - errorCondition = true; + errorOccurred = true; - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) Process::terminate(); return 0; @@ -100,20 +164,18 @@ static int errorHandler (Display* display, XErrorEvent* event) return 0; } -static bool breakIn = false; - // Breakin from keyboard -static void sig_handler (int sig) +static void signalHandler (int sig) { if (sig == SIGINT) { - breakIn = true; + keyboardBreakOccurred = true; return; } static bool reentrant = false; - if (reentrant == false) + if (! reentrant) { reentrant = true; @@ -121,14 +183,14 @@ static void sig_handler (int sig) fflush (stdout); Logger::outputDebugString ("ERROR: Program executed illegal instruction.. terminating"); - errorCondition = true; + errorOccurred = true; - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) Process::terminate(); } else { - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) exit(0); } } @@ -146,7 +208,7 @@ void MessageManager::doPlatformSpecificInitialisation() // This is fatal! Print error and closedown Logger::outputDebugString ("Failed to initialise xlib thread support."); - if (juce_isRunningAsApplication()) + if (JUCEApplication::getInstance() != 0) Process::terminate(); return; @@ -165,7 +227,7 @@ void MessageManager::doPlatformSpecificInitialisation() struct sigaction saction; sigset_t maskSet; sigemptyset (&maskSet); - saction.sa_handler = sig_handler; + saction.sa_handler = signalHandler; saction.sa_mask = maskSet; saction.sa_flags = 0; sigaction (SIGINT, &saction, NULL); @@ -179,6 +241,10 @@ void MessageManager::doPlatformSpecificInitialisation() sigaction (SIGSYS, &saction, NULL); #endif + // Create the internal message queue + juce_internalMessageQueue = new InternalMessageQueue(); + + // Try to connect to a display String displayName (getenv ("DISPLAY")); if (displayName.isEmpty()) displayName = T(":0.0"); @@ -187,12 +253,7 @@ void MessageManager::doPlatformSpecificInitialisation() if (display == 0) { - // This is fatal! Print error and closedown - Logger::outputDebugString ("Failed to open the X display."); - - if (juce_isRunningAsApplication()) - Process::terminate(); - + // This is not fatal! we can run headless. return; } @@ -223,7 +284,9 @@ void MessageManager::doPlatformSpecificInitialisation() void MessageManager::doPlatformSpecificShutdown() { - if (errorCondition == false) + deleteAndZero (juce_internalMessageQueue); + + if (display != 0 && ! errorOccurred) { XDestroyWindow (display, juce_messageWindowHandle); XCloseDisplay (display); @@ -242,9 +305,15 @@ void MessageManager::doPlatformSpecificShutdown() bool juce_postMessageToSystemQueue (void* message) { - if (errorCondition) + if (errorOccurred) return false; + juce_internalMessageQueue->postMessage ((Message*) message); + return true; +} + +/*bool juce_postMessageToX11Queue (void *message) +{ XClientMessageEvent clientMsg; clientMsg.display = display; clientMsg.window = juce_messageWindowHandle; @@ -264,131 +333,79 @@ bool juce_postMessageToSystemQueue (void* message) XFlush (display); // This is necessary to ensure the event is delivered return true; -} +}*/ void MessageManager::broadcastMessage (const String& value) throw() { + /* TODO */ } void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func, void* parameter) { - void* retVal = 0; + if (errorOccurred) + return 0; - if (! errorCondition) + if (! isThisTheMessageThread()) { - if (! isThisTheMessageThread()) - { - static MessageThreadFuncCall messageFuncCallContext; + MessageThreadFuncCall messageCallContext; + messageCallContext.func = func; + messageCallContext.parameter = parameter; - const ScopedLock sl (messageFuncCallContext.lock); + juce_internalMessageQueue->postMessage (new Message (MessageThreadFuncCall::uniqueID, + 0, 0, &messageCallContext)); - XClientMessageEvent clientMsg; - clientMsg.display = display; - clientMsg.window = juce_messageWindowHandle; - clientMsg.type = ClientMessage; - clientMsg.format = 32; - clientMsg.message_type = specialCallbackId; -#if JUCE_64BIT - clientMsg.data.l[0] = (long) (0x00000000ffffffff & (((uint64) &messageFuncCallContext) >> 32)); - clientMsg.data.l[1] = (long) (0x00000000ffffffff & (uint64) &messageFuncCallContext); -#else - clientMsg.data.l[0] = (long) &messageFuncCallContext; -#endif + // Wait for it to complete before continuing + messageCallContext.event.wait(); - messageFuncCallContext.func = func; - messageFuncCallContext.parameter = parameter; - - if (XSendEvent (display, juce_messageWindowHandle, false, NoEventMask, (XEvent*) &clientMsg) == 0) - return 0; - - XFlush (display); // This is necessary to ensure the event is delivered - - // Wait for it to complete before continuing - messageFuncCallContext.event.wait(); - - retVal = messageFuncCallContext.result; - } - else - { - // Just call the function directly - retVal = func (parameter); - } + return messageCallContext.result; + } + else + { + // Just call the function directly + return func (parameter); } - - return retVal; } -bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) +// Wait for an event (either XEvent, or an internal Message) +static bool juce_sleepUntilEvent (const int timeoutMs) { - if (errorCondition) - return false; + if ((display != 0 && XPending (display)) || ! juce_internalMessageQueue->isEmpty()) + return true; - if (breakIn) + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeoutMs * 1000; + int fd0 = juce_internalMessageQueue->getWaitHandle(); + int fdmax = fd0; + + fd_set readset; + FD_ZERO (&readset); + FD_SET (fd0, &readset); + + if (display != 0) { - errorCondition = true; - - if (juce_isRunningAsApplication()) - Process::terminate(); - - return false; + int fd1 = XConnectionNumber (display); + FD_SET (fd1, &readset); + fdmax = jmax (fd0, fd1); } - if (returnIfNoPendingMessages && ! XPending (display)) + int ret = select (fdmax + 1, &readset, 0, 0, &tv); + return (ret > 0); // ret <= 0 if error or timeout +} + +// Handle next XEvent (if any) +static bool juce_dispatchNextXEvent() +{ + if (display == 0 || ! XPending (display)) return false; XEvent evt; XNextEvent (display, &evt); - if (evt.type == ClientMessage && evt.xany.window == juce_messageWindowHandle) + if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle) { - XClientMessageEvent* const clientMsg = (XClientMessageEvent*) &evt; - - if (clientMsg->format != 32) - { - jassertfalse - DBG ("Error: juce_dispatchNextMessageOnSystemQueue received malformed client message."); - } - else - { - JUCE_TRY - { -#if JUCE_64BIT - void* const messagePtr - = (void*) ((0xffffffff00000000 & (((uint64) clientMsg->data.l[0]) << 32)) - | (clientMsg->data.l[1] & 0x00000000ffffffff)); -#else - void* const messagePtr = (void*) (clientMsg->data.l[0]); -#endif - - if (clientMsg->message_type == specialId) - { - MessageManager::getInstance()->deliverMessage (messagePtr); - } - else if (clientMsg->message_type == specialCallbackId) - { - MessageThreadFuncCall* const call = (MessageThreadFuncCall*) messagePtr; - MessageCallbackFunction* func = call->func; - call->result = (*func) (call->parameter); - call->event.signal(); - } - else if (clientMsg->message_type == broadcastId) - { -#if 0 - TCHAR buffer[8192]; - zeromem (buffer, sizeof (buffer)); - - if (GlobalGetAtomName ((ATOM) lParam, buffer, 8192) != 0) - mq->deliverBroadcastMessage (String (buffer)); -#endif - } - else - { - DBG ("Error: juce_dispatchNextMessageOnSystemQueue received unknown client message."); - } - } - JUCE_CATCH_ALL - } + juce_handleSelectionRequest (evt.xselectionrequest); } else if (evt.xany.window != juce_messageWindowHandle) { @@ -398,4 +415,74 @@ bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) return true; } +// Handle next internal Message (if any) +static bool juce_dispatchNextInternalMessage() +{ + if (juce_internalMessageQueue->isEmpty()) + return false; + + ScopedPointer msg (juce_internalMessageQueue->popMessage()); + + if (msg->intParameter1 == MessageThreadFuncCall::uniqueID) + { + // Handle callback message + MessageThreadFuncCall* const call = (MessageThreadFuncCall*) msg->pointerParameter; + + call->result = (*(call->func)) (call->parameter); + call->event.signal(); + } + else + { + // Handle "normal" messages + MessageManager::getInstance()->deliverMessage (msg.release()); + } + + return true; +} + +// this function expects that it will NEVER be called simultaneously for two concurrent threads +bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) +{ + for (;;) + { + if (errorOccurred) + break; + + if (keyboardBreakOccurred) + { + errorOccurred = true; + + if (JUCEApplication::getInstance() != 0) + Process::terminate(); + + break; + } + + static int totalEventCount = 0; + ++totalEventCount; + + // The purpose here is to give either priority to XEvents or + // to internal messages This is necessary to keep a "good" + // behaviour when the cpu is overloaded + if (totalEventCount & 1) + { + if (juce_dispatchNextXEvent() || juce_dispatchNextInternalMessage()) + return true; + } + else + { + if (juce_dispatchNextInternalMessage() || juce_dispatchNextXEvent()) + return true; + } + + if (returnIfNoPendingMessages) // early exit + break; + + // the timeout is to be on the safe side, but it does not seem to be useful + juce_sleepUntilEvent (2000); + } + + return false; +} + #endif diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index 9c9afbfa3d..7e706bd9db 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -100,12 +100,6 @@ bool Process::isForegroundProcess() return isActiveApplication; } -// (used in the messaging code, declared here for build reasons) -bool juce_isRunningAsApplication() -{ - return JUCEApplication::getInstance() != 0; -} - //============================================================================== // These are defined in juce_linux_Messaging.cpp extern Display* display; @@ -611,7 +605,7 @@ public: // blit results to screen. #if JUCE_USE_XSHM if (usingXShm) - XShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, False); + XShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, True); else #endif XPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh); @@ -1627,6 +1621,10 @@ public: break; default: +#if JUCE_USE_XSHM + if (event->xany.type == XShmGetEventBase (display)) + repainter->notifyPaintCompleted(); +#endif break; } } @@ -1716,6 +1714,8 @@ private: lastTimeImageUsed (0) { #if JUCE_USE_XSHM + shmCompletedDrawing = true; + useARGBImagesForRendering = isShmAvailable(); if (useARGBImagesForRendering) @@ -1738,7 +1738,7 @@ private: void timerCallback() { - if (! regionsNeedingRepaint.isEmpty()) + if (! regionsNeedingRepaint.isEmpty() && shmCompletedDrawing) { stopTimer(); performAnyPendingRepaintsNow(); @@ -1766,6 +1766,8 @@ private: if (! totalArea.isEmpty()) { + shmCompletedDrawing = false; + if (image == 0 || image->getWidth() < totalArea.getWidth() || image->getHeight() < totalArea.getHeight()) { @@ -1809,6 +1811,13 @@ private: startTimer (repaintTimerPeriod); } +#if JUCE_USE_XSHM + void notifyPaintCompleted() + { + shmCompletedDrawing = true; + } +#endif + private: LinuxComponentPeer* const peer; ScopedPointer image; @@ -1817,6 +1826,7 @@ private: #if JUCE_USE_XSHM bool useARGBImagesForRendering; + bool shmCompletedDrawing; #endif LinuxRepaintManager (const LinuxRepaintManager&); const LinuxRepaintManager& operator= (const LinuxRepaintManager&); @@ -2555,6 +2565,9 @@ void juce_windowMessageReceive (XEvent* event) //============================================================================== void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool /*clipToWorkArea*/) throw() { + if (display == 0) + return; + #if JUCE_USE_XINERAMA int major_opcode, first_event, first_error; @@ -3096,85 +3109,6 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* component, #endif -//============================================================================== -static void initClipboard (Window root, Atom* cutBuffers) throw() -{ - static bool init = false; - - if (! init) - { - init = true; - - // Make sure all cut buffers exist before use - for (int i = 0; i < 8; i++) - { - XChangeProperty (display, root, cutBuffers[i], - XA_STRING, 8, PropModeAppend, NULL, 0); - } - } -} - -// Clipboard implemented currently using cut buffers -// rather than the more powerful selection method -void SystemClipboard::copyTextToClipboard (const String& clipText) throw() -{ - Window root = RootWindow (display, DefaultScreen (display)); - Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3, - XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 }; - - initClipboard (root, cutBuffers); - - XRotateWindowProperties (display, root, cutBuffers, 8, 1); - XChangeProperty (display, root, cutBuffers[0], - XA_STRING, 8, PropModeReplace, (const unsigned char*) (const char*) clipText, - clipText.length()); -} - -const String SystemClipboard::getTextFromClipboard() throw() -{ - const int bufSize = 64; // in words - String returnData; - int byteOffset = 0; - - Window root = RootWindow (display, DefaultScreen (display)); - - Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3, - XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 }; - - initClipboard (root, cutBuffers); - - for (;;) - { - unsigned long bytesLeft = 0, nitems = 0; - unsigned char* clipData = 0; - int actualFormat = 0; - Atom actualType; - - if (XGetWindowProperty (display, root, cutBuffers[0], byteOffset >> 2, bufSize, - False, XA_STRING, &actualType, &actualFormat, &nitems, &bytesLeft, - &clipData) == Success) - { - if (actualType == XA_STRING && actualFormat == 8) - { - byteOffset += nitems; - returnData += String ((const char*) clipData, nitems); - } - else - { - bytesLeft = 0; - } - - if (clipData != 0) - XFree (clipData); - } - - if (bytesLeft == 0) - break; - } - - return returnData; -} - //============================================================================== bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) { diff --git a/src/native/mac/juce_mac_CameraDevice.mm b/src/native/mac/juce_mac_CameraDevice.mm index 5a3e378cfa..a689123d58 100644 --- a/src/native/mac/juce_mac_CameraDevice.mm +++ b/src/native/mac/juce_mac_CameraDevice.mm @@ -53,7 +53,6 @@ END_JUCE_NAMESPACE - (void) captureOutput: (QTCaptureFileOutput*) captureOutput didOutputSampleBuffer: (QTSampleBuffer*) sampleBuffer fromConnection: (QTCaptureConnection*) connection; - @end BEGIN_JUCE_NAMESPACE @@ -120,6 +119,7 @@ public: void resetFile() { + [fileOutput recordToOutputFileURL: nil]; [session removeOutput: fileOutput]; [fileOutput release]; fileOutput = [[QTCaptureMovieFileOutput alloc] init]; @@ -199,11 +199,14 @@ END_JUCE_NAMESPACE withSampleBuffer: (QTSampleBuffer*) sampleBuffer fromConnection: (QTCaptureConnection*) connection { - const ScopedAutoReleasePool pool; + if (internal->listeners.size() > 0) + { + const ScopedAutoReleasePool pool; - internal->callListeners ([CIImage imageWithCVImageBuffer: videoFrame], - CVPixelBufferGetWidth (videoFrame), - CVPixelBufferGetHeight (videoFrame)); + internal->callListeners ([CIImage imageWithCVImageBuffer: videoFrame], + CVPixelBufferGetWidth (videoFrame), + CVPixelBufferGetHeight (videoFrame)); + } } - (void) captureOutput: (QTCaptureFileOutput*) captureOutput @@ -338,12 +341,11 @@ CameraDevice* CameraDevice::openDevice (int index, int minWidth, int minHeight, int maxWidth, int maxHeight) { - CameraDevice* d = new CameraDevice (getAvailableDevices() [index], index); + ScopedPointer d (new CameraDevice (getAvailableDevices() [index], index)); if (((QTCameraDeviceInteral*) (d->internal))->openingError.isEmpty()) - return d; + return d.release(); - delete d; return 0; }