diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms.dll.sources b/mcs/class/Managed.Windows.Forms/System.Windows.Forms.dll.sources index 21946d5..8765f81 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms.dll.sources +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms.dll.sources @@ -805,6 +805,10 @@ System.Windows.Forms/X11Dnd.cs System.Windows.Forms/X11Keyboard.cs System.Windows.Forms/X11Structs.cs System.Windows.Forms/XEventQueue.cs +System.Windows.Forms/XplatClipboard.cs +System.Windows.Forms/XplatClipboardCarbon.cs +System.Windows.Forms/XplatClipboardWin32.cs +System.Windows.Forms/XplatClipboardX11.cs System.Windows.Forms/XplatUI.cs System.Windows.Forms/XplatUICarbon.cs System.Windows.Forms/XplatUIDriver.cs diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/.gitignore b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/.gitignore new file mode 100644 index 0000000..b25c15b --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs index 861bd99..615fdaf 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs @@ -21,192 +21,120 @@ // // Authors: // Peter Bartok (pbartok@novell.com) +// Ralph Leckett // // // COMPLETE using System; +using System.ComponentModel; +using System.Collections.Specialized; using System.Drawing; using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Collections; -using System.Collections.Specialized; -using System.ComponentModel; namespace System.Windows.Forms { public sealed class Clipboard { - #region Local Variables - #endregion // Local Variables + internal static XplatClipboard clipboard; - #region Constructors - private Clipboard() { + internal static void SetClipboard (XplatClipboard newClipboard) + { + clipboard = newClipboard; } - #endregion // Constructors - - #region Private Methods - private static bool ConvertToClipboardData(ref int type, object obj, out byte[] data) { - data = null; - return false; + + internal static IntPtr ClipboardOpen (bool primary_selection) + { + return clipboard.ClipboardOpen (primary_selection); } - private static bool ConvertFromClipboardData(int type, IntPtr data, out object obj) { - obj = null; - if (data == IntPtr.Zero) { - return false; - } - return false; + internal static void ClipboardClose (IntPtr handle) + { + clipboard.ClipboardClose (handle); } - #endregion // Private Methods - - #region Public Static Methods -#if NET_2_0 + public static void Clear () { - IntPtr clipboard_handle; - - clipboard_handle = XplatUI.ClipboardOpen (false); - XplatUI.ClipboardStore (clipboard_handle, null, 0, null); + clipboard.Clear (); } public static bool ContainsAudio () { - return ClipboardContainsFormat (DataFormats.WaveAudio); + return clipboard.ContainsAudio (); } public static bool ContainsData (string format) { - return ClipboardContainsFormat (format); + return clipboard.ContainsData (format); } public static bool ContainsFileDropList () { - return ClipboardContainsFormat (DataFormats.FileDrop); + return clipboard.ContainsFileDropList (); } public static bool ContainsImage () { - return ClipboardContainsFormat (DataFormats.Bitmap); + return clipboard.ContainsImage (); } public static bool ContainsText () { - return ClipboardContainsFormat (DataFormats.Text, DataFormats.UnicodeText); + return clipboard.ContainsText (); } public static bool ContainsText (TextDataFormat format) { - switch (format) { - case TextDataFormat.Text: - return ClipboardContainsFormat (DataFormats.Text); - case TextDataFormat.UnicodeText: - return ClipboardContainsFormat (DataFormats.UnicodeText); - case TextDataFormat.Rtf: - return ClipboardContainsFormat (DataFormats.Rtf); - case TextDataFormat.Html: - return ClipboardContainsFormat (DataFormats.Html); - case TextDataFormat.CommaSeparatedValue: - return ClipboardContainsFormat (DataFormats.CommaSeparatedValue); - } - - return false; + return clipboard.ContainsText (format); } public static Stream GetAudioStream () { - IDataObject data = GetDataObject (); - - if (data == null) - return null; - - return (Stream)data.GetData (DataFormats.WaveAudio, true); + return clipboard.GetAudioStream (); } public static Object GetData (string format) { - IDataObject data = GetDataObject (); - - if (data == null) - return null; - - return data.GetData (format, true); + return clipboard.GetData (format); } -#endif public static IDataObject GetDataObject () { - return GetDataObject (false); + return clipboard.GetDataObject (false); } -#if NET_2_0 + public static IDataObject GetDataObject (bool primary_selection) + { + return clipboard.GetDataObject (primary_selection); + } + public static StringCollection GetFileDropList () { - IDataObject data = GetDataObject (); - - if (data == null) - return null; - - return (StringCollection)data.GetData (DataFormats.FileDrop, true); + return clipboard.GetFileDropList (); } public static Image GetImage () { - IDataObject data = GetDataObject (); - - if (data == null) - return null; - - return (Image)data.GetData (DataFormats.Bitmap, true); + return clipboard.GetImage (); } public static string GetText () { - return GetText (TextDataFormat.UnicodeText); + return clipboard.GetText (); } public static string GetText (TextDataFormat format) { if (!Enum.IsDefined (typeof (TextDataFormat), format)) throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for TextDataFormat", format)); - - IDataObject data = GetDataObject (); - - if (data == null) - return string.Empty; - - string retval; - - switch (format) { - case TextDataFormat.Text: - default: - retval = (string)data.GetData (DataFormats.Text, true); - break; - case TextDataFormat.UnicodeText: - retval = (string)data.GetData (DataFormats.UnicodeText, true); - break; - case TextDataFormat.Rtf: - retval = (string)data.GetData (DataFormats.Rtf, true); - break; - case TextDataFormat.Html: - retval = (string)data.GetData (DataFormats.Html, true); - break; - case TextDataFormat.CommaSeparatedValue: - retval = (string)data.GetData (DataFormats.CommaSeparatedValue, true); - break; - } - - return retval == null ? string.Empty : retval; + return clipboard.GetText (format); } public static void SetAudio (byte[] audioBytes) { if (audioBytes == null) throw new ArgumentNullException ("audioBytes"); - - MemoryStream ms = new MemoryStream (audioBytes); - - SetAudio (ms); + + clipboard.SetAudio (audioBytes); } public static void SetAudio (Stream audioStream) @@ -214,135 +142,62 @@ namespace System.Windows.Forms { if (audioStream == null) throw new ArgumentNullException ("audioStream"); - SetData (DataFormats.WaveAudio, audioStream); + clipboard.SetAudio (audioStream); } public static void SetData (string format, Object data) { if (data == null) throw new ArgumentNullException ("data"); - - DataObject data_object = new DataObject (format, data); - SetDataObject (data_object); - } -#endif - - public static void SetDataObject(object data) { - SetDataObject(data, false); // MSDN says default behavior is to place non-persistent data to clipboard - } - public static void SetDataObject(object data, bool copy) { - SetDataObject(data, copy, 10, 100); // MSDN says default behavior is to try 10 times with 100 ms delay + clipboard.SetData (format, data); } - internal static void SetDataObjectImpl(object data, bool copy) { - IntPtr clipboard_handle; - XplatUI.ObjectToClipboard converter; - int native_format; - DataFormats.Format item_format; - - converter = new XplatUI.ObjectToClipboard(ConvertToClipboardData); - - clipboard_handle = XplatUI.ClipboardOpen(false); - XplatUI.ClipboardStore(clipboard_handle, null, 0, null); // Empty clipboard - - native_format = -1; - - if (data is IDataObject) { - string[] formats; - - IDataObject data_object = data as IDataObject; - formats = data_object.GetFormats(); - for (int i = 0; i < formats.Length; i++) { - item_format = DataFormats.GetFormat(formats[i]); - if ((item_format != null) && (item_format.Name != DataFormats.StringFormat)) { - native_format = item_format.Id; - } - - object obj = data_object.GetData (formats [i]); - - // this is used only by custom formats - if (IsDataSerializable (obj)) - item_format.is_serializable = true; - - XplatUI.ClipboardStore(clipboard_handle, obj, native_format, converter); - } - } else { - item_format = DataFormats.Format.Find(data.GetType().FullName); - if ((item_format != null) && (item_format.Name != DataFormats.StringFormat)) { - native_format = item_format.Id; - } - - XplatUI.ClipboardStore(clipboard_handle, data, native_format, converter); - } - XplatUI.ClipboardClose(clipboard_handle); + public static void SetDataObject (object data) + { + clipboard.SetDataObject (data); } - static bool IsDataSerializable (object obj) + public static void SetDataObject (object data, bool copy) { - if (obj is ISerializable) - return true; - - AttributeCollection attrs = TypeDescriptor.GetAttributes (obj); - return attrs [typeof (SerializableAttribute)] != null; + clipboard.SetDataObject (data, copy); } -#if NET_2_0 - public -#else - internal -#endif - static void SetDataObject(object data, bool copy, int retryTimes, int retryDelay) + public static void SetDataObject (object data, bool copy, int retryTimes, int retryDelay) { if (data == null) - throw new ArgumentNullException("data"); + throw new ArgumentNullException ("data"); if (retryTimes < 0) - throw new ArgumentOutOfRangeException("retryTimes"); + throw new ArgumentOutOfRangeException ("retryTimes"); if (retryDelay < 0) - throw new ArgumentOutOfRangeException("retryDelay"); + throw new ArgumentOutOfRangeException ("retryDelay"); - // MS implementation actually puts data to clipboard even when retryTimes == 0 - bool retry = true; - do - { - retry = false; - --retryTimes; - try - { - SetDataObjectImpl(data, copy); - } catch (ExternalException) { - if (retryTimes <= 0) - throw; - retry = true; - Threading.Thread.Sleep(retryDelay); - } - } while (retry && retryTimes > 0); + clipboard.SetDataObject (data, copy, retryTimes, retryDelay); } -#if NET_2_0 [MonoInternalNote ("Needs additional checks for valid paths, see MSDN")] public static void SetFileDropList (StringCollection filePaths) { if (filePaths == null) throw new ArgumentNullException ("filePaths"); - - SetData (DataFormats.FileDrop, filePaths); + + clipboard.SetFileDropList (filePaths); } public static void SetImage (Image image) { if (image == null) throw new ArgumentNullException ("image"); - - SetData (DataFormats.Bitmap, image); + + clipboard.SetImage (image); } public static void SetText (string text) { if (string.IsNullOrEmpty (text)) throw new ArgumentNullException ("text"); - - SetData (DataFormats.UnicodeText, text); + + Clipboard.SetText (text); } public static void SetText (string text, TextDataFormat format) @@ -351,93 +206,13 @@ namespace System.Windows.Forms { throw new ArgumentNullException ("text"); if (!Enum.IsDefined (typeof (TextDataFormat), format)) throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for TextDataFormat", format)); - - switch (format) { - case TextDataFormat.Text: - SetData (DataFormats.Text, text); - break; - case TextDataFormat.UnicodeText: - SetData (DataFormats.UnicodeText, text); - break; - case TextDataFormat.Rtf: - SetData (DataFormats.Rtf, text); - break; - case TextDataFormat.Html: - SetData (DataFormats.Html, text); - break; - case TextDataFormat.CommaSeparatedValue: - SetData (DataFormats.CommaSeparatedValue, text); - break; - } + Clipboard.SetText (text, format); } -#endif - #endregion // Public Static Methods - #region Internal Static Methods - internal static IDataObject GetDataObject (bool primary_selection) + internal static int GetID (string format) { - DataObject clipboard; - IntPtr clipboard_handle; - int[] native_formats; - DataFormats.Format item_format; - object managed_clipboard_item; - XplatUI.ClipboardToObject converter; - - converter = new XplatUI.ClipboardToObject (ConvertFromClipboardData); - - clipboard_handle = XplatUI.ClipboardOpen (primary_selection); - native_formats = XplatUI.ClipboardAvailableFormats (clipboard_handle); - if (native_formats == null) { - return null; // Clipboard empty - } - - // Build the IDataObject - clipboard = new DataObject (); - for (int i = 0; i < native_formats.Length; i++) { - // We might get a format we don't understand or know - item_format = DataFormats.GetFormat (native_formats[i]); - - if (item_format != null) { - managed_clipboard_item = XplatUI.ClipboardRetrieve (clipboard_handle, native_formats[i], converter); - - if (managed_clipboard_item != null) { - clipboard.SetData (item_format.Name, managed_clipboard_item); - // We don't handle 'bitmap' since it involves handles, so we'll equate it to dib - if (item_format.Name == DataFormats.Dib) { - clipboard.SetData (DataFormats.Bitmap, managed_clipboard_item); - } - } - } - } - - XplatUI.ClipboardClose (clipboard_handle); - - return clipboard; + return clipboard.GetID (format); } - - internal static bool ClipboardContainsFormat (params string[] formats) - { - IntPtr clipboard_handle; - int[] native_formats; - DataFormats.Format item_format; - clipboard_handle = XplatUI.ClipboardOpen (false); - native_formats = XplatUI.ClipboardAvailableFormats (clipboard_handle); - - if (native_formats == null) - return false; - - foreach (int i in native_formats) { - // We might get a format we don't understand or know - item_format = DataFormats.GetFormat (i); - - if (item_format != null) - if (((IList)formats).Contains (item_format.Name)) - return true; - } - - return false; - } - #endregion } } diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataFormats.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataFormats.cs index ec20342..a7fb3b1 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataFormats.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataFormats.cs @@ -84,23 +84,14 @@ namespace System.Windows.Forms #region Private Methods internal static Format Add (string name) { - Format f; - - f = Find (name); - if (f == null) { - IntPtr cliphandle; - - cliphandle = XplatUI.ClipboardOpen (false); - f = new Format (name, XplatUI.ClipboardGetID (cliphandle, name)); - XplatUI.ClipboardClose (cliphandle); - } + Format f = Find (name); + if (f == null) + f = new Format (name, Clipboard.GetID (name)); return f; } internal static Format Add (int id) { - Format f; - - f = Find (id); + Format f = Find (id); if (f == null) f = new Format("Format" + id.ToString(), id); return f; @@ -197,31 +188,28 @@ namespace System.Windows.Forms { if (initialized) return; - IntPtr cliphandle = XplatUI.ClipboardOpen(false); - - new Format (Text, XplatUI.ClipboardGetID (cliphandle, Text)); - new Format (Bitmap, XplatUI.ClipboardGetID (cliphandle, Bitmap)); - new Format (MetafilePict, XplatUI.ClipboardGetID (cliphandle, MetafilePict)); - new Format (SymbolicLink, XplatUI.ClipboardGetID (cliphandle, SymbolicLink)); - new Format (Dif, XplatUI.ClipboardGetID (cliphandle, Dif)) ; - new Format (Tiff, XplatUI.ClipboardGetID (cliphandle, Tiff)); - new Format (OemText, XplatUI.ClipboardGetID (cliphandle, OemText)); - new Format (Dib, XplatUI.ClipboardGetID (cliphandle, Dib)); - new Format (Palette, XplatUI.ClipboardGetID (cliphandle, Palette)); - new Format (PenData, XplatUI.ClipboardGetID (cliphandle, PenData)); - new Format (Riff, XplatUI.ClipboardGetID (cliphandle, Riff)); - new Format (WaveAudio, XplatUI.ClipboardGetID (cliphandle, WaveAudio)); - new Format (UnicodeText, XplatUI.ClipboardGetID (cliphandle, UnicodeText)); - new Format (EnhancedMetafile, XplatUI.ClipboardGetID (cliphandle, EnhancedMetafile)); - new Format (FileDrop, XplatUI.ClipboardGetID (cliphandle, FileDrop)); - new Format (Locale, XplatUI.ClipboardGetID (cliphandle, Locale)); - new Format (CommaSeparatedValue, XplatUI.ClipboardGetID (cliphandle, CommaSeparatedValue)); - new Format (Html, XplatUI.ClipboardGetID (cliphandle, Html)); - new Format (Rtf, XplatUI.ClipboardGetID (cliphandle, Rtf)); - new Format (Serializable, XplatUI.ClipboardGetID (cliphandle, Serializable)); - new Format (StringFormat, XplatUI.ClipboardGetID (cliphandle, StringFormat)); - - XplatUI.ClipboardClose (cliphandle); + + new Format (Text, Clipboard.GetID (Text)); + new Format (Bitmap, Clipboard.GetID (Bitmap)); + new Format (MetafilePict, Clipboard.GetID (MetafilePict)); + new Format (SymbolicLink, Clipboard.GetID (SymbolicLink)); + new Format (Dif, Clipboard.GetID (Dif)) ; + new Format (Tiff, Clipboard.GetID (Tiff)); + new Format (OemText, Clipboard.GetID (OemText)); + new Format (Dib, Clipboard.GetID (Dib)); + new Format (Palette, Clipboard.GetID (Palette)); + new Format (PenData, Clipboard.GetID (PenData)); + new Format (Riff, Clipboard.GetID (Riff)); + new Format (WaveAudio, Clipboard.GetID (WaveAudio)); + new Format (UnicodeText, Clipboard.GetID (UnicodeText)); + new Format (EnhancedMetafile, Clipboard.GetID (EnhancedMetafile)); + new Format (FileDrop, Clipboard.GetID (FileDrop)); + new Format (Locale, Clipboard.GetID (Locale)); + new Format (CommaSeparatedValue, Clipboard.GetID (CommaSeparatedValue)); + new Format (Html, Clipboard.GetID (Html)); + new Format (Rtf, Clipboard.GetID (Rtf)); + new Format (Serializable, Clipboard.GetID (Serializable)); + new Format (StringFormat, Clipboard.GetID (StringFormat)); initialized = true; } diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataObject.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataObject.cs index 90dc248..5f53588 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataObject.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataObject.cs @@ -36,10 +36,7 @@ using System.Runtime.InteropServices; namespace System.Windows.Forms { [ClassInterface(ClassInterfaceType.None)] - public class DataObject : IDataObject -#if NET_2_0 - , System.Runtime.InteropServices.ComTypes.IDataObject -#endif + public class DataObject : IDataObject, System.Runtime.InteropServices.ComTypes.IDataObject { #region DataObject.Entry Class private class Entry { diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs index 27a5c78..866ea59 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs @@ -31,6 +31,9 @@ using System.Collections.Specialized; namespace System.Windows.Forms { internal class ClipboardData { + public delegate bool ClipboardToObject(int type, IntPtr data, out object obj); + public delegate bool ObjectToClipboard(ref int type, object obj, out byte[] data); + ListDictionary source_data; // Source in its different formats, if any string plain_text_source; // Cached source as plain-text string Image image_source; // Cached source as image @@ -39,7 +42,7 @@ namespace System.Windows.Forms { internal ArrayList Formats; // list of formats available in the clipboard internal bool Retrieving; // true if we are requesting an item internal bool Enumerating; // true if we are enumerating through all known types - internal XplatUI.ObjectToClipboard Converter; + internal ObjectToClipboard Converter; public ClipboardData () { diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboard.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboard.cs new file mode 100644 index 0000000..f4423ee --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboard.cs @@ -0,0 +1,71 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Authors: +// Ralph Leckett +// + +using System; +using System.Collections.Specialized; +using System.Drawing; +using System.IO; + +namespace System.Windows.Forms { + internal abstract class XplatClipboard { + internal virtual IntPtr ClipboardOpen (bool primary_selection) + { + return IntPtr.Zero; + } + + internal virtual void ClipboardClose (IntPtr token) + { + } + + internal IDataObject GetDataObject () + { + return GetDataObject (false); + } + + internal abstract void Clear (); + internal abstract bool ContainsAudio (); + internal abstract bool ContainsData (string format); + internal abstract bool ContainsFileDropList (); + internal abstract bool ContainsImage (); + internal abstract bool ContainsText (); + internal abstract bool ContainsText (TextDataFormat format); + internal abstract Stream GetAudioStream (); + internal abstract object GetData (string format); + internal abstract IDataObject GetDataObject (bool primary_selection); + internal abstract StringCollection GetFileDropList (); + internal abstract Image GetImage (); + internal abstract string GetText (); + internal abstract string GetText (TextDataFormat format); + internal abstract void SetAudio (byte[] audioBytes); + internal abstract void SetAudio (Stream audioStream); + internal abstract void SetData (string format, object data); + internal abstract void SetDataObject (object dataObject); + internal abstract void SetDataObject (object dataObject, bool copy); + internal abstract void SetDataObject (object dataObject, bool copy, int retryTimes, int retryDelay); + internal abstract void SetFileDropList (StringCollection filePaths); + internal abstract void SetImage (Image image); + internal abstract void SetText (string text); + internal abstract void SetText (string text, TextDataFormat format); + internal abstract int GetID (string format); + } +} diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardCarbon.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardCarbon.cs new file mode 100644 index 0000000..464112f --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardCarbon.cs @@ -0,0 +1,605 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Authors: +// Ralph Leckett +// + +using System; +using System.Collections.Specialized; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; + +namespace System.Windows.Forms +{ + internal class XplatClipboardCarbon : XplatClipboard + { + private const string FLAVOR_TEXT8 = "public.utf8-plain-text"; + private const string FLAVOR_TEXT16 = "public.utf16-plain-text"; + private const string FLAVOR_RTF = "public.rtf"; + private const string FLAVOR_TIFF = "public.tiff"; + private const string FLAVOR_DROP = "public.file-url"; + + private class Mask + { + public bool all = false; + public bool text8 = false; + public bool text16 = false; + public bool rtf = false; + public bool tiff = false; + public bool drop = false; + } + + private IntPtr _pasteboard; + + internal XplatClipboardCarbon () + { + int status = PasteboardCreate ( + __CFStringMakeConstantString ("com.apple.pasteboard.clipboard"), + ref _pasteboard); + if (status != 0) + Console.WriteLine ("PasteboardCreate status = " + Status (status)); + } + + internal override void Clear () + { + int status = PasteboardClear (_pasteboard); + if (status != 0) + Console.WriteLine ("PasteboardClear status = " + Status (status)); + } + + internal override bool ContainsAudio () + { + //TODO + return false; + } + + internal override bool ContainsData (string format) + { + Mask mask = new Mask (); + if (format == DataFormats.Text) + mask.text8 = true; + else if (format == DataFormats.UnicodeText) + mask.text16 = true; + else if (format == DataFormats.Rtf) + mask.rtf = true; + else if (format == DataFormats.Bitmap) + mask.tiff = true; + else if (format == DataFormats.FileDrop) + mask.drop = true; + else + return false; + DataObject dataObject; + return GetMaskedDataObject (mask, false, out dataObject); + } + + internal override bool ContainsFileDropList () + { + Mask mask = new Mask (); + mask.drop = true; + DataObject dataObject; + return GetMaskedDataObject (mask, false, out dataObject); + } + + internal override bool ContainsImage () + { + Mask mask = new Mask (); + mask.tiff = true; + DataObject dataObject; + return GetMaskedDataObject (mask, false, out dataObject); + } + + internal override bool ContainsText () + { + Mask mask = new Mask (); + mask.text8 = true; + mask.text16 = true; + mask.rtf = true; + DataObject dataObject; + return GetMaskedDataObject (mask, false, out dataObject); + } + + internal override bool ContainsText (TextDataFormat format) + { + Mask mask = new Mask (); + if (format == TextDataFormat.Text) + mask.text8 = true; + else if (format == TextDataFormat.UnicodeText) + mask.text16 = true; + else if (format == TextDataFormat.Rtf) + mask.rtf = true; + else + return false; + DataObject dataObject; + return GetMaskedDataObject (mask, false, out dataObject); + } + + internal override Stream GetAudioStream () + { + //TODO + return null; + } + + internal override object GetData (string format) + { + Mask mask = new Mask (); + if (format == DataFormats.Text) + mask.text8 = true; + else if (format == DataFormats.UnicodeText) + mask.text16 = true; + else if (format == DataFormats.Rtf) + mask.rtf = true; + else if (format == DataFormats.Bitmap) + mask.tiff = true; + else if (format == DataFormats.FileDrop) + mask.drop = true; + else + return null; + DataObject dataObject; + if (GetMaskedDataObject (mask, true, out dataObject)) + return dataObject.GetData (format); + return null; + } + + internal override IDataObject GetDataObject (bool primary_selection) + { + Mask mask = new Mask (); + mask.all = true; + DataObject dataObject; + GetMaskedDataObject (mask, true, out dataObject); + return dataObject; + } + + internal override StringCollection GetFileDropList () + { + #if NET_2_0 + Mask mask = new Mask (); + mask.drop = true; + DataObject dataObject; + if (GetMaskedDataObject (mask, true, out dataObject)) + return dataObject.GetFileDropList (); + #endif + return null; + } + + internal override Image GetImage () + { + #if NET_2_0 + Mask mask = new Mask (); + mask.tiff = true; + DataObject dataObject; + if (GetMaskedDataObject (mask, true, out dataObject)) + return dataObject.GetImage (); + #endif + return null; + } + + internal override string GetText () + { + Mask mask = new Mask (); + mask.text8 = true; + mask.text16 = true; + mask.rtf = true; + DataObject dataObject; + if (GetMaskedDataObject (mask, true, out dataObject)) + return dataObject.GetText (); + return null; + } + + internal override string GetText (TextDataFormat format) + { + Mask mask = new Mask (); + if (format == TextDataFormat.Text) + mask.text8 = true; + else if (format == TextDataFormat.UnicodeText) + mask.text16 = true; + else if (format == TextDataFormat.Rtf) + mask.rtf = true; + else + return null; + DataObject dataObject; + if (GetMaskedDataObject (mask, true, out dataObject)) + return dataObject.GetText (format); + return null; + } + + private bool GetMaskedDataObject (Mask mask, bool bGet, out DataObject dataObject) + { + bool bFound = false; + dataObject = null; + + int status = PasteboardSynchronize (_pasteboard); + if (status != 0) + Console.WriteLine ("PasteboardSynchronize status = " + Status (status)); + + UInt32 itemCount = 0; + status = PasteboardGetItemCount (_pasteboard, ref itemCount); + if (status != 0) + Console.WriteLine ("PasteboardGetItemCount status = " + Status (status)); + + bool bSearching = true; + for (UInt32 itemIndex = 1; itemIndex <= itemCount && bSearching; itemIndex++) { + UInt32 itemID = 0; + status = PasteboardGetItemIdentifier (_pasteboard, itemIndex, ref itemID); + if (status != 0) + Console.WriteLine ("PasteboardGetItemIdentifier status = " + Status (status)); + + IntPtr flavorTypeArray = IntPtr.Zero; + status = PasteboardCopyItemFlavors (_pasteboard, itemID, ref flavorTypeArray); + if (status != 0) + Console.WriteLine ("PasteboardCopyItemFlavors status = " + Status (status)); + + Int32 flavorCount = CFArrayGetCount (flavorTypeArray); + + for (Int32 flavorIndex = 0; flavorIndex < flavorCount && bSearching; flavorIndex++) { + IntPtr flavorType = CFArrayGetValueAtIndex (flavorTypeArray, flavorIndex); + IntPtr flavorCStr = CFStringGetCStringPtr (flavorType, 0); + string flavor = Marshal.PtrToStringAnsi (flavorCStr); + + if (flavor == FLAVOR_TEXT8) { + if (mask.all || mask.text8) { + bFound = true; + if (bGet) + dataObject = GetText8 (GetCFData (itemID, flavorType)); + } + bSearching = false; + } else if (flavor == FLAVOR_TEXT16) { + if (mask.all || mask.text16) { + bFound = true; + if (bGet) + dataObject = GetText16 (GetCFData (itemID, flavorType)); + } + bSearching = false; + } else if (flavor == FLAVOR_RTF) { + if (mask.all || mask.rtf) { + bFound = true; + if (bGet) + dataObject = GetRtf (GetCFData (itemID, flavorType)); + } + bSearching = false; + } else if (flavor == FLAVOR_TIFF) { + if (mask.all || mask.tiff) { + bFound = true; + if (bGet) + dataObject = GetBitmap (GetCFData (itemID, flavorType)); + } + bSearching = false; + } else if (flavor == FLAVOR_DROP) { + if (mask.all || mask.drop) { + bFound = true; + if (bGet) + dataObject = GetDrop (GetCFData (itemID, flavorType)); + } + bSearching = false; + } + } + CFRelease (flavorTypeArray); + } + return bFound; + } + + private IntPtr GetCFData (UInt32 itemID, IntPtr flavorType) + { + IntPtr data = IntPtr.Zero; + int status = PasteboardCopyItemFlavorData (_pasteboard, itemID, flavorType, ref data); + if (status != 0) + Console.WriteLine ("PasteboardCopyItemFlavorData status = " + Status (status)); + return data; + } + + private DataObject GetText8 (IntPtr data) + { + IntPtr dataPtr = CFDataGetBytePtr (data); + Int32 dataLen = CFDataGetLength (data); + + DataObject dataObject = new DataObject (DataFormats.Text, Marshal.PtrToStringAnsi (dataPtr, dataLen)); + CFRelease (data); + return dataObject; + } + + private DataObject GetText16 (IntPtr data) + { + IntPtr dataPtr = CFDataGetBytePtr (data); + Int32 dataLen = CFDataGetLength (data); + + DataObject dataObject = new DataObject (DataFormats.UnicodeText, Marshal.PtrToStringUni (dataPtr, dataLen)); + CFRelease (data); + return dataObject; + } + + private DataObject GetRtf (IntPtr data) + { + IntPtr dataPtr = CFDataGetBytePtr (data); + Int32 dataLen = CFDataGetLength (data); + + DataObject dataObject = new DataObject (DataFormats.Rtf, Marshal.PtrToStringAnsi (dataPtr, dataLen)); + CFRelease (data); + return dataObject; + } + + private DataObject GetBitmap (IntPtr data) + { + IntPtr dataPtr = CFDataGetBytePtr (data); + Int32 dataLen = CFDataGetLength (data); + + byte[] buffer = new byte[dataLen]; + Marshal.Copy (dataPtr, buffer, 0, dataLen); + + Stream stream = new MemoryStream (buffer); + Image image = Image.FromStream (stream); + stream.Close (); + stream.Dispose (); + DataObject dataObject = new DataObject (DataFormats.Bitmap, image); + CFRelease (data); + return dataObject; + } + + private DataObject GetDrop (IntPtr data) + { + IntPtr dataPtr = CFDataGetBytePtr (data); + Int32 dataLen = CFDataGetLength (data); + + string fileName = (string)Marshal.PtrToStringAnsi (dataPtr, dataLen); + if (fileName.StartsWith ("file://localhost/")) + fileName = "/" + fileName.Substring (16); + StringCollection fileCollection = new StringCollection (); + fileCollection.Add (fileName); + + DataObject dataObject = new DataObject (DataFormats.FileDrop, null); + dataObject.SetFileDropList (fileCollection); + + CFRelease (data); + return dataObject; + } + + internal override void SetAudio (byte[] audioBytes) + { + //TODO + } + + internal override void SetAudio (Stream audioStream) + { + //TODO + } + + internal override void SetData (string format, object data) + { + if (format == DataFormats.Text) + SetDataObject (new DataObject (DataFormats.Text, data), true); + else if (format == DataFormats.UnicodeText) + SetDataObject (new DataObject (DataFormats.UnicodeText, data), true); + else if (format == DataFormats.Rtf) + SetDataObject (new DataObject (DataFormats.Rtf, data), true); + else if (format == DataFormats.Bitmap) + SetDataObject (new DataObject (DataFormats.Bitmap, data), true); + } + + internal override void SetDataObject (object data) + { + SetDataObject (data, false); + } + + internal override void SetDataObject (object data, bool copy) + { + int status = PasteboardClear (_pasteboard); + if (status != 0) + Console.WriteLine ("PasteboardClear status = " + Status (status)); + + IDataObject dataObject = data as IDataObject; + if (dataObject == null) + dataObject = new DataObject (data); + + string[] formatList = dataObject.GetFormats (); + + for (int i = 0; i < formatList.Length; i++) { + string format = formatList[i]; + + if (format == DataFormats.Text) { + SetCFData (SetText8 ( (string)dataObject.GetData (DataFormats.Text)), FLAVOR_TEXT8); + break; + } + if (format == DataFormats.UnicodeText) { + SetCFData (SetText16 ( (string)dataObject.GetData (DataFormats.UnicodeText)), FLAVOR_TEXT16); + break; + } + if (format == DataFormats.Rtf) { + SetCFData (SetText8 ( (string)dataObject.GetData (DataFormats.Rtf)), FLAVOR_RTF); + break; + } + if (format == DataFormats.Bitmap) { + SetCFData ( + SetBitmap ( (Image)dataObject.GetData (DataFormats.Bitmap)), + FLAVOR_TIFF); + break; + } + } + } + + internal override void SetDataObject (object data, bool copy, int retryTimes, int retryDelay) + { + SetDataObject (data, copy); + } + + internal override void SetFileDropList (StringCollection filePaths) + { + //TODO + } + + internal override void SetImage (Image image) + { + SetDataObject (new DataObject (DataFormats.Bitmap, image), true); + } + + internal override void SetText (string text) + { + SetDataObject (new DataObject (DataFormats.Text, text), true); + } + + internal override void SetText (string text, TextDataFormat format) + { + if (format == TextDataFormat.Text) + SetDataObject (new DataObject (DataFormats.Text, text), true); + else if (format == TextDataFormat.UnicodeText) + SetDataObject (new DataObject (DataFormats.UnicodeText, text), true); + else if (format == TextDataFormat.Rtf) + SetDataObject (new DataObject (DataFormats.Rtf, text), true); + } + + private IntPtr SetText8 (string text) + { + IntPtr memory = Marshal.StringToHGlobalAnsi (text); + IntPtr data = CFDataCreate (IntPtr.Zero, memory, text.Length + 1); + Marshal.FreeHGlobal (memory); + return data; + } + + private IntPtr SetText16 (string text) + { + IntPtr memory = Marshal.StringToHGlobalUni (text); + IntPtr data = CFDataCreate (IntPtr.Zero, memory, (text.Length + 1) * 2); + Marshal.FreeHGlobal (memory); + return data; + } + + private IntPtr SetBitmap (Image image_parm) + { + Image image = new Bitmap (image_parm); //must make a copy so GDI doesn't get upset + string fileName = Path.GetTempFileName (); + image.Save (fileName, ImageFormat.Tiff); + image.Dispose (); + + Stream stream = new FileStream (fileName, FileMode.Open, FileAccess.Read); + int size = (int)stream.Length; + byte[] buffer = new byte[size]; + stream.Read (buffer, 0, size); + stream.Close (); + stream.Dispose (); + File.Delete (fileName); + + IntPtr memory = Marshal.AllocHGlobal (size); + Marshal.Copy (buffer, 0, memory, size); + + IntPtr data = CFDataCreate (IntPtr.Zero, memory, size); + Marshal.FreeHGlobal (memory); + return data; + } + + private void SetCFData (IntPtr data, string flavor) + { + int status = PasteboardPutItemFlavor (_pasteboard, 789514, __CFStringMakeConstantString (flavor), data, 0); + if (status != 0) + Console.WriteLine ("PasteboardPutItemFlavor status = " + Status (status)); + } + + private string Status (int status) + { + const int badPasteboardSyncErr = -25130; + const int badPasteboardIndexErr = -25131; + const int badPasteboardItemErr = -25132; + const int badPasteboardFlavorErr = -25133; + const int duplicatePasteboardFlavorErr = -25134; + const int notPasteboardOwnerErr = -25135; + const int noPasteboardPromiseKeeperErr = -25136; + + switch (status) + { + case badPasteboardSyncErr: return "Bad Pasteboard Sync Err"; + case badPasteboardIndexErr: return "Bad Pasteboard Index Err"; + case badPasteboardItemErr: return "Bad Pasteboard Item Err"; + case badPasteboardFlavorErr: return "Bad Pasteboard Flavor Err"; + case duplicatePasteboardFlavorErr: return "Duplicate Pasteboard Flavor Err"; + case notPasteboardOwnerErr: return "Not Pasteboard Owner Err"; + case noPasteboardPromiseKeeperErr: return "No Pasteboard Promise Keeper Err"; + default: return status.ToString (); + } + } + + internal override int GetID (string format) + { + if (format == "Text") return (int)ClipboardFormats.CF_TEXT; + else if (format == "Bitmap") return (int)ClipboardFormats.CF_BITMAP; + else if (format == "MetaFilePict") return (int)ClipboardFormats.CF_METAFILEPICT; + else if (format == "SymbolicLink") return (int)ClipboardFormats.CF_SYLK; + else if (format == "DataInterchangeFormat") return (int)ClipboardFormats.CF_DIF; + else if (format == "Tiff") return (int)ClipboardFormats.CF_TIFF; + else if (format == "OEMText") return (int)ClipboardFormats.CF_OEMTEXT; + else if (format == "DeviceIndependentBitmap") return (int)ClipboardFormats.CF_DIB; + else if (format == "Palette") return (int)ClipboardFormats.CF_PALETTE; + else if (format == "PenData") return (int)ClipboardFormats.CF_PENDATA; + else if (format == "RiffAudio") return (int)ClipboardFormats.CF_RIFF; + else if (format == "WaveAudio") return (int)ClipboardFormats.CF_WAVE; + else if (format == "UnicodeText") return (int)ClipboardFormats.CF_UNICODETEXT; + else if (format == "EnhancedMetafile") return (int)ClipboardFormats.CF_ENHMETAFILE; + else if (format == "FileDrop") return (int)ClipboardFormats.CF_HDROP; + else if (format == "Locale") return (int)ClipboardFormats.CF_LOCALE; + + return 0; //don't know + } + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern IntPtr __CFStringMakeConstantString (string cString); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern Int32 CFArrayGetCount (IntPtr array); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern IntPtr CFArrayGetValueAtIndex (IntPtr array, Int32 index); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern IntPtr CFDataCreate (IntPtr allocator, IntPtr data, Int32 length); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern IntPtr CFDataGetBytePtr (IntPtr data); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern Int32 CFDataGetLength (IntPtr data); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern void CFRelease (IntPtr data); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern IntPtr CFStringGetCStringPtr (IntPtr cfstr, UInt32 encoding); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardClear (IntPtr pasteboard); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardCreate (IntPtr name, ref IntPtr pasteboard); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardCopyItemFlavorData (IntPtr pasteboard, UInt32 itemID, IntPtr flavorType, ref IntPtr data); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardCopyItemFlavors (IntPtr pasteboard, UInt32 itemID, ref IntPtr flavorTypeArray); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardGetItemCount (IntPtr pasteboard, ref UInt32 itemCount); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardGetItemIdentifier (IntPtr pasteboard, UInt32 itemIndex, ref UInt32 itemID); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardPutItemFlavor (IntPtr pasteboard, UInt32 itemID, IntPtr flavorType, IntPtr data, UInt32 flags); + + [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] + static extern int PasteboardSynchronize (IntPtr pasteboard); + } +} diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardWin32.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardWin32.cs new file mode 100644 index 0000000..4f2ebb8 --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardWin32.cs @@ -0,0 +1,602 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Authors: +// Peter Bartok +// Ralph Leckett +// + +using System; +using System.Drawing; +using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Threading; + +namespace System.Windows.Forms { + internal class XplatClipboardWin32 : XplatClipboard { + public delegate bool ClipboardToObject(int type, IntPtr data, out object obj); + public delegate bool ObjectToClipboard(ref int type, object obj, out byte[] data); + + private static IntPtr clip_magic = new IntPtr(27051977); + + internal override void Clear() + { + IntPtr clipboard_handle; + + clipboard_handle = ClipboardOpen (false); + ClipboardStore (clipboard_handle, null, 0, null); + } + + internal override bool ContainsAudio () + { + return ClipboardContainsFormat (DataFormats.WaveAudio); + } + + internal override bool ContainsData (string format) + { + return ClipboardContainsFormat (format); + } + + internal override bool ContainsFileDropList () + { + return ClipboardContainsFormat (DataFormats.FileDrop); + } + + internal override bool ContainsImage () + { + return ClipboardContainsFormat (DataFormats.Bitmap); + } + + internal override bool ContainsText () + { + return ClipboardContainsFormat (DataFormats.Text, DataFormats.UnicodeText); + } + + internal override bool ContainsText (TextDataFormat format) + { + switch (format) { + case TextDataFormat.Text: + return ClipboardContainsFormat (DataFormats.Text); + case TextDataFormat.UnicodeText: + return ClipboardContainsFormat (DataFormats.UnicodeText); + case TextDataFormat.Rtf: + return ClipboardContainsFormat (DataFormats.Rtf); + case TextDataFormat.Html: + return ClipboardContainsFormat (DataFormats.Html); + case TextDataFormat.CommaSeparatedValue: + return ClipboardContainsFormat (DataFormats.CommaSeparatedValue); + } + + return false; + } + + private bool ClipboardContainsFormat (params string[] formats) + { + IntPtr clipboard_handle; + int[] native_formats; + DataFormats.Format item_format; + + clipboard_handle = ClipboardOpen (false); + native_formats = ClipboardAvailableFormats (clipboard_handle); + + if (native_formats == null) + return false; + + foreach (int i in native_formats) { + // We might get a format we don't understand or know + item_format = DataFormats.GetFormat (i); + + if (item_format != null) + if (( (IList)formats).Contains (item_format.Name)) + return true; + } + + return false; + } + + internal override Stream GetAudioStream () + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return (Stream)data.GetData (DataFormats.WaveAudio, true); + } + + internal override object GetData (string format) + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return data.GetData (format, true); + } + + internal override IDataObject GetDataObject (bool primary_selection) + { + DataObject clipboard; + IntPtr clipboard_handle; + int[] native_formats; + DataFormats.Format item_format; + object managed_clipboard_item; + ClipboardToObject converter; + + converter = new ClipboardToObject (ConvertFromClipboardData); + + clipboard_handle = ClipboardOpen (primary_selection); + native_formats = ClipboardAvailableFormats (clipboard_handle); + if (native_formats == null) + { + return null; // Clipboard empty + } + + // Build the IDataObject + clipboard = new DataObject (); + for (int i = 0; i < native_formats.Length; i++) { + // We might get a format we don't understand or know + item_format = DataFormats.GetFormat (native_formats[i]); + + if (item_format != null) { + managed_clipboard_item = ClipboardRetrieve (clipboard_handle, native_formats[i], converter); + + if (managed_clipboard_item != null) + { + clipboard.SetData (item_format.Name, managed_clipboard_item); + // We don't handle 'bitmap' since it involves handles, so we'll equate it to dib + if (item_format.Name == DataFormats.Dib) + { + clipboard.SetData (DataFormats.Bitmap, managed_clipboard_item); + } + } + } + } + + ClipboardClose (clipboard_handle); + + return clipboard; + } + + internal override StringCollection GetFileDropList () + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return (StringCollection)data.GetData (DataFormats.FileDrop, true); + } + + internal override Image GetImage () + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return (Image)data.GetData (DataFormats.Bitmap, true); + } + + internal override string GetText () + { + return GetText (TextDataFormat.UnicodeText); + } + + + internal override string GetText (TextDataFormat format) + { + IDataObject data = GetDataObject (); + + if (data == null) + return string.Empty; + + string retval; + + switch (format) { + case TextDataFormat.Text: + default: + retval = (string)data.GetData (DataFormats.Text, true); + break; + case TextDataFormat.UnicodeText: + retval = (string)data.GetData (DataFormats.UnicodeText, true); + break; + case TextDataFormat.Rtf: + retval = (string)data.GetData (DataFormats.Rtf, true); + break; + case TextDataFormat.Html: + retval = (string)data.GetData (DataFormats.Html, true); + break; + case TextDataFormat.CommaSeparatedValue: + retval = (string)data.GetData (DataFormats.CommaSeparatedValue, true); + break; + } + + return retval == null ? string.Empty : retval; + } + + internal override void SetAudio (byte[] audioBytes) + { + MemoryStream ms = new MemoryStream (audioBytes); + + SetAudio (ms); + } + + internal override void SetAudio (Stream audioStream) + { + SetData (DataFormats.WaveAudio, audioStream); + } + + internal override void SetData (string format, object data) + { + DataObject data_object = new DataObject (format, data); + SetDataObject (data_object); + } + + internal override void SetDataObject (object data) + { + SetDataObject (data, false); // MSDN says default behavior is to place non-persistent data to clipboard + } + + internal override void SetDataObject (object data, bool copy) + { + SetDataObject (data, copy, 10, 100); // MSDN says default behavior is to try 10 times with 100 ms delay + } + + internal override void SetDataObject (object data, bool copy, int retryTimes, int retryDelay) + { + // MS implementation actually puts data to clipboard even when retryTimes == 0 + bool retry = true; + do { + retry = false; + --retryTimes; + try { + SetDataObjectImpl (data, copy); + } catch (ExternalException) { + if (retryTimes <= 0) + throw; + retry = true; + Thread.Sleep (retryDelay); + } + } while (retry && retryTimes > 0); + } + + private void SetDataObjectImpl (object data, bool copy) + { + IntPtr clipboard_handle; + ObjectToClipboard converter; + int native_format; + DataFormats.Format item_format; + + converter = new ObjectToClipboard (ConvertToClipboardData); + + clipboard_handle = ClipboardOpen (false); + ClipboardStore (clipboard_handle, null, 0, null); // Empty clipboard + + native_format = -1; + + if (data is IDataObject) { + string[] formats; + + IDataObject data_object = data as IDataObject; + formats = data_object.GetFormats (); + for (int i = 0; i < formats.Length; i++) { + item_format = DataFormats.GetFormat (formats[i]); + if ((item_format != null) && (item_format.Name != DataFormats.StringFormat)) { + native_format = item_format.Id; + } + + object obj = data_object.GetData (formats[i]); + + // this is used only by custom formats + if (IsDataSerializable (obj)) + item_format.is_serializable = true; + + ClipboardStore (clipboard_handle, obj, native_format, converter); + } + } else { + item_format = DataFormats.Format.Find (data.GetType ().FullName); + if ((item_format != null) && (item_format.Name != DataFormats.StringFormat)) { + native_format = item_format.Id; + } + + ClipboardStore (clipboard_handle, data, native_format, converter); + } + ClipboardClose (clipboard_handle); + } + + private bool IsDataSerializable (object obj) + { + if (obj is ISerializable) + return true; + + AttributeCollection attrs = TypeDescriptor.GetAttributes (obj); + return attrs[typeof (SerializableAttribute)] != null; + } + + [MonoInternalNote ("Needs additional checks for valid paths, see MSDN")] + internal override void SetFileDropList (StringCollection filePaths) + { + SetData (DataFormats.FileDrop, filePaths); + } + + internal override void SetImage (Image image) + { + SetData (DataFormats.Bitmap, image); + } + + internal override void SetText (string text) + { + SetData (DataFormats.UnicodeText, text); + } + + internal override void SetText (string text, TextDataFormat format) + { + switch (format) { + case TextDataFormat.Text: + SetData (DataFormats.Text, text); + break; + case TextDataFormat.UnicodeText: + SetData (DataFormats.UnicodeText, text); + break; + case TextDataFormat.Rtf: + SetData (DataFormats.Rtf, text); + break; + case TextDataFormat.Html: + SetData (DataFormats.Html, text); + break; + case TextDataFormat.CommaSeparatedValue: + SetData (DataFormats.CommaSeparatedValue, text); + break; + } + } + + private bool ConvertToClipboardData (ref int type, object obj, out byte[] data) + { + data = null; + return false; + } + + private bool ConvertFromClipboardData (int type, IntPtr data, out object obj) + { + obj = null; + if (data == IntPtr.Zero) + { + return false; + } + return false; + } + + internal override int GetID (string format) + { + if (format == "Text") return (int)ClipboardFormats.CF_TEXT; + else if (format == "Bitmap") return (int)ClipboardFormats.CF_BITMAP; + else if (format == "MetaFilePict") return (int)ClipboardFormats.CF_METAFILEPICT; + else if (format == "SymbolicLink") return (int)ClipboardFormats.CF_SYLK; + else if (format == "DataInterchangeFormat") return (int)ClipboardFormats.CF_DIF; + else if (format == "Tiff") return (int)ClipboardFormats.CF_TIFF; + else if (format == "OEMText") return (int)ClipboardFormats.CF_OEMTEXT; + else if (format == "DeviceIndependentBitmap") return (int)ClipboardFormats.CF_DIB; + else if (format == "Palette") return (int)ClipboardFormats.CF_PALETTE; + else if (format == "PenData") return (int)ClipboardFormats.CF_PENDATA; + else if (format == "RiffAudio") return (int)ClipboardFormats.CF_RIFF; + else if (format == "WaveAudio") return (int)ClipboardFormats.CF_WAVE; + else if (format == "UnicodeText") return (int)ClipboardFormats.CF_UNICODETEXT; + else if (format == "EnhancedMetafile") return (int)ClipboardFormats.CF_ENHMETAFILE; + else if (format == "FileDrop") return (int)ClipboardFormats.CF_HDROP; + else if (format == "Locale") return (int)ClipboardFormats.CF_LOCALE; + + return (int)Win32RegisterClipboardFormat (format); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // stuff formerly in XplatUIWin32 + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + internal override void ClipboardClose (IntPtr handle) + { + if (handle != clip_magic) + throw new ArgumentException ("handle is not a valid clipboard handle"); + Win32CloseClipboard (); + } + + internal override IntPtr ClipboardOpen (bool primary_selection) + { + // Win32 does not have primary selection + Win32OpenClipboard (XplatUIWin32.FosterParent); + return clip_magic; + } + + private int[] ClipboardAvailableFormats (IntPtr handle) + { + uint format; + int[] result; + int count; + + if (handle != clip_magic) + return null; + + // Count first + count = 0; + format = 0; + do { + format = Win32EnumClipboardFormats (format); + if (format != 0) + count++; + } while (format != 0); + + // Now assign + result = new int[count]; + count = 0; + format = 0; + do { + format = Win32EnumClipboardFormats (format); + if (format != 0) + result[count++] = (int)format; + } while (format != 0); + + return result; + } + + private object ClipboardRetrieve (IntPtr handle, int type, ClipboardToObject converter) + { + IntPtr hmem; + IntPtr data; + object obj; + + if (handle != clip_magic) + throw new ArgumentException ("handle is not a valid clipboard handle"); + + hmem = Win32GetClipboardData ((uint)type); + if (hmem == IntPtr.Zero) + return null; + + data = XplatUIWin32.Win32GlobalLock (hmem); + if (data == IntPtr.Zero) { + uint error = XplatUIWin32.Win32GetLastError (); + Console.WriteLine ("Error: {0}", error); + return null; + } + + obj = null; + + if (type == DataFormats.GetFormat (DataFormats.Rtf).Id) + obj = XplatUIWin32.AnsiToString (data); + else { + switch ((ClipboardFormats)type){ + case ClipboardFormats.CF_TEXT: + obj = XplatUIWin32.AnsiToString (data); + break; + + case ClipboardFormats.CF_DIB: + obj = XplatUIWin32.DIBtoImage (data); + break; + + case ClipboardFormats.CF_UNICODETEXT: + obj = XplatUIWin32.UnicodeToString (data); + break; + + default: + if (converter != null && !converter (type, data, out obj)) + obj = null; + break; + } + } + XplatUIWin32.Win32GlobalUnlock (hmem); + + return obj; + } + + private void ClipboardStore (IntPtr handle, object obj, int type, ObjectToClipboard converter) + { + byte[] data = null; + + if (handle != clip_magic) + throw new ArgumentException ("handle is not a valid clipboard handle"); + + if (obj == null) { + // Just clear it + if (!Win32EmptyClipboard ()) + throw new ExternalException ("Win32EmptyClipboard"); + return; + } + + if (type == -1) { + if (obj is string) + type = (int)ClipboardFormats.CF_UNICODETEXT; + else if (obj is Image) + type = (int)ClipboardFormats.CF_DIB; + } + + if (type == DataFormats.GetFormat (DataFormats.Rtf).Id) + data = XplatUIWin32.StringToAnsi ((string)obj); + + else { + switch ((ClipboardFormats)type) { + case ClipboardFormats.CF_UNICODETEXT: + data = XplatUIWin32.StringToUnicode ((string)obj); + break; + + case ClipboardFormats.CF_TEXT: + data = XplatUIWin32.StringToAnsi ((string)obj); + break; + + case ClipboardFormats.CF_BITMAP: + case ClipboardFormats.CF_DIB: + data = XplatUIWin32.ImageToDIB ((Image)obj); + type = (int)ClipboardFormats.CF_DIB; + break; + + default: + if (converter != null && !converter (ref type, obj, out data)) + data = null; // ensure that a failed conversion leaves null. + break; + } + } + if (data != null) + SetClipboardData ((uint)type, data); + } + + private void SetClipboardData (uint type, byte[] data) + { + // Shouldn't call Win32SetClipboard with NULL, as, from MSDN: + // "This parameter can be NULL, indicating that the window provides data + // in the specified clipboard format (renders the format) upon request." + // and I don't think we support that... + // Note this is unrelated to the fact that passing a null obj to + // ClipboardStore is actually a request to empty the clipboard! + if (data.Length == 0) + return; + + IntPtr hmem = XplatUIWin32.CopyToMoveableMemory (data); + // As above, should not call with null. + // (Not that CopyToMoveableMemory should ever return null!) + if (hmem == IntPtr.Zero) + throw new ExternalException ("CopyToMoveableMemory failed."); + if (Win32SetClipboardData (type, hmem) == IntPtr.Zero) + throw new ExternalException ("Win32SetClipboardData"); + } + + [DllImport ("user32.dll", EntryPoint = "OpenClipboard", CallingConvention = CallingConvention.StdCall)] + private extern static bool Win32OpenClipboard (IntPtr hwnd); + + [DllImport ("user32.dll", EntryPoint = "EmptyClipboard", CallingConvention = CallingConvention.StdCall)] + private extern static bool Win32EmptyClipboard (); + + [DllImport ("user32.dll", EntryPoint = "RegisterClipboardFormatW", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] + private extern static uint Win32RegisterClipboardFormat (string format); + + [DllImport ("user32.dll", EntryPoint = "CloseClipboard", CallingConvention = CallingConvention.StdCall)] + private extern static bool Win32CloseClipboard (); + + [DllImport ("user32.dll", EntryPoint = "EnumClipboardFormats", CallingConvention = CallingConvention.StdCall)] + private extern static uint Win32EnumClipboardFormats (uint format); + + [DllImport ("user32.dll", EntryPoint = "GetClipboardData", CallingConvention = CallingConvention.StdCall)] + private extern static IntPtr Win32GetClipboardData (uint format); + + [DllImport ("user32.dll", EntryPoint = "SetClipboardData", CallingConvention = CallingConvention.StdCall)] + private extern static IntPtr Win32SetClipboardData (uint format, IntPtr handle); + + } +} diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardX11.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardX11.cs new file mode 100644 index 0000000..fd9a0a0 --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatClipboardX11.cs @@ -0,0 +1,495 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2005 Novell, Inc. (http://www.novell.com) +// +// Authors: +// Peter Bartok (pbartok@novell.com) +// +// + +// COMPLETE + +using System; +using System.Drawing; +using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Threading; + +namespace System.Windows.Forms +{ + internal class XplatClipboardX11 : XplatClipboard + { + private static IntPtr ClipMagic; + + private XplatUIX11 driver; + + internal XplatClipboardX11 (XplatUIDriver driver) + { + this.driver = driver as XplatUIX11; + } + + internal override void Clear () + { + IntPtr clipboard_handle; + + clipboard_handle = ClipboardOpen (false); + ClipboardStore (clipboard_handle, null, 0, null); + } + + internal override bool ContainsAudio () + { + return ClipboardContainsFormat (DataFormats.WaveAudio); + } + + internal override bool ContainsData (string format) + { + return ClipboardContainsFormat (format); + } + + internal override bool ContainsFileDropList () + { + return ClipboardContainsFormat (DataFormats.FileDrop); + } + + internal override bool ContainsImage () + { + return ClipboardContainsFormat (DataFormats.Bitmap); + } + + internal override bool ContainsText () + { + return ClipboardContainsFormat (DataFormats.Text, DataFormats.UnicodeText); + } + + internal override bool ContainsText (TextDataFormat format) + { + switch (format) { + case TextDataFormat.Text: + return ClipboardContainsFormat (DataFormats.Text); + case TextDataFormat.UnicodeText: + return ClipboardContainsFormat (DataFormats.UnicodeText); + case TextDataFormat.Rtf: + return ClipboardContainsFormat (DataFormats.Rtf); + case TextDataFormat.Html: + return ClipboardContainsFormat (DataFormats.Html); + case TextDataFormat.CommaSeparatedValue: + return ClipboardContainsFormat (DataFormats.CommaSeparatedValue); + } + + return false; + } + + private bool ClipboardContainsFormat (params string[] formats) + { + IntPtr clipboard_handle; + int[] native_formats; + DataFormats.Format item_format; + + clipboard_handle = ClipboardOpen (false); + native_formats = ClipboardAvailableFormats (clipboard_handle); + + if (native_formats == null) + return false; + + foreach (int i in native_formats) { + // We might get a format we don't understand or know + item_format = DataFormats.GetFormat (i); + + if (item_format == null) + continue; + + if (((IList)formats).Contains (item_format.Name)) + return true; + } + + return false; + } + + internal override Stream GetAudioStream () + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return (Stream)data.GetData (DataFormats.WaveAudio, true); + } + + internal override object GetData (string format) + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return data.GetData (format, true); + } + + internal override IDataObject GetDataObject (bool primary_selection) + { + DataObject clipboard; + IntPtr clipboard_handle; + int[] native_formats; + DataFormats.Format item_format; + object managed_clipboard_item; + ClipboardData.ClipboardToObject converter; + + converter = new ClipboardData.ClipboardToObject (ConvertFromClipboardData); + + clipboard_handle = ClipboardOpen (primary_selection); + native_formats = ClipboardAvailableFormats (clipboard_handle); + if (native_formats == null){ + ClipboardClose (clipboard_handle); + return null; // Clipboard empty + } + + // Build the IDataObject + clipboard = new DataObject (); + for (int i = 0; i < native_formats.Length; i++) { + // We might get a format we don't understand or know + item_format = DataFormats.GetFormat (native_formats[i]); + + if (item_format != null){ + managed_clipboard_item = ClipboardRetrieve (clipboard_handle, native_formats[i], converter); + + if (managed_clipboard_item != null) { + clipboard.SetData (item_format.Name, managed_clipboard_item); + // We don't handle 'bitmap' since it involves handles, so we'll equate it to dib + if (item_format.Name == DataFormats.Dib) + clipboard.SetData (DataFormats.Bitmap, managed_clipboard_item); + } + } + } + + ClipboardClose (clipboard_handle); + + return clipboard; + } + + internal override StringCollection GetFileDropList () + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return (StringCollection)data.GetData (DataFormats.FileDrop, true); + } + + internal override Image GetImage () + { + IDataObject data = GetDataObject (); + + if (data == null) + return null; + + return (Image)data.GetData (DataFormats.Bitmap, true); + } + + internal override string GetText () + { + return GetText (TextDataFormat.UnicodeText); + } + + internal override string GetText (TextDataFormat format) + { + IDataObject data = GetDataObject (); + + if (data == null) + return string.Empty; + + string retval; + + switch (format) { + case TextDataFormat.Text: + default: + retval = (string)data.GetData (DataFormats.Text, true); + break; + case TextDataFormat.UnicodeText: + retval = (string)data.GetData (DataFormats.UnicodeText, true); + break; + case TextDataFormat.Rtf: + retval = (string)data.GetData (DataFormats.Rtf, true); + break; + case TextDataFormat.Html: + retval = (string)data.GetData (DataFormats.Html, true); + break; + case TextDataFormat.CommaSeparatedValue: + retval = (string)data.GetData (DataFormats.CommaSeparatedValue, true); + break; + } + + return retval == null ? string.Empty : retval; + } + + internal override void SetAudio (byte[] audioBytes) + { + MemoryStream ms = new MemoryStream (audioBytes); + + SetAudio (ms); + } + + internal override void SetAudio (Stream audioStream) + { + SetData (DataFormats.WaveAudio, audioStream); + } + + internal override void SetData (string format, object data) + { + DataObject data_object = new DataObject (format, data); + SetDataObject (data_object); + } + + internal override void SetDataObject (object data) + { + SetDataObject (data, false); // MSDN says default behavior is to place non-persistent data to clipboard + } + + internal override void SetDataObject (object data, bool copy) + { + SetDataObject (data, copy, 10, 100); // MSDN says default behavior is to try 10 times with 100 ms delay + } + + internal override void SetDataObject (object data, bool copy, int retryTimes, int retryDelay) + { + // MS implementation actually puts data to clipboard even when retryTimes == 0 + bool retry = true; + do { + retry = false; + --retryTimes; + try { + SetDataObjectImpl (data, copy); + } catch (ExternalException) { + if (retryTimes <= 0) + throw; + retry = true; + Thread.Sleep (retryDelay); + } + } while (retry && retryTimes > 0); + } + + private void SetDataObjectImpl (object data, bool copy) + { + IntPtr clipboard_handle; + ClipboardData.ObjectToClipboard converter; + int native_format; + DataFormats.Format item_format; + + converter = new ClipboardData.ObjectToClipboard (ConvertToClipboardData); + + clipboard_handle = ClipboardOpen (false); + ClipboardStore (clipboard_handle, null, 0, null); // Empty clipboard + + native_format = -1; + + if (data is IDataObject) { + string[] formats; + + IDataObject data_object = data as IDataObject; + formats = data_object.GetFormats (); + for (int i = 0; i < formats.Length; i++) + { + item_format = DataFormats.GetFormat (formats[i]); + if ((item_format != null) && (item_format.Name != DataFormats.StringFormat)) + native_format = item_format.Id; + + object obj = data_object.GetData (formats[i]); + + // this is used only by custom formats + if (IsDataSerializable (obj)) + item_format.is_serializable = true; + + ClipboardStore (clipboard_handle, obj, native_format, converter); + } + } else { + item_format = DataFormats.Format.Find (data.GetType ().FullName); + if ((item_format != null) && (item_format.Name != DataFormats.StringFormat)) + native_format = item_format.Id; + + ClipboardStore (clipboard_handle, data, native_format, converter); + } + ClipboardClose (clipboard_handle); + } + + private bool IsDataSerializable (object obj) + { + if (obj is ISerializable) + return true; + + AttributeCollection attrs = TypeDescriptor.GetAttributes (obj); + return attrs[typeof (SerializableAttribute)] != null; + } + + [MonoInternalNote ("Needs additional checks for valid paths, see MSDN")] + internal override void SetFileDropList (StringCollection filePaths) + { + SetData (DataFormats.FileDrop, filePaths); + } + + internal override void SetImage (Image image) + { + SetData (DataFormats.Bitmap, image); + } + + internal override void SetText (string text) + { + SetData (DataFormats.UnicodeText, text); + } + + internal override void SetText (string text, TextDataFormat format) + { + switch (format) { + case TextDataFormat.Text: + SetData (DataFormats.Text, text); + break; + case TextDataFormat.UnicodeText: + SetData (DataFormats.UnicodeText, text); + break; + case TextDataFormat.Rtf: + SetData (DataFormats.Rtf, text); + break; + case TextDataFormat.Html: + SetData (DataFormats.Html, text); + break; + case TextDataFormat.CommaSeparatedValue: + SetData (DataFormats.CommaSeparatedValue, text); + break; + } + } + + private bool ConvertToClipboardData (ref int type, object obj, out byte[] data) + { + data = null; + return false; + } + + private bool ConvertFromClipboardData (int type, IntPtr data, out object obj) + { + obj = null; + if (data == IntPtr.Zero) + { + return false; + } + return false; + } + + internal override int GetID (string format) + { + if (format == "Text") return (int)Atom.XA_STRING; + else if (format == "Bitmap") return (int)Atom.XA_BITMAP; + //else if (format == "MetaFilePict" ) return 3; + //else if (format == "SymbolicLink" ) return 4; + //else if (format == "DataInterchangeFormat" ) return 5; + //else if (format == "Tiff" ) return 6; + else if (format == "OEMText") return XplatUIX11.OEMTEXT.ToInt32 (); + else if (format == "DeviceIndependentBitmap") return (int)Atom.XA_PIXMAP; + else if (format == "Palette") return (int)Atom.XA_COLORMAP; // Useless + //else if (format == "PenData" ) return 10; + //else if (format == "RiffAudio" ) return 11; + //else if (format == "WaveAudio" ) return 12; + else if (format == "UnicodeText") return XplatUIX11.UTF16_STRING.ToInt32 (); + //else if (format == "EnhancedMetafile" ) return 14; + //else if (format == "FileDrop" ) return 15; + //else if (format == "Locale" ) return 16; + else if (format == "Rich Text Format") return XplatUIX11.RICHTEXTFORMAT.ToInt32 (); + + return XplatUIX11.XInternAtom (XplatUIX11.DisplayHandle, format, false).ToInt32 (); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // stuff formerly in XplatUIX11 + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + private int[] ClipboardAvailableFormats (IntPtr handle) + { + DataFormats.Format f; + int[] result; + + f = DataFormats.Format.List; + + if (XplatUIX11.XGetSelectionOwner (XplatUIX11.DisplayHandle, XplatUIX11.CLIPBOARD) == IntPtr.Zero) + return null; + + XplatUIX11.Clipboard.Formats = new ArrayList (); + + while (f != null) { + XplatUIX11.XConvertSelection (XplatUIX11.DisplayHandle, XplatUIX11.CLIPBOARD, (IntPtr)f.Id, (IntPtr)f.Id, XplatUIX11.FosterParent, IntPtr.Zero); + + XplatUIX11.Clipboard.Enumerating = true; + while (XplatUIX11.Clipboard.Enumerating) + driver.UpdateMessageQueue (null); + f = f.Next; + } + + result = new int[XplatUIX11.Clipboard.Formats.Count]; + + for (int i = 0; i < XplatUIX11.Clipboard.Formats.Count; i++) + result[i] = ((IntPtr)XplatUIX11.Clipboard.Formats[i]).ToInt32 (); + + XplatUIX11.Clipboard.Formats = null; + return result; + } + + internal override void ClipboardClose (IntPtr handle) + { + if (handle != ClipMagic) + throw new ArgumentException ("handle is not a valid clipboard handle"); + return; + } + + internal override IntPtr ClipboardOpen (bool primary_selection) + { + if (!primary_selection) + ClipMagic = XplatUIX11.CLIPBOARD; + else + ClipMagic = XplatUIX11.PRIMARY; + return ClipMagic; + } + + private object ClipboardRetrieve (IntPtr handle, int type, ClipboardData.ClipboardToObject converter) + { + XplatUIX11.XConvertSelection (XplatUIX11.DisplayHandle, handle, (IntPtr)type, (IntPtr)type, XplatUIX11.FosterParent, IntPtr.Zero); + + XplatUIX11.Clipboard.Retrieving = true; + while (XplatUIX11.Clipboard.Retrieving) + driver.UpdateMessageQueue (null); + + return XplatUIX11.Clipboard.Item; + } + + private void ClipboardStore (IntPtr handle, object obj, int type, ClipboardData.ObjectToClipboard converter) + { + XplatUIX11.Clipboard.Converter = converter; + + if (obj != null) { + XplatUIX11.Clipboard.AddSource (type, obj); + XplatUIX11.XSetSelectionOwner (XplatUIX11.DisplayHandle, XplatUIX11.CLIPBOARD, XplatUIX11.FosterParent, IntPtr.Zero); + } else { + // Clearing the selection + XplatUIX11.Clipboard.ClearSources (); + XplatUIX11.XSetSelectionOwner (XplatUIX11.DisplayHandle, XplatUIX11.CLIPBOARD, IntPtr.Zero, IntPtr.Zero); + } + } + } +} diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs index 8d3facf..f60df2e 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs @@ -41,17 +41,15 @@ using System.Threading; namespace System.Windows.Forms { internal class XplatUI { - #region Local Variables + static XplatUIDriver driver; static String default_class_name; + internal static ArrayList key_filters = new ArrayList (); - #endregion // Local Variables - #region Private Methods internal static string Window(IntPtr handle) { return String.Format("'{0}' ({1:X})", Control.FromHandle(handle), handle.ToInt32()); } - #endregion // Private Methods #region Subclasses public class State { @@ -77,48 +75,48 @@ namespace System.Windows.Forms { #endregion // Subclasses #region Constructor & Destructor - static XplatUI() { + static XplatUI() + { // Compose name with current domain id because on Win32 we register class name // and name must be unique to process. If we load MWF into multiple appdomains // and try to register same class name we fail. default_class_name = "SWFClass" + System.Threading.Thread.GetDomainID().ToString(); if (RunningOnUnix) { - //if (Environment.GetEnvironmentVariable ("not_supported_MONO_MWF_USE_NEW_X11_BACKEND") != null) { - // driver=XplatUIX11_new.GetInstance (); - //} else - if (Environment.GetEnvironmentVariable ("MONO_MWF_MAC_FORCE_X11") != null) { - driver = XplatUIX11.GetInstance (); - } else { + bool onDarwin = false; + + if (Environment.GetEnvironmentVariable ("MONO_MWF_MAC_FORCE_X11") == null) { IntPtr buf = Marshal.AllocHGlobal (8192); - // This is a hacktastic way of getting sysname from uname () - if (uname (buf) != 0) { - // WTF: We cannot run uname - driver=XplatUIX11.GetInstance (); - } else { + + // Use uname to determine the OS, see if we are running on Darwin + if (uname (buf) == 0) { string os = Marshal.PtrToStringAnsi (buf); if (os == "Darwin") - driver=XplatUICarbon.GetInstance (); - else - driver=XplatUIX11.GetInstance (); + onDarwin = true; } Marshal.FreeHGlobal (buf); } + if (onDarwin){ + driver = XplatUICarbon.GetInstance (); + Clipboard.SetClipboard (new XplatClipboardCarbon ()); + } else { + driver = XplatUIX11.GetInstance (); + Clipboard.SetClipboard (new XplatClipboardX11 (driver)); + } } else { - driver=XplatUIWin32.GetInstance(); + driver = XplatUIWin32.GetInstance (); + Clipboard.SetClipboard (new XplatClipboardWin32 ()); } - driver.InitializeDriver(); + driver.InitializeDriver (); // Initialize things that need to be done after the driver is ready - DataFormats.GetFormat(0); + DataFormats.GetFormat (0); -#if NET_2_0 // Signal that the Application loop can be run. // This allows UIA to initialize a11y support for MWF // before the main loop begins. Application.FirePreRun (); -#endif } #endregion // Constructor & Destructor @@ -374,11 +372,9 @@ namespace System.Windows.Forms { get { return driver.PopupMenuAlignment; } } -#if NET_2_0 public static PowerStatus PowerStatus { get { return driver.PowerStatus; } } -#endif public static bool RequiresPositiveClientAreaSize { get { @@ -524,48 +520,6 @@ namespace System.Windows.Forms { driver.ClientToScreen(handle, ref x, ref y); } - internal static int[] ClipboardAvailableFormats(IntPtr handle) { - #if DriverDebug - Console.WriteLine("ClipboardAvailableTypes({0:X}): Called", handle.ToInt32()); - #endif - return driver.ClipboardAvailableFormats(handle); - } - - internal static void ClipboardClose(IntPtr handle) { - #if DriverDebug - Console.WriteLine("ClipboardClose({0:X}): Called", handle.ToInt32()); - #endif - driver.ClipboardClose(handle); - } - - internal static int ClipboardGetID(IntPtr handle, string format) { - #if DriverDebug - Console.WriteLine("ClipboardGetID({0:X}, {1}): Called", handle.ToInt32(), format); - #endif - return driver.ClipboardGetID(handle, format); - } - - internal static IntPtr ClipboardOpen(bool primary_selection) { - #if DriverDebug - Console.WriteLine("ClipboardOpen(): Called"); - #endif - return driver.ClipboardOpen (primary_selection); - } - - internal static void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) { - #if DriverDebug - Console.WriteLine("ClipboardStore({0:X}, {1}, {2}): Called", handle.ToInt32(), obj, type, converter); - #endif - driver.ClipboardStore(handle, obj, type, converter); - } - - internal static object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) { - #if DriverDebug - Console.WriteLine("ClipboardRetrieve({0:X}, type, {1}): Called", handle.ToInt32(), converter); - #endif - return driver.ClipboardRetrieve(handle, type, converter); - } - internal static IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) { #if DriverDebug Console.WriteLine("DefineCursor(...): Called"); @@ -1186,14 +1140,12 @@ namespace System.Windows.Forms { driver.SystrayRemove(handle, ref tt); } -#if NET_2_0 internal static void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon) { #if DriverDebug Console.WriteLine("SystrayBalloon ({0}, {1}, {2}, {3}, {4}): Called", Window(handle), timeout, title, text, icon); #endif driver.SystrayBalloon(handle, timeout, title, text, icon); } -#endif internal static bool Text(IntPtr handle, string text) { #if DriverDebug @@ -1286,11 +1238,6 @@ namespace System.Windows.Forms { } #endregion // Public Static Methods - #region Delegates - public delegate bool ClipboardToObject(int type, IntPtr data, out object obj); - public delegate bool ObjectToClipboard(ref int type, object obj, out byte[] data); - #endregion // Delegates - [DllImport ("libc")] static extern int uname (IntPtr buf); } diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs index e06fa86..f06c457 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs @@ -842,40 +842,6 @@ namespace System.Windows.Forms { y = point.Y; } - internal override int[] ClipboardAvailableFormats(IntPtr handle) { - ArrayList list = new ArrayList (); - DataFormats.Format f = DataFormats.Format.List; - - while (f != null) { - list.Add (f.Id); - f = f.Next; - } - - return (int [])list.ToArray (typeof (int)); - } - - internal override void ClipboardClose(IntPtr handle) { - } - - //TODO: Map our internal formats to the right os code where we can - internal override int ClipboardGetID(IntPtr handle, string format) { - return (int)__CFStringMakeConstantString (format); - } - - internal override IntPtr ClipboardOpen(bool primary_selection) { - if (primary_selection) - return Carbon.Pasteboard.Primary; - return Carbon.Pasteboard.Application; - } - - internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) { - return Carbon.Pasteboard.Retrieve (handle, type); - } - - internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) { - Carbon.Pasteboard.Store (handle, obj, type); - } - internal override void CreateCaret (IntPtr hwnd, int width, int height) { if (Caret.Hwnd != IntPtr.Zero) DestroyCaret (Caret.Hwnd); diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs index 4ea795d..62471b1 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs @@ -400,13 +400,6 @@ namespace System.Windows.Forms { internal abstract void SetIcon(IntPtr handle, Icon icon); - internal abstract void ClipboardClose(IntPtr handle); - internal abstract IntPtr ClipboardOpen (bool primary_selection); - internal abstract int ClipboardGetID(IntPtr handle, string format); - internal abstract void ClipboardStore(IntPtr handle, object obj, int id, XplatUI.ObjectToClipboard converter); - internal abstract int[] ClipboardAvailableFormats(IntPtr handle); - internal abstract object ClipboardRetrieve(IntPtr handle, int id, XplatUI.ClipboardToObject converter); - internal abstract void DrawReversibleLine(Point start, Point end, Color backColor); internal abstract void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width); internal abstract void FillReversibleRectangle (Rectangle rectangle, Color backColor); diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs index aceae31..e26048e 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs @@ -44,8 +44,8 @@ namespace System.Windows.Forms { #region Local Variables private static XplatUIWin32 instance; private static int ref_count; - private static IntPtr FosterParent; + internal static IntPtr FosterParent; internal static MouseButtons mouse_state; internal static Point mouse_position; internal static bool grab_confined; @@ -2791,185 +2791,6 @@ namespace System.Windows.Forms { Win32SendMessage(hwnd, Msg.WM_SETICON, (IntPtr)1, icon == null ? IntPtr.Zero : icon.Handle); // 1 = large icon (0 would be small) } - internal override void ClipboardClose(IntPtr handle) { - if (handle != clip_magic) { - throw new ArgumentException("handle is not a valid clipboard handle"); - } - Win32CloseClipboard(); - } - - internal override int ClipboardGetID(IntPtr handle, string format) { - if (handle != clip_magic) { - throw new ArgumentException("handle is not a valid clipboard handle"); - } - if (format == "Text" ) return 1; - else if (format == "Bitmap" ) return 2; - else if (format == "MetaFilePict" ) return 3; - else if (format == "SymbolicLink" ) return 4; - else if (format == "DataInterchangeFormat" ) return 5; - else if (format == "Tiff" ) return 6; - else if (format == "OEMText" ) return 7; - else if (format == "DeviceIndependentBitmap" ) return 8; - else if (format == "Palette" ) return 9; - else if (format == "PenData" ) return 10; - else if (format == "RiffAudio" ) return 11; - else if (format == "WaveAudio" ) return 12; - else if (format == "UnicodeText" ) return 13; - else if (format == "EnhancedMetafile" ) return 14; - else if (format == "FileDrop" ) return 15; - else if (format == "Locale" ) return 16; - - return (int)Win32RegisterClipboardFormat(format); - } - - internal override IntPtr ClipboardOpen(bool primary_selection) { - // Win32 does not have primary selection - Win32OpenClipboard(FosterParent); - return clip_magic; - } - - internal override int[] ClipboardAvailableFormats(IntPtr handle) { - uint format; - int[] result; - int count; - - if (handle != clip_magic) { - return null; - } - - // Count first - count = 0; - format = 0; - do { - format = Win32EnumClipboardFormats(format); - if (format != 0) { - count++; - } - } while (format != 0); - - // Now assign - result = new int[count]; - count = 0; - format = 0; - do { - format = Win32EnumClipboardFormats(format); - if (format != 0) { - result[count++] = (int)format; - } - } while (format != 0); - - return result; - } - - - internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) { - IntPtr hmem; - IntPtr data; - object obj; - - if (handle != clip_magic) { - throw new ArgumentException("handle is not a valid clipboard handle"); - } - - hmem = Win32GetClipboardData((uint)type); - if (hmem == IntPtr.Zero) { - return null; - } - - data = Win32GlobalLock(hmem); - if (data == IntPtr.Zero) { - uint error = Win32GetLastError(); - Console.WriteLine("Error: {0}", error); - return null; - } - - obj = null; - - if (type == DataFormats.GetFormat(DataFormats.Rtf).Id) { - obj = AnsiToString(data); - } else switch ((ClipboardFormats)type) { - case ClipboardFormats.CF_TEXT: { - obj = AnsiToString(data); - break; - } - - case ClipboardFormats.CF_DIB: { - obj = DIBtoImage(data); - break; - } - - case ClipboardFormats.CF_UNICODETEXT: { - obj = UnicodeToString(data); - break; - } - - default: { - if (converter != null && !converter(type, data, out obj)) { - obj = null; - } - break; - } - } - Win32GlobalUnlock(hmem); - - return obj; - - } - - internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) { - byte[] data = null; - - if (handle != clip_magic) { - throw new ArgumentException("handle is not a valid clipboard handle"); - } - - if (obj == null) { - // Just clear it - if (!Win32EmptyClipboard()) - throw new ExternalException("Win32EmptyClipboard"); - return; - } - - if (type == -1) { - if (obj is string) { - type = (int)ClipboardFormats.CF_UNICODETEXT; - } else if (obj is Image) { - type = (int)ClipboardFormats.CF_DIB; - } - } - - if (type == DataFormats.GetFormat(DataFormats.Rtf).Id) { - data = StringToAnsi ((string)obj); - } else switch((ClipboardFormats)type) { - case ClipboardFormats.CF_UNICODETEXT: { - data = StringToUnicode ((string)obj); - break; - } - - case ClipboardFormats.CF_TEXT: { - data = StringToAnsi ((string)obj); - break; - } - - case ClipboardFormats.CF_BITMAP: - case ClipboardFormats.CF_DIB: { - data = ImageToDIB ((Image)obj); - type = (int)ClipboardFormats.CF_DIB; - break; - } - - default: { - if (converter != null && !converter(ref type, obj, out data)) { - data = null; // ensure that a failed conversion leaves null. - } - break; - } - } - if (data != null) { - SetClipboardData ((uint)type, data); - } - } - internal static byte[] StringToUnicode (string text) { return Encoding.Unicode.GetBytes (text + "\0"); @@ -2983,25 +2804,6 @@ namespace System.Windows.Forms { return Encoding.UTF8.GetBytes (text + "\0"); } - private void SetClipboardData (uint type, byte[] data) - { - if (data.Length == 0) - // Shouldn't call Win32SetClipboard with NULL, as, from MSDN: - // "This parameter can be NULL, indicating that the window provides data - // in the specified clipboard format (renders the format) upon request." - // and I don't think we support that... - // Note this is unrelated to the fact that passing a null obj to - // ClipboardStore is actually a request to empty the clipboard! - return; - IntPtr hmem = CopyToMoveableMemory (data); - if (hmem == IntPtr.Zero) - // As above, should not call with null. - // (Not that CopyToMoveableMemory should ever return null!) - throw new ExternalException ("CopyToMoveableMemory failed."); - if (Win32SetClipboardData (type, hmem) == IntPtr.Zero) - throw new ExternalException ("Win32SetClipboardData"); - } - /// /// Creates a memory block with GlobalAlloc(GMEM_MOVEABLE), copies the data /// into it, and returns the handle to the memory. @@ -3335,7 +3137,7 @@ namespace System.Windows.Forms { #region Win32 Imports [DllImport ("kernel32.dll", EntryPoint="GetLastError", CallingConvention=CallingConvention.StdCall)] - private extern static uint Win32GetLastError(); + internal extern static uint Win32GetLastError(); [DllImport ("user32.dll", EntryPoint="CreateWindowExW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)] internal extern static IntPtr Win32CreateWindow(WindowExStyles dwExStyle, string lpClassName, string lpWindowName, WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lParam); diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs index f01a993..614645b 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs @@ -83,13 +83,13 @@ namespace System.Windows.Forms { private static bool themes_enabled; // General X11 - private static IntPtr DisplayHandle; // X11 handle to display + internal static IntPtr DisplayHandle; // X11 handle to display private static int ScreenNo; // Screen number used private static IntPtr DefaultColormap; // Colormap for screen private static IntPtr CustomVisual; // Visual for window creation private static IntPtr CustomColormap; // Colormap for window creation private static IntPtr RootWindow; // Handle of the root window for the screen/display - private static IntPtr FosterParent; // Container to hold child windows until their parent exists + internal static IntPtr FosterParent; // Container to hold child windows until their parent exists private static XErrorHandler ErrorHandler; // Error handler delegate private static bool ErrorExceptions; // Throw exceptions on X errors private int render_major_opcode; @@ -98,7 +98,7 @@ namespace System.Windows.Forms { // Clipboard private static IntPtr ClipMagic; - private static ClipboardData Clipboard; // Our clipboard + internal static ClipboardData Clipboard; // Our clipboard // Communication private static IntPtr PostAtom; // PostMessage atom @@ -203,15 +203,16 @@ namespace System.Windows.Forms { //private static IntPtr _NET_WM_WINDOW_TYPE_SPLASH; // private static IntPtr _NET_WM_WINDOW_TYPE_DIALOG; private static IntPtr _NET_WM_WINDOW_TYPE_NORMAL; - private static IntPtr CLIPBOARD; - private static IntPtr PRIMARY; + internal static IntPtr CLIPBOARD; + internal static IntPtr PRIMARY; //private static IntPtr DIB; - private static IntPtr OEMTEXT; - private static IntPtr UTF8_STRING; - private static IntPtr UTF16_STRING; - private static IntPtr RICHTEXTFORMAT; private static IntPtr TARGETS; + internal static IntPtr OEMTEXT; + internal static IntPtr UTF8_STRING; + internal static IntPtr UTF16_STRING; + internal static IntPtr RICHTEXTFORMAT; + // mouse hover message generation private static HoverStruct HoverState; // @@ -1647,7 +1648,7 @@ namespace System.Windows.Forms { } } - private void UpdateMessageQueue (XEventQueue queue) { + internal void UpdateMessageQueue (XEventQueue queue) { DateTime now; int pending; Hwnd hwnd; @@ -2662,103 +2663,6 @@ namespace System.Windows.Forms { y = dest_y_return; } - internal override int[] ClipboardAvailableFormats(IntPtr handle) { - DataFormats.Format f; - int[] result; - - f = DataFormats.Format.List; - - if (XGetSelectionOwner(DisplayHandle, CLIPBOARD) == IntPtr.Zero) { - return null; - } - - Clipboard.Formats = new ArrayList(); - - while (f != null) { - XConvertSelection(DisplayHandle, CLIPBOARD, (IntPtr)f.Id, (IntPtr)f.Id, FosterParent, IntPtr.Zero); - - Clipboard.Enumerating = true; - while (Clipboard.Enumerating) { - UpdateMessageQueue(null); - } - f = f.Next; - } - - result = new int[Clipboard.Formats.Count]; - - for (int i = 0; i < Clipboard.Formats.Count; i++) { - result[i] = ((IntPtr)Clipboard.Formats[i]).ToInt32 (); - } - - Clipboard.Formats = null; - return result; - } - - internal override void ClipboardClose(IntPtr handle) { - if (handle != ClipMagic) { - throw new ArgumentException("handle is not a valid clipboard handle"); - } - return; - } - - internal override int ClipboardGetID(IntPtr handle, string format) { - if (handle != ClipMagic) { - throw new ArgumentException("handle is not a valid clipboard handle"); - } - - if (format == "Text" ) return (int)Atom.XA_STRING; - else if (format == "Bitmap" ) return (int)Atom.XA_BITMAP; - //else if (format == "MetaFilePict" ) return 3; - //else if (format == "SymbolicLink" ) return 4; - //else if (format == "DataInterchangeFormat" ) return 5; - //else if (format == "Tiff" ) return 6; - else if (format == "OEMText" ) return OEMTEXT.ToInt32(); - else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP; - else if (format == "Palette" ) return (int)Atom.XA_COLORMAP; // Useless - //else if (format == "PenData" ) return 10; - //else if (format == "RiffAudio" ) return 11; - //else if (format == "WaveAudio" ) return 12; - else if (format == "UnicodeText" ) return UTF16_STRING.ToInt32(); - //else if (format == "EnhancedMetafile" ) return 14; - //else if (format == "FileDrop" ) return 15; - //else if (format == "Locale" ) return 16; - else if (format == "Rich Text Format") return RICHTEXTFORMAT.ToInt32 (); - - return XInternAtom(DisplayHandle, format, false).ToInt32(); - } - - internal override IntPtr ClipboardOpen(bool primary_selection) { - if (!primary_selection) - ClipMagic = CLIPBOARD; - else - ClipMagic = PRIMARY; - return ClipMagic; - } - - internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) { - XConvertSelection(DisplayHandle, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero); - - Clipboard.Retrieving = true; - while (Clipboard.Retrieving) { - UpdateMessageQueue(null); - } - - return Clipboard.Item; - } - - internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) { - Clipboard.Converter = converter; - - if (obj != null) { - Clipboard.AddSource (type, obj); - XSetSelectionOwner(DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero); - } else { - // Clearing the selection - Clipboard.ClearSources (); - XSetSelectionOwner(DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero); - } - } - internal override void CreateCaret (IntPtr handle, int width, int height) { XGCValues gc_values;