Merge pull request #260 from pcc/topmost
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUIX11.cs
index 9059b1b33f4a5a70281f96df828f36462f2c76a0..be2966157251a3edacf74110190c667537623fb2 100644 (file)
@@ -47,6 +47,9 @@
 #undef DriverDebugThreads
 #undef DriverDebugXEmbed
 
+//#define TRACE
+//#define DEBUG
+
 using System;
 using System.ComponentModel;
 using System.Collections;
@@ -59,6 +62,8 @@ using System.Net;
 using System.Net.Sockets;
 using System.Reflection;
 using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 using System.Text;
 using System.Threading;
 
@@ -73,146 +78,155 @@ namespace System.Windows.Forms {
                #region Local Variables
                // General
                static volatile XplatUIX11      Instance;
-               private static int              RefCount;
-               private static object           XlibLock;               // Our locking object
-               private static bool             themes_enabled;
+               static int              RefCount;
+               static object           XlibLock;               // Our locking object
+               static bool             themes_enabled;
 
                // General X11
-               private 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
-               private static XErrorHandler    ErrorHandler;           // Error handler delegate
-               private static bool             ErrorExceptions;        // Throw exceptions on X errors
+               static IntPtr           DisplayHandle;          // X11 handle to display
+               static int              ScreenNo;               // Screen number used
+               static IntPtr           DefaultColormap;        // Colormap for screen
+               static IntPtr           CustomVisual;           // Visual for window creation
+               static IntPtr           CustomColormap;         // Colormap for window creation
+               static IntPtr           RootWindow;             // Handle of the root window for the screen/display
+               static IntPtr           FosterParent;           // Container to hold child windows until their parent exists
+               static XErrorHandler    ErrorHandler;           // Error handler delegate
+               static bool             ErrorExceptions;        // Throw exceptions on X errors
+               int                     render_major_opcode;
+               int                     render_first_event;
+               int                     render_first_error;
 
                // Clipboard
-               private static IntPtr           ClipMagic;
-               private static ClipboardStruct  Clipboard;              // Our clipboard
+               static IntPtr           ClipMagic;
+               static ClipboardData    Clipboard;              // Our clipboard
 
                // Communication
-               private static IntPtr           PostAtom;               // PostMessage atom
-               private static IntPtr           AsyncAtom;              // Support for async messages
+               static IntPtr           PostAtom;               // PostMessage atom
+               static IntPtr           AsyncAtom;              // Support for async messages
 
                // Message Loop
-               private static Hashtable        MessageQueues;          // Holds our thread-specific XEventQueues
+               static Hashtable        MessageQueues;          // Holds our thread-specific XEventQueues
+               static ArrayList        unattached_timer_list; // holds timers that are enabled but not attached to a window.
                #if __MonoCS__                                          //
-               private static Pollfd[]         pollfds;                // For watching the X11 socket
-               private static bool wake_waiting;
-               private static object wake_waiting_lock = new object ();
+               static Pollfd[]         pollfds;                // For watching the X11 socket
+               static bool wake_waiting;
+               static object wake_waiting_lock = new object ();
                #endif                                                  //
-               private static X11Keyboard      Keyboard;               //
-               private static X11Dnd           Dnd;
-               private static Socket           listen;                 //
-               private static Socket           wake;                   //
-               private static Socket           wake_receive;           //
-               private static byte[]           network_buffer;         //
-               private static bool             detectable_key_auto_repeat;
+               static X11Keyboard      Keyboard;               //
+               static X11Dnd           Dnd;
+               static Socket           listen;                 //
+               static Socket           wake;                   //
+               static Socket           wake_receive;           //
+               static byte[]           network_buffer;         //
+               static bool             detectable_key_auto_repeat;
 
                // Focus tracking
-               private static IntPtr           ActiveWindow;           // Handle of the active window
-               private static IntPtr           FocusWindow;            // Handle of the window with keyboard focus (if any)
+               static IntPtr           ActiveWindow;           // Handle of the active window
+               static IntPtr           FocusWindow;            // Handle of the window with keyboard focus (if any)
 
                // Modality support
-               private static Stack            ModalWindows;           // Stack of our modal windows
+               static Stack            ModalWindows;           // Stack of our modal windows
 
                // Systray
-               private static IntPtr           SystrayMgrWindow;       // Handle of the Systray Manager window
+               static IntPtr           SystrayMgrWindow;       // Handle of the Systray Manager window
 
                // Cursors
-               private static IntPtr           LastCursorWindow;       // The last window we set the cursor on
-               private static IntPtr           LastCursorHandle;       // The handle that was last set on LastCursorWindow
-               private static IntPtr           OverrideCursorHandle;   // The cursor that is set to override any other cursors
+               static IntPtr           LastCursorWindow;       // The last window we set the cursor on
+               static IntPtr           LastCursorHandle;       // The handle that was last set on LastCursorWindow
+               static IntPtr           OverrideCursorHandle;   // The cursor that is set to override any other cursors
 
                // Caret
-               private static CaretStruct      Caret;                  //
+               static CaretStruct      Caret;                  //
+
+               // Last window containing the pointer
+               static IntPtr           LastPointerWindow;      // The last window containing the pointer
 
                // Our atoms
-               private static IntPtr WM_PROTOCOLS;
-               private static IntPtr WM_DELETE_WINDOW;
-               private static IntPtr WM_TAKE_FOCUS;
-               //private static IntPtr _NET_SUPPORTED;
-               //private static IntPtr _NET_CLIENT_LIST;
-               //private static IntPtr _NET_NUMBER_OF_DESKTOPS;
-               //private static IntPtr _NET_DESKTOP_GEOMETRY;
-               //private static IntPtr _NET_DESKTOP_VIEWPORT;
-               private static IntPtr _NET_CURRENT_DESKTOP;
-               //private static IntPtr _NET_DESKTOP_NAMES;
-               private static IntPtr _NET_ACTIVE_WINDOW;
-               private static IntPtr _NET_WORKAREA;
-               //private static IntPtr _NET_SUPPORTING_WM_CHECK;
-               //private static IntPtr _NET_VIRTUAL_ROOTS;
-               //private static IntPtr _NET_DESKTOP_LAYOUT;
-               //private static IntPtr _NET_SHOWING_DESKTOP;
-               //private static IntPtr _NET_CLOSE_WINDOW;
-               //private static IntPtr _NET_MOVERESIZE_WINDOW;
-               //private static IntPtr _NET_WM_MOVERESIZE;
-               //private static IntPtr _NET_RESTACK_WINDOW;
-               //private static IntPtr _NET_REQUEST_FRAME_EXTENTS;
-               private static IntPtr _NET_WM_NAME;
-               //private static IntPtr _NET_WM_VISIBLE_NAME;
-               //private static IntPtr _NET_WM_ICON_NAME;
-               //private static IntPtr _NET_WM_VISIBLE_ICON_NAME;
-               //private static IntPtr _NET_WM_DESKTOP;
-               private static IntPtr _NET_WM_WINDOW_TYPE;
-               private static IntPtr _NET_WM_STATE;
-               //private static IntPtr _NET_WM_ALLOWED_ACTIONS;
-               //private static IntPtr _NET_WM_STRUT;
-               //private static IntPtr _NET_WM_STRUT_PARTIAL;
-               //private static IntPtr _NET_WM_ICON_GEOMETRY;
-               private static IntPtr _NET_WM_ICON;
-               //private static IntPtr _NET_WM_PID;
-               //private static IntPtr _NET_WM_HANDLED_ICONS;
-               private static IntPtr _NET_WM_USER_TIME;
-               private static IntPtr _NET_FRAME_EXTENTS;
-               //private static IntPtr _NET_WM_PING;
-               //private static IntPtr _NET_WM_SYNC_REQUEST;
-               private static IntPtr _NET_SYSTEM_TRAY_S;
-               //private static IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
-               private static IntPtr _NET_SYSTEM_TRAY_OPCODE;
-               private static IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
-               private static IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
-               private static IntPtr _XEMBED;
-               private static IntPtr _XEMBED_INFO;
-               private static IntPtr _MOTIF_WM_HINTS;
-               private static IntPtr _NET_WM_STATE_SKIP_TASKBAR;
-               //private static IntPtr _NET_WM_STATE_ABOVE;
-               //private static IntPtr _NET_WM_STATE_MODAL;
-               private static IntPtr _NET_WM_STATE_HIDDEN;
-               private static IntPtr _NET_WM_CONTEXT_HELP;
-               private static IntPtr _NET_WM_WINDOW_OPACITY;
-               //private static IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
-               //private static IntPtr _NET_WM_WINDOW_TYPE_DOCK;
-               //private static IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
-               //private static IntPtr _NET_WM_WINDOW_TYPE_MENU;
-               private static IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
-               //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;
-               //private static IntPtr DIB;
-               private static IntPtr OEMTEXT;
-               private static IntPtr UNICODETEXT;
-               private static IntPtr TARGETS;
+               static IntPtr WM_PROTOCOLS;
+               static IntPtr WM_DELETE_WINDOW;
+               static IntPtr WM_TAKE_FOCUS;
+               //static IntPtr _NET_SUPPORTED;
+               //static IntPtr _NET_CLIENT_LIST;
+               //static IntPtr _NET_NUMBER_OF_DESKTOPS;
+               static IntPtr _NET_DESKTOP_GEOMETRY;
+               //static IntPtr _NET_DESKTOP_VIEWPORT;
+               static IntPtr _NET_CURRENT_DESKTOP;
+               //static IntPtr _NET_DESKTOP_NAMES;
+               static IntPtr _NET_ACTIVE_WINDOW;
+               static IntPtr _NET_WORKAREA;
+               //static IntPtr _NET_SUPPORTING_WM_CHECK;
+               //static IntPtr _NET_VIRTUAL_ROOTS;
+               //static IntPtr _NET_DESKTOP_LAYOUT;
+               //static IntPtr _NET_SHOWING_DESKTOP;
+               //static IntPtr _NET_CLOSE_WINDOW;
+               //static IntPtr _NET_MOVERESIZE_WINDOW;
+               static IntPtr _NET_WM_MOVERESIZE;
+               //static IntPtr _NET_RESTACK_WINDOW;
+               //static IntPtr _NET_REQUEST_FRAME_EXTENTS;
+               static IntPtr _NET_WM_NAME;
+               //static IntPtr _NET_WM_VISIBLE_NAME;
+               //static IntPtr _NET_WM_ICON_NAME;
+               //static IntPtr _NET_WM_VISIBLE_ICON_NAME;
+               //static IntPtr _NET_WM_DESKTOP;
+               static IntPtr _NET_WM_WINDOW_TYPE;
+               static IntPtr _NET_WM_STATE;
+               //static IntPtr _NET_WM_ALLOWED_ACTIONS;
+               //static IntPtr _NET_WM_STRUT;
+               //static IntPtr _NET_WM_STRUT_PARTIAL;
+               //static IntPtr _NET_WM_ICON_GEOMETRY;
+               static IntPtr _NET_WM_ICON;
+               //static IntPtr _NET_WM_PID;
+               //static IntPtr _NET_WM_HANDLED_ICONS;
+               static IntPtr _NET_WM_USER_TIME;
+               static IntPtr _NET_FRAME_EXTENTS;
+               //static IntPtr _NET_WM_PING;
+               //static IntPtr _NET_WM_SYNC_REQUEST;
+               static IntPtr _NET_SYSTEM_TRAY_S;
+               //static IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
+               static IntPtr _NET_SYSTEM_TRAY_OPCODE;
+               static IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
+               static IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
+               static IntPtr _XEMBED;
+               static IntPtr _XEMBED_INFO;
+               static IntPtr _MOTIF_WM_HINTS;
+               static IntPtr _NET_WM_STATE_SKIP_TASKBAR;
+               static IntPtr _NET_WM_STATE_ABOVE;
+               static IntPtr _NET_WM_STATE_MODAL;
+               static IntPtr _NET_WM_STATE_HIDDEN;
+               static IntPtr _NET_WM_CONTEXT_HELP;
+               static IntPtr _NET_WM_WINDOW_OPACITY;
+               //static IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
+               //static IntPtr _NET_WM_WINDOW_TYPE_DOCK;
+               //static IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
+               //static IntPtr _NET_WM_WINDOW_TYPE_MENU;
+               static IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
+               //static IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
+               // static IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
+               static IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
+               static IntPtr CLIPBOARD;
+               static IntPtr PRIMARY;
+               //static IntPtr DIB;
+               static IntPtr OEMTEXT;
+               static IntPtr UTF8_STRING;
+               static IntPtr UTF16_STRING;
+               static IntPtr RICHTEXTFORMAT;
+               static IntPtr TARGETS;
 
                // mouse hover message generation
-               private static HoverStruct      HoverState;             //
+               static HoverStruct      HoverState;             //
 
                // double click message generation
-               private static ClickStruct      ClickPending;           //
+               static ClickStruct      ClickPending;           //
 
                // Support for mouse grab
-               private static GrabStruct       Grab;                   //
+               static GrabStruct       Grab;                   //
 
                // State
                Point           mouse_position;         // Last position of mouse, in screen coords
                internal static MouseButtons    MouseState;             // Last state of mouse buttons
-
+               internal static bool in_doevents;
                // 'Constants'
-               private static int              DoubleClickInterval;    // msec; max interval between clicks to count as double click
+               static int              DoubleClickInterval;    // msec; max interval between clicks to count as double click
 
                const EventMask SelectInputMask = (EventMask.ButtonPressMask | 
                                                   EventMask.ButtonReleaseMask | 
@@ -223,19 +237,29 @@ namespace System.Windows.Forms {
                                                   EventMask.ExposureMask |
                                                   EventMask.FocusChangeMask |
                                                   EventMask.PointerMotionMask | 
+                                                  EventMask.PointerMotionHintMask | 
                                                   EventMask.SubstructureNotifyMask);
 
                static readonly object lockobj = new object ();
 
+               // messages WaitForHwndMwssage is waiting on
+               static Hashtable        messageHold;
+
                #endregion      // Local Variables
                #region Constructors
-               private XplatUIX11() {
+               XplatUIX11()
+               {
                        // Handle singleton stuff first
                        RefCount = 0;
+                       in_doevents = false;
 
                        // Now regular initialization
                        XlibLock = new object ();
+                       X11Keyboard.XlibLock = XlibLock;
                        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;
@@ -334,6 +358,14 @@ namespace System.Windows.Forms {
                                CustomColormap = value;
                        }
                }
+
+#if DEBUG_shana
+               internal static IntPtr DefaultColorMap {
+                       get {
+                               return DefaultColormap;
+                       }
+               }
+#endif
                #endregion
 
                #region XExceptionClass
@@ -379,7 +411,7 @@ namespace System.Windows.Forms {
                                        if (c != null) {
                                                control_text = c.ToString();
                                        } else {
-                                               control_text = String.Format("<handle {0:X} non-existant>", hwnd.Handle);
+                                               control_text = String.Format("<handle {0:X} non-existant>", hwnd.Handle.ToInt32());
                                        }
                                } else {
                                        hwnd_text = "<null>";
@@ -387,14 +419,15 @@ namespace System.Windows.Forms {
                                }
 
 
-                               error = String.Format("\n  Error: {0}\n  Request:     {1:D} ({2})\n  Resource ID: 0x{3:X}\n  Serial:      {4}\n  Hwnd:        {5}\n  Control:     {6}", x_error_text, RequestCode, RequestCode, ResourceID.ToInt32(), Serial, hwnd_text, control_text);
+                               error = String.Format("\n  Error: {0}\n  Request:     {1:D} ({2})\n  Resource ID: 0x{3:X}\n  Serial:      {4}\n  Hwnd:        {5}\n  Control:     {6}", x_error_text, RequestCode, MinorCode, ResourceID.ToInt32(), Serial, hwnd_text, control_text);
                                return error;
                        }
                }
                #endregion      // XExceptionClass
 
                #region Internal Methods
-               internal void SetDisplay(IntPtr display_handle) {
+               internal void SetDisplay(IntPtr display_handle)
+               {
                        if (display_handle != IntPtr.Zero) {
                                Hwnd    hwnd;
 
@@ -414,6 +447,13 @@ namespace System.Windows.Forms {
                                // been hacked to do this for us.
                                Graphics.FromHdcInternal (DisplayHandle);
 
+                               // query for the render extension so
+                               // we can ignore the spurious
+                               // BadPicture errors that are
+                               // generated by cairo/render.
+                               XQueryExtension (DisplayHandle, "RENDER",
+                                                ref render_major_opcode, ref render_first_event, ref render_first_error);
+
                                // Debugging support
                                if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
                                        XSynchronize(DisplayHandle, true);
@@ -429,11 +469,14 @@ namespace System.Windows.Forms {
                                DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);
 
                                // Create the foster parent
-                               FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 4, UIntPtr.Zero, UIntPtr.Zero);
+                               // it is important that border_width is kept in synch with the other XCreateWindow calls
+                               FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 0, UIntPtr.Zero, UIntPtr.Zero);
                                if (FosterParent==IntPtr.Zero) {
                                        Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
                                }
 
+                               DebugHelper.WriteLine ("FosterParent created 0x{0:x}", FosterParent.ToInt32());
+
                                hwnd = new Hwnd();
                                hwnd.Queue = ThreadQueue(Thread.CurrentThread);
                                hwnd.WholeWindow = FosterParent;
@@ -456,6 +499,12 @@ namespace System.Windows.Forms {
 
                                wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                                wake.Connect(listen.LocalEndPoint);
+
+                               // Make this non-blocking, so it doesn't
+                               // deadlock if too many wakes are sent
+                               // before the wake_receive end is polled
+                               wake.Blocking = false;
+
                                wake_receive = listen.Accept();
 
                                #if __MonoCS__
@@ -497,7 +546,7 @@ namespace System.Windows.Forms {
                                SetupAtoms();
 
                                // Grab atom changes off the root window to catch certain WM events
-                               XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int)EventMask.PropertyChangeMask));
+                               XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int) (EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
 
                                // Handle any upcoming errors
                                ErrorHandler = new XErrorHandler(HandleError);
@@ -508,14 +557,20 @@ namespace System.Windows.Forms {
                }
                #endregion      // Internal Methods
 
-               #region Private Methods
-               private int unixtime() {
+               #region Methods
+               [Conditional ("DriverDebug")]
+               static void DriverDebug (string format, params object [] args)
+               {
+                       Console.WriteLine (String.Format (format, args));
+               }
+               
+               int unixtime() {
                        TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
 
                        return (int) t.TotalSeconds;
                }
 
-               private static void SetupAtoms() {
+               static void SetupAtoms() {
                        // make sure this array stays in sync with the statements below
                        string [] atom_names = new string[] {
                                "WM_PROTOCOLS",
@@ -524,7 +579,7 @@ namespace System.Windows.Forms {
                                //"_NET_SUPPORTED",
                                //"_NET_CLIENT_LIST",
                                //"_NET_NUMBER_OF_DESKTOPS",
-                               //"_NET_DESKTOP_GEOMETRY",
+                               "_NET_DESKTOP_GEOMETRY",
                                //"_NET_DESKTOP_VIEWPORT",
                                "_NET_CURRENT_DESKTOP",
                                //"_NET_DESKTOP_NAMES",
@@ -536,7 +591,7 @@ namespace System.Windows.Forms {
                                //"_NET_SHOWING_DESKTOP",
                                //"_NET_CLOSE_WINDOW",
                                //"_NET_MOVERESIZE_WINDOW",
-                               //"_NET_WM_MOVERESIZE",
+                               "_NET_WM_MOVERESIZE",
                                //"_NET_RESTACK_WINDOW",
                                //"_NET_REQUEST_FRAME_EXTENTS",
                                "_NET_WM_NAME",
@@ -566,8 +621,8 @@ namespace System.Windows.Forms {
                                "_XEMBED_INFO",
                                "_MOTIF_WM_HINTS",
                                "_NET_WM_STATE_SKIP_TASKBAR",
-                               //"_NET_WM_STATE_ABOVE",
-                               //"_NET_WM_STATE_MODAL",
+                               "_NET_WM_STATE_ABOVE",
+                               "_NET_WM_STATE_MODAL",
                                "_NET_WM_CONTEXT_HELP",
                                "_NET_WM_WINDOW_OPACITY",
                                //"_NET_WM_WINDOW_TYPE_DESKTOP",
@@ -575,13 +630,15 @@ namespace System.Windows.Forms {
                                //"_NET_WM_WINDOW_TYPE_TOOLBAR",
                                //"_NET_WM_WINDOW_TYPE_MENU",
                                "_NET_WM_WINDOW_TYPE_UTILITY",
-                               //"_NET_WM_WINDOW_TYPE_DIALOG",
+                               // "_NET_WM_WINDOW_TYPE_DIALOG",
                                //"_NET_WM_WINDOW_TYPE_SPLASH",
                                "_NET_WM_WINDOW_TYPE_NORMAL",
                                "CLIPBOARD",
                                "PRIMARY",
                                "COMPOUND_TEXT",
                                "UTF8_STRING",
+                               "UTF16_STRING",
+                               "RICHTEXTFORMAT",
                                "TARGETS",
                                "_SWF_AsyncAtom",
                                "_SWF_PostMessageAtom",
@@ -598,7 +655,7 @@ namespace System.Windows.Forms {
                        //_NET_SUPPORTED = atoms [off++];
                        //_NET_CLIENT_LIST = atoms [off++];
                        //_NET_NUMBER_OF_DESKTOPS = atoms [off++];
-                       //_NET_DESKTOP_GEOMETRY = atoms [off++];
+                       _NET_DESKTOP_GEOMETRY = atoms [off++];
                        //_NET_DESKTOP_VIEWPORT = atoms [off++];
                        _NET_CURRENT_DESKTOP = atoms [off++];
                        //_NET_DESKTOP_NAMES = atoms [off++];
@@ -610,7 +667,7 @@ namespace System.Windows.Forms {
                        //_NET_SHOWING_DESKTOP = atoms [off++];
                        //_NET_CLOSE_WINDOW = atoms [off++];
                        //_NET_MOVERESIZE_WINDOW = atoms [off++];
-                       //_NET_WM_MOVERESIZE = atoms [off++];
+                       _NET_WM_MOVERESIZE = atoms [off++];
                        //_NET_RESTACK_WINDOW = atoms [off++];
                        //_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
                        _NET_WM_NAME = atoms [off++];
@@ -640,8 +697,8 @@ namespace System.Windows.Forms {
                        _XEMBED_INFO = atoms [off++];
                        _MOTIF_WM_HINTS = atoms [off++];
                        _NET_WM_STATE_SKIP_TASKBAR = atoms [off++];
-                       //_NET_WM_STATE_ABOVE = atoms [off++];
-                       //_NET_WM_STATE_MODAL = atoms [off++];
+                       _NET_WM_STATE_ABOVE = atoms [off++];
+                       _NET_WM_STATE_MODAL = atoms [off++];
                        _NET_WM_CONTEXT_HELP = atoms [off++];
                        _NET_WM_WINDOW_OPACITY = atoms [off++];
                        //_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
@@ -649,13 +706,15 @@ namespace System.Windows.Forms {
                        //_NET_WM_WINDOW_TYPE_TOOLBAR = atoms [off++];
                        //_NET_WM_WINDOW_TYPE_MENU = atoms [off++];
                        _NET_WM_WINDOW_TYPE_UTILITY = atoms [off++];
-                       //_NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
+                       // _NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
                        //_NET_WM_WINDOW_TYPE_SPLASH = atoms [off++];
                        _NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
                        CLIPBOARD = atoms [off++];
                        PRIMARY = atoms [off++];
                        OEMTEXT = atoms [off++];
-                       UNICODETEXT = atoms [off++];
+                       UTF8_STRING = atoms [off++];
+                       UTF16_STRING = atoms [off++];
+                       RICHTEXTFORMAT = atoms [off++];
                        TARGETS = atoms [off++];
                        AsyncAtom = atoms [off++];
                        PostAtom = atoms [off++];
@@ -665,14 +724,18 @@ namespace System.Windows.Forms {
                        _NET_SYSTEM_TRAY_S = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
                }
 
-               private void GetSystrayManagerWindow() {
+               void GetSystrayManagerWindow() {
                        XGrabServer(DisplayHandle);
                        SystrayMgrWindow = XGetSelectionOwner(DisplayHandle, _NET_SYSTEM_TRAY_S);
                        XUngrabServer(DisplayHandle);
                        XFlush(DisplayHandle);
                }
 
-               private void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
+               void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
+                       SendNetWMMessage (window, message_type, l0, l1, l2, IntPtr.Zero);
+               }
+
+               void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2, IntPtr l3) {
                        XEvent  xev;
 
                        xev = new XEvent();
@@ -684,10 +747,11 @@ namespace System.Windows.Forms {
                        xev.ClientMessageEvent.ptr1 = l0;
                        xev.ClientMessageEvent.ptr2 = l1;
                        xev.ClientMessageEvent.ptr3 = l2;
+                       xev.ClientMessageEvent.ptr4 = l3;
                        XSendEvent(DisplayHandle, RootWindow, false, new IntPtr ((int) (EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask)), ref xev);
                }
 
-               private void SendNetClientMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
+               void SendNetClientMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
                        XEvent  xev;
 
                        xev = new XEvent();
@@ -753,9 +817,114 @@ namespace System.Windows.Forms {
                        return (ex & (int)exws) == (int)exws;
                }
 
-               private void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out bool border_static, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
+               internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd)
+               {
+                       return TranslateClientRectangleToXClientRectangle (hwnd, Control.FromHandle (hwnd.Handle));
+               }
+               
+               internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd, Control ctrl)
+               {
+                       /* 
+                        * If this is a form with no window manager, X is handling all the border and caption painting
+                        * so remove that from the area (since the area we set of the window here is the part of the window 
+                        * we're painting in only)
+                        */
+                       Rectangle rect = hwnd.ClientRect;
+                       Form form = ctrl as Form;
+                       CreateParams cp = null;
+
+                       if (form != null)
+                               cp = form.GetCreateParams ();
+
+                       if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
+                               Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
+                               Rectangle xrect = rect;
+
+                               xrect.Y -= borders.top;
+                               xrect.X -= borders.left;
+                               xrect.Width += borders.left + borders.right;
+                               xrect.Height += borders.top + borders.bottom;
+
+                               rect = xrect;
+                       }
+                       
+                       if (rect.Width < 1 || rect.Height < 1) {
+                               rect.Width = 1;
+                               rect.Height = 1;
+                               rect.X = -5;
+                               rect.Y = -5;
+                       }
+                       
+                       return rect;
+               }
+
+               internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp)
+               {
+                       return TranslateWindowSizeToXWindowSize (cp, new Size (cp.Width, cp.Height));
+               }
+
+               internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp, Size size)
+               {
+                       /* 
+                        * If this is a form with no window manager, X is handling all the border and caption painting
+                        * so remove that from the area (since the area we set of the window here is the part of the window 
+                        * we're painting in only)
+                        */
+                       Form form = cp.control as Form;
+                       if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
+                               Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
+                               Size xrect = size;
+
+                               xrect.Width -= borders.left + borders.right;
+                               xrect.Height -= borders.top + borders.bottom;
+
+                               size = xrect;
+                       }
+                       if (size.Height == 0)
+                               size.Height = 1;
+                       if (size.Width == 0)
+                               size.Width = 1;
+                       return size;
+               }
+
+               internal static Size TranslateXWindowSizeToWindowSize (CreateParams cp, int xWidth, int xHeight)
+               {
+                       /* 
+                        * If this is a form with no window manager, X is handling all the border and caption painting
+                        * so remove that from the area (since the area we set of the window here is the part of the window 
+                        * we're painting in only)
+                        */
+                       Size rect = new Size (xWidth, xHeight);
+                       Form form = cp.control as Form;
+                       if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
+                               Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
+                               Size xrect = rect;
+
+                               xrect.Width += borders.left + borders.right;
+                               xrect.Height += borders.top + borders.bottom;
+
+                               rect = xrect;
+                       }
+                       return rect;
+               }
+               
+               internal static Point GetTopLevelWindowLocation (Hwnd hwnd)
+               {
+                       IntPtr dummy; 
+                       int x, y;
+                       Hwnd.Borders frame;
+
+                       XTranslateCoordinates (DisplayHandle, hwnd.whole_window, RootWindow, 0, 0, out x, out y, out dummy);
+                       frame = FrameExtents (hwnd.whole_window);
+
+                       x -= frame.left;
+                       y -= frame.top;
+                       
+                       return new Point (x, y);
+               }
+               
+               void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out bool border_static, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
 
-                       // Only MDI windows get caption_heights
                        caption_height = 0;
                        tool_caption_height = 19;
                        border_static = false;
@@ -772,18 +941,19 @@ namespace System.Windows.Forms {
                                        border_style = FormBorderStyle.FixedSingle;
                                }
                                title_style = TitleStyle.None;
+                               
+                               if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
+                                       caption_height = 19;
+                                       if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
+                                               title_style = TitleStyle.Tool;
+                                       } else {
+                                               title_style = TitleStyle.Normal;
+                                       }
+                               }
 
                                if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_MDICHILD)) {
                                        caption_height = 19;
 
-                                       if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
-                                               if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
-                                                       title_style = TitleStyle.Tool;
-                                               } else {
-                                                       title_style = TitleStyle.Normal;
-                                               }
-                                       }
-
                                        if (StyleSet (Style, WindowStyles.WS_OVERLAPPEDWINDOW) ||
                                            ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
                                                border_style = (FormBorderStyle) 0xFFFF;
@@ -833,20 +1003,24 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
+               void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
                        DeriveStyles(cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.border_static, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
                }
 
-               private void SetWMStyles(Hwnd hwnd, CreateParams cp) {
+               void SetWMStyles(Hwnd hwnd, CreateParams cp) {
                        MotifWmHints            mwmHints;
                        MotifFunctions          functions;
                        MotifDecorations        decorations;
                        int[]                   atoms;
                        int                     atom_count;
                        Rectangle               client_rect;
-
-                       // Child windows don't need WM window styles
-                       if (StyleSet (cp.Style, WindowStyles.WS_CHILDWINDOW)) {
+                       Form                    form;
+                       IntPtr                  window_type;
+                       bool                    hide_from_taskbar;
+                       IntPtr                  transient_for_parent;
+                       
+                       // Windows we manage ourselves don't need WM window styles.
+                       if (cp.HasWindowManager && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
                                return;
                        }
 
@@ -854,17 +1028,18 @@ namespace System.Windows.Forms {
                        mwmHints = new MotifWmHints();
                        functions = 0;
                        decorations = 0;
+                       window_type = _NET_WM_WINDOW_TYPE_NORMAL;
+                       transient_for_parent = IntPtr.Zero;
 
                        mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
                        mwmHints.functions = (IntPtr)0;
                        mwmHints.decorations = (IntPtr)0;
 
-                       if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)
-                           || !StyleSet (cp.Style, WindowStyles.WS_CAPTION | WindowStyles.WS_BORDER | WindowStyles.WS_DLGFRAME)) {
+                       form = cp.control as Form;
+
+                       if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
                                /* tool windows get no window manager
-                                  decorations, and neither do windows
-                                  which lack CAPTION/BORDER/DLGFRAME
-                                  styles.
+                                  decorations.
                                */
 
                                /* just because the window doesn't get any decorations doesn't
@@ -872,8 +1047,10 @@ namespace System.Windows.Forms {
                                   MotifFunctions.Maximize, changing the windowstate to Maximized
                                   is ignored by metacity. */
                                functions |= MotifFunctions.Move | MotifFunctions.Resize | MotifFunctions.Minimize | MotifFunctions.Maximize;
-                       }
-                       else {
+                       } else if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
+                               /* allow borderless window to be maximized */
+                               functions |= MotifFunctions.All | MotifFunctions.Resize;
+                       } else {
                                if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
                                        functions |= MotifFunctions.Move;
                                        decorations |= MotifDecorations.Title | MotifDecorations.Menu;
@@ -926,7 +1103,8 @@ namespace System.Windows.Forms {
 
                        if ((functions & MotifFunctions.Resize) == 0) {
                                hwnd.fixed_size = true;
-                               XplatUI.SetWindowMinMax(hwnd.Handle, new Rectangle(cp.X, cp.Y, cp.Width, cp.Height), new Size(cp.Width, cp.Height), new Size(cp.Width, cp.Height));
+                               Rectangle fixed_rectangle = new Rectangle (cp.X, cp.Y, cp.Width, cp.Height);
+                               SetWindowMinMax(hwnd.Handle, fixed_rectangle, fixed_rectangle.Size, fixed_rectangle.Size, cp);
                        } else {
                                hwnd.fixed_size = false;
                        }
@@ -934,49 +1112,59 @@ namespace System.Windows.Forms {
                        mwmHints.functions = (IntPtr)functions;
                        mwmHints.decorations = (IntPtr)decorations;
 
+                       DriverDebug ("SetWMStyles ({0}, {1}) functions = {2}, decorations = {3}", hwnd, cp, functions, decorations);
+
+                       if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
+                               // needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
+                               // and get those windows in front of their parents
+                               window_type = _NET_WM_WINDOW_TYPE_UTILITY;
+                       } else {
+                               window_type = _NET_WM_WINDOW_TYPE_NORMAL;
+                       }
+                       
+                       if (!cp.IsSet (WindowExStyles.WS_EX_APPWINDOW)) {
+                               hide_from_taskbar = true;
+                       } else if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW) &&  form != null && form.Parent != null && !form.ShowInTaskbar) {
+                               hide_from_taskbar = true;
+                       } else {
+                               hide_from_taskbar = false;
+                       }
+
+                       if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
+                               if (form != null && !hwnd.reparented) {
+                                       if (form.Owner != null && form.Owner.Handle != IntPtr.Zero) {
+                                               Hwnd owner_hwnd = Hwnd.ObjectFromHandle (form.Owner.Handle);
+                                               if (owner_hwnd != null)
+                                                       transient_for_parent = owner_hwnd.whole_window;
+                                       }
+                               }
+                       } 
+                       if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
+                               transient_for_parent = hwnd.parent.whole_window;
+                       }
+                       
                        FormWindowState current_state = GetWindowState (hwnd.Handle);
                        if (current_state == (FormWindowState)(-1))
                                current_state = FormWindowState.Normal;
 
-                       client_rect = hwnd.ClientRect;
+                       client_rect = TranslateClientRectangleToXClientRectangle (hwnd);
+
                        lock (XlibLock) {
                                atom_count = 0;
 
-                               // needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
-                               // and get those windows in front of their parents
-                               if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
-                                       atoms [0] = _NET_WM_WINDOW_TYPE_UTILITY.ToInt32 ();
-                                       XChangeProperty (DisplayHandle, hwnd.whole_window,  _NET_WM_WINDOW_TYPE,
-                                                        (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
-
-                                       Form f = Control.FromHandle(hwnd.Handle) as Form;
-                                       if (f != null && !hwnd.reparented) {
-                                               if (f.Owner != null && f.Owner.Handle != IntPtr.Zero) {
-                                                       Hwnd owner_hwnd = Hwnd.ObjectFromHandle(f.Owner.Handle);
-                                                       if (owner_hwnd != null)
-                                                               XSetTransientForHint(DisplayHandle, hwnd.whole_window,
-                                                                                    owner_hwnd.whole_window);
-                                               }
-                                       }
-                               }
-                               
+                               atoms [0] = window_type.ToInt32 ();
+                               XChangeProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
+
                                XChangeProperty(DisplayHandle, hwnd.whole_window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropertyMode.Replace, ref mwmHints, 5);
-                               if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
-                                       atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
-                                       XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
 
-                                       XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd.parent.whole_window);
-                               } else if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_APPWINDOW)) {
-                                       /* this line keeps the window from showing up in gnome's taskbar */
-                                       atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
-                               }
-                               if ((client_rect.Width < 1) || (client_rect.Height < 1)) {
-                                       XMoveResizeWindow(DisplayHandle, hwnd.client_window, -5, -5, 1, 1);
-                               } else {
-                                       XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
+                               if (transient_for_parent != IntPtr.Zero) {
+                                       XSetTransientForHint (DisplayHandle, hwnd.whole_window, transient_for_parent);
                                }
 
-                               if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
+                               MoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
+
+                               if (hide_from_taskbar) {
+                                       /* this line keeps the window from showing up in gnome's taskbar */
                                        atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
                                }
                                /* we need to add these atoms in the
@@ -990,6 +1178,11 @@ namespace System.Windows.Forms {
                                        atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_HORZ.ToInt32();
                                        atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_VERT.ToInt32();
                                }
+                               
+                               if (form != null && form.Modal) {
+                                       atoms[atom_count++] = _NET_WM_STATE_MODAL.ToInt32 ();
+                               }
+                               
                                XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
 
                                atom_count = 0;
@@ -1003,7 +1196,7 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void SetIcon(Hwnd hwnd, Icon icon)
+               void SetIcon(Hwnd hwnd, Icon icon)
                {
                        if (icon == null) {
                                // XXX
@@ -1042,11 +1235,17 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void WakeupMain () {
-                       wake.Send (new byte [] { 0xFF });
+               void WakeupMain () {
+                       try {
+                               wake.Send (new byte [] { 0xFF });
+                       } catch (SocketException ex) {
+                               if (ex.SocketErrorCode != SocketError.WouldBlock) {
+                                       throw;
+                               }
+                       }
                }
 
-               private XEventQueue ThreadQueue(Thread thread) {
+               XEventQueue ThreadQueue(Thread thread) {
                        XEventQueue     queue;
 
                        queue = (XEventQueue)MessageQueues[thread];
@@ -1058,7 +1257,7 @@ namespace System.Windows.Forms {
                        return queue;
                }
 
-               private void TranslatePropertyToClipboard(IntPtr property) {
+               void TranslatePropertyToClipboard(IntPtr property) {
                        IntPtr                  actual_atom;
                        int                     actual_format;
                        IntPtr                  nitems;
@@ -1071,22 +1270,100 @@ namespace System.Windows.Forms {
 
                        if ((long)nitems > 0) {
                                if (property == (IntPtr)Atom.XA_STRING) {
-                                       Clipboard.Item = Marshal.PtrToStringAnsi(prop);
+                                       // Xamarin-5116: PtrToStringAnsi expects to get UTF-8, but we might have
+                                       // Latin-1 instead.
+                                       var s = Marshal.PtrToStringAnsi (prop);
+                                       if (string.IsNullOrEmpty (s)) {
+                                               var sb = new StringBuilder ();
+                                               for (int i = 0; i < (int)nitems; i++) {
+                                                       var b = Marshal.ReadByte (prop, i);
+                                                       sb.Append ((char)b);
+                                               }
+                                               s = sb.ToString ();
+                                       }
+                                       // Some X managers/apps pass unicode chars as escaped strings, so
+                                       // we may need to unescape them.
+                                       Clipboard.Item = UnescapeUnicodeFromAnsi (s);
                                } else if (property == (IntPtr)Atom.XA_BITMAP) {
                                        // FIXME - convert bitmap to image
                                } else if (property == (IntPtr)Atom.XA_PIXMAP) {
                                        // FIXME - convert pixmap to image
                                } else if (property == OEMTEXT) {
+                                       Clipboard.Item = UnescapeUnicodeFromAnsi (Marshal.PtrToStringAnsi(prop));
+                               } else if (property == UTF8_STRING) {
+                                       byte [] buffer = new byte [(int)nitems];
+                                       for (int i = 0; i < (int)nitems; i++)
+                                               buffer [i] = Marshal.ReadByte (prop, i);
+                                       Clipboard.Item = Encoding.UTF8.GetString (buffer);
+                               } else if (property == UTF16_STRING) {
+                                       Clipboard.Item = Marshal.PtrToStringUni (prop, Encoding.Unicode.GetMaxCharCount ((int)nitems));
+                               } else if (property == RICHTEXTFORMAT)
                                        Clipboard.Item = Marshal.PtrToStringAnsi(prop);
-                               } else if (property == UNICODETEXT) {
-                                       Clipboard.Item = Marshal.PtrToStringAnsi(prop);
+                               else if (DataFormats.ContainsFormat (property.ToInt32 ())) {
+                                       if (DataFormats.GetFormat (property.ToInt32 ()).is_serializable) {
+                                               MemoryStream memory_stream = new MemoryStream ((int)nitems);
+                                               for (int i = 0; i < (int)nitems; i++)
+                                                       memory_stream.WriteByte (Marshal.ReadByte (prop, i));
+
+                                               memory_stream.Position = 0;
+                                               BinaryFormatter formatter = new BinaryFormatter ();
+                                               Clipboard.Item = formatter.Deserialize (memory_stream);
+                                               memory_stream.Close ();
+                                       }
                                }
 
                                XFree(prop);
                        }
                }
 
-               private void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
+               string UnescapeUnicodeFromAnsi (string value)
+               {
+                       if (value == null || value.IndexOf ("\\u") == -1)
+                               return value;
+
+                       StringBuilder sb = new StringBuilder (value.Length);
+                       int start, pos;
+
+                       start = pos = 0;
+                       while (start < value.Length) {
+                               pos = value.IndexOf ("\\u", start);
+                               if (pos == -1)
+                                       break;
+
+                               sb.Append (value, start, pos - start);
+                               pos += 2;
+                               start = pos;
+
+                               int length = 0;
+                               while (pos < value.Length) {
+                                       if (!ValidHexDigit (value [pos]))
+                                               break;
+                                       length++;
+                                       pos++;
+                               }
+
+                               int res;
+                               if (!Int32.TryParse (value.Substring (start, length), System.Globalization.NumberStyles.HexNumber, 
+                                                       null, out res))
+                                       return value; // Error, return the unescaped original value.
+                               
+                               sb.Append ((char)res);
+                               start = pos;
+                       }
+
+                       // Append any remaining data.
+                       if (start < value.Length)
+                               sb.Append (value, start, value.Length - start);
+
+                       return sb.ToString ();
+               }
+
+               private static bool ValidHexDigit (char e)
+               {
+                       return Char.IsDigit (e) || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
+               }
+
+               void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
                        // Don't waste time
                        if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
                                return;
@@ -1121,77 +1398,62 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void FrameExtents(IntPtr window, out int left, out int top) {
-                       IntPtr                  actual_atom;
-                       int                     actual_format;
-                       IntPtr                  nitems;
-                       IntPtr                  bytes_after;
-                       IntPtr                  prop = IntPtr.Zero;
-
-                       XGetWindowProperty(DisplayHandle, window, _NET_FRAME_EXTENTS, IntPtr.Zero, new IntPtr (16), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
-                       if (((long)nitems == 4) && (prop != IntPtr.Zero)) {
-                               left = Marshal.ReadIntPtr(prop, 0).ToInt32();
-                               //right = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
-                               top = Marshal.ReadIntPtr(prop, IntPtr.Size * 2).ToInt32();
-                               //bottom = Marshal.ReadIntPtr(prop, IntPtr.Size * 3).ToInt32();
-                       } else {
-                               left = 0;
-                               top = 0;
-                       }
-
+               static Hwnd.Borders FrameExtents (IntPtr window)
+               {
+                       IntPtr actual_atom;
+                       int actual_format;
+                       IntPtr nitems;
+                       IntPtr bytes_after;
+                       IntPtr prop = IntPtr.Zero;
+                       Hwnd.Borders rect = new Hwnd.Borders ();
+
+                       XGetWindowProperty (DisplayHandle, window, _NET_FRAME_EXTENTS, IntPtr.Zero, new IntPtr (16), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
                        if (prop != IntPtr.Zero) {
-                               XFree(prop);
+                               if (nitems.ToInt32 () == 4) {
+                                       rect.left = Marshal.ReadInt32 (prop, 0);
+                                       rect.right = Marshal.ReadInt32 (prop, IntPtr.Size);
+                                       rect.top = Marshal.ReadInt32 (prop, 2 * IntPtr.Size);
+                                       rect.bottom = Marshal.ReadInt32 (prop, 3 * IntPtr.Size);
+                               }
+                               XFree (prop);
                        }
-                       return;
+                       
+                       return rect;
                }
 
-               private void AddConfigureNotify (XEvent xevent) {
+               void AddConfigureNotify (XEvent xevent) {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.GetObjectFromWindow(xevent.ConfigureEvent.window);
 
                        // Don't waste time
-                       if (hwnd == null) {
+                       if (hwnd == null || hwnd.zombie) {
                                return;
                        }
-
-                       if ((xevent.ConfigureEvent.window == hwnd.whole_window) && (xevent.ConfigureEvent.window == xevent.ConfigureEvent.xevent)) {
-                               if (!hwnd.reparented) {
-                                       hwnd.x = xevent.ConfigureEvent.x;
-                                       hwnd.y = xevent.ConfigureEvent.y;
-                               } else {
-                                       // This sucks ass, part 1
-                                       // Every WM does the ConfigureEvents of toplevel windows different, so there's
-                                       // no standard way of getting our adjustment. 
-                                       // The code below is needed for KDE and FVWM, the 'whacky_wm' part is for metacity
-                                       // Several other WMs do their decorations different yet again and we fail to deal 
-                                       // with that, since I couldn't find any frigging commonality between them.
-                                       // The only sane WM seems to be KDE
-
-                                       if (!xevent.ConfigureEvent.send_event) {
-                                               IntPtr  dummy_ptr;
-
-                                               XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, -xevent.ConfigureEvent.x, -xevent.ConfigureEvent.y, out hwnd.x, out hwnd.y, out dummy_ptr);
-                                       } else {
-                                               // This is a synthetic event, coordinates are in root space
-                                               hwnd.x = xevent.ConfigureEvent.x;
-                                               hwnd.y = xevent.ConfigureEvent.y;
-                                               if (hwnd.whacky_wm) {
-                                                       int frame_left;
-                                                       int frame_top;
-
-                                                       FrameExtents(hwnd.whole_window, out frame_left, out frame_top);
-                                                       hwnd.x -= frame_left;
-                                                       hwnd.y -= frame_top;
-                                               }
-                                       }
+                       if ((xevent.ConfigureEvent.window == hwnd.whole_window)/* && (xevent.ConfigureEvent.window == xevent.ConfigureEvent.xevent)*/) {
+                               if (hwnd.parent == null) {
+                                       // The location given by the event is not reliable between different wm's, 
+                                       // so use an alternative way of getting it.
+                                       Point location = GetTopLevelWindowLocation (hwnd);
+                                       hwnd.x = location.X;
+                                       hwnd.y = location.Y;
                                }
 
                                // XXX this sucks.  this isn't thread safe
-                               hwnd.width = xevent.ConfigureEvent.width;
-                               hwnd.height = xevent.ConfigureEvent.height;
+                               Control ctrl = Control.FromHandle (hwnd.Handle);
+                               Size TranslatedSize;
+                               if (ctrl != null) {
+                                       TranslatedSize = TranslateXWindowSizeToWindowSize (ctrl.GetCreateParams (), xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
+                               } else {
+                                       TranslatedSize = new Size (xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
+                               }
+                               hwnd.width = TranslatedSize.Width;
+                               hwnd.height = TranslatedSize.Height;
                                hwnd.ClientRect = Rectangle.Empty;
 
+                               DriverDebug ("AddConfigureNotify (hwnd.Handle = {1}, final hwnd.rect = {0}, reported rect={2})",
+                                            new Rectangle (hwnd.x, hwnd.y, hwnd.width, hwnd.height), hwnd.Handle,
+                                            new Rectangle (xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.width));
                                lock (hwnd.configure_lock) {
                                        if (!hwnd.configure_pending) {
                                                hwnd.Queue.EnqueueLocked (xevent);
@@ -1202,7 +1464,7 @@ namespace System.Windows.Forms {
                        // We drop configure events for Client windows
                }
 
-               private void ShowCaret() {
+               void ShowCaret() {
                        if ((Caret.gc == IntPtr.Zero) || Caret.On) {
                                return;
                        }
@@ -1213,7 +1475,7 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void HideCaret() {
+               void HideCaret() {
                        if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
                                return;
                        }
@@ -1224,8 +1486,8 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private int NextTimeout (ArrayList timers, DateTime now) {
-                       int timeout = Int32.MaxValue
+               int NextTimeout (ArrayList timers, DateTime now) {
+                       int timeout = 0
 
                        foreach (Timer timer in timers) {
                                int next = (int) (timer.Expires - now).TotalMilliseconds;
@@ -1246,7 +1508,7 @@ namespace System.Windows.Forms {
                        return timeout;
                }
 
-               private void CheckTimers (ArrayList timers, DateTime now) {
+               void CheckTimers (ArrayList timers, DateTime now) {
                        int count;
 
                        count = timers.Count;
@@ -1259,34 +1521,183 @@ namespace System.Windows.Forms {
 
                                timer = (Timer) timers [i];
 
-                               if (timer.Enabled && timer.Expires <= now) {
-                                       timer.Update (now);
-                                       timer.FireTick ();
+                               if (timer.Enabled && timer.Expires <= now && !timer.Busy) {
+                                       // Timer ticks:
+                                       //  - Before MainForm.OnLoad if DoEvents () is called.
+                                       //  - After MainForm.OnLoad if not.
+                                       //
+                                       if (in_doevents ||
+                                           (Application.MWFThread.Current.Context != null && 
+                                            (Application.MWFThread.Current.Context.MainForm == null || 
+                                             Application.MWFThread.Current.Context.MainForm.IsLoaded))) {
+                                               timer.Busy = true;
+                                               timer.Update (now);
+                                               timer.FireTick ();
+                                               timer.Busy = false;
+                                       }
                                }
                        }
                }
 
-               private void MapWindow(Hwnd hwnd, WindowType windows) {
-                       hwnd.mapped = true;
-                       if ((windows & WindowType.Whole) != 0) {
-                               XMapWindow(DisplayHandle, hwnd.whole_window);
-                       }
-                       if ((windows & WindowType.Client) != 0) {
-                               XMapWindow(DisplayHandle, hwnd.client_window);
-                       }
+               void WaitForHwndMessage (Hwnd hwnd, Msg message) {
+                       WaitForHwndMessage (hwnd, message, false);
+
+               }
+
+               void WaitForHwndMessage (Hwnd hwnd, Msg message, bool process) {
+                       MSG msg = new MSG ();
+                       XEventQueue queue;
+
+                       queue = ThreadQueue(Thread.CurrentThread);
+
+                       queue.DispatchIdle = false;
+
+                       bool done = false;
+                       string key = hwnd.Handle + ":" + message;
+                       if (!messageHold.ContainsKey (key))     
+                               messageHold.Add (key, 1);
+                       else
+                               messageHold[key] = ((int)messageHold[key]) + 1;
+                       
+                                       
+                       do {
+
+                               DebugHelper.WriteLine  ("Waiting for message " + message + " on hwnd " + String.Format("0x{0:x}", hwnd.Handle.ToInt32 ()));
+                               DebugHelper.Indent ();
+                               
+                               if (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
+                                       if ((Msg)msg.message == Msg.WM_QUIT) {
+                                               PostQuitMessage (0);
+                                               done = true;
+                                       }
+                                       else {
+                                               
+                                               DebugHelper.WriteLine  ("PeekMessage got " + msg);
+                                               
+                                               if (msg.hwnd == hwnd.Handle) {
+                                                       if ((Msg)msg.message == message) {
+                                                               if (process) {
+                                                                       TranslateMessage (ref msg);
+                                                                       DispatchMessage (ref msg);
+                                                               }
+                                                               break;
+                                                       }
+                                                       else if ((Msg)msg.message == Msg.WM_DESTROY)
+                                                               done = true;
+                                               }
+
+                                               TranslateMessage (ref msg);
+                                               DispatchMessage (ref msg);
+                                       }
+                               }
+                               
+                               done = !messageHold.ContainsKey (key) || ((int)messageHold[key] < 1) || done;
+                       } while (!done);
+                                               
+                       messageHold.Remove (key);
+
+                       DebugHelper.Unindent ();
+                       DebugHelper.WriteLine  ("Finished waiting for " + key);                 
+
+                       queue.DispatchIdle = true;
+
                }
 
-               private void UnmapWindow(Hwnd hwnd, WindowType windows) {
-                       hwnd.mapped = false;
-                       if ((windows & WindowType.Whole) != 0) {
-                               XUnmapWindow(DisplayHandle, hwnd.whole_window);
+               void MapWindow(Hwnd hwnd, WindowType windows) {
+                       if (!hwnd.mapped) {
+                               Form f = Control.FromHandle(hwnd.Handle) as Form;
+                               if (f != null) {
+                                       if (f.WindowState == FormWindowState.Normal) {
+                                               f.waiting_showwindow = true;
+                                               SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
+                                       }
+                               }
+
+                               // it's possible that our Hwnd is no
+                               // longer valid after making that
+                               // SendMessage call, so check here.
+                               if (hwnd.zombie)
+                                       return;
+
+                               if (hwnd.topmost) {
+                                       // Most window managers will respect the _NET_WM_STATE property.
+                                       // If not, use XMapRaised to map the window at the top level as
+                                       // a last ditch effort.
+                                       if ((windows & WindowType.Whole) != 0) {
+                                               XMapRaised(DisplayHandle, hwnd.whole_window);
+                                       }
+                                       if ((windows & WindowType.Client) != 0) {
+                                               XMapRaised(DisplayHandle, hwnd.client_window);
+                                       }
+                               } else {
+                                       if ((windows & WindowType.Whole) != 0) {
+                                               XMapWindow(DisplayHandle, hwnd.whole_window);
+                                       }
+                                       if ((windows & WindowType.Client) != 0) {
+                                               XMapWindow(DisplayHandle, hwnd.client_window);
+                                       }
+                               }
+
+                               hwnd.mapped = true;
+
+                               if (f != null) {
+                                       if (f.waiting_showwindow) {
+                                               WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
+                                               CreateParams cp = f.GetCreateParams();
+                                               if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
+                                                   !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
+                                                       WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
+                                               }
+                                       }
+                               }
                        }
-                       if ((windows & WindowType.Client) != 0) {
-                               XUnmapWindow(DisplayHandle, hwnd.client_window);
+               }
+
+               void UnmapWindow(Hwnd hwnd, WindowType windows) {
+                       if (hwnd.mapped) {
+                               Form f = null;
+                               if (Control.FromHandle(hwnd.Handle) is Form) {
+                                       f = Control.FromHandle(hwnd.Handle) as Form;
+                                       if (f.WindowState == FormWindowState.Normal) {
+                                               f.waiting_showwindow = true;
+                                               SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, IntPtr.Zero, IntPtr.Zero);
+                                       }
+                               }
+
+                               // it's possible that our Hwnd is no
+                               // longer valid after making that
+                               // SendMessage call, so check here.
+                               // FIXME: it is likely wrong, as it has already sent WM_SHOWWINDOW
+                               if (hwnd.zombie)
+                                       return;
+
+                               if ((windows & WindowType.Client) != 0) {
+                                       XUnmapWindow(DisplayHandle, hwnd.client_window);
+                               }
+                               if ((windows & WindowType.Whole) != 0) {
+                                       XUnmapWindow(DisplayHandle, hwnd.whole_window);
+                               }
+
+                               hwnd.mapped = false;
+
+                               if (f != null) {
+                                       if (f.waiting_showwindow) {
+                                               WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
+                                               CreateParams cp = f.GetCreateParams();
+                                               if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
+                                                   !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
+                                                       WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
+                                               }
+                                       }
+                               }
                        }
                }
 
-               private void UpdateMessageQueue (XEventQueue queue) {
+               void UpdateMessageQueue (XEventQueue queue) {
+                       UpdateMessageQueue(queue, true);
+               }
+
+               void UpdateMessageQueue (XEventQueue queue, bool allowIdle) {
                        DateTime        now;
                        int             pending;
                        Hwnd            hwnd;
@@ -1297,7 +1708,7 @@ namespace System.Windows.Forms {
                                pending = XPending (DisplayHandle);
                        }
 
-                       if (pending == 0) {
+                       if (pending == 0 && allowIdle) {
                                if ((queue == null || queue.DispatchIdle) && Idle != null) {
                                        Idle (this, EventArgs.Empty);
                                }
@@ -1355,17 +1766,26 @@ namespace System.Windows.Forms {
 
                                        XNextEvent (DisplayHandle, ref xevent);
 
-                                       if (xevent.AnyEvent.type == XEventName.KeyPress) {
-                                               if (XFilterEvent(ref xevent, FosterParent)) {
+                                       if (xevent.AnyEvent.type == XEventName.KeyPress ||
+                                           xevent.AnyEvent.type == XEventName.KeyRelease) {
+                                               // PreFilter() handles "shift key state updates.
+                                               Keyboard.PreFilter (xevent);
+                                               if (XFilterEvent (ref xevent, Keyboard.ClientWindow)) {
+                                                       // probably here we could raise WM_IME_KEYDOWN and
+                                                       // WM_IME_KEYUP, but I'm not sure it is worthy.
                                                        continue;
                                                }
                                        }
+                                       else if (XFilterEvent (ref xevent, IntPtr.Zero))
+                                               continue;
                                }
 
                                hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
                                if (hwnd == null)
                                        continue;
 
+                               DebugHelper.WriteLine  ("UpdateMessageQueue got Event: " + xevent.ToString ());
+
                                switch (xevent.type) {
                                case XEventName.Expose:
                                        AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
@@ -1391,63 +1811,105 @@ namespace System.Windows.Forms {
                                        sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
                                        sel_event.SelectionEvent.property = IntPtr.Zero;
 
+                                       IntPtr format_atom = xevent.SelectionRequestEvent.target;
+
                                        // Seems that some apps support asking for supported types
-                                       if (xevent.SelectionEvent.target == TARGETS) {
+                                       if (format_atom == TARGETS) {
                                                int[]   atoms;
                                                int     atom_count;
 
                                                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)UNICODETEXT;
-                                               } else if (Clipboard.Item is Image) {
+                                                       atoms[atom_count++] = (int)UTF8_STRING;
+                                                       atoms[atom_count++] = (int)UTF16_STRING;
+                                                       atoms[atom_count++] = (int)RICHTEXTFORMAT;
+                                               } else if (Clipboard.IsSourceImage) {
                                                        atoms[atom_count++] = (int)Atom.XA_PIXMAP;
                                                        atoms[atom_count++] = (int)Atom.XA_BITMAP;
                                                } else {
                                                        // FIXME - handle other types
                                                }
 
-                                               XChangeProperty(DisplayHandle, xevent.SelectionEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
-                                       } else if (Clipboard.Item is string) {
-                                               IntPtr  buffer;
+                                               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 (format_atom == (IntPtr)RICHTEXTFORMAT) {
+                                               string rtf_text = Clipboard.GetRtfText ();
+                                               if (rtf_text != null) {
+                                                       // The RTF spec mentions that ascii is enough to contain it
+                                                       Byte [] bytes = Encoding.ASCII.GetBytes (rtf_text);
+                                                       int buflen = bytes.Length;
+                                                       IntPtr buffer = Marshal.AllocHGlobal (buflen);
+
+                                                       for (int i = 0; i < buflen; i++)
+                                                               Marshal.WriteByte (buffer, i, bytes[i]);
+
+                                                       XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
+                                                                       (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
+                                                       sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
+                                                       Marshal.FreeHGlobal(buffer);
+                                               }
+                                       } else if (Clipboard.IsSourceText && 
+                                                  (format_atom == (IntPtr)Atom.XA_STRING 
+                                                   || format_atom == OEMTEXT
+                                                   || format_atom == UTF16_STRING
+                                                   || format_atom == UTF8_STRING)) {
+                                               IntPtr  buffer = IntPtr.Zero;
                                                int     buflen;
+                                               Encoding encoding = null;
 
                                                buflen = 0;
 
-                                               if (xevent.SelectionRequestEvent.target == (IntPtr)Atom.XA_STRING) {
-                                                       Byte[] bytes;
+                                               // Select an encoding depending on the target
+                                               IntPtr target_atom = xevent.SelectionRequestEvent.target;
+                                               if (target_atom == (IntPtr)Atom.XA_STRING || target_atom == OEMTEXT)
+                                                       // FIXME - EOMTEXT should encode into ISO2022
+                                                       encoding = Encoding.ASCII;
+                                               else if (target_atom == UTF16_STRING)
+                                                       encoding = Encoding.Unicode;
+                                               else if (target_atom == UTF8_STRING)
+                                                       encoding = Encoding.UTF8;
 
-                                                       bytes = new ASCIIEncoding().GetBytes((string)Clipboard.Item);
-                                                       buffer = Marshal.AllocHGlobal(bytes.Length);
-                                                       buflen = bytes.Length;
+                                               Byte [] bytes;
 
-                                                       for (int i = 0; i < buflen; i++) {
-                                                               Marshal.WriteByte(buffer, i, bytes[i]);
-                                                       }
-                                               } else if (xevent.SelectionRequestEvent.target == OEMTEXT) {
-                                                       // FIXME - this should encode into ISO2022
-                                                       buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Item);
-                                                       while (Marshal.ReadByte(buffer, buflen) != 0) {
-                                                               buflen++;
-                                                       }
-                                               } else if (xevent.SelectionRequestEvent.target == UNICODETEXT) {
-                                                       buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Item);
-                                                       while (Marshal.ReadByte(buffer, buflen) != 0) {
-                                                               buflen++;
-                                                       }
-                                               } else {
-                                                       buffer = IntPtr.Zero;
-                                               }
+                                               bytes = encoding.GetBytes (Clipboard.GetPlainText ());
+                                               buffer = Marshal.AllocHGlobal (bytes.Length);
+                                               buflen = bytes.Length;
+
+                                               for (int i = 0; i < buflen; i++)
+                                                       Marshal.WriteByte (buffer, i, bytes [i]);
 
                                                if (buffer != IntPtr.Zero) {
                                                        XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
                                                        sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
                                                        Marshal.FreeHGlobal(buffer);
                                                }
-                                       } else if (Clipboard.Item is Image) {
+                                       } else if (Clipboard.GetSource (format_atom.ToInt32 ()) != null) { // check if we have an available value of this format
+                                               if (DataFormats.GetFormat (format_atom.ToInt32 ()).is_serializable) {
+                                                       object serializable = Clipboard.GetSource (format_atom.ToInt32 ());
+
+                                                       BinaryFormatter formatter = new BinaryFormatter ();
+                                                       MemoryStream memory_stream = new MemoryStream ();
+                                                       formatter.Serialize (memory_stream, serializable);
+
+                                                       int buflen = (int)memory_stream.Length;
+                                                       IntPtr buffer = Marshal.AllocHGlobal (buflen);
+                                                       memory_stream.Position = 0;
+                                                       for (int i = 0; i < buflen; i++)
+                                                               Marshal.WriteByte (buffer, i, (byte)memory_stream.ReadByte ());
+                                                       memory_stream.Close ();
+
+                                                       XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target,
+                                                                       8, PropertyMode.Replace, buffer, buflen);
+                                                       sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
+                                                       Marshal.FreeHGlobal (buffer);
+                                               }
+
+                                       } 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) {
@@ -1466,9 +1928,7 @@ namespace System.Windows.Forms {
                                                        XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
                                                        if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
                                                                Clipboard.Formats.Add(xevent.SelectionEvent.property);
-                                                               #if DriverDebugExtra
-                                                               Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
-                                                               #endif
+                                                               DriverDebug("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
                                                        }
                                                }
                                        } else if (Clipboard.Retrieving) {
@@ -1476,6 +1936,7 @@ namespace System.Windows.Forms {
                                                if (xevent.SelectionEvent.property != IntPtr.Zero) {
                                                        TranslatePropertyToClipboard(xevent.SelectionEvent.property);
                                                } else {
+                                                       Clipboard.ClearSources ();
                                                        Clipboard.Item = null;
                                                }
                                        } else {
@@ -1484,20 +1945,6 @@ namespace System.Windows.Forms {
                                        break;
                                }
 
-                               case XEventName.MapNotify: {
-                                       if (hwnd.client_window == xevent.MapEvent.window) {
-                                               hwnd.mapped = true;
-                                       }
-                                       break;
-                               }
-
-                               case XEventName.UnmapNotify: {
-                                       if (hwnd.client_window == xevent.MapEvent.window) {
-                                               hwnd.mapped = false;
-                                       }
-                                       break;
-                               }
-
                                case XEventName.KeyRelease:
                                        if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
                                                XEvent nextevent = new XEvent ();
@@ -1526,6 +1973,10 @@ namespace System.Windows.Forms {
                                }
 
                                case XEventName.KeyPress:
+                                       hwnd.Queue.EnqueueLocked (xevent);
+                                       /* Process KeyPresses immediately. Otherwise multiple Compose messages as a result of a
+                                        * single physical keypress are not processed correctly */
+                                       return;
                                case XEventName.ButtonPress:
                                case XEventName.ButtonRelease:
                                case XEventName.EnterNotify:
@@ -1536,6 +1987,8 @@ namespace System.Windows.Forms {
                                case XEventName.FocusOut:
                                case XEventName.ClientMessage:
                                case XEventName.ReparentNotify:
+                               case XEventName.MapNotify:
+                               case XEventName.UnmapNotify:
                                        hwnd.Queue.EnqueueLocked (xevent);
                                        break;
 
@@ -1544,6 +1997,7 @@ namespace System.Windows.Forms {
                                        break;
 
                                case XEventName.PropertyNotify:
+                                       DriverDebug ("UpdateMessageQueue (), got Event: {0}", xevent.ToString ());
                                        if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
                                                IntPtr  actual_atom;
                                                int     actual_format;
@@ -1555,9 +2009,11 @@ namespace System.Windows.Forms {
                                                prev_active = ActiveWindow;
                                                XGetWindowProperty(DisplayHandle, RootWindow, _NET_ACTIVE_WINDOW, IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
                                                if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
-                                                       ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));
+                                                       ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));                                                       
                                                        XFree(prop);
 
+                                                       DebugHelper.WriteLine ("PropertyNotify: _NET_ACTIVE_WINDOW: previous = 0x{0:x}, new = 0x{1:x}", prev_active.ToInt32 (), ActiveWindow.ToInt32 ());
+                                                       
                                                        if (prev_active != ActiveWindow) {
                                                                if (prev_active != IntPtr.Zero) {
                                                                        PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
@@ -1569,11 +2025,23 @@ namespace System.Windows.Forms {
                                                        if (ModalWindows.Count == 0) {
                                                                break;
                                                        } else {
-                                                               // Modality handling, if we are modal and the new active window is one
-                                                               // of ours but not the modal one, switch back to the modal window
-
-                                                               if (NativeWindow.FindWindow(ActiveWindow) != null) {
-                                                                       if (ActiveWindow != (IntPtr)ModalWindows.Peek()) {
+                                                               // Modality Handling
+                                                               // 
+                                                               // If there is a modal window on the stack and the new active 
+                                                               // window is MWF window, but not the modal one and not a non-modal 
+                                                               // child of the modal one, switch back to the modal window.
+                                                               //
+                                                               // To identify if a non-modal form is child of a modal form 
+                                                               // we match their ApplicationContexts, which will be the same.
+                                                               // This is because each modal form runs the loop with a 
+                                                               // new ApplicationContext, which is inherited by the non-modal 
+                                                               // forms.
+
+                                                               Form activeForm = Control.FromHandle (ActiveWindow) as Form;
+                                                               if (activeForm != null) {
+                                                                       Form modalForm = Control.FromHandle ((IntPtr)ModalWindows.Peek()) as Form;
+                                                                       if (ActiveWindow != (IntPtr)ModalWindows.Peek() && 
+                                                                           (modalForm == null || activeForm.context == modalForm.context)) {
                                                                                Activate((IntPtr)ModalWindows.Peek());
                                                                        }
                                                                }
@@ -1581,13 +2049,18 @@ namespace System.Windows.Forms {
                                                        }
                                                }
                                        }
+                                       else if (xevent.PropertyEvent.atom == _NET_WM_STATE) {
+                                               // invalidate our cache - we'll query again the next time someone does GetWindowState.
+                                               hwnd.cached_window_state = (FormWindowState)(-1);
+                                               PostMessage (hwnd.Handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
+                                       }
                                        break;
 
                                }
                        }
                }
 
-               private IntPtr GetMousewParam(int Delta) {
+               IntPtr GetMousewParam(int Delta) {
                        int     result = 0;
 
                        if ((MouseState & MouseButtons.Left) != 0) {
@@ -1615,7 +2088,7 @@ namespace System.Windows.Forms {
 
                        return (IntPtr)result;
                }
-               private IntPtr XGetParent(IntPtr handle) {
+               IntPtr XGetParent(IntPtr handle) {
                        IntPtr  Root;
                        IntPtr  Parent;
                        IntPtr  Children;
@@ -1633,38 +2106,57 @@ namespace System.Windows.Forms {
                        return Parent;
                }
 
-               private int HandleError(IntPtr display, ref XErrorEvent error_event) {
-                       if (ErrorExceptions) {
-                               throw new XException(error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code);
+               int HandleError (IntPtr display, ref XErrorEvent error_event)
+               {
+                       // we need to workaround a problem with the
+                       // ordering of destruction of Drawables and
+                       // Pictures that exists between cairo and
+                       // RENDER on the server.
+                       if (error_event.request_code == (XRequest)render_major_opcode
+                           && error_event.minor_code == 7 /* X_RenderFreePicture from render.h */
+                           && error_event.error_code == render_first_error + 1 /* BadPicture from render.h */) {
+                               return 0;
+                       }
+
+                       if (ErrorExceptions) {
+                               XUngrabPointer (display, IntPtr.Zero);
+                               throw new XException (error_event.display, error_event.resourceid,
+                                                     error_event.serial, error_event.error_code,
+                                                     error_event.request_code, error_event.minor_code);
                        } else {
-                               Console.WriteLine("X11 Error encountered: {0}{1}\n", XException.GetMessage(error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code), Environment.StackTrace);
+                               Console.WriteLine("X11 Error encountered: {0}{1}\n",
+                                                 XException.GetMessage (error_event.display, error_event.resourceid,
+                                                                        error_event.serial, error_event.error_code,
+                                                                        error_event.request_code, error_event.minor_code),
+                                                 Environment.StackTrace);
                        }
                        return 0;
                }
 
-               private void AccumulateDestroyedHandles (Control c, ArrayList list)
+               void AccumulateDestroyedHandles (Control c, ArrayList list)
                {
+                       DebugHelper.Enter ();
                        if (c != null) {
+                               
                                Control[] controls = c.Controls.GetAllControls ();
+                               
+                               DebugHelper.WriteLine  ("Checking control:0x{0:x}", c.IsHandleCreated ? c.Handle.ToInt32() : 0);
 
                                if (c.IsHandleCreated && !c.IsDisposed) {
                                        Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
 
-                                       #if DriverDebug || DriverDebugDestroy
-                                       Console.WriteLine (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
-                                       Console.WriteLine (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
-                                       #endif
+                                       DriverDebug (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
+                                       DriverDebug (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
 
                                        list.Add (hwnd);
                                        CleanupCachedWindows (hwnd);
-                                       hwnd.zombie = true;
                                }
 
                                for (int  i = 0; i < controls.Length; i ++) {
                                        AccumulateDestroyedHandles (controls[i], list);
-                               }
+                               }                                
                        }
-                       
+                       DebugHelper.Leave ();
                }
 
                void CleanupCachedWindows (Hwnd hwnd)
@@ -1687,12 +2179,12 @@ namespace System.Windows.Forms {
                        DestroyCaret (hwnd.Handle);
                }
 
-               private void PerformNCCalc(Hwnd hwnd) {
+               void PerformNCCalc(Hwnd hwnd) {
                        XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
                        IntPtr                          ptr;
                        Rectangle                       rect;
 
-                       rect = hwnd.DefaultClientRect;
+                       rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
 
                        ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
                        ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
@@ -1707,25 +2199,22 @@ namespace System.Windows.Forms {
                        ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
                        Marshal.FreeHGlobal(ptr);
 
-                       // FIXME - debug this with Menus
 
                        rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
                        hwnd.ClientRect = rect;
+               
+                       rect = TranslateClientRectangleToXClientRectangle (hwnd);
 
                        if (hwnd.visible) {
-                               if ((rect.Width < 1) || (rect.Height < 1)) {
-                                       XMoveResizeWindow(DisplayHandle, hwnd.client_window, -5, -5, 1, 1);
-                               } else {
-                                       XMoveResizeWindow(DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
-                               }
+                               MoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
                        }
 
-                       AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
+                       AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
                }
-               #endregion      // Private Methods
+               #endregion      // Methods
 
                #region Callbacks
-               private void MouseHover(object sender, EventArgs e) {
+               void MouseHover(object sender, EventArgs e) {
                        XEvent  xevent;
                        Hwnd    hwnd;
 
@@ -1750,7 +2239,7 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void CaretCallback(object sender, EventArgs e) {
+               void CaretCallback(object sender, EventArgs e) {
                        if (Caret.Paused) {
                                return;
                        }
@@ -1762,7 +2251,7 @@ namespace System.Windows.Forms {
 
                #region Public Properties
 
-               internal override int Caption {
+               internal override int CaptionHeight {
                        get {
                                return 19;
                        }
@@ -1791,11 +2280,11 @@ namespace System.Windows.Forms {
                        get {
                                return new Size(4, 4);
                        }
-               } 
+               }
 
                internal override  Size FrameBorderSize { 
                        get {
-                               throw new NotImplementedException(); 
+                               return new Size (4, 4);
                        }
                }
 
@@ -1888,13 +2377,13 @@ namespace System.Windows.Forms {
                        get {
                                return new Size (WorkingArea.Width, WorkingArea.Height);
                        }
-               } 
+               }
 
-               internal override  Size MinimizedWindowSize {
+               internal override bool MenuAccessKeysUnderlined {
                        get {
-                               return new Size(1, 1);
+                               return false;
                        }
-               } 
+               }
 
                internal override  Size MinimizedWindowSpacingSize {
                        get {
@@ -1904,16 +2393,22 @@ namespace System.Windows.Forms {
 
                internal override  Size MinimumWindowSize {
                        get {
-                               return new Size(1, 1);
+                               return new Size(110, 22);
                        }
                } 
 
-               internal override  Size MinWindowTrackSize {
-                       get {
-                               return new Size(1, 1);
-                       }
+               internal override Size MinimumFixedToolWindowSize {
+                       get { return new Size (27, 22); }
+               }
+
+               internal override Size MinimumSizeableToolWindowSize {
+                       get { return new Size (37, 22); }
                }
 
+               internal override Size MinimumNoBorderWindowSize {
+                       get { return new Size (2, 2); }
+               }
+               
                internal override Keys ModifierKeys {
                        get {
                                return Keyboard.ModifierKeys;
@@ -2016,9 +2511,41 @@ namespace System.Windows.Forms {
                        }
                } 
 
+               internal override MouseButtons MouseButtons {
+                       get {
+                               return MouseState;
+                       }
+               }
+
                internal override  Rectangle VirtualScreen {
                        get {
-                               return WorkingArea;
+                               IntPtr                  actual_atom;
+                               int                     actual_format;
+                               IntPtr                  nitems;
+                               IntPtr                  bytes_after;
+                               IntPtr                  prop = IntPtr.Zero;
+                               int                     width;
+                               int                     height;
+
+                               XGetWindowProperty(DisplayHandle, RootWindow, _NET_DESKTOP_GEOMETRY, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+                               if ((long)nitems < 2)
+                                       goto failsafe;
+
+                               width = Marshal.ReadIntPtr(prop, 0).ToInt32();
+                               height = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
+
+                               XFree(prop);
+
+                               return new Rectangle(0, 0, width, height);
+
+                       failsafe:
+                               XWindowAttributes       attributes=new XWindowAttributes();
+
+                               lock (XlibLock) {
+                                       XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
+                               }
+
+                               return new Rectangle(0, 0, attributes.width, attributes.height);
                        }
                } 
 
@@ -2044,7 +2571,7 @@ namespace System.Windows.Forms {
                                XFree(prop);
 
                                XGetWindowProperty(DisplayHandle, RootWindow, _NET_WORKAREA, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
-                               if ((long)nitems < 4 * current_desktop) {
+                               if ((long)nitems < 4 * (current_desktop + 1)) {
                                        goto failsafe;
                                }
 
@@ -2077,7 +2604,14 @@ namespace System.Windows.Forms {
                #endregion      // Public properties
 
                #region Public Static Methods
-               internal override IntPtr InitializeDriver() {
+               internal override void RaiseIdle (EventArgs e)
+               {
+                       if (Idle != null)
+                               Idle (this, e);
+               }
+               
+               internal override IntPtr InitializeDriver()
+               {
                        lock (this) {
                                if (DisplayHandle==IntPtr.Zero) {
                                        SetDisplay(XOpenDisplay(IntPtr.Zero));
@@ -2086,7 +2620,8 @@ namespace System.Windows.Forms {
                        return IntPtr.Zero;
                }
 
-               internal override void ShutdownDriver(IntPtr token) {
+               internal override void ShutdownDriver(IntPtr token)
+               {
                        lock (this) {
                                if (DisplayHandle!=IntPtr.Zero) {
                                        XCloseDisplay(DisplayHandle);
@@ -2095,12 +2630,14 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void EnableThemes() {
+               internal override void EnableThemes()
+               {
                        themes_enabled = true;
                }
 
 
-               internal override void Activate(IntPtr handle) {
+               internal override void Activate(IntPtr handle)
+               {
                        Hwnd hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -2109,6 +2646,16 @@ namespace System.Windows.Forms {
                                lock (XlibLock) {
                                        if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
                                                SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
+                                               XEventQueue q = null;
+                                               lock (unattached_timer_list) {
+                                                       foreach (Timer t in unattached_timer_list) {
+                                                               if (q == null)
+                                                                       q= (XEventQueue) MessageQueues [Thread.CurrentThread];
+                                                               t.thread = q.Thread;
+                                                               q.timer_list.Add (t);
+                                                       }
+                                                       unattached_timer_list.Clear ();
+                                               }
                                        }
 //                                     else {
 //                                             XRaiseWindow(DisplayHandle, handle);
@@ -2117,13 +2664,15 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void AudibleAlert() {
+               internal override void AudibleAlert(AlertType alert)
+               {
                        XBell(DisplayHandle, 0);
                        return;
                }
 
 
-               internal override void CaretVisible(IntPtr handle, bool visible) {
+               internal override void CaretVisible(IntPtr handle, bool visible)
+               {
                        if (Caret.Hwnd == handle) {
                                if (visible) {
                                        if (!Caret.Visible) {
@@ -2139,23 +2688,14 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override bool CalculateWindowRect(ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect) {
-                       FormBorderStyle border_style;
-                       TitleStyle      title_style;
-                       bool border_static;
-                       int caption_height;
-                       int tool_caption_height;
-
-                       DeriveStyles(Style, ExStyle, out border_style, out border_static, out title_style,
-                               out caption_height, out tool_caption_height);
-
-                       WindowRect = Hwnd.GetWindowRectangle(border_style, border_static, menu, title_style,
-                                       caption_height, tool_caption_height,
-                                       ClientRect);
+               internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect)
+               {
+                       WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
                        return true;
                }
 
-               internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
+               internal override void ClientToScreen(IntPtr handle, ref int x, ref int y)
+               {
                        int     dest_x_return;
                        int     dest_y_return;
                        IntPtr  child;
@@ -2171,7 +2711,8 @@ namespace System.Windows.Forms {
                        y = dest_y_return;
                }
 
-               internal override int[] ClipboardAvailableFormats(IntPtr handle) {
+               internal override int[] ClipboardAvailableFormats(IntPtr handle)
+               {
                        DataFormats.Format      f;
                        int[]                   result;
 
@@ -2188,7 +2729,7 @@ namespace System.Windows.Forms {
 
                                Clipboard.Enumerating = true;
                                while (Clipboard.Enumerating) {
-                                       UpdateMessageQueue(null);
+                                       UpdateMessageQueue(null, false);
                                }
                                f = f.Next;
                        }
@@ -2203,14 +2744,16 @@ namespace System.Windows.Forms {
                        return result;
                }
 
-               internal override void ClipboardClose(IntPtr handle) {
+               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) {
+               internal override int ClipboardGetID(IntPtr handle, string format)
+               {
                        if (handle != ClipMagic) {
                                throw new ArgumentException("handle is not a valid clipboard handle");
                        }
@@ -2227,15 +2770,17 @@ namespace System.Windows.Forms {
                        //else if (format == "PenData" ) return 10;
                        //else if (format == "RiffAudio" ) return 11;
                        //else if (format == "WaveAudio" ) return 12;
-                       else if (format == "UnicodeText" ) return UNICODETEXT.ToInt32();
+                       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) {
+               internal override IntPtr ClipboardOpen(bool primary_selection)
+               {
                        if (!primary_selection)
                                ClipMagic = CLIPBOARD;
                        else
@@ -2243,31 +2788,53 @@ namespace System.Windows.Forms {
                        return ClipMagic;
                }
 
-               internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
+               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);
+                               UpdateMessageQueue(null, false);
                        }
 
                        return Clipboard.Item;
                }
 
-               internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) {
-                       Clipboard.Item = obj;
-                       Clipboard.Type = type;
+               internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
+               {
                        Clipboard.Converter = converter;
 
                        if (obj != null) {
-                               XSetSelectionOwner(DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
+                               Clipboard.AddSource (type, obj);
+                               XSetSelectionOwner (DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
+
+                               if (copy) {
+                                       try {
+                                               var clipboardAtom = gdk_atom_intern ("CLIPBOARD", true);
+                                               var clipboard = gtk_clipboard_get (clipboardAtom);
+                                               if (clipboard != null) {
+                                                       // for now we only store text
+                                                       var text = Clipboard.GetRtfText ();
+                                                       if (string.IsNullOrEmpty (text))
+                                                               text = Clipboard.GetPlainText ();
+                                                       if (!string.IsNullOrEmpty (text)) {
+                                                               gtk_clipboard_set_text (clipboard, text, text.Length);
+                                                               gtk_clipboard_store (clipboard);
+                                                       }
+                                               }
+                                       } catch {
+                                               // ignore any errors - most likely because gtk isn't installed?
+                                       }
+                               }
                        } else {
                                // Clearing the selection
-                               XSetSelectionOwner(DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
+                               Clipboard.ClearSources ();
+                               XSetSelectionOwner (DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
                        }
                }
 
-               internal override void CreateCaret(IntPtr handle, int width, int height) {
+               internal override void CreateCaret (IntPtr handle, int width, int height)
+               {
                        XGCValues       gc_values;
                        Hwnd            hwnd;
 
@@ -2296,9 +2863,11 @@ namespace System.Windows.Forms {
                        XSetFunction(DisplayHandle, Caret.gc, GXFunction.GXinvert);
                }
 
-               internal override IntPtr CreateWindow(CreateParams cp) {
+               internal override IntPtr CreateWindow (CreateParams cp)
+               {
                        XSetWindowAttributes    Attributes;
                        Hwnd                    hwnd;
+                       Hwnd                    parent_hwnd = null;
                        int                     X;
                        int                     Y;
                        int                     Width;
@@ -2306,7 +2875,6 @@ namespace System.Windows.Forms {
                        IntPtr                  ParentHandle;
                        IntPtr                  WholeWindow;
                        IntPtr                  ClientWindow;
-                       Rectangle               ClientRect;
                        SetWindowValuemask      ValueMask;
                        int[]                   atoms;
 
@@ -2322,21 +2890,24 @@ namespace System.Windows.Forms {
                        if (Height<1) Height=1;
 
                        if (cp.Parent != IntPtr.Zero) {
-                               ParentHandle = Hwnd.ObjectFromHandle(cp.Parent).client_window;
+                               parent_hwnd = Hwnd.ObjectFromHandle(cp.Parent);
+                               ParentHandle = parent_hwnd.client_window;
                        } else {
                                if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
                                        // We need to use our foster parent window until this poor child gets it's parent assigned
                                        ParentHandle=FosterParent;
-                               } else if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
-                                       ParentHandle=RootWindow;
                                } else {
-                                       // Default position on screen, if window manager doesn't place us somewhere else
-                                       if (X<0) X = 50;
-                                       if (Y<0) Y = 50;
                                        ParentHandle=RootWindow;
                                }
                        }
 
+                       // Set the default location location for forms.
+                       Point next;
+                       if (cp.control is Form) {
+                               next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
+                               X = next.X;
+                               Y = next.Y;
+                       }
                        ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
 
                        Attributes.bit_gravity = Gravity.NorthWestGravity;
@@ -2360,17 +2931,20 @@ namespace System.Windows.Forms {
                        hwnd.width = Width;
                        hwnd.height = Height;
                        hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
-                       hwnd.initial_ex_style = (WindowExStyles) cp.ExStyle;
+                       hwnd.initial_style = cp.WindowStyle;
+                       hwnd.initial_ex_style = cp.WindowExStyle;
 
                        if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
                                hwnd.enabled = false;
                        }
 
-                       ClientRect = hwnd.ClientRect;
                        ClientWindow = IntPtr.Zero;
 
+                       Size XWindowSize = TranslateWindowSizeToXWindowSize (cp);
+                       Rectangle XClientRect = TranslateClientRectangleToXClientRectangle (hwnd, cp.control);
+                               
                        lock (XlibLock) {
-                               WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, Width, Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, new UIntPtr ((uint)ValueMask), ref Attributes);
+                               WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, XWindowSize.Width, XWindowSize.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, new UIntPtr ((uint)ValueMask), ref Attributes);
                                if (WholeWindow != IntPtr.Zero) {
                                        ValueMask &= ~(SetWindowValuemask.OverrideRedirect | SetWindowValuemask.SaveUnder);
 
@@ -2378,7 +2952,7 @@ namespace System.Windows.Forms {
                                                ValueMask = SetWindowValuemask.ColorMap;
                                                Attributes.colormap = CustomColormap;
                                        }
-                                       ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, ClientRect.X, ClientRect.Y, ClientRect.Width, ClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, new UIntPtr ((uint)ValueMask), ref Attributes);
+                                       ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, XClientRect.X, XClientRect.Y, XClientRect.Width, XClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, new UIntPtr ((uint)ValueMask), ref Attributes);
                                }
                        }
 
@@ -2390,10 +2964,8 @@ namespace System.Windows.Forms {
                        hwnd.WholeWindow = WholeWindow;
                        hwnd.ClientWindow = ClientWindow;
 
-                       #if DriverDebug || DriverDebugCreate
-                               Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}, Style {3}, ExStyle {4}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, (WindowStyles)cp.Style, (WindowExStyles)cp.ExStyle);
-                       #endif
-
+                       DriverDebug("Created window {0:X} / {1:X} parent {2:X}, Style {3}, ExStyle {4}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, (WindowStyles)cp.Style, (WindowExStyles)cp.ExStyle);
+                       
                        if (!StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
                                if ((X != unchecked((int)0x80000000)) && (Y != unchecked((int)0x80000000))) {
                                        XSizeHints      hints;
@@ -2407,23 +2979,13 @@ namespace System.Windows.Forms {
                        }
 
                        lock (XlibLock) {
-                               XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask)));
+                               XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
                                if (hwnd.whole_window != hwnd.client_window)
-                                       XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)SelectInputMask));
-
-                               if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
-                                       MapWindow(hwnd, WindowType.Both);
-                                       hwnd.visible = true;
-                               }
+                                       XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
                        }
 
-                       if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST)) {
-                               atoms = new int[2];
-                               atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
-                               XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
-
-                               XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
-                       }
+                       if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST))
+                               SetTopmost(hwnd.whole_window, true);
 
                        SetWMStyles(hwnd, cp);
                        
@@ -2455,13 +3017,22 @@ namespace System.Windows.Forms {
 
                        // Set caption/window title
                        Text(hwnd.Handle, cp.Caption);
-                       
+
+                       SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
                        SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
 
+                       if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
+                               hwnd.visible = true;
+                               MapWindow(hwnd, WindowType.Both);
+                               if (!(Control.FromHandle(hwnd.Handle) is Form))
+                                       SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
+                       }
+
                        return hwnd.Handle;
                }
 
-               internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
+               internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height)
+               {
                        CreateParams create_params = new CreateParams();
 
                        create_params.Caption = "";
@@ -2470,7 +3041,7 @@ namespace System.Windows.Forms {
                        create_params.Width = Width;
                        create_params.Height = Height;
 
-                       create_params.ClassName=XplatUI.DefaultClassName;
+                       create_params.ClassName=XplatUI.GetDefaultClassName (GetType ());
                        create_params.ClassStyle = 0;
                        create_params.ExStyle=0;
                        create_params.Parent=IntPtr.Zero;
@@ -2479,7 +3050,8 @@ namespace System.Windows.Forms {
                        return CreateWindow(create_params);
                }
 
-               internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
+               internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
+               {
                        IntPtr  cursor;
                        Bitmap  cursor_bitmap;
                        Bitmap  cursor_mask;
@@ -2566,10 +3138,74 @@ namespace System.Windows.Forms {
                        return cursor;
                }
 
-               internal override IntPtr DefineStdCursor(StdCursor id) {
+               internal override Bitmap DefineStdCursorBitmap (StdCursor id)
+               {
+                       CursorFontShape shape;
+                       string name;
+                       IntPtr theme;
+                       int size;
+                       Bitmap bmp = null;
+                       
+                       try {
+                               shape = StdCursorToFontShape (id);
+                               name = shape.ToString ().Replace ("XC_", string.Empty);
+                               size = XcursorGetDefaultSize (DisplayHandle);
+                               theme = XcursorGetTheme (DisplayHandle);
+                               IntPtr images_ptr = XcursorLibraryLoadImages (name, theme, size);
+                               DriverDebug ("DefineStdCursorBitmap, id={0}, #id={1}, name{2}, size={3}, theme: {4}, images_ptr={5}", id, (int) id, name, size, Marshal.PtrToStringAnsi (theme), images_ptr);
+
+                               if (images_ptr == IntPtr.Zero) {
+                                       return null;
+                               }
+
+                               XcursorImages images = (XcursorImages) Marshal.PtrToStructure (images_ptr, typeof (XcursorImages));
+                               DriverDebug ("DefineStdCursorBitmap, cursor has {0} images", images.nimage);
+
+                               if (images.nimage > 0) {                        
+                                       // We only care about the first image.
+                                       XcursorImage image = (XcursorImage)Marshal.PtrToStructure (Marshal.ReadIntPtr (images.images), typeof (XcursorImage));
+                                       
+                                       DriverDebug ("DefineStdCursorBitmap, loaded image <size={0}, height={1}, width={2}, xhot={3}, yhot={4}, pixels={5}", image.size, image.height, image.width, image.xhot, image.yhot, image.pixels);
+                                       // A sanity check
+                                       if (image.width <= short.MaxValue && image.height <= short.MaxValue) {
+                                               int [] pixels = new int [image.width * image.height];
+                                               Marshal.Copy (image.pixels, pixels, 0, pixels.Length);
+                                               bmp = new Bitmap (image.width, image.height);
+                                               for (int w = 0; w < image.width; w++) {
+                                                       for (int h = 0; h < image.height; h++) {
+                                                               bmp.SetPixel (w, h, Color.FromArgb (pixels [h * image.width + w]));
+                                                       }
+                                               }
+                                       }
+                               }
+                               
+                               XcursorImagesDestroy (images_ptr);
+                               
+                       } catch (DllNotFoundException ex) {
+                               Console.WriteLine ("Could not load libXcursor: " + ex.Message + " (" + ex.GetType ().Name + ")");
+                               return null;
+                       }
+                       
+                       return bmp;
+               }
+
+               
+               internal override IntPtr DefineStdCursor(StdCursor id)
+               {
                        CursorFontShape shape;
                        IntPtr          cursor;
 
+                       shape = StdCursorToFontShape (id);
+
+                       lock (XlibLock) {
+                               cursor = XCreateFontCursor(DisplayHandle, shape);
+                       }
+                       return cursor;
+               }
+
+               internal static CursorFontShape StdCursorToFontShape (StdCursor id)
+               {
+                       CursorFontShape shape;
                        // FIXME - define missing shapes
 
                        switch (id) {
@@ -2714,18 +3350,31 @@ namespace System.Windows.Forms {
                                }
 
                                default: {
-                                       return IntPtr.Zero;
+                                       shape = (CursorFontShape) 0;
+                                       break;
                                }
                        }
-
-                       lock (XlibLock) {
-                               cursor = XCreateFontCursor(DisplayHandle, shape);
-                       }
-                       return cursor;
+                       
+                       return shape;
                }
 
-               internal override IntPtr DefWndProc(ref Message msg) {
+               internal override IntPtr DefWndProc(ref Message msg)
+               {
                        switch ((Msg)msg.Msg) {
+                               
+                               case Msg.WM_IME_COMPOSITION:
+                                       string s = Keyboard.GetCompositionString ();
+                                       foreach (char c in s)
+                                               SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
+                                       return IntPtr.Zero;
+
+                               case Msg.WM_IME_CHAR:
+                                       // On Windows API it sends two WM_CHAR messages for each byte, but
+                                       // I wonder if it is worthy to emulate it (also no idea how to 
+                                       // reconstruct those bytes into chars).
+                                       SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
+                                       return IntPtr.Zero;
+
                                case Msg.WM_PAINT: {
                                        Hwnd hwnd;
 
@@ -2748,6 +3397,33 @@ namespace System.Windows.Forms {
                                        return IntPtr.Zero;
                                }
 
+                               case Msg.WM_NCCALCSIZE: {
+                                       Hwnd hwnd;
+
+                                       if (msg.WParam == (IntPtr)1) {
+                                               hwnd = Hwnd.GetObjectFromWindow (msg.HWnd);
+                                               
+                                               XplatUIWin32.NCCALCSIZE_PARAMS ncp;
+                                               ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
+
+                                               // Add all the stuff X is supposed to draw.
+                                               Control ctrl = Control.FromHandle (hwnd.Handle);
+                                               
+                                               if (ctrl != null) {
+                                                       Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
+                                                       
+                                                       ncp.rgrc1.top += rect.top;
+                                                       ncp.rgrc1.bottom -= rect.bottom;
+                                                       ncp.rgrc1.left += rect.left;
+                                                       ncp.rgrc1.right -= rect.right;
+                                                       
+                                                       Marshal.StructureToPtr (ncp, msg.LParam, true);
+                                               }
+                                       }
+
+                                       return IntPtr.Zero;
+                               }
+
                                case Msg.WM_CONTEXTMENU: {
                                        Hwnd hwnd;
 
@@ -2795,7 +3471,7 @@ namespace System.Windows.Forms {
                                                        case HitTest.HTBOTTOMLEFT:      handle = Cursors.SizeNESW.handle; break;
                                                        case HitTest.HTBOTTOMRIGHT:     handle = Cursors.SizeNWSE.handle; break;
                                                        case HitTest.HTERROR:           if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
-                                                                                               AudibleAlert();
+                                                                                               AudibleAlert(AlertType.Default);
                                                                                        }
                                                                                        handle = Cursors.Default.handle;
                                                                                        break;
@@ -2834,7 +3510,8 @@ namespace System.Windows.Forms {
                        return IntPtr.Zero;
                }
 
-               internal override void DestroyCaret(IntPtr handle) {
+               internal override void DestroyCaret(IntPtr handle)
+               {
                        if (Caret.Hwnd == handle) {
                                if (Caret.Visible) {
                                        HideCaret ();
@@ -2850,27 +3527,27 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void DestroyCursor(IntPtr cursor) {
+               internal override void DestroyCursor(IntPtr cursor)
+               {
                        lock (XlibLock) {
                                XFreeCursor(DisplayHandle, cursor);
                        }
                }
 
-               internal override void DestroyWindow(IntPtr handle) {
+               internal override void DestroyWindow(IntPtr handle)
+               {
                        Hwnd    hwnd;
-
                        hwnd = Hwnd.ObjectFromHandle(handle);
-
-                       if (hwnd == null) {
-                               #if DriverDebug || DriverDebugDestroy
-                                       Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
-                               #endif
+                       
+                       // The window should never ever be a zombie here, since we should
+                       // wait until it's completely dead before returning from 
+                       // "destroying" calls, but just in case....
+                       if (hwnd == null || hwnd.zombie) {
+                               DriverDebug ("window {0:X} already destroyed", handle.ToInt32());
                                return;
                        }
 
-                       #if DriverDebug || DriverDebugDestroy
-                               Console.WriteLine("Destroying window {0}", XplatUI.Window(hwnd.client_window));
-                       #endif
+                       DriverDebug ("Destroying window {0}", XplatUI.Window(hwnd.client_window));
 
                        SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
                                
@@ -2880,28 +3557,29 @@ namespace System.Windows.Forms {
 
                        AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
 
+
+                       foreach (Hwnd h in windows) {
+                               SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
+                               h.zombie = true;                                
+                       }
+
                        lock (XlibLock) {
                                if (hwnd.whole_window != IntPtr.Zero) {
-                                       #if DriverDebug || DriverDebugDestroy
-                                       Console.WriteLine ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
-                                       #endif
+                                       DriverDebug ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
+                                       Keyboard.DestroyICForWindow (hwnd.whole_window);
                                        XDestroyWindow(DisplayHandle, hwnd.whole_window);
                                }
                                else if (hwnd.client_window != IntPtr.Zero) {
-                                       #if DriverDebug || DriverDebugDestroy
-                                       Console.WriteLine ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
-                                       #endif
+                                       DriverDebug ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
+                                       Keyboard.DestroyICForWindow (hwnd.client_window);
                                        XDestroyWindow(DisplayHandle, hwnd.client_window);
                                }
 
                        }
-
-                       foreach (Hwnd h in windows) {
-                               SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
-                       }
                }
 
-               internal override IntPtr DispatchMessage(ref MSG msg) {
+               internal override IntPtr DispatchMessage(ref MSG msg)
+               {
                        return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
                }
 
@@ -2980,6 +3658,9 @@ namespace System.Windows.Forms {
 
                internal override void DrawReversibleLine(Point start, Point end, Color backColor)
                {
+                       if (backColor.GetBrightness() < 0.5)
+                               backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
+
                        IntPtr gc = GetReversibleScreenGC (backColor);
 
                        XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
@@ -2989,6 +3670,9 @@ namespace System.Windows.Forms {
 
                internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
                {
+                       if (backColor.GetBrightness() < 0.5)
+                               backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
+
                        IntPtr gc = GetReversibleScreenGC (backColor);
 
                        if (rectangle.Width < 0) {
@@ -3023,6 +3707,9 @@ namespace System.Windows.Forms {
 
                internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor) 
                {
+                       if (backColor.GetBrightness() < 0.5)
+                               backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
+
                        IntPtr gc = GetReversibleScreenGC (backColor);
 
                        if (rectangle.Width < 0) {
@@ -3038,7 +3725,8 @@ namespace System.Windows.Forms {
                        XFreeGC(DisplayHandle, gc);
                }
 
-               internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
+               internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width)
+               {
                        IntPtr          gc;
                        Control control = Control.FromHandle(handle);
 
@@ -3056,7 +3744,10 @@ namespace System.Windows.Forms {
                        XFreeGC(DisplayHandle, gc);
                }
 
-               internal override void DoEvents() {
+               internal override void DoEvents()
+               {
+                       DebugHelper.Enter ();
+
                        MSG     msg = new MSG ();
                        XEventQueue queue;
 
@@ -3067,16 +3758,32 @@ namespace System.Windows.Forms {
                        queue = ThreadQueue(Thread.CurrentThread);
 
                        queue.DispatchIdle = false;
+                       in_doevents = true;
 
                        while (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
+                               Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
+
+                               if (Application.FilterMessage (ref m))
+                                       continue;
+
                                TranslateMessage (ref msg);
                                DispatchMessage (ref msg);
+
+                               string key = msg.hwnd + ":" + msg.message;                              
+                               if (messageHold[key] != null) {
+                                       messageHold[key] = ((int)messageHold[key]) - 1;
+                                       DebugHelper.WriteLine  ("Got " + msg + " for " + key);
+                               }
                        }
 
+                       in_doevents = false;
                        queue.DispatchIdle = true;
+
+                       DebugHelper.Leave ();
                }
 
-               internal override void EnableWindow(IntPtr handle, bool Enable) {
+               internal override void EnableWindow(IntPtr handle, bool Enable)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -3085,12 +3792,13 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void EndLoop(Thread thread) {
+               internal override void EndLoop(Thread thread)
+               {
                        // This is where we one day will shut down the loop for the thread
                }
 
-
-               internal override IntPtr GetActive() {
+               internal override IntPtr GetActive()
+               {
                        IntPtr  actual_atom;
                        int     actual_format;
                        IntPtr  nitems;
@@ -3102,6 +3810,10 @@ namespace System.Windows.Forms {
                        if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
                                active = (IntPtr)Marshal.ReadInt32(prop);
                                XFree(prop);
+                       } else {
+                               // The window manager does not support _NET_ACTIVE_WINDOW.  Fall back to XGetInputFocus.
+                               IntPtr  revert_to = IntPtr.Zero;
+                               XGetInputFocus(DisplayHandle, out active, out revert_to);
                        }
 
                        if (active != IntPtr.Zero) {
@@ -3117,7 +3829,8 @@ namespace System.Windows.Forms {
                        return active;
                }
 
-               internal override Region GetClipRegion(IntPtr handle) {
+               internal override Region GetClipRegion(IntPtr handle)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -3128,14 +3841,16 @@ namespace System.Windows.Forms {
                        return null;
                }
 
-               internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
+               internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
+               {
                        width = 20;
                        height = 20;
                        hotspot_x = 0;
                        hotspot_y = 0;
                }
 
-               internal override void GetDisplaySize(out Size size) {
+               internal override void GetDisplaySize(out Size size)
+               {
                        XWindowAttributes       attributes=new XWindowAttributes();
 
                        lock (XlibLock) {
@@ -3146,7 +3861,8 @@ namespace System.Windows.Forms {
                        size = new Size(attributes.width, attributes.height);
                }
 
-               internal override SizeF GetAutoScaleSize(Font font) {
+               internal override SizeF GetAutoScaleSize(Font font)
+               {
                        Graphics        g;
                        float           width;
                        string          magic_string = "The quick brown fox jumped over the lazy dog.";
@@ -3158,7 +3874,8 @@ namespace System.Windows.Forms {
                        return new SizeF(width, font.Height);
                }
 
-               internal override IntPtr GetParent(IntPtr handle) {
+               internal override IntPtr GetParent(IntPtr handle)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -3167,8 +3884,15 @@ namespace System.Windows.Forms {
                        }
                        return IntPtr.Zero;
                }
+               
+               // This is a nop on win32 and x11
+               internal override IntPtr GetPreviousWindow(IntPtr handle)
+               {
+                       return handle;
+               }
 
-               internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
+               internal override void GetCursorPos(IntPtr handle, out int x, out int y)
+               {
                        IntPtr  use_handle;
                        IntPtr  root;
                        IntPtr  child;
@@ -3197,16 +3921,22 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override IntPtr GetFocus() {
+               internal override IntPtr GetFocus()
+               {
                        return FocusWindow;
                }
 
 
-               internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent) {
-                       return GetFontMetrics(g.GetHdc(), font.ToHfont(), out ascent, out descent);
+               internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent)
+               {
+                       FontFamily ff = font.FontFamily;
+                       ascent = ff.GetCellAscent (font.Style);
+                       descent = ff.GetCellDescent (font.Style);
+                       return true;
                }
 
-               internal override Point GetMenuOrigin(IntPtr handle) {
+               internal override Point GetMenuOrigin(IntPtr handle)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -3218,7 +3948,8 @@ namespace System.Windows.Forms {
                }
 
                [MonoTODO("Implement filtering")]
-               internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax) {
+               internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
+               {
                        XEvent  xevent;
                        bool    client;
                        Hwnd    hwnd;
@@ -3235,21 +3966,21 @@ namespace System.Windows.Forms {
                                } else if (((XEventQueue)queue_id).Paint.Count > 0) {
                                        xevent = ((XEventQueue)queue_id).Paint.Dequeue();
                                } else {
-                                       if (!ThreadQueue(Thread.CurrentThread).PostQuitState) {
-                                               msg.hwnd= IntPtr.Zero;
-                                               msg.message = Msg.WM_ENTERIDLE;
-                                               return true;
-                                       }
-
-                                       // We reset ourselves so GetMessage can be called again
-                                       ThreadQueue(Thread.CurrentThread).PostQuitState = false;
-
-                                       return false;
+                                       msg.hwnd= IntPtr.Zero;
+                                       msg.message = Msg.WM_ENTERIDLE;
+                                       return true;
                                }
                        }
 
                        hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
 
+#if DriverDebugDestroy                 
+                       if (hwnd != null)
+                               if (hwnd.zombie)
+                                       Console.WriteLine ( "GetMessage zombie, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
+                               else    
+                                       Console.WriteLine ( "GetMessage, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
+#endif
                        // Handle messages for windows that are already or are about to be destroyed.
 
                        // we need a special block for this because unless we remove the hwnd from the paint
@@ -3265,13 +3996,20 @@ namespace System.Windows.Forms {
                        // hwnds, since much of the event handling code makes requests using the hwnd's
                        // client_window, and that'll result in BadWindow errors if there's some lag
                        // between the XDestroyWindow call and the DestroyNotify event.
-                       if (hwnd == null || hwnd.zombie) {
-                               #if DriverDebug || DriverDebugDestroy
-                                       Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
-                               #endif
+                       if (hwnd == null || hwnd.zombie && xevent.AnyEvent.type != XEventName.ClientMessage) {
+                               DriverDebug("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
                                goto ProcessNextMessage;
                        }
 
+
+                       // If we get here, that means the window is no more but there are Client Messages
+                       // to be processed, probably a Posted message (for instance, an WM_ACTIVATE message) 
+                       // We don't want anything else to run but the ClientMessage block, so reset all hwnd
+                       // properties that might cause other processing to occur.
+                       if (hwnd.zombie) {
+                               hwnd.resizing_or_moving = false;
+                       }
+
                        if (hwnd.client_window == xevent.AnyEvent.window) {
                                client = true;
                                //Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
@@ -3282,15 +4020,52 @@ namespace System.Windows.Forms {
 
                        msg.hwnd = hwnd.Handle;
 
+                       // Windows sends WM_ENTERSIZEMOVE when a form resize/move operation starts and WM_EXITSIZEMOVE 
+                       // when it is done. The problem in X11 is that there is no concept of start-end of a moving/sizing.
+                       // Configure events ("this window has resized/moved") are sent for each step of the resize. We send a
+                       // WM_ENTERSIZEMOVE when we get the first Configure event. The problem is the WM_EXITSIZEMOVE.
+                       // 
+                       //  - There is no way for us to know which is the last Configure event. We can't traverse the events 
+                       //    queue, because the next configure event might not be pending yet.
+                       //  - We can't get ButtonPress/Release events for the window decorations, because they are not part 
+                       //    of the window(s) we manage.
+                       //  - We can't rely on the mouse state to change to "up" before the last Configure event. It doesn't.
+                       // 
+                       // We are almost 100% guaranteed to get another event (e.g Expose or other), but we can't know for sure 
+                       // which, so we have here to check if the mouse buttons state is "up" and send the WM_EXITSIZEMOVE
+                       //
+                       if (hwnd.resizing_or_moving) {
+                               int root_x, root_y, win_x, win_y, keys_buttons;
+                               IntPtr  root, child;
+                               XQueryPointer (DisplayHandle, hwnd.Handle, out root, out child, out root_x, out root_y, 
+                                              out win_x, out win_y, out keys_buttons);
+                               if ((keys_buttons & (int)MouseKeyMasks.Button1Mask) == 0 &&
+                                   (keys_buttons & (int)MouseKeyMasks.Button2Mask) == 0 &&
+                                   (keys_buttons & (int)MouseKeyMasks.Button3Mask) == 0) {
+                                       hwnd.resizing_or_moving = false;
+                                       SendMessage (hwnd.Handle, Msg.WM_EXITSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
+                               }
+                       }
+
                        //
                        // If you add a new event to this switch make sure to add it in
                        // UpdateMessage also unless it is not coming through the X event system.
                        //
                        switch(xevent.type) {
                                case XEventName.KeyPress: {
-                                       if (Dnd.InDrag ())
-                                               Dnd.HandleKeyPress (ref xevent);
                                        Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
+
+                                       // F1 key special case - WM_HELP sending
+                                       if (msg.wParam == (IntPtr)VirtualKeys.VK_F1 || msg.wParam == (IntPtr)VirtualKeys.VK_HELP) {
+                                               // Send wM_HELP and then return it as a keypress message in
+                                               // case it needs to be preproccessed.
+                                               HELPINFO helpInfo = new HELPINFO ();
+                                               GetCursorPos (IntPtr.Zero, out helpInfo.MousePos.x, out helpInfo.MousePos.y);
+                                               IntPtr helpInfoPtr = Marshal.AllocHGlobal (Marshal.SizeOf (helpInfo));
+                                               Marshal.StructureToPtr (helpInfo, helpInfoPtr, true);
+                                               NativeWindow.WndProc (FocusWindow, Msg.WM_HELP, IntPtr.Zero, helpInfoPtr);
+                                               Marshal.FreeHGlobal (helpInfoPtr);
+                                       }
                                        break;
                                }
 
@@ -3305,12 +4080,12 @@ namespace System.Windows.Forms {
                                                        MouseState |= MouseButtons.Left;
                                                        if (client) {
                                                                msg.message = Msg.WM_LBUTTONDOWN;
+                                                               msg.wParam = GetMousewParam (0);
                                                        } else {
                                                                msg.message = Msg.WM_NCLBUTTONDOWN;
+                                                               msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
-                                                       // TODO: For WM_NCLBUTTONDOWN wParam specifies a hit-test value not the virtual keys down
-                                                       msg.wParam=GetMousewParam(0);
                                                        break;
                                                }
 
@@ -3318,11 +4093,12 @@ namespace System.Windows.Forms {
                                                        MouseState |= MouseButtons.Middle;
                                                        if (client) {
                                                                msg.message = Msg.WM_MBUTTONDOWN;
+                                                               msg.wParam = GetMousewParam (0);
                                                        } else {
                                                                msg.message = Msg.WM_NCMBUTTONDOWN;
+                                                               msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
-                                                       msg.wParam=GetMousewParam(0);
                                                        break;
                                                }
 
@@ -3330,11 +4106,12 @@ namespace System.Windows.Forms {
                                                        MouseState |= MouseButtons.Right;
                                                        if (client) {
                                                                msg.message = Msg.WM_RBUTTONDOWN;
+                                                               msg.wParam = GetMousewParam (0);
                                                        } else {
                                                                msg.message = Msg.WM_NCRBUTTONDOWN;
+                                                               msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
-                                                       msg.wParam=GetMousewParam(0);
                                                        break;
                                                }
 
@@ -3398,30 +4175,25 @@ namespace System.Windows.Forms {
                                                ClickPending.Time = (long)xevent.ButtonEvent.time;
                                        }
                                        
-                                       if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN)
+                                       if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN) {
                                                SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
+                                       }
                                        
                                        break;
                                }
 
                                case XEventName.ButtonRelease: {
-                                       if (Dnd.InDrag()) {
-                                               if (Dnd.HandleButtonRelease (ref xevent)) {
-                                                       break;
-                                               }
-                                               // Allow the LBUTTONUP message to get through
-                                       }
-
                                        switch(xevent.ButtonEvent.button) {
                                                case 1: {
                                                        if (client) {
                                                                msg.message = Msg.WM_LBUTTONUP;
                                                        } else {
                                                                msg.message = Msg.WM_NCLBUTTONUP;
+                                                               msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
                                                        MouseState &= ~MouseButtons.Left;
-                                                       msg.wParam=GetMousewParam(0);
+                                                       msg.wParam = GetMousewParam (0);
                                                        break;
                                                }
 
@@ -3430,10 +4202,11 @@ namespace System.Windows.Forms {
                                                                msg.message = Msg.WM_MBUTTONUP;
                                                        } else {
                                                                msg.message = Msg.WM_NCMBUTTONUP;
+                                                               msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
                                                        MouseState &= ~MouseButtons.Middle;
-                                                       msg.wParam=GetMousewParam(0);
+                                                       msg.wParam = GetMousewParam (0);
                                                        break;
                                                }
 
@@ -3442,10 +4215,11 @@ namespace System.Windows.Forms {
                                                                msg.message = Msg.WM_RBUTTONUP;
                                                        } else {
                                                                msg.message = Msg.WM_NCRBUTTONUP;
+                                                               msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
                                                        MouseState &= ~MouseButtons.Right;
-                                                       msg.wParam=GetMousewParam(0);
+                                                       msg.wParam = GetMousewParam (0);
                                                        break;
                                                }
 
@@ -3473,21 +4247,46 @@ namespace System.Windows.Forms {
                                        msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
                                        mouse_position.X = xevent.ButtonEvent.x;
                                        mouse_position.Y = xevent.ButtonEvent.y;
+
+                                       // Win32 splurts MouseMove events all over the place, regardless of whether the mouse is actually moving or
+                                       // not, especially after mousedown and mouseup. To support apps relying on mousemove events between and after 
+                                       // mouse clicks to repaint or whatever, we generate a mousemove event here. *sigh*
+                                       if (msg.message == Msg.WM_LBUTTONUP || msg.message == Msg.WM_MBUTTONUP || msg.message == Msg.WM_RBUTTONUP) {
+                                               XEvent motionEvent = new XEvent ();
+                                               motionEvent.type = XEventName.MotionNotify;
+                                               motionEvent.MotionEvent.display = DisplayHandle;
+                                               motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
+                                               motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
+                                               motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
+                                               hwnd.Queue.EnqueueLocked (motionEvent);
+                                       }
                                        break;
                                }
 
                                case XEventName.MotionNotify: {
                                        if (client) {
-                                               #if DriverDebugExtra
-                                                       Console.WriteLine("GetMessage(): Window {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
-                                               #endif
+                                               DriverDebug("GetMessage(): Window {0:X} MotionNotify x={1} y={2}",
+                                                           client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
+                                                           xevent.MotionEvent.x, xevent.MotionEvent.y);
 
-                                               if (Dnd.HandleMotionNotify (ref xevent))
-                                                       goto ProcessNextMessage;
                                                if (Grab.Hwnd != IntPtr.Zero) {
                                                        msg.hwnd = Grab.Hwnd;
                                                } else {
-                                                       NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
+                                                       if (hwnd.Enabled) {
+                                                               NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
+                                                       }
+                                               }
+
+                                               if (xevent.MotionEvent.is_hint != 0)
+                                               {
+                                                       IntPtr root, child;
+                                                       int mask;
+                                                       XQueryPointer (DisplayHandle, xevent.AnyEvent.window,
+                                                                                       out root, out child,
+                                                                                       out xevent.MotionEvent.x_root, 
+                                                                                       out xevent.MotionEvent.y_root,
+                                                                                       out xevent.MotionEvent.x,      
+                                                                                       out xevent.MotionEvent.y, out mask);
                                                }
 
                                                msg.message = Msg.WM_MOUSEMOVE;
@@ -3520,12 +4319,10 @@ namespace System.Windows.Forms {
                                        } else {
                                                HitTest ht;
                                                IntPtr dummy;
-                                               int screen_x;
-                                               int screen_y;
 
-                                               #if DriverDebugExtra
-                                                       Console.WriteLine("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
-                                               #endif
+                                               DriverDebug("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}",
+                                                           client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
+                                                           xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                msg.message = Msg.WM_NCMOUSEMOVE;
 
                                                if (!hwnd.Enabled) {
@@ -3534,14 +4331,7 @@ namespace System.Windows.Forms {
                                                        msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
                                                }
 
-                                               // The hit test is sent in screen coordinates
-                                               XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, RootWindow,
-                                                               xevent.MotionEvent.x, xevent.MotionEvent.y,
-                                                               out screen_x, out screen_y, out dummy);
-
-                                               msg.lParam = (IntPtr) (screen_y << 16 | screen_x & 0xFFFF);
-                                               ht = (HitTest)NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST,
-                                                               IntPtr.Zero, msg.lParam).ToInt32 ();
+                                               ht = NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
                                                NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
 
                                                mouse_position.X = xevent.MotionEvent.x;
@@ -3555,14 +4345,58 @@ namespace System.Windows.Forms {
                                        if (!hwnd.Enabled) {
                                                goto ProcessNextMessage;
                                        }
-                                       if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
+                                       if (xevent.CrossingEvent.mode == NotifyMode.NotifyGrab || xevent.AnyEvent.window != hwnd.client_window) {
                                                goto ProcessNextMessage;
                                        }
+                                       if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) { // Pseudo motion caused by grabbing
+                                               if (LastPointerWindow == xevent.AnyEvent.window)
+                                                       goto ProcessNextMessage;
+
+                                               if (LastPointerWindow != IntPtr.Zero) {
+                                                       Point enter_loc = new Point (xevent.ButtonEvent.x, xevent.ButtonEvent.y);
+
+                                                       // We need this due to EnterNotify being fired on all the parent controls
+                                                       // of the Control being grabbed, and obviously in that scenario we are not
+                                                       // actuallty entering them
+                                                       Control ctrl = Control.FromHandle (hwnd.client_window);
+                                                       foreach (Control child_control in ctrl.Controls.GetAllControls ())
+                                                               if (child_control.Bounds.Contains (enter_loc))
+                                                                       goto ProcessNextMessage;
+
+                                                       // A MouseLeave/LeaveNotify event is sent to the previous window
+                                                       // until the mouse is ungrabbed, not when actually leaving its bounds
+                                                       int x = xevent.CrossingEvent.x_root;
+                                                       int y = xevent.CrossingEvent.y_root;
+                                                       ScreenToClient (LastPointerWindow, ref x, ref y);
+
+                                                       XEvent leaveEvent = new XEvent ();
+                                                       leaveEvent.type = XEventName.LeaveNotify;
+                                                       leaveEvent.CrossingEvent.display = DisplayHandle;
+                                                       leaveEvent.CrossingEvent.window = LastPointerWindow;
+                                                       leaveEvent.CrossingEvent.x = x;
+                                                       leaveEvent.CrossingEvent.y = y;
+                                                       leaveEvent.CrossingEvent.mode = NotifyMode.NotifyNormal;
+                                                       Hwnd last_pointer_hwnd = Hwnd.ObjectFromHandle (LastPointerWindow);
+                                                       last_pointer_hwnd.Queue.EnqueueLocked (leaveEvent);
+                                               }
+                                       }
+
+                                       LastPointerWindow = xevent.AnyEvent.window;
+
                                        msg.message = Msg.WM_MOUSE_ENTER;
                                        HoverState.X = xevent.CrossingEvent.x;
                                        HoverState.Y = xevent.CrossingEvent.y;
                                        HoverState.Timer.Enabled = true;
                                        HoverState.Window = xevent.CrossingEvent.window;
+
+                                       // Win32 sends a WM_MOUSEMOVE after mouse enter
+                                       XEvent motionEvent = new XEvent ();
+                                       motionEvent.type = XEventName.MotionNotify;
+                                       motionEvent.MotionEvent.display = DisplayHandle;
+                                       motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
+                                       motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
+                                       motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
+                                       hwnd.Queue.EnqueueLocked (motionEvent);
                                        break;
                                }
 
@@ -3577,7 +4411,18 @@ namespace System.Windows.Forms {
                                        if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
                                                goto ProcessNextMessage;
                                        }
-                                       msg.message=Msg.WM_MOUSE_LEAVE;
+                                       // If a grab is taking place, ignore it - we handle it in EnterNotify
+                                       if (Grab.Hwnd != IntPtr.Zero)
+                                               goto ProcessNextMessage;
+
+                                       // Reset the cursor explicitly on X11.
+                                       // X11 remembers the last set cursor for the window and in cases where 
+                                       // the control won't get a WM_SETCURSOR X11 will restore the last 
+                                       // known cursor, which we don't want.
+                                       // 
+                                       SetCursor (hwnd.client_window, IntPtr.Zero);
+
+                                       msg.message=Msg.WM_MOUSELEAVE;
                                        HoverState.Timer.Enabled = false;
                                        HoverState.Window = IntPtr.Zero;
                                        break;
@@ -3599,27 +4444,13 @@ namespace System.Windows.Forms {
                                case XEventName.ReparentNotify: {
                                        if (hwnd.parent == null) {      // Toplevel
                                                if ((xevent.ReparentEvent.parent != IntPtr.Zero) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
-                                                       // We need to adjust x/y
-                                                       // This sucks ass, part 2
-                                                       // Every WM does the reparenting of toplevel windows different, so there's
-                                                       // no standard way of getting our adjustment considering frames/decorations
-                                                       // The code below is needed for metacity. KDE doesn't works just fine without this
-                                                       int     dummy_int;
-                                                       IntPtr  dummy_ptr;
-                                                       int     new_x;
-                                                       int     new_y;
-                                                       int     frame_left;
-                                                       int     frame_top;
-
                                                        hwnd.Reparented = true;
 
-                                                       XGetGeometry(DisplayHandle, XGetParent(hwnd.whole_window), out dummy_ptr, out new_x, out new_y, out dummy_int, out dummy_int, out dummy_int, out dummy_int);
-                                                       FrameExtents(hwnd.whole_window, out frame_left, out frame_top);
-                                                       if ((frame_left != 0) && (frame_top != 0) && (new_x != frame_left) && (new_y != frame_top)) {
-                                                               hwnd.x = new_x;
-                                                               hwnd.y = new_y;
-                                                               hwnd.whacky_wm = true;
-                                                       }
+                                                       // The location given by the event is not reliable between different wm's, 
+                                                       // so use an alternative way of getting it.
+                                                       Point location = GetTopLevelWindowLocation (hwnd);
+                                                       hwnd.X = location.X;
+                                                       hwnd.Y = location.Y;
 
                                                        if (hwnd.opacity != 0xffffffff) {
                                                                IntPtr opacity;
@@ -3638,20 +4469,32 @@ namespace System.Windows.Forms {
                                }
 
                                case XEventName.ConfigureNotify: {
-                                       if (ThreadQueue(Thread.CurrentThread).PostQuitState|| !client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {      // Ignore events for children (SubstructureNotify) and client areas
-                                               #if DriverDebugExtra
-                                                       Console.WriteLine("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}", hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
-                                               #endif
-//                                             if ((hwnd.x != xevent.ConfigureEvent.x) || (hwnd.y != xevent.ConfigureEvent.y) || (hwnd.width != xevent.ConfigureEvent.width) || (hwnd.height != xevent.ConfigureEvent.height)) {
-                                                       lock (hwnd.configure_lock) {
-                                                               SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
-                                                               hwnd.configure_pending = false;
+                                       if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {        // Ignore events for children (SubstructureNotify) and client areas
+                                               DriverDebug("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}",
+                                                           hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x,
+                                                           xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
+
+                                               lock (hwnd.configure_lock) {
+                                                       Form form = Control.FromHandle (hwnd.client_window) as Form;
+                                                       if (form != null && !hwnd.resizing_or_moving) {
+                                                               if (hwnd.x != form.Bounds.X || hwnd.y != form.Bounds.Y) {
+                                                                       SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_MOVE, IntPtr.Zero);
+                                                                       hwnd.resizing_or_moving = true;
+                                                               } else if (hwnd.width != form.Bounds.Width || hwnd.height != form.Bounds.Height) {
+                                                                       SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_SIZE, IntPtr.Zero);
+                                                                       hwnd.resizing_or_moving = true;
+                                                               }
+                                                               if (hwnd.resizing_or_moving)
+                                                                       SendMessage (form.Handle, Msg.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
                                                        }
-
+       
+                                                       SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
+                                                       hwnd.configure_pending = false;
+       
                                                        // We need to adjust our client window to track the resize of whole_window
                                                        if (hwnd.whole_window != hwnd.client_window)
                                                                PerformNCCalc(hwnd);
-//                                             }
+                                               }
                                        }
                                        goto ProcessNextMessage;
                                }
@@ -3665,20 +4508,23 @@ namespace System.Windows.Forms {
                                                goto ProcessNextMessage;
                                        }
 
+                                       
                                        if (FocusWindow == IntPtr.Zero) {
                                                Control c = Control.FromHandle (hwnd.client_window);
+
                                                if (c == null)
-                                                       goto ProcessNextMessage;
+                                                       goto ProcessNextMessage;                                                
                                                Form form = c.FindForm ();
                                                if (form == null)
                                                        goto ProcessNextMessage;
+                                       
                                                if (ActiveWindow != form.Handle) {
                                                        ActiveWindow = form.Handle;
                                                        SendMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr) WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
                                                }
                                                goto ProcessNextMessage;
                                        }
-                                       Keyboard.FocusIn(FocusWindow);
+                                       Keyboard.FocusIn (FocusWindow);
                                        SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
                                        goto ProcessNextMessage;
                                }
@@ -3688,22 +4534,46 @@ namespace System.Windows.Forms {
                                        if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
                                                goto ProcessNextMessage;
                                        }
-                                       Keyboard.FocusOut(FocusWindow);
 
                                        while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
                                                SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
                                        }
 
+                                       Keyboard.FocusOut(hwnd.client_window);
                                        SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
                                        goto ProcessNextMessage;
                                }
 
-                               case XEventName.Expose: {
-                                       if (ThreadQueue(Thread.CurrentThread).PostQuitState || !hwnd.Mapped) {
-                                               if (client) {
-                                                       hwnd.expose_pending = false;
-                                               } else {
-                                                       hwnd.nc_expose_pending = false;
+                               // We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
+                               // in case we break a scenario not taken into account in the tests
+                               case XEventName.MapNotify: {
+                                       /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
+                                               hwnd.mapped = true;
+                                               msg.message = Msg.WM_SHOWWINDOW;
+                                               msg.wParam = (IntPtr) 1;
+                                               // XXX we're missing the lParam..
+                                               break;
+                                       }*/
+                                       goto ProcessNextMessage;
+                               }
+
+                               case XEventName.UnmapNotify: {
+                                       /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
+                                               hwnd.mapped = false;
+                                               msg.message = Msg.WM_SHOWWINDOW;
+                                               msg.wParam = (IntPtr) 0;
+                                               // XXX we're missing the lParam..
+                                               break;
+                                       }*/
+                                       goto ProcessNextMessage;
+                               }
+
+                               case XEventName.Expose: {
+                                       if (!hwnd.Mapped) {
+                                               if (client) {
+                                                       hwnd.expose_pending = false;
+                                               } else {
+                                                       hwnd.nc_expose_pending = false;
                                                }
                                                goto ProcessNextMessage;
                                        }
@@ -3739,9 +4609,9 @@ namespace System.Windows.Forms {
                                                                break;
                                                        }
                                                }
-                                               #if DriverDebugExtra
-                                                       Console.WriteLine("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
-                                               #endif
+                                               DriverDebug("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}",
+                                                           hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
+                                                           xevent.ExposeEvent.width, xevent.ExposeEvent.height);
 
                                                Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
                                                Region region = new Region (rect);
@@ -3751,9 +4621,9 @@ namespace System.Windows.Forms {
                                                msg.refobject = region;
                                                break;
                                        }
-                                       #if DriverDebugExtra
-                                               Console.WriteLine("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
-                                       #endif
+                                       DriverDebug("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}",
+                                                   hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
+                                                   xevent.ExposeEvent.width, xevent.ExposeEvent.height);
                                        if (Caret.Visible == true) {
                                                Caret.Paused = true;
                                                HideCaret();
@@ -3776,9 +4646,7 @@ namespace System.Windows.Forms {
                                        if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
                                                CleanupCachedWindows (hwnd);
 
-                                               #if DriverDebugDestroy
-                                                       Console.WriteLine("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
-                                               #endif
+                                               DriverDebug("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
 
                                                msg.hwnd = hwnd.client_window;
                                                msg.message=Msg.WM_DESTROY;
@@ -3807,12 +4675,18 @@ namespace System.Windows.Forms {
                                                return true;
                                        }
 
-                                       if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
+                                       if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {                                               
+                                               DebugHelper.Indent ();
+                                               DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
+                                               DebugHelper.Unindent ();
                                                msg.hwnd = xevent.ClientMessageEvent.ptr1;
                                                msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
                                                msg.wParam = xevent.ClientMessageEvent.ptr3;
                                                msg.lParam = xevent.ClientMessageEvent.ptr4;
-                                               return true;
+                                               if (msg.message == (Msg)Msg.WM_QUIT)
+                                                       return false;
+                                               else
+                                                       return true;
                                        }
 
                                        if  (xevent.ClientMessageEvent.message_type == _XEMBED) {
@@ -3835,6 +4709,7 @@ namespace System.Windows.Forms {
 
                                        if  (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
                                                if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
+                                                       SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
                                                        msg.message = Msg.WM_CLOSE;
                                                        return true;
                                                }
@@ -3855,7 +4730,34 @@ namespace System.Windows.Forms {
                        return true;
                }
 
-               internal override bool GetText(IntPtr handle, out string text) {
+               HitTest NCHitTest (Hwnd hwnd, int x, int y)
+               {
+                       // The hit test is sent in screen coordinates
+                       IntPtr dummy;
+                       int screen_x, screen_y;
+                       XTranslateCoordinates (DisplayHandle, hwnd.WholeWindow, RootWindow, x, y, out screen_x, out screen_y, out dummy);
+                       return (HitTest) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, 
+                                                              (IntPtr) (screen_y << 16 | screen_x & 0xFFFF));
+               }
+
+               // Our very basic implementation of MoveResize - we can extend it later
+               // *if* needed
+               internal override void BeginMoveResize (IntPtr handle)
+               {
+                       // We *need* to ungrab the pointer in the current display
+                       XplatUI.UngrabWindow (Grab.Hwnd);
+
+                       int x_root, y_root;
+                       GetCursorPos (IntPtr.Zero, out x_root, out y_root);
+
+                       Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
+                       SendNetWMMessage (hwnd.whole_window, _NET_WM_MOVERESIZE, (IntPtr) x_root, (IntPtr) y_root,
+                                       (IntPtr) NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, 
+                                       (IntPtr) 1); // left button
+               }
+
+               internal override bool GetText(IntPtr handle, out string text)
+               {
 
                        lock (XlibLock) {
                                IntPtr actual_atom;
@@ -3866,7 +4768,7 @@ namespace System.Windows.Forms {
 
                                XGetWindowProperty(DisplayHandle, handle,
                                                   _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
-                                                  UNICODETEXT, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+                                                  UTF8_STRING, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
 
                                if ((long)nitems > 0 && prop != IntPtr.Zero) {
                                        text = Marshal.PtrToStringUni (prop, (int)nitems);
@@ -3892,7 +4794,8 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
+               internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height)
+               {
                        Hwnd            hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -3922,7 +4825,19 @@ namespace System.Windows.Forms {
                        client_height = 0;
                }
 
-               internal override FormWindowState GetWindowState(IntPtr handle) {
+               internal override FormWindowState GetWindowState(IntPtr handle)
+               {
+                       Hwnd                    hwnd;
+
+                       hwnd = Hwnd.ObjectFromHandle(handle);
+
+                       if (hwnd.cached_window_state == (FormWindowState)(-1))
+                               hwnd.cached_window_state = UpdateWindowState (handle);
+
+                       return hwnd.cached_window_state;
+               }
+
+               FormWindowState UpdateWindowState (IntPtr handle) {
                        IntPtr                  actual_atom;
                        int                     actual_format;
                        IntPtr                  nitems;
@@ -3967,13 +4882,15 @@ namespace System.Windows.Forms {
                        return FormWindowState.Normal;
                }
 
-               internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea) {
+               internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
+               {
                        handle = Grab.Hwnd;
                        GrabConfined = Grab.Confined;
                        GrabArea = Grab.Area;
                }
 
-               internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
+               internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle)
+               {
                        Hwnd    hwnd;
                        IntPtr  confine_to_window;
 
@@ -4003,12 +4920,13 @@ namespace System.Windows.Forms {
                                XGrabPointer(DisplayHandle, hwnd.client_window, false, 
                                        EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
                                        EventMask.ButtonReleaseMask | EventMask.PointerMotionMask | 
-                                       EventMask.LeaveWindowMask,
+                                       EventMask.PointerMotionHintMask | EventMask.LeaveWindowMask,
                                        GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
                        }
                }
 
-               internal override void UngrabWindow(IntPtr hwnd) {
+               internal override void UngrabWindow(IntPtr hwnd)
+               {
                        lock (XlibLock) {
                                XUngrabPointer(DisplayHandle, IntPtr.Zero);
                                XFlush(DisplayHandle);
@@ -4016,7 +4934,7 @@ namespace System.Windows.Forms {
                        WindowUngrabbed (hwnd);                 
                }
                
-               private void WindowUngrabbed (IntPtr hwnd) {
+               void WindowUngrabbed (IntPtr hwnd) {
                        bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
                        
                        Grab.Hwnd = IntPtr.Zero;
@@ -4033,13 +4951,15 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void HandleException(Exception e) {
+               internal override void HandleException(Exception e)
+               {
                        StackTrace st = new StackTrace(e, true);
                        Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
                        Console.WriteLine("{0}{1}", e.Message, st.ToString());
                }
 
-               internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
+               internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4051,36 +4971,46 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void InvalidateNC (IntPtr handle) {
+               internal override void InvalidateNC (IntPtr handle)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
 
-                       AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
+                       AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
                }
 
-               internal override bool IsEnabled(IntPtr handle) {
+               internal override bool IsEnabled(IntPtr handle)
+               {
                        Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
                        return (hwnd != null && hwnd.Enabled);
                }
                
-               internal override bool IsVisible(IntPtr handle) {
+               internal override bool IsVisible(IntPtr handle)
+               {
                        Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
                        return (hwnd != null && hwnd.visible);
                }
 
-               internal override void KillTimer(Timer timer) {
+               internal override void KillTimer(Timer timer)
+               {
                        XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
 
                        if (queue == null) {
                                // This isn't really an error, MS doesn't start the timer if
-                               // it has no assosciated queue
+                               // it has no assosciated queue. In this case, remove the timer
+                               // from the list of unattached timers (if it was enabled).
+                               lock (unattached_timer_list) {
+                                       if (unattached_timer_list.Contains (timer))
+                                               unattached_timer_list.Remove (timer);
+                               }
                                return;
                        }
                        queue.timer_list.Remove (timer);
                }
 
-               internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
+               internal override void MenuToScreen(IntPtr handle, ref int x, ref int y)
+               {
                        int     dest_x_return;
                        int     dest_y_return;
                        IntPtr  child;
@@ -4102,6 +5032,7 @@ namespace System.Windows.Forms {
                                XChangeActivePointerGrab (DisplayHandle,
                                                EventMask.ButtonMotionMask |
                                                EventMask.PointerMotionMask |
+                                               EventMask.PointerMotionHintMask |
                                                EventMask.ButtonPressMask |
                                                EventMask.ButtonReleaseMask,
                                                cursor, IntPtr.Zero);
@@ -4111,12 +5042,24 @@ namespace System.Windows.Forms {
                        OverrideCursorHandle = cursor;
                }
 
-               internal override PaintEventArgs PaintEventStart(IntPtr handle, bool client) {
+               internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client)
+               {
                        PaintEventArgs  paint_event;
                        Hwnd            hwnd;
-
-                       hwnd = Hwnd.ObjectFromHandle(handle);
-
+                       Hwnd            paint_hwnd;
+                       
+                       // 
+                       // handle  (and paint_hwnd) refers to the window that is should be painted.
+                       // msg.HWnd (and hwnd) refers to the window that got the paint message.
+                       // 
+                       
+                       hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
+                       if (msg.HWnd == handle) {
+                               paint_hwnd = hwnd;
+                       } else {
+                               paint_hwnd = Hwnd.ObjectFromHandle (handle);
+                       }
+       
                        if (Caret.Visible == true) {
                                Caret.Paused = true;
                                HideCaret();
@@ -4125,13 +5068,17 @@ namespace System.Windows.Forms {
                        Graphics dc;
 
                        if (client) {
-                               dc = Graphics.FromHwnd (hwnd.client_window);
+                               dc = Graphics.FromHwnd (paint_hwnd.client_window);
 
                                Region clip_region = new Region ();
                                clip_region.MakeEmpty();
 
                                foreach (Rectangle r in hwnd.ClipRectangles) {
-                                       clip_region.Union (r);
+                                       /* Expand the region slightly.
+                                        * See bug 464464.
+                                        */
+                                       Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
+                                       clip_region.Union (r2);
                                }
 
                                if (hwnd.UserClip != null) {
@@ -4149,7 +5096,7 @@ namespace System.Windows.Forms {
 
                                return paint_event;
                        } else {
-                               dc = Graphics.FromHwnd (hwnd.whole_window);
+                               dc = Graphics.FromHwnd (paint_hwnd.whole_window);
 
                                if (!hwnd.nc_invalid.IsEmpty) {
                                        dc.SetClip (hwnd.nc_invalid);
@@ -4168,10 +5115,11 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void PaintEventEnd(IntPtr handle, bool client) {
+               internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client)
+               {
                        Hwnd    hwnd;
 
-                       hwnd = Hwnd.ObjectFromHandle(handle);
+                       hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
 
                        Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
                        dc.Flush();
@@ -4188,7 +5136,8 @@ namespace System.Windows.Forms {
                }
 
                [MonoTODO("Implement filtering and PM_NOREMOVE")]
-               internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
+               internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
+               {
                        XEventQueue queue = (XEventQueue) queue_id;
                        bool    pending;
 
@@ -4218,7 +5167,8 @@ namespace System.Windows.Forms {
                        return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
                }
 
-               internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam) {
+               internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
+               {
                        XEvent xevent = new XEvent ();
                        Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
 
@@ -4238,15 +5188,23 @@ namespace System.Windows.Forms {
                        xevent.ClientMessageEvent.ptr3 = wparam;
                        xevent.ClientMessageEvent.ptr4 = lparam;
 
-                       hwnd.Queue.EnqueueLocked (xevent);
+                       if (hwnd != null)
+                               hwnd.Queue.EnqueueLocked (xevent);
+                       else
+                               ThreadQueue(Thread.CurrentThread).EnqueueLocked (xevent);
 
                        return true;
                }
 
-               internal override void PostQuitMessage(int exitCode) {
-                       
+               internal override void PostQuitMessage(int exitCode)
+               {
+                       ApplicationContext ctx = Application.MWFThread.Current.Context;
+                       Form f = ctx != null ? ctx.MainForm : null;
+                       if (f != null)
+                               PostMessage (Application.MWFThread.Current.Context.MainForm.window.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
+                       else
+                               PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
                        XFlush(DisplayHandle);
-                       ThreadQueue(Thread.CurrentThread).PostQuitState = true;
                }
 
                internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
@@ -4254,7 +5212,8 @@ namespace System.Windows.Forms {
                        // TODO
                }
 
-               internal override void RequestNCRecalc(IntPtr handle) {
+               internal override void RequestNCRecalc(IntPtr handle)
+               {
                        Hwnd                            hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4268,7 +5227,8 @@ namespace System.Windows.Forms {
                        InvalidateNC(handle);
                }
 
-               internal override void ResetMouseHover(IntPtr handle) {
+               internal override void ResetMouseHover(IntPtr handle)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4283,7 +5243,8 @@ namespace System.Windows.Forms {
                }
 
 
-               internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
+               internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
+               {
                        int     dest_x_return;
                        int     dest_y_return;
                        IntPtr  child;
@@ -4299,7 +5260,8 @@ namespace System.Windows.Forms {
                        y = dest_y_return;
                }
 
-               internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
+               internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y)
+               {
                        int     dest_x_return;
                        int     dest_y_return;
                        IntPtr  child;
@@ -4311,11 +5273,44 @@ namespace System.Windows.Forms {
                                XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
                        }
 
+                       Form form = Control.FromHandle (handle) as Form;
+                       if (form != null && form.window_manager != null) {
+                               dest_y_return -= form.window_manager.TitleBarHeight;
+                       }
+
                        x = dest_x_return;
                        y = dest_y_return;
                }
 
-               internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children) {
+               bool GraphicsExposePredicate (IntPtr display, ref XEvent xevent, IntPtr arg)
+               {
+                       return (xevent.type == XEventName.GraphicsExpose || xevent.type == XEventName.NoExpose) &&
+                               arg == xevent.GraphicsExposeEvent.drawable;
+               }
+
+               delegate bool EventPredicate (IntPtr display, ref XEvent xevent, IntPtr arg);
+
+               void ProcessGraphicsExpose (Hwnd hwnd)
+               {
+                       XEvent xevent = new XEvent ();
+                       IntPtr handle = Hwnd.HandleFromObject (hwnd);
+                       EventPredicate predicate = GraphicsExposePredicate;
+
+                       for (;;) {
+                               XIfEvent (Display, ref xevent, predicate, handle);
+                               if (xevent.type != XEventName.GraphicsExpose)
+                                       break;
+
+                               AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.GraphicsExposeEvent.x, xevent.GraphicsExposeEvent.y,
+                                               xevent.GraphicsExposeEvent.width, xevent.GraphicsExposeEvent.height);
+
+                               if (xevent.GraphicsExposeEvent.count == 0)
+                                       break;
+                       }
+               }
+
+               internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
+               {
                        Hwnd            hwnd;
                        IntPtr          gc;
                        XGCValues       gc_values;
@@ -4353,52 +5348,28 @@ namespace System.Windows.Forms {
 
                        gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
 
-                       int src_x, src_y;
-                       int dest_x, dest_y;
-                       int width, height;
+                       Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
+                       visible_rect.Intersect (area);
 
-                       if (YAmount > 0) {
-                               src_y = area.Y;
-                               height = area.Height - YAmount;
-                               dest_y = area.Y + YAmount;
-                       }
-                       else {
-                               src_y = area.Y - YAmount;
-                               height = area.Height + YAmount;
-                               dest_y = area.Y;
-                       }
+                       Rectangle dest_rect = visible_rect;
+                       dest_rect.Y += YAmount;
+                       dest_rect.X += XAmount;
+                       dest_rect.Intersect (area);
 
-                       if (XAmount > 0) {
-                               src_x = area.X;
-                               width = area.Width - XAmount;
-                               dest_x = area.X + XAmount;
-                       }
-                       else {
-                               src_x = area.X - XAmount;
-                               width = area.Width + XAmount;
-                               dest_x = area.X;
-                       }
+                       Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
+                       XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y, 
+                                       dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
 
-                       XCopyArea(DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src_x, src_y, width, height, dest_x, dest_y);
+                       Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
+                       AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
 
-                       // Generate an expose for the area exposed by the horizontal scroll
-                       // We don't use AddExpose since we're 
-                       if (XAmount > 0) {
-                               AddExpose(hwnd, true, area.X, area.Y, XAmount, area.Height);
-                       } else if (XAmount < 0) {
-                               AddExpose(hwnd, true, XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
-                       }
+                       ProcessGraphicsExpose (hwnd);
 
-                       // Generate an expose for the area exposed by the vertical scroll
-                       if (YAmount > 0) {
-                               AddExpose(hwnd, true, area.X, area.Y, area.Width, YAmount);
-                       } else if (YAmount < 0) {
-                               AddExpose(hwnd, true, area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
-                       }
                        XFreeGC(DisplayHandle, gc);
                }
 
-               internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children) {
+               internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children)
+               {
                        Hwnd            hwnd;
                        Rectangle       rect;
 
@@ -4410,7 +5381,50 @@ namespace System.Windows.Forms {
                        ScrollWindow(handle, rect, XAmount, YAmount, with_children);
                }
 
-               internal override void SendAsyncMethod (AsyncMethodData method) {
+               Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
+               {
+                       Rectangle dirty_area = total_area;
+
+                       if (YAmount > 0)
+                               dirty_area.Height -= valid_area.Height;
+                       else if (YAmount < 0) {
+                               dirty_area.Height -= valid_area.Height;
+                               dirty_area.Y += valid_area.Height;
+                       }
+
+                       if (XAmount > 0)
+                               dirty_area.Width -= valid_area.Width;
+                       else if (XAmount < 0) {
+                               dirty_area.Width -= valid_area.Width;
+                               dirty_area.X += valid_area.Width;
+                       }
+
+                       return dirty_area;
+               }
+
+               Rectangle GetTotalVisibleArea (IntPtr handle)
+               {
+                       Control c = Control.FromHandle (handle);
+
+                       Rectangle visible_area = c.ClientRectangle;
+                       visible_area.Location = c.PointToScreen (Point.Empty);
+
+                       for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
+                               if (!parent.IsHandleCreated || !parent.Visible)
+                                       return visible_area; // Non visible, not need to finish computations
+
+                               Rectangle r = parent.ClientRectangle;
+                               r.Location = parent.PointToScreen (Point.Empty);
+
+                               visible_area.Intersect (r);
+                       }
+
+                       visible_area.Location = c.PointToClient (visible_area.Location);
+                       return visible_area;
+               }
+
+               internal override void SendAsyncMethod (AsyncMethodData method)
+               {
                        Hwnd    hwnd;
                        XEvent  xevent = new XEvent ();
 
@@ -4448,16 +5462,18 @@ namespace System.Windows.Forms {
                                data.Result = result;
                                
                                SendAsyncMethod (data);
-                               #if DriverDebug || DriverDebugThreads
-                               Console.WriteLine ("Sending {0} message across.", message);
-                               #endif
+                               DriverDebug("Sending {0} message across.", message);
 
                                return IntPtr.Zero;
                        }
+                       string key = hwnd + ":" + message;
+                       if (messageHold[key] != null)
+                               messageHold[key] = ((int)messageHold[key]) - 1;
                        return NativeWindow.WndProc(hwnd, message, wParam, lParam);
                }
 
-               internal override int SendInput(IntPtr handle, Queue keys) { 
+               internal override int SendInput(IntPtr handle, Queue keys)
+               { 
                        if (handle == IntPtr.Zero)
                                return 0;
 
@@ -4502,17 +5518,23 @@ namespace System.Windows.Forms {
                        return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
                }
 
-               internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style) {
+               internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style)
+               {
                        Form form = Control.FromHandle (handle) as Form;
-                       if (form != null && form.window_manager == null && (border_style == FormBorderStyle.FixedToolWindow ||
-                                       border_style == FormBorderStyle.SizableToolWindow)) {
-                               form.window_manager = new InternalWindowManager (form);
+                       if (form != null && form.window_manager == null) {
+                               CreateParams cp = form.GetCreateParams ();
+                               if (border_style == FormBorderStyle.FixedToolWindow ||
+                                    border_style == FormBorderStyle.SizableToolWindow || 
+                                    cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
+                                       form.window_manager = new ToolWindowManager (form);
+                               }
                        }
                        
                        RequestNCRecalc(handle);
                }
 
-               internal override void SetCaretPos(IntPtr handle, int x, int y) {
+               internal override void SetCaretPos(IntPtr handle, int x, int y)
+               {
                        if (Caret.Hwnd == handle) {
                                Caret.Timer.Stop();
                                HideCaret();
@@ -4520,6 +5542,8 @@ namespace System.Windows.Forms {
                                Caret.X = x;
                                Caret.Y = y;
 
+                               Keyboard.SetCaretPos (Caret, handle, x, y);
+
                                if (Caret.Visible == true) {
                                        ShowCaret();
                                        Caret.Timer.Start();
@@ -4527,7 +5551,8 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void SetClipRegion(IntPtr handle, Region region) {
+               internal override void SetClipRegion(IntPtr handle, Region region)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4536,10 +5561,10 @@ namespace System.Windows.Forms {
                        }
 
                        hwnd.UserClip = region;
-                       Invalidate(handle, new Rectangle(0, 0, hwnd.Width, hwnd.Height), false);
                }
 
-               internal override void SetCursor(IntPtr handle, IntPtr cursor) {
+               internal override void SetCursor(IntPtr handle, IntPtr cursor)
+               {
                        Hwnd    hwnd;
 
                        if (OverrideCursorHandle == IntPtr.Zero) {
@@ -4568,7 +5593,7 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
+               void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
                                           out int root_x, out int root_y, out int child_x, out int child_y,
                                           out int mask)
                {
@@ -4603,7 +5628,8 @@ namespace System.Windows.Forms {
                        child = child_last;
                }
 
-               internal override void SetCursorPos(IntPtr handle, int x, int y) {
+               internal override void SetCursorPos(IntPtr handle, int x, int y)
+               {
                        if (handle == IntPtr.Zero) {
                                lock (XlibLock) {
                                        IntPtr root, child;
@@ -4669,7 +5695,8 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void SetFocus(IntPtr handle) {
+               internal override void SetFocus(IntPtr handle)
+               {
                        Hwnd    hwnd;
                        IntPtr  prev_focus_window;
 
@@ -4679,18 +5706,24 @@ namespace System.Windows.Forms {
                                return;
                        }
 
+                       // Win32 doesn't do anything if disabled
+                       if (!hwnd.enabled)
+                               return;
+
                        prev_focus_window = FocusWindow;
                        FocusWindow = hwnd.client_window;
 
                        if (prev_focus_window != IntPtr.Zero) {
                                SendMessage(prev_focus_window, Msg.WM_KILLFOCUS, FocusWindow, IntPtr.Zero);
-                       }
+                       }                       
+                       Keyboard.FocusIn (FocusWindow);
                        SendMessage(FocusWindow, Msg.WM_SETFOCUS, prev_focus_window, IntPtr.Zero);
 
                        //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
                }
 
-               internal override void SetIcon(IntPtr handle, Icon icon) {
+               internal override void SetIcon(IntPtr handle, Icon icon)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4699,7 +5732,8 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void SetMenu(IntPtr handle, Menu menu) {
+               internal override void SetMenu(IntPtr handle, Menu menu)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4708,7 +5742,8 @@ namespace System.Windows.Forms {
                        RequestNCRecalc(handle);
                }
 
-               internal override void SetModal(IntPtr handle, bool Modal) {
+               internal override void SetModal(IntPtr handle, bool Modal)
+               {
                        if (Modal) {
                                ModalWindows.Push(handle);
                        } else {
@@ -4719,49 +5754,78 @@ namespace System.Windows.Forms {
                                        Activate((IntPtr)ModalWindows.Peek());
                                }
                        }
+
+                       Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
+                       Control ctrl = Control.FromHandle (handle);
+                       SetWMStyles (hwnd, ctrl.GetCreateParams ());
                }
 
-               internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
+               internal override IntPtr SetParent(IntPtr handle, IntPtr parent)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
                        hwnd.parent = Hwnd.ObjectFromHandle(parent);
 
                        lock (XlibLock) {
-                               #if DriverDebug || DriverDebugParent
-                                       Console.WriteLine("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
-                               #endif
+                               DriverDebug("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
                                XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent == null ? FosterParent : hwnd.parent.client_window, hwnd.x, hwnd.y);
                        }
 
                        return IntPtr.Zero;
                }
 
-               internal override void SetTimer (Timer timer) {
+               internal override void SetTimer (Timer timer)
+               {
                        XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
 
                        if (queue == null) {
                                // This isn't really an error, MS doesn't start the timer if
-                               // it has no assosciated queue
+                               // it has no assosciated queue at this stage (it will be
+                               // enabled when a window is activated).
+                               unattached_timer_list.Add (timer);
                                return;
                        }
                        queue.timer_list.Add (timer);
                        WakeupMain ();
                }
 
-               internal override bool SetTopmost(IntPtr handle, IntPtr handle_owner, bool enabled) {
-                       Hwnd    hwnd;
-                       Hwnd    hwnd_owner;
+               internal override bool SetTopmost(IntPtr handle, bool enabled)
+               {
 
-                       hwnd = Hwnd.ObjectFromHandle(handle);
+                       Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
+                       hwnd.topmost = enabled;
 
-                       if (handle_owner != IntPtr.Zero) {
-                               hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
+                       if (enabled) {
+                               lock (XlibLock) {
+                                       if (hwnd.Mapped) {
+                                               SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_ADD, _NET_WM_STATE_ABOVE, IntPtr.Zero);
+                                       } else {
+                                               int[] atoms = new int[8];
+                                               atoms[0] = _NET_WM_STATE_ABOVE.ToInt32();
+                                               XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
+                                       }
+                               }
                        } else {
-                               hwnd_owner = null;
+                               lock (XlibLock) {
+                                       if (hwnd.Mapped)
+                                               SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_REMOVE, _NET_WM_STATE_ABOVE, IntPtr.Zero);
+                                       else
+                                               XDeleteProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE);
+                               }
                        }
+                       return true;
+               }
 
-                       if (enabled) {
+               internal override bool SetOwner(IntPtr handle, IntPtr handle_owner)
+               {
+                       Hwnd hwnd;
+                       Hwnd hwnd_owner;
+
+                       hwnd = Hwnd.ObjectFromHandle(handle);
+
+                       if (handle_owner != IntPtr.Zero) {
+                               hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
                                lock (XlibLock) {
                                        int[]   atoms;
 
@@ -4784,7 +5848,8 @@ namespace System.Windows.Forms {
                        return true;
                }
 
-               internal override bool SetVisible(IntPtr handle, bool visible, bool activate) {
+               internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4792,30 +5857,36 @@ namespace System.Windows.Forms {
 
                        lock (XlibLock) {
                                if (visible) {
+                                       MapWindow(hwnd, WindowType.Both);
+
                                        if (Control.FromHandle(handle) is Form) {
                                                FormWindowState s;
 
                                                s = ((Form)Control.FromHandle(handle)).WindowState;
 
-                                               MapWindow(hwnd, WindowType.Both);
-
                                                switch(s) {
                                                        case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
                                                        case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
                                                }
-
-                                       } else {
-                                               MapWindow(hwnd, WindowType.Both);
                                        }
+
                                        SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
-                               } else {
-                                       UnmapWindow(hwnd, WindowType.Whole);
+                               }
+                               else {
+                                       UnmapWindow(hwnd, WindowType.Both);
                                }
                        }
                        return true;
                }
 
-               internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
+               internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max)
+               {
+                       Control ctrl = Control.FromHandle (handle);
+                       SetWindowMinMax (handle, maximized, min, max, ctrl != null ? ctrl.GetCreateParams () : null);
+               }
+
+               internal void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max, CreateParams cp)
+               {
                        Hwnd            hwnd;
                        XSizeHints      hints;
                        IntPtr          dummy;
@@ -4825,26 +5896,38 @@ namespace System.Windows.Forms {
                                return;
                        }
 
+                       min.Width = Math.Max (min.Width, SystemInformation.MinimumWindowSize.Width);
+                       min.Height = Math.Max (min.Height, SystemInformation.MinimumWindowSize.Height);
+                       
                        hints = new XSizeHints();
 
                        XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
                        if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
+                               if (cp != null)
+                                       min = TranslateWindowSizeToXWindowSize (cp, min);
                                hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
                                hints.min_width = min.Width;
                                hints.min_height = min.Height;
                        }
 
                        if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
+                               if (cp != null)
+                                       max = TranslateWindowSizeToXWindowSize (cp, max);
                                hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
                                hints.max_width = max.Width;
                                hints.max_height = max.Height;
                        }
 
                        if (hints.flags != IntPtr.Zero) {
+                               // The Metacity team has decided that they won't care about this when clicking the maximize icon, 
+                               // they will maximize the window to fill the screen/parent no matter what.
+                               // http://bugzilla.ximian.com/show_bug.cgi?id=80021
                                XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
                        }
 
                        if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
+                               if (cp != null)
+                                       maximized.Size = TranslateWindowSizeToXWindowSize (cp);
                                hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
                                hints.x = maximized.X;
                                hints.y = maximized.Y;
@@ -4857,7 +5940,8 @@ namespace System.Windows.Forms {
                }
 
 
-               internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
+               internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height)
+               {
                        Hwnd            hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4904,7 +5988,9 @@ namespace System.Windows.Forms {
                                }
 
                                lock (XlibLock) {
-                                       XMoveResizeWindow(DisplayHandle, hwnd.whole_window, x, y, width, height);
+                                       Control ctrl = Control.FromHandle (handle);
+                                       Size TranslatedSize = TranslateWindowSizeToXWindowSize (ctrl.GetCreateParams (), new Size (width, height));
+                                       MoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, TranslatedSize.Width, TranslatedSize.Height);
                                        PerformNCCalc(hwnd);
                                }
                        }
@@ -4920,7 +6006,8 @@ namespace System.Windows.Forms {
                        hwnd.ClientRect = Rectangle.Empty;
                }
 
-               internal override void SetWindowState(IntPtr handle, FormWindowState state) {
+               internal override void SetWindowState(IntPtr handle, FormWindowState state)
+               {
                        FormWindowState current_state;
                        Hwnd            hwnd;
 
@@ -4969,7 +6056,8 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
+               internal override void SetWindowStyle(IntPtr handle, CreateParams cp)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4982,7 +6070,8 @@ namespace System.Windows.Forms {
                        return 1.0;
                }
 
-               internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
+               internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key)
+               {
                        Hwnd    hwnd;
                        IntPtr  opacity;
 
@@ -5001,7 +6090,8 @@ namespace System.Windows.Forms {
                        XChangeProperty(DisplayHandle, w, _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
                }
 
-               internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom) {
+               internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom)
+               {
                        Hwnd    hwnd = Hwnd.ObjectFromHandle(handle);
 
                        if (!hwnd.mapped) {
@@ -5052,20 +6142,25 @@ namespace System.Windows.Forms {
                        return false;
                }
 
-               internal override void ShowCursor(bool show) {
+               internal override void ShowCursor(bool show)
+               {
                        ;       // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
                }
 
-               internal override object StartLoop(Thread thread) {
-                       return (Object) ThreadQueue(thread);
+               internal override object StartLoop(Thread thread)
+               {
+                       XEventQueue q = ThreadQueue(thread);
+                       return q;
                }
 
-               internal override TransparencySupport SupportsTransparency() {
+               internal override TransparencySupport SupportsTransparency()
+               {
                        // We need to check if the x compositing manager is running
                        return TransparencySupport.Set;
                }
 
-               internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {
+               internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt)
+               {
                        GetSystrayManagerWindow();
 
                        if (SystrayMgrWindow != IntPtr.Zero) {
@@ -5073,26 +6168,29 @@ namespace System.Windows.Forms {
                                Hwnd            hwnd;
 
                                hwnd = Hwnd.ObjectFromHandle(handle);
-                               #if DriverDebug
-                                       Console.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
-                               #endif
+                               DriverDebug("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
 
                                // Oh boy.
                                if (hwnd.client_window != hwnd.whole_window) {
+                                       Keyboard.DestroyICForWindow (hwnd.client_window);
                                        XDestroyWindow(DisplayHandle, hwnd.client_window);
                                        hwnd.client_window = hwnd.whole_window;
+                               }       
 
-                                       /* by virtue of the way the tests are ordered when determining if it's PAINT
-                                          or NCPAINT, client_window == whole_window will always be PAINT.  So, if we're
-                                          waiting on an nc_expose, drop it and remove the hwnd from the list (unless
-                                          there's a pending expose). */
-                                       if (hwnd.nc_expose_pending) {
-                                               hwnd.nc_expose_pending = false;
-                                               if (!hwnd.expose_pending)
-                                                       hwnd.Queue.Paint.Remove (hwnd);
-                                       }
+                               /* by virtue of the way the tests are ordered when determining if it's PAINT
+                                  or NCPAINT, client_window == whole_window will always be PAINT.  So, if we're
+                                  waiting on an nc_expose, drop it and remove the hwnd from the list (unless
+                                  there's a pending expose). */
+                               if (hwnd.nc_expose_pending) {
+                                       hwnd.nc_expose_pending = false;
+                                       if (!hwnd.expose_pending)
+                                               hwnd.Queue.Paint.Remove (hwnd);
                                }
 
+                               // We are going to be directly mapped by the system tray, so mark as mapped
+                               // so we can later properly unmap it.
+                               hwnd.mapped = true;
+
                                size_hints = new XSizeHints();
 
                                size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
@@ -5115,7 +6213,7 @@ namespace System.Windows.Forms {
 
                                // Need to pick some reasonable defaults
                                tt = new ToolTip();
-                               tt.AutomaticDelay = 100;
+                               tt.AutomaticDelay = 350;
                                tt.InitialDelay = 250;
                                tt.ReshowDelay = 250;
                                tt.ShowAlways = true;
@@ -5135,59 +6233,49 @@ namespace System.Windows.Forms {
                        return false;
                }
 
-               internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt) {
+               internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt)
+               {
                        Control control;
 
                        control = Control.FromHandle(handle);
                        if (control != null && tt != null) {
                                tt.SetToolTip(control, tip);
                                tt.Active = true;
+                               SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
                                return true;
                        } else {
                                return false;
                        }
                }
 
-               internal override void SystrayRemove(IntPtr handle, ref ToolTip tt) {
-
-#if GTKSOCKET_SUPPORTS_REPARENTING
-                       Hwnd    hwnd;
-
-                       hwnd = Hwnd.ObjectFromHandle(handle);
+               internal override void SystrayRemove(IntPtr handle, ref ToolTip tt)
+               {
 
-                       /* in the XEMBED spec, it mentions 3 ways for a client window to break the protocol with the embedder.
-                        * 1. The embedder can unmap the window and reparent to the root window (we should probably handle this...)
-                        * 2. The client can reparent its window out of the embedder window.
-                        * 3. The client can destroy its window.
-                        *
-                        * this call to SetParent is case 2, but in
-                        * the spec it also mentions that gtk doesn't
-                        * support this at present.  Looking at HEAD
-                        * gtksocket-x11.c jives with this statement.
-                        *
-                        * so we can't reparent.  we have to destroy.
-                        */
-                       SetParent(hwnd.whole_window, FosterParent);
-#else
-                       Control control = Control.FromHandle(handle);
-                       if (control is NotifyIcon.NotifyIconWindow)
-                               ((NotifyIcon.NotifyIconWindow)control).InternalRecreateHandle ();
-#endif
+                       SetVisible (handle, false, false);
 
                        // The caller can now re-dock it later...
                        if (tt != null) {
                                tt.Dispose();
                                tt = null;
                        }
+                       // Close any balloon window *we* fired.
+                       ThemeEngine.Current.HideBalloonWindow (handle);
+               }
+
+               internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
+               {
+                       ThemeEngine.Current.ShowBalloonWindow (handle, timeout, title, text, icon);
+                       SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);    
                }
 
-               internal override bool Text(IntPtr handle, string text) {
+               internal override bool Text(IntPtr handle, string text)
+{
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
 
                        lock (XlibLock) {
-                               XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UNICODETEXT, 8,
+                               XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UTF8_STRING, 8,
                                                PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
 
                                // XXX this has problems with UTF8.
@@ -5200,11 +6288,13 @@ namespace System.Windows.Forms {
                        return true;
                }
 
-               internal override bool TranslateMessage(ref MSG msg) {
+               internal override bool TranslateMessage(ref MSG msg)
+               {
                        return Keyboard.TranslateMessage (ref msg);
                }
 
-               internal override void UpdateWindow(IntPtr handle) {
+               internal override void UpdateWindow(IntPtr handle)
+               {
                        Hwnd    hwnd;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
@@ -5271,7 +6361,29 @@ namespace System.Windows.Forms {
                internal override event EventHandler Idle;
                #endregion      // Events
 
-               #region X11 Imports
+               
+#if TRACE
+               
+#region Xcursor imports
+               [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
+               internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
+
+               [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
+               internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
+               
+               [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
+               internal extern static void XcursorImagesDestroy (IntPtr images);
+               
+               [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
+               internal extern static int XcursorGetDefaultSize (IntPtr display);
+
+               [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
+               internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
+
+               [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
+               internal extern static IntPtr XcursorGetTheme (IntPtr display);
+#endregion
+#region X11 Imports
                [DllImport ("libX11", EntryPoint="XOpenDisplay")]
                internal extern static IntPtr XOpenDisplay(IntPtr display);
                [DllImport ("libX11", EntryPoint="XCloseDisplay")]
@@ -5280,40 +6392,930 @@ namespace System.Windows.Forms {
                internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
 
                [DllImport ("libX11", EntryPoint="XCreateWindow")]
-               internal extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
+               internal extern static IntPtr _XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
+               internal static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes)
+               {
+                       DebugHelper.TraceWriteLine ("XCreateWindow");
+                       return _XCreateWindow(display, parent, x, y, width, height, 
+                                      border_width, depth, xclass, visual, valuemask, ref attributes);
+               }
                [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
-               internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
+               internal extern static IntPtr _XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
+               internal static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background)
+               {
+                       DebugHelper.TraceWriteLine ("XCreateSimpleWindow");
+                       return _XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background);
+               }
                [DllImport ("libX11", EntryPoint="XMapWindow")]
-               internal extern static int XMapWindow(IntPtr display, IntPtr window);
+               internal extern static int _XMapWindow(IntPtr display, IntPtr window);
+               internal static int XMapWindow(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XMapWindow");
+                       return _XMapWindow(display, window);
+               }
+               [DllImport ("libX11", EntryPoint="XMapRaised")]
+               internal extern static int _XMapRaised(IntPtr display, IntPtr window);
+               internal static int XMapRaised(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XMapRaised");
+                       return _XMapRaised(display, window);
+               }
                [DllImport ("libX11", EntryPoint="XUnmapWindow")]
-               internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
+               internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
+               internal static int XUnmapWindow(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XUnmapWindow");
+                       return _XUnmapWindow(display, window);
+               }
                [DllImport ("libX11", EntryPoint="XMapSubwindows")]
-               internal extern static int XMapSubindows(IntPtr display, IntPtr window);
+               internal extern static int _XMapSubindows(IntPtr display, IntPtr window);
+               internal static int XMapSubindows(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XMapSubindows");
+                       return _XMapSubindows(display, window);
+               }
                [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
-               internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
+               internal extern static int _XUnmapSubwindows(IntPtr display, IntPtr window);
+               internal static int XUnmapSubwindows(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XUnmapSubwindows");
+                       return _XUnmapSubwindows(display, window);
+               }
                [DllImport ("libX11", EntryPoint="XRootWindow")]
-               internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
+               internal extern static IntPtr _XRootWindow(IntPtr display, int screen_number);
+               internal static IntPtr XRootWindow(IntPtr display, int screen_number)
+               {
+                       DebugHelper.TraceWriteLine ("XRootWindow");
+                       return _XRootWindow(display, screen_number);
+               }
                [DllImport ("libX11", EntryPoint="XNextEvent")]
-               internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
-               [DllImport ("libX11")]
-               internal extern static int XConnectionNumber (IntPtr diplay);
-               [DllImport ("libX11")]
-               internal extern static int XPending (IntPtr diplay);
+               internal extern static IntPtr _XNextEvent(IntPtr display, ref XEvent xevent);
+               internal static IntPtr XNextEvent(IntPtr display, ref XEvent xevent)
+               {
+                       DebugHelper.TraceWriteLine ("XNextEvent");
+                       return _XNextEvent(display, ref xevent);
+               }
+               [DllImport ("libX11", EntryPoint="XConnectionNumber")]
+               internal extern static int _XConnectionNumber (IntPtr display);
+               internal static int XConnectionNumber (IntPtr display)
+               {
+                       DebugHelper.TraceWriteLine ("XConnectionNumber");
+                       return _XConnectionNumber (display);
+               }
+               [DllImport ("libX11", EntryPoint="XPending")]
+               internal extern static int _XPending (IntPtr display);
+               internal static int XPending (IntPtr display)
+               {
+                       DebugHelper.TraceWriteLine ("XPending");
+                       DebugHelper.DumpCallers (3);
+                       return _XPending (display);
+               }
                [DllImport ("libX11", EntryPoint="XSelectInput")]
-               internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
+               internal extern static IntPtr _XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
+               internal static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask)
+               {
+                       DebugHelper.TraceWriteLine ("XSelectInput");
+                       return _XSelectInput(display, window, mask);
+               }
 
                [DllImport ("libX11", EntryPoint="XDestroyWindow")]
-               internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
+               internal extern static int _XDestroyWindow(IntPtr display, IntPtr window);
+               internal static int XDestroyWindow(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XDestroyWindow 0x{0:x}", window.ToInt32());
+                       return _XDestroyWindow(display, window);
+               }
 
                [DllImport ("libX11", EntryPoint="XReparentWindow")]
-               internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
+               internal extern static int _XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
+               internal static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y)
+               {
+                       DebugHelper.TraceWriteLine ("XReparentWindow");
+                       return _XReparentWindow(display, window, parent, x, y);
+               }
+               
                [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
-               internal extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
+               extern static int _XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
+               static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height) {
+                       DebugHelper.TraceWriteLine ("XMoveResizeWindow");
+                       return _XMoveResizeWindow(display, window, x, y, width, height);
+               }
 
-               [DllImport ("libX11", EntryPoint="XResizeWindow")]
-               internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
+               internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
+               {
+                       int ret = XMoveResizeWindow (display, window, x, y, width, height);
+                       Keyboard.MoveCurrentCaretPos ();
+                       return ret;
+               }
 
-               [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
+               [DllImport ("libX11", EntryPoint="XResizeWindow")]
+               internal extern static int _XResizeWindow(IntPtr display, IntPtr window, int width, int height);
+               internal static int XResizeWindow(IntPtr display, IntPtr window, int width, int height)
+               {
+                       DebugHelper.TraceWriteLine ("XResizeWindow");
+                       return _XResizeWindow(display, window, width, height);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
+               internal extern static int _XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
+               internal static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes)
+               {
+                       DebugHelper.TraceWriteLine ("XGetWindowAttributes");
+                       return _XGetWindowAttributes(display, window, ref attributes);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFlush")]
+               internal extern static int _XFlush(IntPtr display);
+               internal static int XFlush(IntPtr display)
+               {
+                       DebugHelper.TraceWriteLine ("XFlush");
+                       return _XFlush(display);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetWMName")]
+               internal extern static int _XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
+               internal static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop)
+               {
+                       DebugHelper.TraceWriteLine ("XSetWMName");
+                       return _XSetWMName(display, window, ref text_prop);
+               }
+
+               [DllImport ("libX11", EntryPoint="XStoreName")]
+               internal extern static int _XStoreName(IntPtr display, IntPtr window, string window_name);
+               internal static int XStoreName(IntPtr display, IntPtr window, string window_name)
+               {
+                       DebugHelper.TraceWriteLine ("XStoreName");
+                       return _XStoreName(display, window, window_name);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFetchName")]
+               internal extern static int _XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
+               internal static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name)
+               {
+                       DebugHelper.TraceWriteLine ("XFetchName");
+                       return _XFetchName(display, window, ref window_name);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSendEvent")]
+               internal extern static int _XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
+               internal static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event)
+               {
+                       DebugHelper.TraceWriteLine ("XSendEvent");
+                       return _XSendEvent(display, window, propagate, event_mask, ref send_event);
+               }
+
+               [DllImport ("libX11", EntryPoint="XQueryTree")]
+               internal extern static int _XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return);
+               internal static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return)
+               {
+                       DebugHelper.TraceWriteLine ("XQueryTree");
+                       return _XQueryTree(display, window, out root_return, out parent_return, out children_return, out nchildren_return);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFree")]
+               internal extern static int _XFree(IntPtr data);
+               internal static int XFree(IntPtr data)
+               {
+                       DebugHelper.TraceWriteLine ("XFree");
+                       return _XFree(data);
+               }
+
+               [DllImport ("libX11", EntryPoint="XRaiseWindow")]
+               internal extern static int _XRaiseWindow(IntPtr display, IntPtr window);
+               internal static int XRaiseWindow(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XRaiseWindow");
+                       return _XRaiseWindow(display, window);
+               }
+
+               [DllImport ("libX11", EntryPoint="XLowerWindow")]
+               internal extern static uint _XLowerWindow(IntPtr display, IntPtr window);
+               internal static uint XLowerWindow(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XLowerWindow");
+                       return _XLowerWindow(display, window);
+               }
+
+               [DllImport ("libX11", EntryPoint="XConfigureWindow")]
+               internal extern static uint _XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
+               internal static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values)
+               {
+                       DebugHelper.TraceWriteLine ("XConfigureWindow");
+                       return _XConfigureWindow(display, window, value_mask, ref values);
+               }
+
+               [DllImport ("libX11", EntryPoint="XInternAtom")]
+               internal extern static IntPtr _XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
+               internal static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists)
+               {
+                       DebugHelper.TraceWriteLine ("XInternAtom");
+                       return _XInternAtom(display, atom_name, only_if_exists);
+               }
+
+               [DllImport ("libX11", EntryPoint="XInternAtoms")]
+               internal extern static int _XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
+               internal static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms)
+               {
+                       DebugHelper.TraceWriteLine ("XInternAtoms");
+                       return _XInternAtoms(display, atom_names, atom_count, only_if_exists, atoms);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
+               internal extern static int _XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
+               internal static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count)
+               {
+                       DebugHelper.TraceWriteLine ("XSetWMProtocols");
+                       return _XSetWMProtocols(display, window, protocols, count);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGrabPointer")]
+               internal extern static int _XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
+               internal static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp)
+               {
+                       DebugHelper.TraceWriteLine ("XGrabPointer");
+                       return _XGrabPointer(display, window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, timestamp);
+               }
+
+               [DllImport ("libX11", EntryPoint="XUngrabPointer")]
+               internal extern static int _XUngrabPointer(IntPtr display, IntPtr timestamp);
+               internal static int XUngrabPointer(IntPtr display, IntPtr timestamp)
+               {
+                       DebugHelper.TraceWriteLine ("XUngrabPointer");
+                       return _XUngrabPointer(display, timestamp);
+               }
+
+               [DllImport ("libX11", EntryPoint="XQueryPointer")]
+               internal extern static bool _XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons);
+               internal static bool XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons)
+               {
+                       DebugHelper.TraceWriteLine ("XQueryPointer");
+                       return _XQueryPointer(display, window, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
+               }
+
+               [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
+               internal extern static bool _XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return, out int dest_y_return, out IntPtr child_return);
+               internal static bool XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return,         out int dest_y_return, out IntPtr child_return)
+               {
+                       DebugHelper.TraceWriteLine ("XTranslateCoordinates");
+                       return _XTranslateCoordinates (display, src_w, dest_w, src_x, src_y, out intdest_x_return, out dest_y_return, out child_return);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetGeometry")]
+               internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
+               internal static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth)
+               {
+                       DebugHelper.TraceWriteLine ("XGetGeometry");
+                       return _XGetGeometry(display, window, out root, out x, out y, out width, out height, out border_width, out depth);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetGeometry")]
+               internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth);
+               internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth)
+               {
+                       DebugHelper.TraceWriteLine ("XGetGeometry");
+                       return _XGetGeometry(display, window, root, out x, out y, out width, out height, border_width, depth);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetGeometry")]
+               internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
+               internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth)
+               {
+                       DebugHelper.TraceWriteLine ("XGetGeometry");
+                       return _XGetGeometry(display, window, root, out x, out y, width, height, border_width, depth);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetGeometry")]
+               internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth);
+               internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth)
+               {
+                       DebugHelper.TraceWriteLine ("XGetGeometry");
+                       return _XGetGeometry(display, window, root, x, y, out width, out height, border_width, depth);
+               }
+
+               [DllImport ("libX11", EntryPoint="XWarpPointer")]
+               internal extern static uint _XWarpPointer(IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y);
+               internal static uint XWarpPointer(IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y)
+               {
+                       DebugHelper.TraceWriteLine ("XWarpPointer");
+                       return _XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y);
+               }
+
+               [DllImport ("libX11", EntryPoint="XClearWindow")]
+               internal extern static int _XClearWindow(IntPtr display, IntPtr window);
+               internal static int XClearWindow(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XClearWindow");
+                       return _XClearWindow(display, window);
+               }
+
+               [DllImport ("libX11", EntryPoint="XClearArea")]
+               internal extern static int _XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
+               internal static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures)
+               {
+                       DebugHelper.TraceWriteLine ("XClearArea");
+                       return _XClearArea(display, window, x, y, width, height, exposures);
+               }
+
+               // Colormaps
+               [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
+               internal extern static IntPtr _XDefaultScreenOfDisplay(IntPtr display);
+               internal static IntPtr XDefaultScreenOfDisplay(IntPtr display)
+               {
+                       DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
+                       return _XDefaultScreenOfDisplay(display);
+               }
+
+               [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
+               internal extern static int _XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
+               internal static int XDefaultScreenOfDisplay(IntPtr display, IntPtr Screen)
+               {
+                       DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
+                       return _XScreenNumberOfScreen(display, Screen);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDefaultVisual")]
+               internal extern static IntPtr _XDefaultVisual(IntPtr display, int screen_number);
+               internal static IntPtr XDefaultScreenOfDisplay(IntPtr display, int screen_number)
+               {
+                       DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
+                       return _XDefaultVisual(display, screen_number);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDefaultDepth")]
+               internal extern static uint _XDefaultDepth(IntPtr display, int screen_number);
+               internal static uint XDefaultDepth(IntPtr display, int screen_number)
+               {
+                       DebugHelper.TraceWriteLine ("XDefaultDepth");
+                       return _XDefaultDepth(display, screen_number);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDefaultScreen")]
+               internal extern static int _XDefaultScreen(IntPtr display);
+               internal static int XDefaultScreen(IntPtr display)
+               {
+                       DebugHelper.TraceWriteLine ("XDefaultScreen");
+                       return _XDefaultScreen(display);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDefaultColormap")]
+               internal extern static IntPtr _XDefaultColormap(IntPtr display, int screen_number);
+               internal static IntPtr XDefaultColormap(IntPtr display, int screen_number)
+               {
+                       DebugHelper.TraceWriteLine ("XDefaultColormap");
+                       return _XDefaultColormap(display, screen_number);
+               }
+
+               [DllImport ("libX11", EntryPoint="XLookupColor")]
+               internal extern static int _XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
+               internal static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color)
+               {
+                       DebugHelper.TraceWriteLine ("XLookupColor");
+                       return _XLookupColor(display, Colormap, Coloranem, ref exact_def_color, ref screen_def_color);
+               }
+
+               [DllImport ("libX11", EntryPoint="XAllocColor")]
+               internal extern static int _XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
+               internal static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def)
+               {
+                       DebugHelper.TraceWriteLine ("XAllocColor");
+                       return _XAllocColor(display, Colormap, ref colorcell_def);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
+               internal extern static int _XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
+               internal static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window)
+               {
+                       DebugHelper.TraceWriteLine ("XSetTransientForHint");
+                       return _XSetTransientForHint(display, window, prop_window);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty")]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty")]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty")]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty")]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty")]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty")]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty")]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, atoms, nelements);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
+               internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
+               internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeProperty");
+                       return _XChangeProperty(display, window, property, type, format, mode, text, text_length);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDeleteProperty")]
+               internal extern static int _XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
+               internal static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property)
+               {
+                       DebugHelper.TraceWriteLine ("XDeleteProperty");
+                       return _XDeleteProperty(display, window, property);
+               }
+
+               // Drawing
+               [DllImport ("libX11", EntryPoint="XCreateGC")]
+               internal extern static IntPtr _XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
+               internal static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values)
+               {
+                       DebugHelper.TraceWriteLine ("XCreateGC");
+                       return _XCreateGC(display, window, valuemask, ref values);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFreeGC")]
+               internal extern static int _XFreeGC(IntPtr display, IntPtr gc);
+               internal static int XFreeGC(IntPtr display, IntPtr gc)
+               {
+                       DebugHelper.TraceWriteLine ("XFreeGC");
+                       return _XFreeGC(display, gc);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetFunction")]
+               internal extern static int _XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
+               internal static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function)
+               {
+                       DebugHelper.TraceWriteLine ("XSetFunction");
+                       return _XSetFunction(display, gc, function);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
+               internal extern static int _XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
+               internal static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style)
+               {
+                       DebugHelper.TraceWriteLine ("XSetLineAttributes");
+                       return _XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDrawLine")]
+               internal extern static int _XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
+               internal static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2)
+               {
+                       DebugHelper.TraceWriteLine ("XDrawLine");
+                       return _XDrawLine(display, drawable, gc, x1, y1, x2, y2);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDrawRectangle")]
+               internal extern static int _XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
+               internal static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
+               {
+                       DebugHelper.TraceWriteLine ("XDrawRectangle");
+                       return _XDrawRectangle(display, drawable, gc, x1, y1, width, height);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFillRectangle")]
+               internal extern static int _XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
+               internal static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
+               {
+                       DebugHelper.TraceWriteLine ("XFillRectangle");
+                       return _XFillRectangle(display, drawable, gc, x1, y1, width, height);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
+               internal extern static int _XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
+               internal static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background)
+               {
+                       DebugHelper.TraceWriteLine ("XSetWindowBackground");
+                       return _XSetWindowBackground(display, window, background);
+               }
+
+               [DllImport ("libX11", EntryPoint="XCopyArea")]
+               internal extern static int _XCopyArea(IntPtr display, IntPtr src, IntPtr dest, IntPtr gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y);
+               internal static int XCopyArea(IntPtr display, IntPtr src, IntPtr dest, IntPtr gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y)
+               {
+                       DebugHelper.TraceWriteLine ("XCopyArea");
+                       return _XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
+               internal extern static int _XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
+               internal static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop)
+               {
+                       DebugHelper.TraceWriteLine ("XGetWindowProperty");
+                       return _XGetWindowProperty(display, window, atom, long_offset, long_length, delete, req_type, out actual_type, out actual_format, out nitems, out bytes_after, ref prop);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetInputFocus")]
+               internal extern static int _XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
+               internal static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time)
+               {
+                       DebugHelper.TraceWriteLine ("XSetInputFocus");
+                       return _XSetInputFocus(display, window, revert_to, time);
+               }
+
+               [DllImport ("libX11", EntryPoint="XIconifyWindow")]
+               internal extern static int _XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
+               internal static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number)
+               {
+                       DebugHelper.TraceWriteLine ("XIconifyWindow");
+                       return _XIconifyWindow(display, window, screen_number);
+               }
+
+               [DllImport ("libX11", EntryPoint="XDefineCursor")]
+               internal extern static int _XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
+               internal static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor)
+               {
+                       DebugHelper.TraceWriteLine ("XDefineCursor");
+                       return _XDefineCursor(display, window, cursor);
+               }
+
+               [DllImport ("libX11", EntryPoint="XUndefineCursor")]
+               internal extern static int _XUndefineCursor(IntPtr display, IntPtr window);
+               internal static int XUndefineCursor(IntPtr display, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XUndefineCursor");
+                       return _XUndefineCursor(display, window);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFreeCursor")]
+               internal extern static int _XFreeCursor(IntPtr display, IntPtr cursor);
+               internal static int XFreeCursor(IntPtr display, IntPtr cursor)
+               {
+                       DebugHelper.TraceWriteLine ("XFreeCursor");
+                       return _XFreeCursor(display, cursor);
+               }
+
+               [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
+               internal extern static IntPtr _XCreateFontCursor(IntPtr display, CursorFontShape shape);
+               internal static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape)
+               {
+                       DebugHelper.TraceWriteLine ("XCreateFontCursor");
+                       return _XCreateFontCursor(display, shape);
+               }
+
+               [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
+               internal extern static IntPtr _XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot);
+               internal static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot)
+               {
+                       DebugHelper.TraceWriteLine ("XCreatePixmapCursor");
+                       return _XCreatePixmapCursor(display, source, mask, ref foreground_color, ref background_color, x_hot, y_hot);
+               }
+
+               [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
+               internal extern static IntPtr _XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
+               internal static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth)
+               {
+                       DebugHelper.TraceWriteLine ("XCreatePixmapFromBitmapData");
+                       return _XCreatePixmapFromBitmapData(display, drawable, data, width, height, fg, bg, depth);
+               }
+
+               [DllImport ("libX11", EntryPoint="XCreatePixmap")]
+               internal extern static IntPtr _XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
+               internal static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth)
+               {
+                       DebugHelper.TraceWriteLine ("XCreatePixmap");
+                       return _XCreatePixmap(display, d, width, height, depth);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFreePixmap")]
+               internal extern static IntPtr _XFreePixmap(IntPtr display, IntPtr pixmap);
+               internal static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap)
+               {
+                       DebugHelper.TraceWriteLine ("XFreePixmap");
+                       return _XFreePixmap(display, pixmap);
+               }
+
+               [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
+               internal extern static int _XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
+               internal static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height)
+               {
+                       DebugHelper.TraceWriteLine ("XQueryBestCursor");
+                       return _XQueryBestCursor(display, drawable, width, height, out best_width, out best_height);
+               }
+
+               [DllImport ("libX11", EntryPoint="XQueryExtension")]
+               internal extern static int _XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
+               internal static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error)
+               {
+                       DebugHelper.TraceWriteLine ("XQueryExtension");
+                       return _XQueryExtension(display, extension_name, ref major, ref first_event, ref first_error);
+               }
+
+               [DllImport ("libX11", EntryPoint="XWhitePixel")]
+               internal extern static IntPtr _XWhitePixel(IntPtr display, int screen_no);
+               internal static IntPtr XWhitePixel(IntPtr display, int screen_no)
+               {
+                       DebugHelper.TraceWriteLine ("XWhitePixel");
+                       return _XWhitePixel(display, screen_no);
+               }
+
+               [DllImport ("libX11", EntryPoint="XBlackPixel")]
+               internal extern static IntPtr _XBlackPixel(IntPtr display, int screen_no);
+               internal static IntPtr XBlackPixel(IntPtr display, int screen_no)
+               {
+                       DebugHelper.TraceWriteLine ("XBlackPixel");
+                       return _XBlackPixel(display, screen_no);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGrabServer")]
+               internal extern static void _XGrabServer(IntPtr display);
+               internal static void XGrabServer(IntPtr display)
+               {
+                       DebugHelper.TraceWriteLine ("XGrabServer");
+                       _XGrabServer(display);
+               }
+
+               [DllImport ("libX11", EntryPoint="XUngrabServer")]
+               internal extern static void _XUngrabServer(IntPtr display);
+               internal static void XUngrabServer(IntPtr display)
+               {
+                       DebugHelper.TraceWriteLine ("XUngrabServer");
+                       _XUngrabServer(display);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
+               internal extern static void _XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
+               internal static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return)
+               {
+                       DebugHelper.TraceWriteLine ("XGetWMNormalHints");
+                       _XGetWMNormalHints(display, window, ref hints, out supplied_return);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
+               internal extern static void _XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
+               internal static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints)
+               {
+                       DebugHelper.TraceWriteLine ("XSetWMNormalHints");
+                       _XSetWMNormalHints(display, window, ref hints);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetZoomHints")]
+               internal extern static void _XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
+               internal static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints)
+               {
+                       DebugHelper.TraceWriteLine ("XSetZoomHints");
+                       _XSetZoomHints(display, window, ref hints);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetWMHints")]
+               internal extern static void _XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
+               internal static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints)
+               {
+                       DebugHelper.TraceWriteLine ("XSetWMHints");
+                       _XSetWMHints(display, window, ref wmhints);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetIconSizes")]
+               internal extern static int _XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
+               internal static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count)
+               {
+                       DebugHelper.TraceWriteLine ("XGetIconSizes");
+                       return _XGetIconSizes(display, window, out size_list, out count);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
+               internal extern static IntPtr _XSetErrorHandler(XErrorHandler error_handler);
+               internal static IntPtr XSetErrorHandler(XErrorHandler error_handler)
+               {
+                       DebugHelper.TraceWriteLine ("XSetErrorHandler");
+                       return _XSetErrorHandler(error_handler);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetErrorText")]
+               internal extern static IntPtr _XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
+               internal static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length)
+               {
+                       DebugHelper.TraceWriteLine ("XGetErrorText");
+                       return _XGetErrorText(display, code, buffer, length);
+               }
+
+               [DllImport ("libX11", EntryPoint="XInitThreads")]
+               internal extern static int _XInitThreads();
+               internal static int XInitThreads()
+               {
+                       DebugHelper.TraceWriteLine ("XInitThreads");
+                       return _XInitThreads();
+               }
+
+               [DllImport ("libX11", EntryPoint="XConvertSelection")]
+               internal extern static int _XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
+               internal static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time)
+               {
+                       DebugHelper.TraceWriteLine ("XConvertSelection");
+                       return _XConvertSelection(display, selection, target, property, requestor, time);
+               }
+
+               [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
+               internal extern static IntPtr _XGetSelectionOwner(IntPtr display, IntPtr selection);
+               internal static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection)
+               {
+                       DebugHelper.TraceWriteLine ("XGetSelectionOwner");
+                       return _XGetSelectionOwner(display, selection);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
+               internal extern static int _XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
+               internal static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time)
+               {
+                       DebugHelper.TraceWriteLine ("XSetSelectionOwner");
+                       return _XSetSelectionOwner(display, selection, owner, time);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
+               internal extern static int _XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
+               internal static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask)
+               {
+                       DebugHelper.TraceWriteLine ("XSetPlaneMask");
+                       return _XSetPlaneMask(display, gc, mask);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetForeground")]
+               internal extern static int _XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
+               internal static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground)
+               {
+                       DebugHelper.TraceWriteLine ("XSetForeground");
+                       return _XSetForeground(display, gc, foreground);
+               }
+
+               [DllImport ("libX11", EntryPoint="XSetBackground")]
+               internal extern static int _XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
+               internal static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background)
+               {
+                       DebugHelper.TraceWriteLine ("XSetBackground");
+                       return _XSetBackground(display, gc, background);
+               }
+
+               [DllImport ("libX11", EntryPoint="XBell")]
+               internal extern static int _XBell(IntPtr display, int percent);
+               internal static int XBell(IntPtr display, int percent)
+               {
+                       DebugHelper.TraceWriteLine ("XBell");
+                       return _XBell(display, percent);
+               }
+
+               [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
+               internal extern static int _XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
+               internal static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time)
+               {
+                       DebugHelper.TraceWriteLine ("XChangeActivePointerGrab");
+                       return _XChangeActivePointerGrab (display, event_mask, cursor, time);
+               }
+
+               [DllImport ("libX11", EntryPoint="XFilterEvent")]
+               internal extern static bool _XFilterEvent(ref XEvent xevent, IntPtr window);
+               internal static bool XFilterEvent(ref XEvent xevent, IntPtr window)
+               {
+                       DebugHelper.TraceWriteLine ("XFilterEvent");
+                       return _XFilterEvent(ref xevent, window);
+               }
+
+               [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
+               internal extern static void _XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
+               internal static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported)
+               {
+                       DebugHelper.TraceWriteLine ("XkbSetDetectableAutoRepeat");
+                       _XkbSetDetectableAutoRepeat (display, detectable, supported);
+               }
+
+               [DllImport ("libX11", EntryPoint="XPeekEvent")]
+               internal extern static void _XPeekEvent (IntPtr display, ref XEvent xevent);
+               internal static void XPeekEvent (IntPtr display, ref XEvent xevent)
+               {
+                       DebugHelper.TraceWriteLine ("XPeekEvent");
+                       _XPeekEvent (display, ref xevent);
+               }
+
+               [DllImport ("libX11", EntryPoint="XIfEvent")]
+               internal extern static void _XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
+               internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg)
+               {
+                       DebugHelper.TraceWriteLine ("XIfEvent");
+                       _XIfEvent (display, ref xevent, event_predicate, arg);
+               }
+#endregion
+
+
+#else //no TRACE defined
+
+#region Xcursor imports
+               [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
+               internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
+
+               [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
+               internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
+               
+               [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
+               internal extern static void XcursorImagesDestroy (IntPtr images);
+               
+               [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
+               internal extern static int XcursorGetDefaultSize (IntPtr display);
+
+               [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
+               internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
+
+               [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
+               internal extern static IntPtr XcursorGetTheme (IntPtr display);
+#endregion
+               #region X11 Imports
+               [DllImport ("libX11", EntryPoint="XOpenDisplay")]
+               internal extern static IntPtr XOpenDisplay(IntPtr display);
+               [DllImport ("libX11", EntryPoint="XCloseDisplay")]
+               internal extern static int XCloseDisplay(IntPtr display);                                                   
+               [DllImport ("libX11", EntryPoint="XSynchronize")]
+               internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
+
+               [DllImport ("libX11", EntryPoint="XCreateWindow")]
+               internal extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
+               
+               [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
+               internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
+               
+               [DllImport ("libX11", EntryPoint="XMapWindow")]
+               internal extern static int XMapWindow(IntPtr display, IntPtr window);
+               
+               [DllImport ("libX11", EntryPoint="XMapRaised")]
+               internal extern static int XMapRaised(IntPtr display, IntPtr window);
+               
+               [DllImport ("libX11", EntryPoint="XUnmapWindow")]
+               internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
+               
+               [DllImport ("libX11", EntryPoint="XMapSubwindows")]
+               internal extern static int XMapSubindows(IntPtr display, IntPtr window);
+               
+               [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
+               internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
+               
+               [DllImport ("libX11", EntryPoint="XRootWindow")]
+               internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
+               
+               [DllImport ("libX11", EntryPoint="XNextEvent")]
+               internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
+
+               [DllImport ("libX11", EntryPoint="XConnectionNumber")]
+               internal extern static int XConnectionNumber (IntPtr display);
+               
+               [DllImport ("libX11", EntryPoint="XPending")]
+               internal extern static int XPending (IntPtr display);
+               
+               [DllImport ("libX11", EntryPoint="XSelectInput")]
+               internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
+               
+               [DllImport ("libX11", EntryPoint="XDestroyWindow")]
+               internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
+               
+               [DllImport ("libX11", EntryPoint="XReparentWindow")]
+               internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
+               
+               [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
+               extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
+               internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
+               {
+                       int ret = XMoveResizeWindow (display, window, x, y, width, height);
+                       Keyboard.MoveCurrentCaretPos ();
+                       return ret;
+               }
+
+               [DllImport ("libX11", EntryPoint="XResizeWindow")]
+               internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
+
+               [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
                internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
 
                [DllImport ("libX11", EntryPoint="XFlush")]
@@ -5365,7 +7367,7 @@ namespace System.Windows.Forms {
                internal extern static bool XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons);
 
                [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
-               internal extern static bool XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return,  out int dest_y_return, out IntPtr child_return);
+               internal extern static bool XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return, out int dest_y_return, out IntPtr child_return);
 
                [DllImport ("libX11", EntryPoint="XGetGeometry")]
                internal extern static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
@@ -5443,9 +7445,6 @@ namespace System.Windows.Forms {
                [DllImport ("libX11", EntryPoint="XDeleteProperty")]
                internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
 
-               [DllImport ("gdiplus", EntryPoint="GetFontMetrics")]
-               internal extern static bool GetFontMetrics(IntPtr graphicsObject, IntPtr nativeObject, out int ascent, out int descent);
-
                // Drawing
                [DllImport ("libX11", EntryPoint="XCreateGC")]
                internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
@@ -5510,6 +7509,9 @@ namespace System.Windows.Forms {
                [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
                internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
 
+               [DllImport ("libX11", EntryPoint="XQueryExtension")]
+               internal extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
+
                [DllImport ("libX11", EntryPoint="XWhitePixel")]
                internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
 
@@ -5573,11 +7575,32 @@ namespace System.Windows.Forms {
                [DllImport ("libX11", EntryPoint="XFilterEvent")]
                internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
 
-               [DllImport ("libX11")]
+               [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
                internal extern static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
 
-               [DllImport ("libX11")]
+               [DllImport ("libX11", EntryPoint="XPeekEvent")]
                internal extern static void XPeekEvent (IntPtr display, ref XEvent xevent);
+
+               [DllImport ("libX11", EntryPoint="XIfEvent")]
+               internal extern static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
+
+               [DllImport ("libX11", EntryPoint="XGetInputFocus")]
+               internal extern static void XGetInputFocus (IntPtr display, out IntPtr focus, out IntPtr revert_to);
                #endregion
+#region Gtk/Gdk imports
+               [DllImport("libgdk-x11-2.0")]
+               internal extern static IntPtr gdk_atom_intern (string atomName, bool onlyIfExists);
+
+               [DllImport("libgtk-x11-2.0")]
+               internal extern static IntPtr gtk_clipboard_get (IntPtr atom);
+
+               [DllImport("libgtk-x11-2.0")]
+               internal extern static void gtk_clipboard_store (IntPtr clipboard);
+
+               [DllImport("libgtk-x11-2.0")]
+               internal extern static void gtk_clipboard_set_text (IntPtr clipboard, string text, int len);
+#endregion
+
+#endif
        }
 }