2007-01-02 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUIX11.cs
index abff03b9320aeb84fdb53505ea8096606b3dd80b..b306f4c5018d7edcde4628c13f1cac86f1a05810 100644 (file)
@@ -45,6 +45,7 @@
 #undef DriverDebugCreate
 #undef DriverDebugDestroy
 #undef DriverDebugThreads
+#undef DriverDebugXEmbed
 
 using System;
 using System.ComponentModel;
@@ -99,6 +100,8 @@ namespace System.Windows.Forms {
                private static Hashtable        MessageQueues;          // Holds our thread-specific XEventQueues
                #if __MonoCS__                                          //
                private static Pollfd[]         pollfds;                // For watching the X11 socket
+               private static bool wake_waiting;
+               private static object wake_waiting_lock = new object ();
                #endif                                                  //
                private static X11Keyboard      Keyboard;               //
                private static X11Dnd           Dnd;
@@ -130,67 +133,67 @@ namespace System.Windows.Forms {
                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_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_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_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_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_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_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_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_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_NO_TASKBAR;
-               private static IntPtr _NET_WM_STATE_ABOVE;
-               private static IntPtr _NET_WM_STATE_MODAL;
+               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_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_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 DIB;
                private static IntPtr OEMTEXT;
                private static IntPtr UNICODETEXT;
                private static IntPtr TARGETS;
@@ -205,7 +208,7 @@ namespace System.Windows.Forms {
                private static GrabStruct       Grab;                   //
 
                // State
-               private static Point            MousePosition;          // Last position of mouse, in screen coords
+               Point           mouse_position;         // Last position of mouse, in screen coords
                internal static MouseButtons    MouseState;             // Last state of mouse buttons
 
                // 'Constants'
@@ -485,7 +488,7 @@ namespace System.Windows.Forms {
                                ModalWindows = new Stack(3);
 
                                MouseState = MouseButtons.None;
-                               MousePosition = new Point(0, 0);
+                               mouse_position = new Point(0, 0);
 
                                Caret.Timer = new Timer();
                                Caret.Timer.Interval = 500;             // FIXME - where should this number come from?
@@ -503,44 +506,6 @@ namespace System.Windows.Forms {
                                throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
                        }
                }
-
-               internal static void Where() {
-                       Console.WriteLine("Here: {0}\n", WhereString());
-               }
-
-               internal static string WhereString() {
-                       StackTrace      stack;
-                       StackFrame      frame;
-                       string          newline;
-                       string          unknown;
-                       StringBuilder   sb;
-                       MethodBase      method;
-
-                       newline = String.Format("{0}\t {1} ", Environment.NewLine, Locale.GetText("at"));
-                       unknown = Locale.GetText("<unknown method>");
-                       sb = new StringBuilder();
-                       stack = new StackTrace(true);
-
-                       for (int i = 0; i < stack.FrameCount; i++) {
-                               frame = stack.GetFrame(i);
-                               sb.Append(newline);
-
-                               method = frame.GetMethod();
-                               if (method != null) {
-                                       #if not
-                                               sb.AppendFormat(frame.ToString());
-                                       #endif
-                                       if (frame.GetFileLineNumber() != 0) {
-                                               sb.AppendFormat("{0}.{1} () [{2}:{3}]", method.DeclaringType.FullName, method.Name, Path.GetFileName(frame.GetFileName()), frame.GetFileLineNumber());
-                                       } else {
-                                               sb.AppendFormat("{0}.{1} ()", method.DeclaringType.FullName, method.Name);
-                                       }
-                               } else { 
-                                       sb.Append(unknown);
-                               }
-                       }
-                       return sb.ToString();
-               }
                #endregion      // Internal Methods
 
                #region Private Methods
@@ -551,90 +516,153 @@ namespace System.Windows.Forms {
                }
 
                private static void SetupAtoms() {
-                       WM_PROTOCOLS = XInternAtom(DisplayHandle, "WM_PROTOCOLS", false);
-                       WM_DELETE_WINDOW = XInternAtom(DisplayHandle, "WM_DELETE_WINDOW", false);
-                       WM_TAKE_FOCUS = XInternAtom(DisplayHandle, "WM_TAKE_FOCUS", false);
-
-                       _NET_SUPPORTED = XInternAtom(DisplayHandle, "_NET_SUPPORTED", false);
-                       _NET_CLIENT_LIST = XInternAtom(DisplayHandle, "_NET_CLIENT_LIST", false);
-                       _NET_NUMBER_OF_DESKTOPS = XInternAtom(DisplayHandle, "_NET_NUMBER_OF_DESKTOPS", false);
-                       _NET_DESKTOP_GEOMETRY = XInternAtom(DisplayHandle, "_NET_DESKTOP_GEOMETRY", false);
-                       _NET_DESKTOP_VIEWPORT = XInternAtom(DisplayHandle, "_NET_DESKTOP_VIEWPORT", false);
-                       _NET_CURRENT_DESKTOP = XInternAtom(DisplayHandle, "_NET_CURRENT_DESKTOP", false);
-                       _NET_DESKTOP_NAMES = XInternAtom(DisplayHandle, "_NET_DESKTOP_NAMES", false);
-                       _NET_ACTIVE_WINDOW = XInternAtom(DisplayHandle, "_NET_ACTIVE_WINDOW", false);
-                       _NET_WORKAREA = XInternAtom(DisplayHandle, "_NET_WORKAREA", false);
-                       _NET_SUPPORTING_WM_CHECK = XInternAtom(DisplayHandle, "_NET_SUPPORTING_WM_CHECK", false);
-                       _NET_VIRTUAL_ROOTS = XInternAtom(DisplayHandle, "_NET_VIRTUAL_ROOTS", false);
-                       _NET_DESKTOP_LAYOUT = XInternAtom(DisplayHandle, "_NET_DESKTOP_LAYOUT", false);
-                       _NET_SHOWING_DESKTOP = XInternAtom(DisplayHandle, "_NET_SHOWING_DESKTOP", false);
-
-                       _NET_CLOSE_WINDOW = XInternAtom(DisplayHandle, "_NET_CLOSE_WINDOW", false);
-                       _NET_MOVERESIZE_WINDOW = XInternAtom(DisplayHandle, "_NET_MOVERESIZE_WINDOW", false);
-                       _NET_WM_MOVERESIZE = XInternAtom(DisplayHandle, "_NET_WM_MOVERESIZE", false);
-                       _NET_RESTACK_WINDOW = XInternAtom(DisplayHandle, "_NET_RESTACK_WINDOW", false);
-                       _NET_REQUEST_FRAME_EXTENTS = XInternAtom(DisplayHandle, "_NET_REQUEST_FRAME_EXTENTS", false);
-
-                       _NET_WM_NAME = XInternAtom(DisplayHandle, "_NET_WM_NAME", false);
-                       _NET_WM_VISIBLE_NAME = XInternAtom(DisplayHandle, "_NET_WM_VISIBLE_NAME", false);
-                       _NET_WM_ICON_NAME = XInternAtom(DisplayHandle, "_NET_WM_ICON_NAME", false);
-                       _NET_WM_VISIBLE_ICON_NAME = XInternAtom(DisplayHandle, "_NET_WM_VISIBLE_ICON_NAME", false);
-                       _NET_WM_DESKTOP = XInternAtom(DisplayHandle, "_NET_WM_DESKTOP", false);
-                       _NET_WM_WINDOW_TYPE = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE", false);
-                       _NET_WM_STATE = XInternAtom(DisplayHandle, "_NET_WM_STATE", false);
-                       _NET_WM_ALLOWED_ACTIONS = XInternAtom(DisplayHandle, "_NET_WM_ALLOWED_ACTIONS", false);
-                       _NET_WM_STRUT = XInternAtom(DisplayHandle, "_NET_WM_STRUT", false);
-                       _NET_WM_STRUT_PARTIAL = XInternAtom(DisplayHandle, "_NET_WM_STRUT_PARTIAL", false);
-                       _NET_WM_ICON_GEOMETRY = XInternAtom(DisplayHandle, "_NET_WM_ICON_GEOMETRY", false);
-                       _NET_WM_ICON = XInternAtom(DisplayHandle, "_NET_WM_ICON", false);
-                       _NET_WM_PID = XInternAtom(DisplayHandle, "_NET_WM_PID", false);
-                       _NET_WM_HANDLED_ICONS = XInternAtom(DisplayHandle, "_NET_WM_HANDLED_ICONS", false);
-                       _NET_WM_USER_TIME = XInternAtom(DisplayHandle, "_NET_WM_USER_TIME", false);
-                       _NET_FRAME_EXTENTS = XInternAtom(DisplayHandle, "_NET_FRAME_EXTENTS", false);
-
-                       _NET_WM_PING = XInternAtom(DisplayHandle, "_NET_WM_PING", false);
-                       _NET_WM_SYNC_REQUEST = XInternAtom(DisplayHandle, "_NET_WM_SYNC_REQUEST", false);
-
-                       _NET_SYSTEM_TRAY_S = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
-                       _NET_SYSTEM_TRAY_OPCODE = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_OPCODE", false);
-                       _NET_SYSTEM_TRAY_ORIENTATION = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_ORIENTATION", false);
-
-                       _NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
-                       _NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
-                       _NET_WM_STATE_HIDDEN = XInternAtom(DisplayHandle, "_NET_WM_STATE_HIDDEN", false);
-
-                       _XEMBED = XInternAtom(DisplayHandle, "_XEMBED", false);
-                       _XEMBED_INFO = XInternAtom(DisplayHandle, "_XEMBED_INFO", false);
-
-                       _MOTIF_WM_HINTS = XInternAtom(DisplayHandle, "_MOTIF_WM_HINTS", false);
-
-                       _NET_WM_STATE_NO_TASKBAR = XInternAtom(DisplayHandle, "_NET_WM_STATE_NO_TASKBAR", false);
-                       _NET_WM_STATE_ABOVE = XInternAtom(DisplayHandle, "_NET_WM_STATE_ABOVE", false);
-                       _NET_WM_STATE_MODAL = XInternAtom(DisplayHandle, "_NET_WM_STATE_MODAL", false);
-                       _NET_WM_CONTEXT_HELP = XInternAtom(DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
-                       _NET_WM_WINDOW_OPACITY = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_OPACITY", false);
-
-                       _NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DESKTOP", false);
-                       _NET_WM_WINDOW_TYPE_DOCK = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DOCK", false);
-                       _NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_TOOLBAR", false);
-                       _NET_WM_WINDOW_TYPE_MENU = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_MENU", false);
-                       _NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_UTILITY", false);
-                       _NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DIALOG", false);
-                       _NET_WM_WINDOW_TYPE_SPLASH = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_SPLASH", false);
-                       _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_NORMAL", false);
-
-                       // Clipboard support
-                       CLIPBOARD = XInternAtom (DisplayHandle, "CLIPBOARD", false);
-                       PRIMARY = XInternAtom (DisplayHandle, "PRIMARY", false);
-                       DIB = (IntPtr)Atom.XA_PIXMAP;
-                       OEMTEXT = XInternAtom(DisplayHandle, "COMPOUND_TEXT", false);
-                       UNICODETEXT = XInternAtom(DisplayHandle, "UTF8_STRING", false);
-                       TARGETS = XInternAtom(DisplayHandle, "TARGETS", false);
-
-                       // Special Atoms
-                       AsyncAtom = XInternAtom(DisplayHandle, "_SWF_AsyncAtom", false);
-                       PostAtom = XInternAtom (DisplayHandle, "_SWF_PostMessageAtom", false);
-                       HoverState.Atom = XInternAtom(DisplayHandle, "_SWF_HoverAtom", false);
+                       // make sure this array stays in sync with the statements below
+                       string [] atom_names = new string[] {
+                               "WM_PROTOCOLS",
+                               "WM_DELETE_WINDOW",
+                               "WM_TAKE_FOCUS",
+                               //"_NET_SUPPORTED",
+                               //"_NET_CLIENT_LIST",
+                               //"_NET_NUMBER_OF_DESKTOPS",
+                               //"_NET_DESKTOP_GEOMETRY",
+                               //"_NET_DESKTOP_VIEWPORT",
+                               "_NET_CURRENT_DESKTOP",
+                               //"_NET_DESKTOP_NAMES",
+                               "_NET_ACTIVE_WINDOW",
+                               "_NET_WORKAREA",
+                               //"_NET_SUPPORTING_WM_CHECK",
+                               //"_NET_VIRTUAL_ROOTS",
+                               //"_NET_DESKTOP_LAYOUT",
+                               //"_NET_SHOWING_DESKTOP",
+                               //"_NET_CLOSE_WINDOW",
+                               //"_NET_MOVERESIZE_WINDOW",
+                               //"_NET_WM_MOVERESIZE",
+                               //"_NET_RESTACK_WINDOW",
+                               //"_NET_REQUEST_FRAME_EXTENTS",
+                               "_NET_WM_NAME",
+                               //"_NET_WM_VISIBLE_NAME",
+                               //"_NET_WM_ICON_NAME",
+                               //"_NET_WM_VISIBLE_ICON_NAME",
+                               //"_NET_WM_DESKTOP",
+                               "_NET_WM_WINDOW_TYPE",
+                               "_NET_WM_STATE",
+                               //"_NET_WM_ALLOWED_ACTIONS",
+                               //"_NET_WM_STRUT",
+                               //"_NET_WM_STRUT_PARTIAL",
+                               //"_NET_WM_ICON_GEOMETRY",
+                               "_NET_WM_ICON",
+                               //"_NET_WM_PID",
+                               //"_NET_WM_HANDLED_ICONS",
+                               "_NET_WM_USER_TIME",
+                               "_NET_FRAME_EXTENTS",
+                               //"_NET_WM_PING",
+                               //"_NET_WM_SYNC_REQUEST",
+                               "_NET_SYSTEM_TRAY_OPCODE",
+                               //"_NET_SYSTEM_TRAY_ORIENTATION",
+                               "_NET_WM_STATE_MAXIMIZED_HORZ",
+                               "_NET_WM_STATE_MAXIMIZED_VERT",
+                               "_NET_WM_STATE_HIDDEN",
+                               "_XEMBED",
+                               "_XEMBED_INFO",
+                               "_MOTIF_WM_HINTS",
+                               "_NET_WM_STATE_SKIP_TASKBAR",
+                               //"_NET_WM_STATE_ABOVE",
+                               //"_NET_WM_STATE_MODAL",
+                               "_NET_WM_CONTEXT_HELP",
+                               "_NET_WM_WINDOW_OPACITY",
+                               //"_NET_WM_WINDOW_TYPE_DESKTOP",
+                               //"_NET_WM_WINDOW_TYPE_DOCK",
+                               //"_NET_WM_WINDOW_TYPE_TOOLBAR",
+                               //"_NET_WM_WINDOW_TYPE_MENU",
+                               "_NET_WM_WINDOW_TYPE_UTILITY",
+                               //"_NET_WM_WINDOW_TYPE_DIALOG",
+                               //"_NET_WM_WINDOW_TYPE_SPLASH",
+                               "_NET_WM_WINDOW_TYPE_NORMAL",
+                               "CLIPBOARD",
+                               "PRIMARY",
+                               "COMPOUND_TEXT",
+                               "UTF8_STRING",
+                               "TARGETS",
+                               "_SWF_AsyncAtom",
+                               "_SWF_PostMessageAtom",
+                               "_SWF_HoverAtom" };
+
+                       IntPtr[] atoms = new IntPtr [atom_names.Length];;
+
+                       XInternAtoms (DisplayHandle, atom_names, atom_names.Length, false, atoms);
+
+                       int off = 0;
+                       WM_PROTOCOLS = atoms [off++];
+                       WM_DELETE_WINDOW = atoms [off++];
+                       WM_TAKE_FOCUS = atoms [off++];
+                       //_NET_SUPPORTED = atoms [off++];
+                       //_NET_CLIENT_LIST = atoms [off++];
+                       //_NET_NUMBER_OF_DESKTOPS = atoms [off++];
+                       //_NET_DESKTOP_GEOMETRY = atoms [off++];
+                       //_NET_DESKTOP_VIEWPORT = atoms [off++];
+                       _NET_CURRENT_DESKTOP = atoms [off++];
+                       //_NET_DESKTOP_NAMES = atoms [off++];
+                       _NET_ACTIVE_WINDOW = atoms [off++];
+                       _NET_WORKAREA = atoms [off++];
+                       //_NET_SUPPORTING_WM_CHECK = atoms [off++];
+                       //_NET_VIRTUAL_ROOTS = atoms [off++];
+                       //_NET_DESKTOP_LAYOUT = atoms [off++];
+                       //_NET_SHOWING_DESKTOP = atoms [off++];
+                       //_NET_CLOSE_WINDOW = atoms [off++];
+                       //_NET_MOVERESIZE_WINDOW = atoms [off++];
+                       //_NET_WM_MOVERESIZE = atoms [off++];
+                       //_NET_RESTACK_WINDOW = atoms [off++];
+                       //_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
+                       _NET_WM_NAME = atoms [off++];
+                       //_NET_WM_VISIBLE_NAME = atoms [off++];
+                       //_NET_WM_ICON_NAME = atoms [off++];
+                       //_NET_WM_VISIBLE_ICON_NAME = atoms [off++];
+                       //_NET_WM_DESKTOP = atoms [off++];
+                       _NET_WM_WINDOW_TYPE = atoms [off++];
+                       _NET_WM_STATE = atoms [off++];
+                       //_NET_WM_ALLOWED_ACTIONS = atoms [off++];
+                       //_NET_WM_STRUT = atoms [off++];
+                       //_NET_WM_STRUT_PARTIAL = atoms [off++];
+                       //_NET_WM_ICON_GEOMETRY = atoms [off++];
+                       _NET_WM_ICON = atoms [off++];
+                       //_NET_WM_PID = atoms [off++];
+                       //_NET_WM_HANDLED_ICONS = atoms [off++];
+                       _NET_WM_USER_TIME = atoms [off++];
+                       _NET_FRAME_EXTENTS = atoms [off++];
+                       //_NET_WM_PING = atoms [off++];
+                       //_NET_WM_SYNC_REQUEST = atoms [off++];
+                       _NET_SYSTEM_TRAY_OPCODE = atoms [off++];
+                       //_NET_SYSTEM_TRAY_ORIENTATION = atoms [off++];
+                       _NET_WM_STATE_MAXIMIZED_HORZ = atoms [off++];
+                       _NET_WM_STATE_MAXIMIZED_VERT = atoms [off++];
+                       _NET_WM_STATE_HIDDEN = atoms [off++];
+                       _XEMBED = atoms [off++];
+                       _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_CONTEXT_HELP = atoms [off++];
+                       _NET_WM_WINDOW_OPACITY = atoms [off++];
+                       //_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
+                       //_NET_WM_WINDOW_TYPE_DOCK = atoms [off++];
+                       //_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_SPLASH = atoms [off++];
+                       _NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
+                       CLIPBOARD = atoms [off++];
+                       PRIMARY = atoms [off++];
+                       OEMTEXT = atoms [off++];
+                       UNICODETEXT = atoms [off++];
+                       TARGETS = atoms [off++];
+                       AsyncAtom = atoms [off++];
+                       PostAtom = atoms [off++];
+                       HoverState.Atom = atoms [off++];
+
+                       //DIB = (IntPtr)Atom.XA_PIXMAP;
+                       _NET_SYSTEM_TRAY_S = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
                }
 
                private void GetSystrayManagerWindow() {
@@ -674,6 +702,47 @@ namespace System.Windows.Forms {
                        XSendEvent(DisplayHandle, window, false, new IntPtr ((int)EventMask.NoEventMask), ref xev);
                }
 
+               // For WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN, WM_XBUTTONDOWN
+               //     WM_CREATE and WM_DESTROY causes
+               void SendParentNotify(IntPtr child, Msg cause, int x, int y)
+               {       
+                       Hwnd hwnd;
+                       
+                       if (child == IntPtr.Zero) {
+                               return;
+                       }
+                       
+                       hwnd = Hwnd.GetObjectFromWindow (child);
+                       
+                       if (hwnd == null) {
+                               return;
+                       }
+                       
+                       if (hwnd.Handle == IntPtr.Zero) {
+                               return;
+                       }
+                       
+                       if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
+                               return;
+                       }
+                       
+                       if (hwnd.Parent == null) {
+                               return;
+                       }
+                       
+                       if (hwnd.Parent.Handle == IntPtr.Zero) {
+                               return;
+                       }
+
+                       if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
+                               SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
+                       } else {
+                               SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
+                       }
+                       
+                       SendParentNotify (hwnd.Parent.Handle, cause, x, y);
+               }
+               
                bool StyleSet (int s, WindowStyles ws)
                {
                        return (s & (int)ws) == (int)ws;
@@ -864,12 +933,24 @@ namespace System.Windows.Forms {
 
                        client_rect = hwnd.ClientRect;
                        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);
+                                               }
+                                       }
                                }
                                
                                XChangeProperty(DisplayHandle, hwnd.whole_window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropertyMode.Replace, ref mwmHints, 5);
@@ -880,7 +961,7 @@ namespace System.Windows.Forms {
                                        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 */
-                                       XSetTransientForHint(DisplayHandle, hwnd.whole_window, FosterParent);
+                                       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);
@@ -888,10 +969,8 @@ namespace System.Windows.Forms {
                                        XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
                                }
 
-                               atom_count = 0;
-
                                if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
-                                       atoms[atom_count++] = _NET_WM_STATE_NO_TASKBAR.ToInt32();
+                                       atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
                                }
                                /* we need to add these atoms in the
                                 * event we're maximized, since we're
@@ -940,10 +1019,6 @@ namespace System.Windows.Forms {
                        XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_ICON, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
                }
 
-               private IntPtr ImageToPixmap(Image image) {
-                       return IntPtr.Zero;
-               }
-
                private void WakeupMain () {
                        wake.Send (new byte [] { 0xFF });
                }
@@ -1023,82 +1098,6 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private void InvalidateWholeWindow(IntPtr handle) {
-                       Hwnd    hwnd;
-
-                       hwnd = Hwnd.ObjectFromHandle(handle);
-
-                       InvalidateWholeWindow(handle, new Rectangle(0, 0, hwnd.Width, hwnd.Height));
-               }
-
-               private void InvalidateWholeWindow(IntPtr handle, Rectangle rectangle) {
-                       Hwnd    hwnd;
-
-                       hwnd = Hwnd.ObjectFromHandle(handle);
-
-                       AddExpose (hwnd, false, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
-               }
-
-               private void WholeToScreen(IntPtr handle, ref int x, ref int y) {
-                       int     dest_x_return;
-                       int     dest_y_return;
-                       IntPtr  child;
-                       Hwnd    hwnd;
-
-                       hwnd = Hwnd.ObjectFromHandle(handle);
-
-                       lock (XlibLock) {
-                               XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
-                       }
-
-                       x = dest_x_return;
-                       y = dest_y_return;
-               }
-
-               private void AbsoluteGeometry(IntPtr window, out int ret_x, out int ret_y, out int width, out int height) {
-                       IntPtr  root;
-                       IntPtr  win;
-                       IntPtr  parent;
-                       IntPtr  children;
-                       int     x;
-                       int     y;
-                       int     w;
-                       int     h;
-                       int     absX;
-                       int     absY;
-                       int     b;
-                       int     d;
-                       int     nchildren;
-
-                       absX = 0;
-                       absY = 0;
-                       win = window;
-                       width = 0;
-                       height = 0;
-                       do {
-                               XGetGeometry(DisplayHandle, win, out root, out x, out y, out w, out h, out b, out d);
-                               if (win == window) {
-                                       width = w;
-                                       height = h;
-                               }
-                               absX += x;
-                               absY += y;
-                               if (XQueryTree(DisplayHandle, win, out root, out parent,  out children, out nchildren) == 0) {
-                                       break;
-                               }
-
-                               if (children != IntPtr.Zero) {
-                                       XFree(children);
-                               }
-                               win = parent;
-                       } while (win != root);
-
-                       ret_x = absX;
-                       ret_y = absY;
-
-//Console.WriteLine("Absolute pos for window {0} = {1},{2} {3}x{4}", XplatUI.Window(window), ret_x, ret_y, width, height);
-               }
-
                private void FrameExtents(IntPtr window, out int left, out int top) {
                        IntPtr                  actual_atom;
                        int                     actual_format;
@@ -1164,13 +1163,17 @@ namespace System.Windows.Forms {
                                                }
                                        }
                                }
+
+                               // XXX this sucks.  this isn't thread safe
                                hwnd.width = xevent.ConfigureEvent.width;
                                hwnd.height = xevent.ConfigureEvent.height;
                                hwnd.ClientRect = Rectangle.Empty;
 
-                               if (!hwnd.configure_pending) {
-                                       hwnd.Queue.Enqueue(xevent);
-                                       hwnd.configure_pending = true;
+                               lock (hwnd.configure_lock) {
+                                       if (!hwnd.configure_pending) {
+                                               hwnd.Queue.EnqueueLocked (xevent);
+                                               hwnd.configure_pending = true;
+                                       }
                                }
                        }
                        // We drop configure events for Client windows
@@ -1293,10 +1296,19 @@ namespace System.Windows.Forms {
 
                                if (timeout > 0) {
                                        #if __MonoCS__
-                                       Syscall.poll (pollfds, (uint) pollfds.Length, timeout);
+                                       int length = pollfds.Length - 1;
+                                       lock (wake_waiting_lock) {
+                                               if (wake_waiting == false) {
+                                                       length ++;
+                                                       wake_waiting = true;
+                                               }
+                                       }
+
+                                       Syscall.poll (pollfds, (uint)length, timeout);
                                        // Clean out buffer, so we're not busy-looping on the same data
                                        if (pollfds[1].revents != 0) {
                                                wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
+                                               wake_waiting = false;
                                        }
                                        #endif
                                        lock (XlibLock) {
@@ -1325,227 +1337,225 @@ namespace System.Windows.Forms {
                                }
 
                                hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
-                               if (hwnd == null) {
-                                       if (xevent.type == XEventName.Expose) {
-                                       }
+                               if (hwnd == null)
                                        continue;
-                               }
 
                                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);
-                                               break;
+                               case XEventName.Expose:
+                                       AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
+                                       break;
 
-                                       case XEventName.SelectionClear: {
-                                               // Should we do something?
-                                               break;
-                                       }
+                               case XEventName.SelectionClear: {
+                                       // Should we do something?
+                                       break;
+                               }
 
-                                       case XEventName.SelectionRequest: {
-                                               if (Dnd.HandleSelectionRequestEvent (ref xevent))
-                                                       break;
-                                               XEvent sel_event;
-
-                                               sel_event = new XEvent();
-                                               sel_event.SelectionEvent.type = XEventName.SelectionNotify;
-                                               sel_event.SelectionEvent.send_event = true;
-                                               sel_event.SelectionEvent.display = DisplayHandle;
-                                               sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
-                                               sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
-                                               sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
-                                               sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
-                                               sel_event.SelectionEvent.property = IntPtr.Zero;
-
-                                               // Seems that some apps support asking for supported types
-                                               if (xevent.SelectionEvent.target == TARGETS) {
-                                                       int[]   atoms;
-                                                       int     atom_count;
-
-                                                       atoms = new int[5];
-                                                       atom_count = 0;
-
-                                                       if (Clipboard.Item is String) {
-                                                               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)Atom.XA_PIXMAP;
-                                                               atoms[atom_count++] = (int)Atom.XA_BITMAP;
-                                                       } else {
-                                                               // FIXME - handle other types
-                                                       }
+                               case XEventName.SelectionRequest: {
+                                       if (Dnd.HandleSelectionRequestEvent (ref xevent))
+                                               break;
+                                       XEvent sel_event;
+
+                                       sel_event = new XEvent();
+                                       sel_event.SelectionEvent.type = XEventName.SelectionNotify;
+                                       sel_event.SelectionEvent.send_event = true;
+                                       sel_event.SelectionEvent.display = DisplayHandle;
+                                       sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
+                                       sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
+                                       sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
+                                       sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
+                                       sel_event.SelectionEvent.property = IntPtr.Zero;
+
+                                       // Seems that some apps support asking for supported types
+                                       if (xevent.SelectionEvent.target == TARGETS) {
+                                               int[]   atoms;
+                                               int     atom_count;
+
+                                               atoms = new int[5];
+                                               atom_count = 0;
+
+                                               if (Clipboard.Item is String) {
+                                                       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)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;
-                                                       int     buflen;
+                                               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;
+                                               int     buflen;
 
-                                                       buflen = 0;
+                                               buflen = 0;
 
-                                                       if (xevent.SelectionRequestEvent.target == (IntPtr)Atom.XA_STRING) {
-                                                               Byte[] bytes;
+                                               if (xevent.SelectionRequestEvent.target == (IntPtr)Atom.XA_STRING) {
+                                                       Byte[] bytes;
 
-                                                               bytes = new ASCIIEncoding().GetBytes((string)Clipboard.Item);
-                                                               buffer = Marshal.AllocHGlobal(bytes.Length);
-                                                               buflen = bytes.Length;
+                                                       bytes = new ASCIIEncoding().GetBytes((string)Clipboard.Item);
+                                                       buffer = Marshal.AllocHGlobal(bytes.Length);
+                                                       buflen = bytes.Length;
 
-                                                               for (int i = 0; i < buflen; i++) {
-                                                                       Marshal.WriteByte(buffer, i, bytes[i]);
-                                                               }
-                                                       } else if (xevent.SelectionRequestEvent.target == OEMTEXT) {
-                                                               // 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;
+                                                       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 (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 (Clipboard.Item is Image) {
-                                                       if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
-                                                               // FIXME - convert image and store as property
-                                                       } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
-                                                               // FIXME - convert image and store as property
+                                               } else if (xevent.SelectionRequestEvent.target == UNICODETEXT) {
+                                                       buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Item);
+                                                       while (Marshal.ReadByte(buffer, buflen) != 0) {
+                                                               buflen++;
                                                        }
+                                               } else {
+                                                       buffer = IntPtr.Zero;
                                                }
 
-                                               XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
-                                               break;
+                                               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) {
+                                               if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
+                                                       // FIXME - convert image and store as property
+                                               } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
+                                                       // FIXME - convert image and store as property
+                                               }
                                        }
 
-                                       case XEventName.SelectionNotify: {
-                                               if (Clipboard.Enumerating) {
-                                                       Clipboard.Enumerating = false;
-                                                       if (xevent.SelectionEvent.property != IntPtr.Zero) {
-                                                               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
-                                                               }
-                                                       }
-                                               } else if (Clipboard.Retrieving) {
-                                                       Clipboard.Retrieving = false;
-                                                       if (xevent.SelectionEvent.property != IntPtr.Zero) {
-                                                               TranslatePropertyToClipboard(xevent.SelectionEvent.property);
-                                                       } else {
-                                                               Clipboard.Item = null;
+                                       XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
+                                       break;
+                               }
+
+                               case XEventName.SelectionNotify: {
+                                       if (Clipboard.Enumerating) {
+                                               Clipboard.Enumerating = false;
+                                               if (xevent.SelectionEvent.property != IntPtr.Zero) {
+                                                       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
                                                        }
+                                               }
+                                       } else if (Clipboard.Retrieving) {
+                                               Clipboard.Retrieving = false;
+                                               if (xevent.SelectionEvent.property != IntPtr.Zero) {
+                                                       TranslatePropertyToClipboard(xevent.SelectionEvent.property);
                                                } else {
-                                                       Dnd.HandleSelectionNotifyEvent (ref xevent);
+                                                       Clipboard.Item = null;
                                                }
-                                               break;
+                                       } else {
+                                               Dnd.HandleSelectionNotifyEvent (ref xevent);
                                        }
+                                       break;
+                               }
 
-                                       case XEventName.MapNotify: {
-                                               if (hwnd.client_window == xevent.MapEvent.window) {
-                                                       hwnd.mapped = true;
-                                               }
-                                               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.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 ();
+                               case XEventName.KeyRelease:
+                                       if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
+                                               XEvent nextevent = new XEvent ();
 
-                                                       XPeekEvent (DisplayHandle, ref nextevent);
+                                               XPeekEvent (DisplayHandle, ref nextevent);
 
-                                                       if (nextevent.type == XEventName.KeyPress &&
-                                                       nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
-                                                       nextevent.KeyEvent.time == xevent.KeyEvent.time) {
-                                                               continue;
-                                                       }
+                                               if (nextevent.type == XEventName.KeyPress &&
+                                                   nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
+                                                   nextevent.KeyEvent.time == xevent.KeyEvent.time) {
+                                                       continue;
                                                }
-                                               goto case XEventName.KeyPress;
+                                       }
+                                       goto case XEventName.KeyPress;
                                        
-                                       case XEventName.MotionNotify: {
-                                               XEvent peek;
+                               case XEventName.MotionNotify: {
+                                       XEvent peek;
 
-                                               if (hwnd.Queue.Count > 0) {
-                                                       peek = hwnd.Queue.Peek();
-                                                       if (peek.AnyEvent.type == XEventName.MotionNotify) {
-                                                               continue;
-                                                       }
+                                       /* we can't do motion compression across threads, so just punt if we don't match up */
+                                       if (Thread.CurrentThread == hwnd.Queue.Thread && hwnd.Queue.Count > 0) {
+                                               peek = hwnd.Queue.Peek();
+                                               if (peek.AnyEvent.type == XEventName.MotionNotify) {
+                                                       continue;
                                                }
-                                               goto case XEventName.KeyPress;
                                        }
+                                       goto case XEventName.KeyPress;
+                               }
+
+                               case XEventName.KeyPress:
+                               case XEventName.ButtonPress:
+                               case XEventName.ButtonRelease:
+                               case XEventName.EnterNotify:
+                               case XEventName.LeaveNotify:
+                               case XEventName.CreateNotify:
+                               case XEventName.DestroyNotify:
+                               case XEventName.FocusIn:
+                               case XEventName.FocusOut:
+                               case XEventName.ClientMessage:
+                               case XEventName.ReparentNotify:
+                                       hwnd.Queue.EnqueueLocked (xevent);
+                                       break;
 
-                                       case XEventName.KeyPress:
-                                       case XEventName.ButtonPress:
-                                       case XEventName.ButtonRelease:
-                                       case XEventName.EnterNotify:
-                                       case XEventName.LeaveNotify:
-                                       case XEventName.CreateNotify:
-                                       case XEventName.DestroyNotify:
-                                       case XEventName.FocusIn:
-                                       case XEventName.FocusOut:
-                                       case XEventName.ClientMessage:
-                                       case XEventName.ReparentNotify:
-                                               hwnd.Queue.Enqueue (xevent);
-                                               break;
-
-                                       case XEventName.ConfigureNotify:
-                                               AddConfigureNotify(xevent);
-                                               break;
+                               case XEventName.ConfigureNotify:
+                                       AddConfigureNotify(xevent);
+                                       break;
 
-                                       case XEventName.PropertyNotify:
-                                               if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
-                                                       IntPtr  actual_atom;
-                                                       int     actual_format;
-                                                       IntPtr  nitems;
-                                                       IntPtr  bytes_after;
-                                                       IntPtr  prop = IntPtr.Zero;
-                                                       IntPtr  prev_active;;
-
-                                                       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));
-                                                               XFree(prop);
-
-                                                               if (prev_active != ActiveWindow) {
-                                                                       if (prev_active != IntPtr.Zero) {
-                                                                               PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
-                                                                       }
-                                                                       if (ActiveWindow != IntPtr.Zero) {
-                                                                               PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
-                                                                       }
+                               case XEventName.PropertyNotify:
+                                       if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
+                                               IntPtr  actual_atom;
+                                               int     actual_format;
+                                               IntPtr  nitems;
+                                               IntPtr  bytes_after;
+                                               IntPtr  prop = IntPtr.Zero;
+                                               IntPtr  prev_active;
+
+                                               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));
+                                                       XFree(prop);
+
+                                                       if (prev_active != ActiveWindow) {
+                                                               if (prev_active != IntPtr.Zero) {
+                                                                       PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
                                                                }
-                                                               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()) {
-                                                                                       Activate((IntPtr)ModalWindows.Peek());
-                                                                               }
+                                                               if (ActiveWindow != IntPtr.Zero) {
+                                                                       PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
+                                                               }
+                                                       }
+                                                       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()) {
+                                                                               Activate((IntPtr)ModalWindows.Peek());
                                                                        }
-                                                                       break;
                                                                }
+                                                               break;
                                                        }
                                                }
-                                               break;
+                                       }
+                                       break;
 
                                }
                        }
@@ -1601,7 +1611,7 @@ namespace System.Windows.Forms {
                        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);
                        } 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), WhereString());
+                               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;
                }
@@ -1609,7 +1619,7 @@ namespace System.Windows.Forms {
                private void AccumulateDestroyedHandles (Control c, ArrayList list)
                {
                        if (c != null) {
-                               Control[] controls = c.child_controls.GetAllControls ();
+                               Control[] controls = c.Controls.GetAllControls ();
 
                                if (c.IsHandleCreated && !c.IsDisposed) {
                                        Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
@@ -1643,6 +1653,11 @@ namespace System.Windows.Forms {
                                FocusWindow = IntPtr.Zero;
                        }
 
+                       if (Grab.Hwnd == hwnd.Handle) {
+                               Grab.Hwnd = IntPtr.Zero;
+                               Grab.Confined = false;
+                       }
+
                        DestroyCaret (hwnd.Handle);
                }
 
@@ -1678,6 +1693,8 @@ namespace System.Windows.Forms {
                                        XMoveResizeWindow(DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
                                }
                        }
+
+                       AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
                }
                #endregion      // Private Methods
 
@@ -1947,6 +1964,12 @@ namespace System.Windows.Forms {
                        }
                } 
 
+               internal override Point MousePosition {
+                       get {
+                               return mouse_position;
+                       }
+               }
+
                internal override Size MouseHoverSize {
                        get {
                                return new Size (1, 1);
@@ -2061,9 +2084,9 @@ namespace System.Windows.Forms {
                                        if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
                                                SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
                                        }
-                                       else {
-                                               //XRaiseWindow(DisplayHandle, handle);
-                                       }
+//                                     else {
+//                                             XRaiseWindow(DisplayHandle, handle);
+//                                     }
                                }
                        }
                }
@@ -2171,13 +2194,13 @@ namespace System.Windows.Forms {
                        //else if (format == "SymbolicLink" ) return 4;
                        //else if (format == "DataInterchangeFormat" ) return 5;
                        //else if (format == "Tiff" ) return 6;
-                       else if (format == "OEMText" ) return XInternAtom(DisplayHandle, "COMPOUND_TEXT", false).ToInt32();
+                       else if (format == "OEMText" ) return OEMTEXT.ToInt32();
                        else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP;
                        else if (format == "Palette" ) return (int)Atom.XA_COLORMAP;    // Useless
                        //else if (format == "PenData" ) return 10;
                        //else if (format == "RiffAudio" ) return 11;
                        //else if (format == "WaveAudio" ) return 12;
-                       else if (format == "UnicodeText" ) return XInternAtom(DisplayHandle, "UTF8_STRING", false).ToInt32();
+                       else if (format == "UnicodeText" ) return UNICODETEXT.ToInt32();
                        //else if (format == "EnhancedMetafile" ) return 14;
                        //else if (format == "FileDrop" ) return 15;
                        //else if (format == "Locale" ) return 16;
@@ -2310,6 +2333,7 @@ namespace System.Windows.Forms {
                        hwnd.width = Width;
                        hwnd.height = Height;
                        hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
+                       hwnd.initial_ex_style = (WindowExStyles) cp.ExStyle;
 
                        if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
                                hwnd.enabled = false;
@@ -2356,14 +2380,9 @@ namespace System.Windows.Forms {
                        }
 
                        lock (XlibLock) {
-                               EventMask whole_window_mask = SelectInputMask;
-                               /* if we're a toplevel form, we want
-                                * to know about user-driven resizes.
-                                * otherwise, ignore them. */
-                               if (!StyleSet (cp.Style, WindowStyles.WS_CHILD))
-                                       whole_window_mask |= EventMask.StructureNotifyMask;
-                               XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)whole_window_mask));
-                               XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)SelectInputMask));
+                               XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask)));
+                               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);
@@ -2377,8 +2396,6 @@ namespace System.Windows.Forms {
                                XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
 
                                XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
-                       } else if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_APPWINDOW)) {
-//                             XSetTransientForHint (DisplayHandle, hwnd.whole_window, FosterParent);
                        }
 
                        SetWMStyles(hwnd, cp);
@@ -2411,6 +2428,8 @@ namespace System.Windows.Forms {
 
                        // Set caption/window title
                        Text(hwnd.Handle, cp.Caption);
+                       
+                       SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
 
                        return hwnd.Handle;
                }
@@ -2790,7 +2809,8 @@ namespace System.Windows.Forms {
 
                internal override void DestroyCaret(IntPtr handle) {
                        if (Caret.Hwnd == handle) {
-                               if (Caret.Visible == true) {
+                               if (Caret.Visible) {
+                                       HideCaret ();
                                        Caret.Timer.Stop();
                                }
                                if (Caret.gc != IntPtr.Zero) {
@@ -2825,6 +2845,8 @@ namespace System.Windows.Forms {
                                Console.WriteLine("Destroying window {0}", XplatUI.Window(hwnd.client_window));
                        #endif
 
+                       SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
+                               
                        CleanupCachedWindows (hwnd);
 
                        ArrayList windows = new ArrayList ();
@@ -2856,12 +2878,36 @@ namespace System.Windows.Forms {
                        return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
                }
 
-               internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
-                       Hwnd            hwnd;
+               IntPtr GetReversibleScreenGC (Color backColor)
+               {
                        XGCValues       gc_values;
                        IntPtr          gc;
+                       uint pixel;
 
-                       hwnd = Hwnd.ObjectFromHandle(handle);
+                       XColor xcolor = new XColor();
+                       xcolor.red = (ushort)(backColor.R * 257);
+                       xcolor.green = (ushort)(backColor.G * 257);
+                       xcolor.blue = (ushort)(backColor.B * 257);
+                       XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
+                       pixel = (uint)xcolor.pixel.ToInt32();
+
+
+                       gc_values = new XGCValues();
+
+                       gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
+                       gc_values.foreground = (IntPtr)pixel;
+
+                       gc = XCreateGC(DisplayHandle, RootWindow, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCForeground)), ref gc_values);
+                       XSetForeground(DisplayHandle, gc, (UIntPtr)pixel);
+                       XSetFunction(DisplayHandle,   gc, GXFunction.GXxor);
+
+                       return gc;
+               }
+
+               IntPtr GetReversibleControlGC (Control control, int line_width)
+               {
+                       XGCValues       gc_values;
+                       IntPtr          gc;
 
                        gc_values = new XGCValues();
 
@@ -2877,13 +2923,10 @@ namespace System.Windows.Forms {
                        //XSetPlaneMask(DisplayHandle,  gc, mask);
 
 
-                       gc = XCreateGC(DisplayHandle, hwnd.client_window, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
+                       gc = XCreateGC(DisplayHandle, control.Handle, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
                        uint foreground;
                        uint background;
 
-                       Control control;
-                       control = Control.FromHandle(handle);
-
                        XColor xcolor = new XColor();
 
                        xcolor.red = (ushort)(control.ForeColor.R * 257);
@@ -2905,13 +2948,82 @@ namespace System.Windows.Forms {
                        XSetFunction(DisplayHandle,   gc, GXFunction.GXxor);
                        XSetPlaneMask(DisplayHandle,  gc, (IntPtr)mask);
 
+                       return gc;
+               }
+
+               internal override void DrawReversibleLine(Point start, Point end, Color backColor)
+               {
+                       IntPtr gc = GetReversibleScreenGC (backColor);
+
+                       XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
+
+                       XFreeGC(DisplayHandle, gc);
+               }
+
+               internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
+               {
+                       IntPtr gc = GetReversibleScreenGC (backColor);
+
+                       if (rectangle.Width < 0) {
+                               rectangle.X += rectangle.Width;
+                               rectangle.Width = -rectangle.Width;
+                       }
+                       if (rectangle.Height < 0) {
+                               rectangle.Y += rectangle.Height;
+                               rectangle.Height = -rectangle.Height;
+                       }
+
+                       int line_width = 1;
+                       GCLineStyle line_style = GCLineStyle.LineSolid;
+                       GCCapStyle cap_style = GCCapStyle.CapButt;
+                       GCJoinStyle join_style = GCJoinStyle.JoinMiter;
+
+                       switch (style) {
+                       case FrameStyle.Dashed:
+                               line_style = GCLineStyle.LineOnOffDash;
+                               break;
+                       case FrameStyle.Thick:
+                               line_width = 2;
+                               break;
+                       }
+
+                       XSetLineAttributes (DisplayHandle, gc, line_width, line_style, cap_style, join_style);
+
+                       XDrawRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
+
+                       XFreeGC(DisplayHandle, gc);
+               }
+
+               internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor) 
+               {
+                       IntPtr gc = GetReversibleScreenGC (backColor);
+
+                       if (rectangle.Width < 0) {
+                               rectangle.X += rectangle.Width;
+                               rectangle.Width = -rectangle.Width;
+                       }
+                       if (rectangle.Height < 0) {
+                               rectangle.Y += rectangle.Height;
+                               rectangle.Height = -rectangle.Height;
+                       }
+                       XFillRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
+
+                       XFreeGC(DisplayHandle, gc);
+               }
+
+               internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
+                       IntPtr          gc;
+                       Control control = Control.FromHandle(handle);
+
+                       gc = GetReversibleControlGC (control, line_width);
+
                        if ((rect.Width > 0) && (rect.Height > 0)) {
-                               XDrawRectangle(DisplayHandle, hwnd.client_window, gc, rect.Left, rect.Top, rect.Width, rect.Height);
+                               XDrawRectangle(DisplayHandle, control.Handle, gc, rect.Left, rect.Top, rect.Width, rect.Height);
                        } else {
                                if (rect.Width > 0) {
-                                       XDrawLine(DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.Right, rect.Y);
+                                       XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.Right, rect.Y);
                                } else {
-                                       XDrawLine(DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.X, rect.Bottom);
+                                       XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.X, rect.Bottom);
                                }
                        }
                        XFreeGC(DisplayHandle, gc);
@@ -3214,15 +3326,15 @@ namespace System.Windows.Forms {
                                        }
 
                                        msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
-                                       MousePosition.X = xevent.ButtonEvent.x;
-                                       MousePosition.Y = xevent.ButtonEvent.y;
+                                       mouse_position.X = xevent.ButtonEvent.x;
+                                       mouse_position.Y = xevent.ButtonEvent.y;
 
                                        if (!hwnd.Enabled) {
                                                IntPtr dummy;
 
                                                msg.hwnd = hwnd.EnabledHwnd;
                                                XTranslateCoordinates(DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle(msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
-                                               msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
+                                               msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
                                        }
 
                                        if (Grab.Hwnd != IntPtr.Zero) {
@@ -3256,7 +3368,10 @@ namespace System.Windows.Forms {
                                                ClickPending.lParam = msg.lParam;
                                                ClickPending.Time = (long)xevent.ButtonEvent.time;
                                        }
-
+                                       
+                                       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;
                                }
 
@@ -3268,37 +3383,37 @@ namespace System.Windows.Forms {
 
                                        switch(xevent.ButtonEvent.button) {
                                                case 1: {
-                                                       MouseState &= ~MouseButtons.Left;
                                                        if (client) {
                                                                msg.message = Msg.WM_LBUTTONUP;
                                                        } else {
                                                                msg.message = Msg.WM_NCLBUTTONUP;
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
+                                                       MouseState &= ~MouseButtons.Left;
                                                        msg.wParam=GetMousewParam(0);
                                                        break;
                                                }
 
                                                case 2: {
-                                                       MouseState &= ~MouseButtons.Middle;
                                                        if (client) {
                                                                msg.message = Msg.WM_MBUTTONUP;
                                                        } else {
                                                                msg.message = Msg.WM_NCMBUTTONUP;
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
+                                                       MouseState &= ~MouseButtons.Middle;
                                                        msg.wParam=GetMousewParam(0);
                                                        break;
                                                }
 
                                                case 3: {
-                                                       MouseState &= ~MouseButtons.Right;
                                                        if (client) {
                                                                msg.message = Msg.WM_RBUTTONUP;
                                                        } else {
                                                                msg.message = Msg.WM_NCRBUTTONUP;
                                                                MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
                                                        }
+                                                       MouseState &= ~MouseButtons.Right;
                                                        msg.wParam=GetMousewParam(0);
                                                        break;
                                                }
@@ -3317,7 +3432,7 @@ namespace System.Windows.Forms {
 
                                                msg.hwnd = hwnd.EnabledHwnd;
                                                XTranslateCoordinates(DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle(msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
-                                               msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
+                                               msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
                                        }
 
                                        if (Grab.Hwnd != IntPtr.Zero) {
@@ -3325,8 +3440,8 @@ namespace System.Windows.Forms {
                                        }
 
                                        msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
-                                       MousePosition.X = xevent.ButtonEvent.x;
-                                       MousePosition.Y = xevent.ButtonEvent.y;
+                                       mouse_position.X = xevent.ButtonEvent.x;
+                                       mouse_position.Y = xevent.ButtonEvent.y;
                                        break;
                                }
 
@@ -3353,21 +3468,21 @@ namespace System.Windows.Forms {
 
                                                        msg.hwnd = hwnd.EnabledHwnd;
                                                        XTranslateCoordinates(DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle(msg.hwnd).ClientWindow, xevent.MotionEvent.x, xevent.MotionEvent.y, out xevent.MotionEvent.x, out xevent.MotionEvent.y, out dummy);
-                                                       msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
+                                                       msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
                                                }
 
-                                               MousePosition.X = xevent.MotionEvent.x;
-                                               MousePosition.Y = xevent.MotionEvent.y;
+                                               mouse_position.X = xevent.MotionEvent.x;
+                                               mouse_position.Y = xevent.MotionEvent.y;
 
                                                if ((HoverState.Timer.Enabled) &&
-                                                   (((MousePosition.X + HoverState.Size.Width) < HoverState.X) ||
-                                                   ((MousePosition.X - HoverState.Size.Width) > HoverState.X) ||
-                                                   ((MousePosition.Y + HoverState.Size.Height) < HoverState.Y) ||
-                                                   ((MousePosition.Y - HoverState.Size.Height) > HoverState.Y))) {
+                                                   (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
+                                                   ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
+                                                   ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
+                                                   ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
                                                        HoverState.Timer.Stop();
                                                        HoverState.Timer.Start();
-                                                       HoverState.X = MousePosition.X;
-                                                       HoverState.Y = MousePosition.Y;
+                                                       HoverState.X = mouse_position.X;
+                                                       HoverState.Y = mouse_position.Y;
                                                }
 
                                                break;
@@ -3385,7 +3500,7 @@ namespace System.Windows.Forms {
                                                if (!hwnd.Enabled) {
                                                        msg.hwnd = hwnd.EnabledHwnd;
                                                        XTranslateCoordinates(DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle(msg.hwnd).ClientWindow, xevent.MotionEvent.x, xevent.MotionEvent.y, out xevent.MotionEvent.x, out xevent.MotionEvent.y, out dummy);
-                                                       msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
+                                                       msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
                                                }
 
                                                // The hit test is sent in screen coordinates
@@ -3398,8 +3513,8 @@ namespace System.Windows.Forms {
                                                                IntPtr.Zero, msg.lParam).ToInt32 ();
                                                NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
 
-                                               MousePosition.X = xevent.MotionEvent.x;
-                                               MousePosition.Y = xevent.MotionEvent.y;
+                                               mouse_position.X = xevent.MotionEvent.x;
+                                               mouse_position.Y = xevent.MotionEvent.y;
                                        }
 
                                        break;
@@ -3493,11 +3608,14 @@ namespace System.Windows.Forms {
                                                        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)) {
-                                                       SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
-                                                       hwnd.configure_pending = false;
+                                                       lock (hwnd.configure_lock) {
+                                                               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
-                                                       PerformNCCalc(hwnd);
+                                                       if (hwnd.whole_window != hwnd.client_window)
+                                                               PerformNCCalc(hwnd);
 //                                             }
                                        }
                                        goto ProcessNextMessage;
@@ -3590,6 +3708,7 @@ namespace System.Windows.Forms {
                                                IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
                                                msg.message = Msg.WM_NCPAINT;
                                                msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
+                                               msg.refobject = region;
                                                break;
                                        }
                                        #if DriverDebugExtra
@@ -3656,12 +3775,23 @@ namespace System.Windows.Forms {
                                                return true;
                                        }
 
-                                       #if dontcare
                                        if  (xevent.ClientMessageEvent.message_type == _XEMBED) {
-                                               Console.WriteLine("GOT EMBED MESSAGE {0:X}", xevent.ClientMessageEvent.ptr2.ToInt32());
-                                               break;
+#if DriverDebugXEmbed
+                                               Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
+#endif
+
+                                               if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
+                                                       XSizeHints hints = new XSizeHints();
+                                                       IntPtr dummy;
+
+                                                       XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
+
+                                                       hwnd.width = hints.max_width;
+                                                       hwnd.height = hints.max_height;
+                                                       hwnd.ClientRect = Rectangle.Empty;
+                                                       SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
+                                               }
                                        }
-                                       #endif
 
                                        if  (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
                                                if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
@@ -3677,11 +3807,6 @@ namespace System.Windows.Forms {
                                        goto ProcessNextMessage;
                                }
 
-                               case XEventName.TimerNotify: {
-                                       xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
-                                       goto ProcessNextMessage;
-                               }
-                                       
                                default: {
                                        goto ProcessNextMessage;
                                }
@@ -3691,21 +3816,39 @@ namespace System.Windows.Forms {
                }
 
                internal override bool GetText(IntPtr handle, out string text) {
-                       IntPtr  textptr;
-
-                       textptr = IntPtr.Zero;
 
                        lock (XlibLock) {
-                               // FIXME - use _NET properties
-                               XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
-                       }
-                       if (textptr != IntPtr.Zero) {
-                               text = Marshal.PtrToStringAnsi(textptr);
-                               XFree(textptr);
-                               return true;
-                       } else {
-                               text = "";
-                               return false;
+                               IntPtr actual_atom;
+                               int actual_format;
+                               IntPtr nitems;
+                               IntPtr bytes_after;
+                               IntPtr prop = IntPtr.Zero;
+
+                               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);
+
+                               if ((long)nitems > 0 && prop != IntPtr.Zero) {
+                                       text = Marshal.PtrToStringUni (prop, (int)nitems);
+                                       XFree (prop);
+                                       return true;
+                               }
+                               else {
+                                       // fallback on the non-_NET property
+                                       IntPtr  textptr;
+
+                                       textptr = IntPtr.Zero;
+
+                                       XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
+                                       if (textptr != IntPtr.Zero) {
+                                               text = Marshal.PtrToStringAnsi(textptr);
+                                               XFree(textptr);
+                                               return true;
+                                       } else {
+                                               text = "";
+                                               return false;
+                                       }
+                               }
                        }
                }
 
@@ -3851,6 +3994,14 @@ namespace System.Windows.Forms {
                        }
                }
 
+               internal override void InvalidateNC (IntPtr handle) {
+                       Hwnd    hwnd;
+
+                       hwnd = Hwnd.ObjectFromHandle(handle);
+
+                       AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
+               }
+
                internal override bool IsEnabled(IntPtr handle) {
                        Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
                        return (hwnd != null && hwnd.Enabled);
@@ -3925,6 +4076,7 @@ namespace System.Windows.Forms {
 
                                hwnd.ClearInvalidArea();
 
+                               hwnd.drawing_stack.Push (paint_event);
                                hwnd.drawing_stack.Push (dc);
 
                                return paint_event;
@@ -3941,6 +4093,7 @@ namespace System.Windows.Forms {
 
                                hwnd.ClearNcInvalidArea ();
 
+                               hwnd.drawing_stack.Push (paint_event);
                                hwnd.drawing_stack.Push (dc);
 
                                return paint_event;
@@ -3955,6 +4108,10 @@ namespace System.Windows.Forms {
                        Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
                        dc.Flush();
                        dc.Dispose();
+                       
+                       PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
+                       pe.SetGraphics (null);
+                       pe.Dispose ();
 
                        if (Caret.Visible == true) {
                                ShowCaret();
@@ -4014,7 +4171,7 @@ namespace System.Windows.Forms {
                        xevent.ClientMessageEvent.ptr3 = wparam;
                        xevent.ClientMessageEvent.ptr4 = lparam;
 
-                       hwnd.Queue.Enqueue (xevent);
+                       hwnd.Queue.EnqueueLocked (xevent);
 
                        return true;
                }
@@ -4025,6 +4182,11 @@ namespace System.Windows.Forms {
                        ThreadQueue(Thread.CurrentThread).PostQuitState = true;
                }
 
+               internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
+               {
+                       // TODO
+               }
+
                internal override void RequestNCRecalc(IntPtr handle) {
                        Hwnd                            hwnd;
 
@@ -4036,7 +4198,7 @@ namespace System.Windows.Forms {
 
                        PerformNCCalc(hwnd);
                        SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
-                       InvalidateWholeWindow(handle);
+                       InvalidateNC(handle);
                }
 
                internal override void ResetMouseHover(IntPtr handle) {
@@ -4048,8 +4210,8 @@ namespace System.Windows.Forms {
                        }
 
                        HoverState.Timer.Enabled = true;
-                       HoverState.X = MousePosition.X;
-                       HoverState.Y = MousePosition.Y;
+                       HoverState.X = mouse_position.X;
+                       HoverState.Y = mouse_position.Y;
                        HoverState.Window = handle;
                }
 
@@ -4090,12 +4252,11 @@ namespace System.Windows.Forms {
                        Hwnd            hwnd;
                        IntPtr          gc;
                        XGCValues       gc_values;
-                       Rectangle       r;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
 
-                       r = hwnd.Invalid;
-                       if (r != Rectangle.Empty) {
+                       Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
+                       if (!r.IsEmpty) {
                                /* We have an invalid area in the window we're scrolling. 
                                   Adjust our stored invalid rectangle to to match the scrolled amount */
 
@@ -4112,7 +4273,8 @@ namespace System.Windows.Forms {
                                        r.Y =0;
                                }
 
-                               hwnd.ClearInvalidArea();
+                               if (area.Contains (hwnd.Invalid))
+                                       hwnd.ClearInvalidArea ();
                                hwnd.AddInvalidArea(r);
                        }
 
@@ -4228,6 +4390,33 @@ namespace System.Windows.Forms {
                        return NativeWindow.WndProc(hwnd, message, wParam, lParam);
                }
 
+               internal override int SendInput(IntPtr handle, Queue keys) { 
+                       int count = keys.Count;
+
+                       while (keys.Count > 0) {
+                       
+                               MSG msg = (MSG)keys.Dequeue();
+
+                               XEvent xevent = new XEvent ();
+                               Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
+
+                               xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
+                               xevent.KeyEvent.display = DisplayHandle;
+
+                               if (hwnd != null) {
+                                       xevent.KeyEvent.window = hwnd.whole_window;
+                               } else {
+                                       xevent.KeyEvent.window = IntPtr.Zero;
+                               }
+
+                               xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
+
+                               hwnd.Queue.EnqueueLocked (xevent);
+                       }
+                       return count;
+               }
+
+
                internal override void SetAllowDrop (IntPtr handle, bool value)
                {
                        // We allow drop on all windows
@@ -4403,7 +4592,7 @@ namespace System.Windows.Forms {
                                        xevent.MotionEvent.y_root = root_y;
                                        xevent.MotionEvent.state = mask;
 
-                                       child_hwnd.Queue.Enqueue (xevent);
+                                       child_hwnd.Queue.EnqueueLocked (xevent);
                                }
                        } else {
                                Hwnd    hwnd;
@@ -4612,6 +4801,12 @@ namespace System.Windows.Forms {
                                return;
                        }
 
+                       // Win32 automatically changes negative width/height to 0.
+                       if (width < 0)
+                               width = 0;
+                       if (height < 0)
+                               height = 0;
+                               
                        // X requires a sanity check for width & height; otherwise it dies
                        if (hwnd.zero_sized && width > 0 && height > 0) {
                                if (hwnd.visible) {
@@ -4657,6 +4852,7 @@ namespace System.Windows.Forms {
                        hwnd.y = y;
                        hwnd.width = width;
                        hwnd.height = height;
+                       hwnd.ClientRect = Rectangle.Empty;
                }
 
                internal override void SetWindowState(IntPtr handle, FormWindowState state) {
@@ -4716,6 +4912,11 @@ namespace System.Windows.Forms {
                        SetWMStyles(hwnd, cp);
                }
 
+               internal override double GetWindowTransparency(IntPtr handle)
+               {
+                       return 1.0;
+               }
+
                internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
                        Hwnd    hwnd;
                        IntPtr  opacity;
@@ -4729,9 +4930,10 @@ namespace System.Windows.Forms {
                        hwnd.opacity = (uint)(0xffffffff * transparency);
                        opacity = (IntPtr)((int)hwnd.opacity);
 
-                       if (hwnd.reparented) {
-                               XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
-                       }
+                       IntPtr w = hwnd.whole_window;
+                       if (hwnd.reparented)
+                               w = XGetParent (hwnd.whole_window);
+                       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) {
@@ -4793,9 +4995,9 @@ namespace System.Windows.Forms {
                        return (Object) ThreadQueue(thread);
                }
 
-               internal override bool SupportsTransparency() {
+               internal override TransparencySupport SupportsTransparency() {
                        // We need to check if the x compositing manager is running
-                       return true;
+                       return TransparencySupport.Set;
                }
 
                internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {
@@ -4803,7 +5005,6 @@ namespace System.Windows.Forms {
 
                        if (SystrayMgrWindow != IntPtr.Zero) {
                                XSizeHints      size_hints;
-                               IntPtr          dummy;
                                Hwnd            hwnd;
 
                                hwnd = Hwnd.ObjectFromHandle(handle);
@@ -4829,16 +5030,15 @@ namespace System.Windows.Forms {
 
                                size_hints = new XSizeHints();
 
-                               XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints, out dummy);
                                size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
-                               size_hints.min_width = icon.Width;
-                               size_hints.min_height = icon.Height;
 
-                               size_hints.max_width = icon.Width;
-                               size_hints.max_height = icon.Height;
+                               size_hints.min_width = 24;
+                               size_hints.min_height = 24;
+                               size_hints.max_width = 24;
+                               size_hints.max_height = 24;
+                               size_hints.base_width = 24;
+                               size_hints.base_height = 24;
 
-                               size_hints.base_width = icon.Width;
-                               size_hints.base_height = icon.Height;
                                XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
 
                                int[] atoms = new int[2];
@@ -4917,8 +5117,19 @@ namespace System.Windows.Forms {
                }
 
                internal override bool Text(IntPtr handle, string text) {
+                       Hwnd    hwnd;
+
+                       hwnd = Hwnd.ObjectFromHandle(handle);
+
                        lock (XlibLock) {
-                               // FIXME - use _NET properties
+                               XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UNICODETEXT, 8,
+                                               PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
+
+                               // XXX this has problems with UTF8.
+                               // we need to either use the actual
+                               // text if it's latin-1, or convert it
+                               // to compound text if it's in a
+                               // different charset.
                                XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
                        }
                        return true;
@@ -4941,6 +5152,54 @@ namespace System.Windows.Forms {
                        hwnd.Queue.Paint.Remove(hwnd);
                }
 
+               internal override void CreateOffscreenDrawable (IntPtr handle,
+                                                               int width, int height,
+                                                               out object offscreen_drawable)
+               {
+                       IntPtr root_out;
+                       int x_out, y_out, width_out, height_out, border_width_out, depth_out;
+
+                       XGetGeometry (DisplayHandle, handle,
+                                     out root_out,
+                                     out x_out, out y_out,
+                                     out width_out, out height_out,
+                                     out border_width_out, out depth_out);
+
+                       IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
+
+                       offscreen_drawable = pixmap;
+
+               }
+
+               internal override void DestroyOffscreenDrawable (object offscreen_drawable)
+               {
+                       XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
+               }
+
+               internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
+               {
+                       return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
+               }
+               
+               internal override void BlitFromOffscreen (IntPtr dest_handle,
+                                                         Graphics dest_dc,
+                                                         object offscreen_drawable,
+                                                         Graphics offscreen_dc,
+                                                         Rectangle r)
+               {
+                       XGCValues gc_values;
+                       IntPtr gc;
+
+                       gc_values = new XGCValues();
+
+                       gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
+
+                       XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
+                                  gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
+
+                       XFreeGC (DisplayHandle, gc);
+               }
+
                #endregion      // Public Static Methods
 
                #region Events
@@ -5025,6 +5284,9 @@ namespace System.Windows.Forms {
                [DllImport ("libX11", EntryPoint="XInternAtom")]
                internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool 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);
+
                [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
                internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
 
@@ -5129,12 +5391,18 @@ namespace System.Windows.Forms {
                [DllImport ("libX11", EntryPoint="XSetFunction")]
                internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction 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);
+
                [DllImport ("libX11", EntryPoint="XDrawLine")]
                internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
 
                [DllImport ("libX11", EntryPoint="XDrawRectangle")]
                internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
 
+               [DllImport ("libX11", EntryPoint="XFillRectangle")]
+               internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
+
                [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
                internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
 
@@ -5168,6 +5436,9 @@ namespace System.Windows.Forms {
                [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);
 
+               [DllImport ("libX11", EntryPoint="XCreatePixmap")]
+               internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
+
                [DllImport ("libX11", EntryPoint="XFreePixmap")]
                internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);