From 475a5dc66e75229e3d472e11b0287ab3fd30a68e Mon Sep 17 00:00:00 2001 From: Carlos Alberto Cortez Date: Mon, 30 Mar 2009 07:40:48 +0000 Subject: [PATCH] * X11Structs: * X11Clipboard.cs: Move internal ClipboardStruct from X11Structs to its own file, since it is adding some functionality and thus is not a simple struct as before. * XplatUIX11.cs: Add support to store different formats that could have been specified by the user when puting data in the Clipboard - this is important when more than one format is supported (such plain text and rtf text). Update in the needed places, as well as simplify the code. Fixes #489625. 2009-03-30 Carlos Alberto Cortez svn path=/trunk/mcs/; revision=130537 --- .../System.Windows.Forms/ChangeLog | 13 +++ .../System.Windows.Forms/X11Clipboard.cs | 108 ++++++++++++++++++ .../System.Windows.Forms/X11Structs.cs | 10 -- .../System.Windows.Forms/XplatUIX11.cs | 39 ++++--- 4 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog index 9fe35bf4370..dcabaa08a17 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog @@ -1,3 +1,16 @@ +2009-03-30 Carlos Alberto Cortez + + * X11Structs: + * X11Clipboard.cs: Move internal ClipboardStruct from X11Structs to + its own file, since it is adding some functionality and thus is not a + simple struct as before. + * XplatUIX11.cs: Add support to store different formats that could + have been specified by the user when puting data in the Clipboard - + this is important when more than one format is supported (such plain + text and rtf text). Update in the needed places, as well as simplify + the code. + Fixes #489625. + 2009-03-30 Carlos Alberto Cortez * XplatUIX11.cs: When handling the SelectionRequest event, use diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs new file mode 100644 index 00000000000..c9f6857df29 --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Clipboard.cs @@ -0,0 +1,108 @@ +// 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) 2009 Novell, Inc. +// +// Authors: +// Carlos Alberto Cortez (calberto.cortez@gmail.com) +// + +using System; +using System.Drawing; +using System.Collections; +using System.Collections.Specialized; + +namespace System.Windows.Forms { + + internal class ClipboardData { + 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 + bool is_source_text; // Is any form of text supported? (plain, rtf, etc) + + internal object Item; // Object on the clipboard + 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; + + public ClipboardData () + { + source_data = new ListDictionary (); + } + + public void ClearSources () + { + source_data.Clear (); + plain_text_source = null; + image_source = null; + is_source_text = false; + } + + public void AddSource (int type, object source) + { + // Try to detect plain text, based on the old behaviour of XplatUIX11, which usually assigns + // -1 as the type when a string is stored in the Clipboard + if (source is string && (type == DataFormats.GetFormat (DataFormats.Text).Id || type == -1)) + plain_text_source = source as string; + else if (source is Image) + image_source = source as Image; + + is_source_text = source is string || is_source_text; + source_data [type] = source; + } + + public object GetSource (int type) + { + return source_data [type]; + } + + public string GetPlainText () + { + return plain_text_source; + } + + public string GetRtfText () + { + DataFormats.Format format = DataFormats.GetFormat (DataFormats.Text); + if (format == null) + return null; // FIXME - is RTF not supported on any system? + + return (string)GetSource (format.Id); + } + + public Image GetImage () + { + return image_source; + } + + public bool IsSourceText { + get { + return is_source_text; + } + } + + public bool IsSourceImage { + get { + return image_source != null; + } + } + } +} + diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs index 497d5a7d669..7b154d83fbf 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs @@ -1478,16 +1478,6 @@ namespace System.Windows.Forms { internal Rectangle Area; // The area the current grab is confined to } - internal struct ClipboardStruct { - internal object Source; - internal object Item; // Object on the clipboard - internal object Type; // Type if object on the clipboard - 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 delegate int XErrorHandler(IntPtr DisplayHandle, ref XErrorEvent error_event); internal enum XRequest : byte { 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 495be1f0220..03913369784 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs @@ -96,7 +96,7 @@ namespace System.Windows.Forms { // Clipboard private static IntPtr ClipMagic; - private static ClipboardStruct Clipboard; // Our clipboard + private static ClipboardData Clipboard; // Our clipboard // Communication private static IntPtr PostAtom; // PostMessage atom @@ -256,6 +256,7 @@ namespace System.Windows.Forms { MessageQueues = Hashtable.Synchronized (new Hashtable(7)); unattached_timer_list = ArrayList.Synchronized (new ArrayList (3)); messageHold = Hashtable.Synchronized (new Hashtable(3)); + Clipboard = new ClipboardData (); XInitThreads(); ErrorExceptions = false; @@ -1708,13 +1709,13 @@ namespace System.Windows.Forms { atoms = new int[5]; atom_count = 0; - if (Clipboard.Item is String) { + if (Clipboard.IsSourceText) { atoms[atom_count++] = (int)Atom.XA_STRING; atoms[atom_count++] = (int)OEMTEXT; atoms[atom_count++] = (int)UTF8_STRING; atoms[atom_count++] = (int)UTF16_STRING; atoms[atom_count++] = (int)RICHTEXTFORMAT; - } else if (Clipboard.Item is Image) { + } else if (Clipboard.IsSourceImage) { atoms[atom_count++] = (int)Atom.XA_PIXMAP; atoms[atom_count++] = (int)Atom.XA_BITMAP; } else { @@ -1724,34 +1725,41 @@ namespace System.Windows.Forms { XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count); sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property; - } else if (Clipboard.Item is string) { + } else if (Clipboard.IsSourceText) { IntPtr buffer; int buflen; buflen = 0; // The RTF spec mentions that ascii is enough to contain it - if (xevent.SelectionRequestEvent.target == (IntPtr)Atom.XA_STRING || - xevent.SelectionRequestEvent.target == (IntPtr)RICHTEXTFORMAT) { + IntPtr target_atom = xevent.SelectionRequestEvent.target; + if (target_atom == (IntPtr)Atom.XA_STRING || + target_atom == (IntPtr)RICHTEXTFORMAT) { Byte[] bytes; - bytes = new ASCIIEncoding().GetBytes((string)Clipboard.Source); + string source_data = null; + if (target_atom == (IntPtr)RICHTEXTFORMAT) + source_data = Clipboard.GetRtfText (); + if (source_data == null) // fallback to plain text if needed + source_data = Clipboard.GetPlainText (); + + bytes = Encoding.ASCII.GetBytes(source_data); buffer = Marshal.AllocHGlobal(bytes.Length); buflen = bytes.Length; for (int i = 0; i < buflen; i++) { Marshal.WriteByte(buffer, i, bytes[i]); } - } else if (xevent.SelectionRequestEvent.target == OEMTEXT) { + } else if (target_atom == OEMTEXT) { // FIXME - this should encode into ISO2022 - buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Source); + buffer = Marshal.StringToHGlobalAnsi(Clipboard.GetPlainText ()); while (Marshal.ReadByte(buffer, buflen) != 0) { buflen++; } - } else if (xevent.SelectionRequestEvent.target == UTF16_STRING) { + } else if (target_atom == UTF16_STRING) { Byte [] bytes; - bytes = Encoding.Unicode.GetBytes ((string)Clipboard.Source); + bytes = Encoding.Unicode.GetBytes (Clipboard.GetPlainText ()); buffer = Marshal.AllocHGlobal (bytes.Length); buflen = bytes.Length; @@ -1767,7 +1775,7 @@ namespace System.Windows.Forms { sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property; Marshal.FreeHGlobal(buffer); } - } else if (Clipboard.Item is Image) { + } else if (Clipboard.IsSourceImage) { if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) { // FIXME - convert image and store as property } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) { @@ -1796,8 +1804,8 @@ namespace System.Windows.Forms { if (xevent.SelectionEvent.property != IntPtr.Zero) { TranslatePropertyToClipboard(xevent.SelectionEvent.property); } else { + Clipboard.ClearSources (); Clipboard.Item = null; - Clipboard.Source = null; } } else { Dnd.HandleSelectionNotifyEvent (ref xevent); @@ -2652,15 +2660,14 @@ namespace System.Windows.Forms { } internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) { - Clipboard.Source = obj; - Clipboard.Item = obj; - Clipboard.Type = type; 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); } } -- 2.25.1