2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUIX11.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25 //
26
27 // NOTE:
28 //      This driver understands the following environment variables: (Set the var to enable feature)
29 //
30 //      MONO_XEXCEPTIONS        = throw an exception when a X11 error is encountered;
31 //                                by default a message is displayed but execution continues
32 //
33 //      MONO_XSYNC              = perform all X11 commands synchronous; this is slower but
34 //                                helps in debugging errors
35 //
36
37 // NOT COMPLETE
38
39 // define to log Window handles and relationships to stdout
40 #undef DriverDebug
41
42 // Extra detailed debug
43 #undef DriverDebugExtra
44 #undef DriverDebugParent
45 #undef DriverDebugCreate
46 #undef DriverDebugDestroy
47 #undef DriverDebugThreads
48 #undef DriverDebugXEmbed
49
50 //#define TRACE
51 //#define DEBUG
52
53 using System;
54 using System.ComponentModel;
55 using System.Collections;
56 using System.Diagnostics;
57 using System.Drawing;
58 using System.Drawing.Drawing2D;
59 using System.Drawing.Imaging;
60 using System.IO;
61 using System.Net;
62 using System.Net.Sockets;
63 using System.Reflection;
64 using System.Runtime.InteropServices;
65 using System.Runtime.Serialization;
66 using System.Runtime.Serialization.Formatters.Binary;
67 using System.Text;
68 using System.Threading;
69
70 // Only do the poll when building with mono for now
71 #if __MonoCS__
72 using Mono.Unix.Native;
73 #endif
74
75 /// X11 Version
76 namespace System.Windows.Forms {
77         internal class XplatUIX11 : XplatUIDriver {
78                 #region Local Variables
79                 // General
80                 static volatile XplatUIX11      Instance;
81                 private static int              RefCount;
82                 private static object           XlibLock;               // Our locking object
83                 private static bool             themes_enabled;
84
85                 // General X11
86                 private static IntPtr           DisplayHandle;          // X11 handle to display
87                 private static int              ScreenNo;               // Screen number used
88                 private static IntPtr           DefaultColormap;        // Colormap for screen
89                 private static IntPtr           CustomVisual;           // Visual for window creation
90                 private static IntPtr           CustomColormap;         // Colormap for window creation
91                 private static IntPtr           RootWindow;             // Handle of the root window for the screen/display
92                 private static IntPtr           FosterParent;           // Container to hold child windows until their parent exists
93                 private static XErrorHandler    ErrorHandler;           // Error handler delegate
94                 private static bool             ErrorExceptions;        // Throw exceptions on X errors
95                 private int                     render_major_opcode;
96                 private int                     render_first_event;
97                 private int                     render_first_error;
98
99                 // Clipboard
100                 private static IntPtr           ClipMagic;
101                 private static ClipboardData    Clipboard;              // Our clipboard
102
103                 // Communication
104                 private static IntPtr           PostAtom;               // PostMessage atom
105                 private static IntPtr           AsyncAtom;              // Support for async messages
106
107                 // Message Loop
108                 private static Hashtable        MessageQueues;          // Holds our thread-specific XEventQueues
109                 private static ArrayList        unattached_timer_list; // holds timers that are enabled but not attached to a window.
110                 #if __MonoCS__                                          //
111                 private static Pollfd[]         pollfds;                // For watching the X11 socket
112                 private static bool wake_waiting;
113                 private static object wake_waiting_lock = new object ();
114                 #endif                                                  //
115                 private static X11Keyboard      Keyboard;               //
116                 private static X11Dnd           Dnd;
117                 private static Socket           listen;                 //
118                 private static Socket           wake;                   //
119                 private static Socket           wake_receive;           //
120                 private static byte[]           network_buffer;         //
121                 private static bool             detectable_key_auto_repeat;
122
123                 // Focus tracking
124                 private static IntPtr           ActiveWindow;           // Handle of the active window
125                 private static IntPtr           FocusWindow;            // Handle of the window with keyboard focus (if any)
126
127                 // Modality support
128                 private static Stack            ModalWindows;           // Stack of our modal windows
129
130                 // Systray
131                 private static IntPtr           SystrayMgrWindow;       // Handle of the Systray Manager window
132
133                 // Cursors
134                 private static IntPtr           LastCursorWindow;       // The last window we set the cursor on
135                 private static IntPtr           LastCursorHandle;       // The handle that was last set on LastCursorWindow
136                 private static IntPtr           OverrideCursorHandle;   // The cursor that is set to override any other cursors
137
138                 // Caret
139                 private static CaretStruct      Caret;                  //
140
141                 // Last window containing the pointer
142                 private static IntPtr           LastPointerWindow;      // The last window containing the pointer
143
144                 // Our atoms
145                 private static IntPtr WM_PROTOCOLS;
146                 private static IntPtr WM_DELETE_WINDOW;
147                 private static IntPtr WM_TAKE_FOCUS;
148                 //private static IntPtr _NET_SUPPORTED;
149                 //private static IntPtr _NET_CLIENT_LIST;
150                 //private static IntPtr _NET_NUMBER_OF_DESKTOPS;
151                 private static IntPtr _NET_DESKTOP_GEOMETRY;
152                 //private static IntPtr _NET_DESKTOP_VIEWPORT;
153                 private static IntPtr _NET_CURRENT_DESKTOP;
154                 //private static IntPtr _NET_DESKTOP_NAMES;
155                 private static IntPtr _NET_ACTIVE_WINDOW;
156                 private static IntPtr _NET_WORKAREA;
157                 //private static IntPtr _NET_SUPPORTING_WM_CHECK;
158                 //private static IntPtr _NET_VIRTUAL_ROOTS;
159                 //private static IntPtr _NET_DESKTOP_LAYOUT;
160                 //private static IntPtr _NET_SHOWING_DESKTOP;
161                 //private static IntPtr _NET_CLOSE_WINDOW;
162                 //private static IntPtr _NET_MOVERESIZE_WINDOW;
163                 //private static IntPtr _NET_WM_MOVERESIZE;
164                 //private static IntPtr _NET_RESTACK_WINDOW;
165                 //private static IntPtr _NET_REQUEST_FRAME_EXTENTS;
166                 private static IntPtr _NET_WM_NAME;
167                 //private static IntPtr _NET_WM_VISIBLE_NAME;
168                 //private static IntPtr _NET_WM_ICON_NAME;
169                 //private static IntPtr _NET_WM_VISIBLE_ICON_NAME;
170                 //private static IntPtr _NET_WM_DESKTOP;
171                 private static IntPtr _NET_WM_WINDOW_TYPE;
172                 private static IntPtr _NET_WM_STATE;
173                 //private static IntPtr _NET_WM_ALLOWED_ACTIONS;
174                 //private static IntPtr _NET_WM_STRUT;
175                 //private static IntPtr _NET_WM_STRUT_PARTIAL;
176                 //private static IntPtr _NET_WM_ICON_GEOMETRY;
177                 private static IntPtr _NET_WM_ICON;
178                 //private static IntPtr _NET_WM_PID;
179                 //private static IntPtr _NET_WM_HANDLED_ICONS;
180                 private static IntPtr _NET_WM_USER_TIME;
181                 private static IntPtr _NET_FRAME_EXTENTS;
182                 //private static IntPtr _NET_WM_PING;
183                 //private static IntPtr _NET_WM_SYNC_REQUEST;
184                 private static IntPtr _NET_SYSTEM_TRAY_S;
185                 //private static IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
186                 private static IntPtr _NET_SYSTEM_TRAY_OPCODE;
187                 private static IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
188                 private static IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
189                 private static IntPtr _XEMBED;
190                 private static IntPtr _XEMBED_INFO;
191                 private static IntPtr _MOTIF_WM_HINTS;
192                 private static IntPtr _NET_WM_STATE_SKIP_TASKBAR;
193                 private static IntPtr _NET_WM_STATE_ABOVE;
194                 private static IntPtr _NET_WM_STATE_MODAL;
195                 private static IntPtr _NET_WM_STATE_HIDDEN;
196                 private static IntPtr _NET_WM_CONTEXT_HELP;
197                 private static IntPtr _NET_WM_WINDOW_OPACITY;
198                 //private static IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
199                 //private static IntPtr _NET_WM_WINDOW_TYPE_DOCK;
200                 //private static IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
201                 //private static IntPtr _NET_WM_WINDOW_TYPE_MENU;
202                 private static IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
203                 //private static IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
204                 // private static IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
205                 private static IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
206                 private static IntPtr CLIPBOARD;
207                 private static IntPtr PRIMARY;
208                 //private static IntPtr DIB;
209                 private static IntPtr OEMTEXT;
210                 private static IntPtr UTF8_STRING;
211                 private static IntPtr UTF16_STRING;
212                 private static IntPtr RICHTEXTFORMAT;
213                 private static IntPtr TARGETS;
214
215                 // mouse hover message generation
216                 private static HoverStruct      HoverState;             //
217
218                 // double click message generation
219                 private static ClickStruct      ClickPending;           //
220
221                 // Support for mouse grab
222                 private static GrabStruct       Grab;                   //
223
224                 // State
225                 Point           mouse_position;         // Last position of mouse, in screen coords
226                 internal static MouseButtons    MouseState;             // Last state of mouse buttons
227                 internal static bool in_doevents;
228                 // 'Constants'
229                 private static int              DoubleClickInterval;    // msec; max interval between clicks to count as double click
230
231                 const EventMask SelectInputMask = (EventMask.ButtonPressMask | 
232                                                    EventMask.ButtonReleaseMask | 
233                                                    EventMask.KeyPressMask | 
234                                                    EventMask.KeyReleaseMask | 
235                                                    EventMask.EnterWindowMask | 
236                                                    EventMask.LeaveWindowMask |
237                                                    EventMask.ExposureMask |
238                                                    EventMask.FocusChangeMask |
239                                                    EventMask.PointerMotionMask | 
240                                                    EventMask.PointerMotionHintMask | 
241                                                    EventMask.SubstructureNotifyMask);
242
243                 static readonly object lockobj = new object ();
244
245                 // messages WaitForHwndMwssage is waiting on
246                 static Hashtable        messageHold;
247
248                 #endregion      // Local Variables
249                 #region Constructors
250                 private XplatUIX11() {
251                         // Handle singleton stuff first
252                         RefCount = 0;
253                         in_doevents = false;
254
255                         // Now regular initialization
256                         XlibLock = new object ();
257                         X11Keyboard.XlibLock = XlibLock;
258                         MessageQueues = Hashtable.Synchronized (new Hashtable(7));
259                         unattached_timer_list = ArrayList.Synchronized (new ArrayList (3));
260                         messageHold = Hashtable.Synchronized (new Hashtable(3));
261                         Clipboard = new ClipboardData ();
262                         XInitThreads();
263
264                         ErrorExceptions = false;
265
266                         // X11 Initialization
267                         SetDisplay(XOpenDisplay(IntPtr.Zero));
268                         X11DesktopColors.Initialize();
269
270                         
271                         // Disable keyboard autorepeat
272                         try {
273                                 XkbSetDetectableAutoRepeat (DisplayHandle, true,  IntPtr.Zero);
274                                 detectable_key_auto_repeat = true;
275                         } catch {
276                                 Console.Error.WriteLine ("Could not disable keyboard auto repeat, will attempt to disable manually.");
277                                 detectable_key_auto_repeat = false;
278                         }
279
280                         // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
281                         ErrorHandler = new XErrorHandler(HandleError);
282                         XSetErrorHandler(ErrorHandler);
283                 }
284
285                 ~XplatUIX11() {
286                         // Remove our display handle from S.D
287                         Graphics.FromHdcInternal (IntPtr.Zero);
288                 }
289
290                 #endregion      // Constructors
291
292                 #region Singleton Specific Code
293                 public static XplatUIX11 GetInstance() {
294                         lock (lockobj) {
295                                 if (Instance == null) {
296                                         Instance=new XplatUIX11();
297                                 }
298                                 RefCount++;
299                         }
300                         return Instance;
301                 }
302
303                 public int Reference {
304                         get {
305                                 return RefCount;
306                         }
307                 }
308                 #endregion
309
310                 #region Internal Properties
311                 internal static IntPtr Display {
312                         get {
313                                 return DisplayHandle;
314                         }
315
316                         set {
317                                 XplatUIX11.GetInstance().SetDisplay(value);
318                         }
319                 }
320
321                 internal static int Screen {
322                         get {
323                                 return ScreenNo;
324                         }
325
326                         set {
327                                 ScreenNo = value;
328                         }
329                 }
330
331                 internal static IntPtr RootWindowHandle {
332                         get {
333                                 return RootWindow;
334                         }
335
336                         set {
337                                 RootWindow = value;
338                         }
339                 }
340
341                 internal static IntPtr Visual {
342                         get {
343                                 return CustomVisual;
344                         }
345
346                         set {
347                                 CustomVisual = value;
348                         }
349                 }
350
351                 internal static IntPtr ColorMap {
352                         get {
353                                 return CustomColormap;
354                         }
355
356                         set {
357                                 CustomColormap = value;
358                         }
359                 }
360
361 #if DEBUG_shana
362                 internal static IntPtr DefaultColorMap {
363                         get {
364                                 return DefaultColormap;
365                         }
366                 }
367 #endif
368                 #endregion
369
370                 #region XExceptionClass
371                 internal class XException : ApplicationException {
372                         IntPtr          Display;
373                         IntPtr          ResourceID;
374                         IntPtr          Serial;
375                         XRequest        RequestCode;
376                         byte            ErrorCode;
377                         byte            MinorCode;
378
379                         public XException(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
380                                 this.Display = Display;
381                                 this.ResourceID = ResourceID;
382                                 this.Serial = Serial;
383                                 this.RequestCode = RequestCode;
384                                 this.ErrorCode = ErrorCode;
385                                 this.MinorCode = MinorCode;
386                         }
387
388                         public override string Message {
389                                 get {
390                                         return GetMessage(Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
391                                 }
392                         }
393
394                         public static string GetMessage(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
395                                 StringBuilder   sb;
396                                 string          x_error_text;
397                                 string          error;
398                                 string          hwnd_text;
399                                 string          control_text;
400                                 Hwnd            hwnd;
401                                 Control         c;
402
403                                 sb = new StringBuilder(160);
404                                 XGetErrorText(Display, ErrorCode, sb, sb.Capacity);
405                                 x_error_text = sb.ToString();
406                                 hwnd = Hwnd.ObjectFromHandle(ResourceID);
407                                 if (hwnd != null) {
408                                         hwnd_text = hwnd.ToString();
409                                         c = Control.FromHandle(hwnd.Handle);
410                                         if (c != null) {
411                                                 control_text = c.ToString();
412                                         } else {
413                                                 control_text = String.Format("<handle {0:X} non-existant>", hwnd.Handle.ToInt32());
414                                         }
415                                 } else {
416                                         hwnd_text = "<null>";
417                                         control_text = "<null>";
418                                 }
419
420
421                                 error = String.Format("\n  Error: {0}\n  Request:     {1:D} ({2})\n  Resource ID: 0x{3:X}\n  Serial:      {4}\n  Hwnd:        {5}\n  Control:     {6}", x_error_text, RequestCode, MinorCode, ResourceID.ToInt32(), Serial, hwnd_text, control_text);
422                                 return error;
423                         }
424                 }
425                 #endregion      // XExceptionClass
426
427                 #region Internal Methods
428                 internal void SetDisplay(IntPtr display_handle) {
429                         if (display_handle != IntPtr.Zero) {
430                                 Hwnd    hwnd;
431
432                                 if ((DisplayHandle != IntPtr.Zero) && (FosterParent != IntPtr.Zero)) {
433                                         hwnd = Hwnd.ObjectFromHandle(FosterParent);
434                                         XDestroyWindow(DisplayHandle, FosterParent);
435                                         hwnd.Dispose();
436                                 }
437
438                                 if (DisplayHandle != IntPtr.Zero) {
439                                         XCloseDisplay(DisplayHandle);
440                                 }
441
442                                 DisplayHandle=display_handle;
443
444                                 // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
445                                 // been hacked to do this for us.
446                                 Graphics.FromHdcInternal (DisplayHandle);
447
448                                 // query for the render extension so
449                                 // we can ignore the spurious
450                                 // BadPicture errors that are
451                                 // generated by cairo/render.
452                                 XQueryExtension (DisplayHandle, "RENDER",
453                                                  ref render_major_opcode, ref render_first_event, ref render_first_error);
454
455                                 // Debugging support
456                                 if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
457                                         XSynchronize(DisplayHandle, true);
458                                 }
459
460                                 if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
461                                         ErrorExceptions = true;
462                                 }
463
464                                 // Generic X11 setup
465                                 ScreenNo = XDefaultScreen(DisplayHandle);
466                                 RootWindow = XRootWindow(DisplayHandle, ScreenNo);
467                                 DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);
468
469                                 // Create the foster parent
470                                 // it is important that border_width is kept in synch with the other XCreateWindow calls
471                                 FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 0, UIntPtr.Zero, UIntPtr.Zero);
472                                 if (FosterParent==IntPtr.Zero) {
473                                         Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
474                                 }
475
476                                 DebugHelper.WriteLine ("FosterParent created 0x{0:x}", FosterParent.ToInt32());
477
478                                 hwnd = new Hwnd();
479                                 hwnd.Queue = ThreadQueue(Thread.CurrentThread);
480                                 hwnd.WholeWindow = FosterParent;
481                                 hwnd.ClientWindow = FosterParent;
482
483                                 // Create a HWND for RootWIndow as well, so our queue doesn't eat the events
484                                 hwnd = new Hwnd();
485                                 hwnd.Queue = ThreadQueue(Thread.CurrentThread);
486                                 hwnd.whole_window = RootWindow;
487                                 hwnd.ClientWindow = RootWindow;
488
489                                 // For sleeping on the X11 socket
490                                 listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
491                                 IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
492                                 listen.Bind(ep);
493                                 listen.Listen(1);
494
495                                 // To wake up when a timer is ready
496                                 network_buffer = new byte[10];
497
498                                 wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
499                                 wake.Connect(listen.LocalEndPoint);
500                                 wake_receive = listen.Accept();
501
502                                 #if __MonoCS__
503                                 pollfds = new Pollfd [2];
504                                 pollfds [0] = new Pollfd ();
505                                 pollfds [0].fd = XConnectionNumber (DisplayHandle);
506                                 pollfds [0].events = PollEvents.POLLIN;
507
508                                 pollfds [1] = new Pollfd ();
509                                 pollfds [1].fd = wake_receive.Handle.ToInt32 ();
510                                 pollfds [1].events = PollEvents.POLLIN;
511                                 #endif
512
513                                 Keyboard = new X11Keyboard(DisplayHandle, FosterParent);
514                                 Dnd = new X11Dnd (DisplayHandle, Keyboard);
515
516                                 DoubleClickInterval = 500;
517
518                                 HoverState.Interval = 500;
519                                 HoverState.Timer = new Timer();
520                                 HoverState.Timer.Enabled = false;
521                                 HoverState.Timer.Interval = HoverState.Interval;
522                                 HoverState.Timer.Tick += new EventHandler(MouseHover);
523                                 HoverState.Size = new Size(4, 4);
524                                 HoverState.X = -1;
525                                 HoverState.Y = -1;
526
527                                 ActiveWindow = IntPtr.Zero;
528                                 FocusWindow = IntPtr.Zero;
529                                 ModalWindows = new Stack(3);
530
531                                 MouseState = MouseButtons.None;
532                                 mouse_position = new Point(0, 0);
533
534                                 Caret.Timer = new Timer();
535                                 Caret.Timer.Interval = 500;             // FIXME - where should this number come from?
536                                 Caret.Timer.Tick += new EventHandler(CaretCallback);
537
538                                 SetupAtoms();
539
540                                 // Grab atom changes off the root window to catch certain WM events
541                                 XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int) (EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
542
543                                 // Handle any upcoming errors
544                                 ErrorHandler = new XErrorHandler(HandleError);
545                                 XSetErrorHandler(ErrorHandler);
546                         } else {
547                                 throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
548                         }
549                 }
550                 #endregion      // Internal Methods
551
552                 #region Private Methods
553                 private int unixtime() {
554                         TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
555
556                         return (int) t.TotalSeconds;
557                 }
558
559                 private static void SetupAtoms() {
560                         // make sure this array stays in sync with the statements below
561                         string [] atom_names = new string[] {
562                                 "WM_PROTOCOLS",
563                                 "WM_DELETE_WINDOW",
564                                 "WM_TAKE_FOCUS",
565                                 //"_NET_SUPPORTED",
566                                 //"_NET_CLIENT_LIST",
567                                 //"_NET_NUMBER_OF_DESKTOPS",
568                                 "_NET_DESKTOP_GEOMETRY",
569                                 //"_NET_DESKTOP_VIEWPORT",
570                                 "_NET_CURRENT_DESKTOP",
571                                 //"_NET_DESKTOP_NAMES",
572                                 "_NET_ACTIVE_WINDOW",
573                                 "_NET_WORKAREA",
574                                 //"_NET_SUPPORTING_WM_CHECK",
575                                 //"_NET_VIRTUAL_ROOTS",
576                                 //"_NET_DESKTOP_LAYOUT",
577                                 //"_NET_SHOWING_DESKTOP",
578                                 //"_NET_CLOSE_WINDOW",
579                                 //"_NET_MOVERESIZE_WINDOW",
580                                 //"_NET_WM_MOVERESIZE",
581                                 //"_NET_RESTACK_WINDOW",
582                                 //"_NET_REQUEST_FRAME_EXTENTS",
583                                 "_NET_WM_NAME",
584                                 //"_NET_WM_VISIBLE_NAME",
585                                 //"_NET_WM_ICON_NAME",
586                                 //"_NET_WM_VISIBLE_ICON_NAME",
587                                 //"_NET_WM_DESKTOP",
588                                 "_NET_WM_WINDOW_TYPE",
589                                 "_NET_WM_STATE",
590                                 //"_NET_WM_ALLOWED_ACTIONS",
591                                 //"_NET_WM_STRUT",
592                                 //"_NET_WM_STRUT_PARTIAL",
593                                 //"_NET_WM_ICON_GEOMETRY",
594                                 "_NET_WM_ICON",
595                                 //"_NET_WM_PID",
596                                 //"_NET_WM_HANDLED_ICONS",
597                                 "_NET_WM_USER_TIME",
598                                 "_NET_FRAME_EXTENTS",
599                                 //"_NET_WM_PING",
600                                 //"_NET_WM_SYNC_REQUEST",
601                                 "_NET_SYSTEM_TRAY_OPCODE",
602                                 //"_NET_SYSTEM_TRAY_ORIENTATION",
603                                 "_NET_WM_STATE_MAXIMIZED_HORZ",
604                                 "_NET_WM_STATE_MAXIMIZED_VERT",
605                                 "_NET_WM_STATE_HIDDEN",
606                                 "_XEMBED",
607                                 "_XEMBED_INFO",
608                                 "_MOTIF_WM_HINTS",
609                                 "_NET_WM_STATE_SKIP_TASKBAR",
610                                 "_NET_WM_STATE_ABOVE",
611                                 "_NET_WM_STATE_MODAL",
612                                 "_NET_WM_CONTEXT_HELP",
613                                 "_NET_WM_WINDOW_OPACITY",
614                                 //"_NET_WM_WINDOW_TYPE_DESKTOP",
615                                 //"_NET_WM_WINDOW_TYPE_DOCK",
616                                 //"_NET_WM_WINDOW_TYPE_TOOLBAR",
617                                 //"_NET_WM_WINDOW_TYPE_MENU",
618                                 "_NET_WM_WINDOW_TYPE_UTILITY",
619                                 // "_NET_WM_WINDOW_TYPE_DIALOG",
620                                 //"_NET_WM_WINDOW_TYPE_SPLASH",
621                                 "_NET_WM_WINDOW_TYPE_NORMAL",
622                                 "CLIPBOARD",
623                                 "PRIMARY",
624                                 "COMPOUND_TEXT",
625                                 "UTF8_STRING",
626                                 "UTF16_STRING",
627                                 "RICHTEXTFORMAT",
628                                 "TARGETS",
629                                 "_SWF_AsyncAtom",
630                                 "_SWF_PostMessageAtom",
631                                 "_SWF_HoverAtom" };
632
633                         IntPtr[] atoms = new IntPtr [atom_names.Length];;
634
635                         XInternAtoms (DisplayHandle, atom_names, atom_names.Length, false, atoms);
636
637                         int off = 0;
638                         WM_PROTOCOLS = atoms [off++];
639                         WM_DELETE_WINDOW = atoms [off++];
640                         WM_TAKE_FOCUS = atoms [off++];
641                         //_NET_SUPPORTED = atoms [off++];
642                         //_NET_CLIENT_LIST = atoms [off++];
643                         //_NET_NUMBER_OF_DESKTOPS = atoms [off++];
644                         _NET_DESKTOP_GEOMETRY = atoms [off++];
645                         //_NET_DESKTOP_VIEWPORT = atoms [off++];
646                         _NET_CURRENT_DESKTOP = atoms [off++];
647                         //_NET_DESKTOP_NAMES = atoms [off++];
648                         _NET_ACTIVE_WINDOW = atoms [off++];
649                         _NET_WORKAREA = atoms [off++];
650                         //_NET_SUPPORTING_WM_CHECK = atoms [off++];
651                         //_NET_VIRTUAL_ROOTS = atoms [off++];
652                         //_NET_DESKTOP_LAYOUT = atoms [off++];
653                         //_NET_SHOWING_DESKTOP = atoms [off++];
654                         //_NET_CLOSE_WINDOW = atoms [off++];
655                         //_NET_MOVERESIZE_WINDOW = atoms [off++];
656                         //_NET_WM_MOVERESIZE = atoms [off++];
657                         //_NET_RESTACK_WINDOW = atoms [off++];
658                         //_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
659                         _NET_WM_NAME = atoms [off++];
660                         //_NET_WM_VISIBLE_NAME = atoms [off++];
661                         //_NET_WM_ICON_NAME = atoms [off++];
662                         //_NET_WM_VISIBLE_ICON_NAME = atoms [off++];
663                         //_NET_WM_DESKTOP = atoms [off++];
664                         _NET_WM_WINDOW_TYPE = atoms [off++];
665                         _NET_WM_STATE = atoms [off++];
666                         //_NET_WM_ALLOWED_ACTIONS = atoms [off++];
667                         //_NET_WM_STRUT = atoms [off++];
668                         //_NET_WM_STRUT_PARTIAL = atoms [off++];
669                         //_NET_WM_ICON_GEOMETRY = atoms [off++];
670                         _NET_WM_ICON = atoms [off++];
671                         //_NET_WM_PID = atoms [off++];
672                         //_NET_WM_HANDLED_ICONS = atoms [off++];
673                         _NET_WM_USER_TIME = atoms [off++];
674                         _NET_FRAME_EXTENTS = atoms [off++];
675                         //_NET_WM_PING = atoms [off++];
676                         //_NET_WM_SYNC_REQUEST = atoms [off++];
677                         _NET_SYSTEM_TRAY_OPCODE = atoms [off++];
678                         //_NET_SYSTEM_TRAY_ORIENTATION = atoms [off++];
679                         _NET_WM_STATE_MAXIMIZED_HORZ = atoms [off++];
680                         _NET_WM_STATE_MAXIMIZED_VERT = atoms [off++];
681                         _NET_WM_STATE_HIDDEN = atoms [off++];
682                         _XEMBED = atoms [off++];
683                         _XEMBED_INFO = atoms [off++];
684                         _MOTIF_WM_HINTS = atoms [off++];
685                         _NET_WM_STATE_SKIP_TASKBAR = atoms [off++];
686                         _NET_WM_STATE_ABOVE = atoms [off++];
687                         _NET_WM_STATE_MODAL = atoms [off++];
688                         _NET_WM_CONTEXT_HELP = atoms [off++];
689                         _NET_WM_WINDOW_OPACITY = atoms [off++];
690                         //_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
691                         //_NET_WM_WINDOW_TYPE_DOCK = atoms [off++];
692                         //_NET_WM_WINDOW_TYPE_TOOLBAR = atoms [off++];
693                         //_NET_WM_WINDOW_TYPE_MENU = atoms [off++];
694                         _NET_WM_WINDOW_TYPE_UTILITY = atoms [off++];
695                         // _NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
696                         //_NET_WM_WINDOW_TYPE_SPLASH = atoms [off++];
697                         _NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
698                         CLIPBOARD = atoms [off++];
699                         PRIMARY = atoms [off++];
700                         OEMTEXT = atoms [off++];
701                         UTF8_STRING = atoms [off++];
702                         UTF16_STRING = atoms [off++];
703                         RICHTEXTFORMAT = atoms [off++];
704                         TARGETS = atoms [off++];
705                         AsyncAtom = atoms [off++];
706                         PostAtom = atoms [off++];
707                         HoverState.Atom = atoms [off++];
708
709                         //DIB = (IntPtr)Atom.XA_PIXMAP;
710                         _NET_SYSTEM_TRAY_S = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
711                 }
712
713                 private void GetSystrayManagerWindow() {
714                         XGrabServer(DisplayHandle);
715                         SystrayMgrWindow = XGetSelectionOwner(DisplayHandle, _NET_SYSTEM_TRAY_S);
716                         XUngrabServer(DisplayHandle);
717                         XFlush(DisplayHandle);
718                 }
719
720                 private void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
721                         XEvent  xev;
722
723                         xev = new XEvent();
724                         xev.ClientMessageEvent.type = XEventName.ClientMessage;
725                         xev.ClientMessageEvent.send_event = true;
726                         xev.ClientMessageEvent.window = window;
727                         xev.ClientMessageEvent.message_type = message_type;
728                         xev.ClientMessageEvent.format = 32;
729                         xev.ClientMessageEvent.ptr1 = l0;
730                         xev.ClientMessageEvent.ptr2 = l1;
731                         xev.ClientMessageEvent.ptr3 = l2;
732                         XSendEvent(DisplayHandle, RootWindow, false, new IntPtr ((int) (EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask)), ref xev);
733                 }
734
735                 private void SendNetClientMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
736                         XEvent  xev;
737
738                         xev = new XEvent();
739                         xev.ClientMessageEvent.type = XEventName.ClientMessage;
740                         xev.ClientMessageEvent.send_event = true;
741                         xev.ClientMessageEvent.window = window;
742                         xev.ClientMessageEvent.message_type = message_type;
743                         xev.ClientMessageEvent.format = 32;
744                         xev.ClientMessageEvent.ptr1 = l0;
745                         xev.ClientMessageEvent.ptr2 = l1;
746                         xev.ClientMessageEvent.ptr3 = l2;
747                         XSendEvent(DisplayHandle, window, false, new IntPtr ((int)EventMask.NoEventMask), ref xev);
748                 }
749
750                 // For WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN, WM_XBUTTONDOWN
751                 //     WM_CREATE and WM_DESTROY causes
752                 void SendParentNotify(IntPtr child, Msg cause, int x, int y)
753                 {       
754                         Hwnd hwnd;
755                         
756                         if (child == IntPtr.Zero) {
757                                 return;
758                         }
759                         
760                         hwnd = Hwnd.GetObjectFromWindow (child);
761                         
762                         if (hwnd == null) {
763                                 return;
764                         }
765                         
766                         if (hwnd.Handle == IntPtr.Zero) {
767                                 return;
768                         }
769                         
770                         if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
771                                 return;
772                         }
773                         
774                         if (hwnd.Parent == null) {
775                                 return;
776                         }
777                         
778                         if (hwnd.Parent.Handle == IntPtr.Zero) {
779                                 return;
780                         }
781
782                         if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
783                                 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
784                         } else {
785                                 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
786                         }
787                         
788                         SendParentNotify (hwnd.Parent.Handle, cause, x, y);
789                 }
790                 
791                 bool StyleSet (int s, WindowStyles ws)
792                 {
793                         return (s & (int)ws) == (int)ws;
794                 }
795
796                 bool ExStyleSet (int ex, WindowExStyles exws)
797                 {
798                         return (ex & (int)exws) == (int)exws;
799                 }
800
801                 internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd)
802                 {
803                         return TranslateClientRectangleToXClientRectangle (hwnd, Control.FromHandle (hwnd.Handle));
804                 }
805                 
806                 internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd, Control ctrl)
807                 {
808                         /* 
809                          * If this is a form with no window manager, X is handling all the border and caption painting
810                          * so remove that from the area (since the area we set of the window here is the part of the window 
811                          * we're painting in only)
812                          */
813                         Rectangle rect = hwnd.ClientRect;
814                         Form form = ctrl as Form;
815                         CreateParams cp = null;
816
817                         if (form != null)
818                                 cp = form.GetCreateParams ();
819
820                         if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
821                                 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
822                                 Rectangle xrect = rect;
823
824                                 xrect.Y -= borders.top;
825                                 xrect.X -= borders.left;
826                                 xrect.Width += borders.left + borders.right;
827                                 xrect.Height += borders.top + borders.bottom;
828
829                                 rect = xrect;
830                         }
831                         
832                         if (rect.Width < 1 || rect.Height < 1) {
833                                 rect.Width = 1;
834                                 rect.Height = 1;
835                                 rect.X = -5;
836                                 rect.Y = -5;
837                         }
838                         
839                         return rect;
840                 }
841
842                 internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp)
843                 {
844                         return TranslateWindowSizeToXWindowSize (cp, new Size (cp.Width, cp.Height));
845                 }
846
847                 internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp, Size size)
848                 {
849                         /* 
850                          * If this is a form with no window manager, X is handling all the border and caption painting
851                          * so remove that from the area (since the area we set of the window here is the part of the window 
852                          * we're painting in only)
853                          */
854                         Form form = cp.control as Form;
855                         if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
856                                 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
857                                 Size xrect = size;
858
859                                 xrect.Width -= borders.left + borders.right;
860                                 xrect.Height -= borders.top + borders.bottom;
861
862                                 size = xrect;
863                         }
864                         if (size.Height == 0)
865                                 size.Height = 1;
866                         if (size.Width == 0)
867                                 size.Width = 1;
868                         return size;
869                 }
870
871                 internal static Size TranslateXWindowSizeToWindowSize (CreateParams cp, int xWidth, int xHeight)
872                 {
873                         /* 
874                          * If this is a form with no window manager, X is handling all the border and caption painting
875                          * so remove that from the area (since the area we set of the window here is the part of the window 
876                          * we're painting in only)
877                          */
878                         Size rect = new Size (xWidth, xHeight);
879                         Form form = cp.control as Form;
880                         if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
881                                 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
882                                 Size xrect = rect;
883
884                                 xrect.Width += borders.left + borders.right;
885                                 xrect.Height += borders.top + borders.bottom;
886
887                                 rect = xrect;
888                         }
889                         return rect;
890                 }
891                 
892                 internal static Point GetTopLevelWindowLocation (Hwnd hwnd)
893                 {
894                         IntPtr dummy; 
895                         int x, y;
896                         Hwnd.Borders frame;
897
898                         XTranslateCoordinates (DisplayHandle, hwnd.whole_window, RootWindow, 0, 0, out x, out y, out dummy);
899                         frame = FrameExtents (hwnd.whole_window);
900
901                         x -= frame.left;
902                         y -= frame.top;
903                         
904                         return new Point (x, y);
905                 }
906                 
907                 private void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out bool border_static, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
908
909                         caption_height = 0;
910                         tool_caption_height = 19;
911                         border_static = false;
912
913                         if (StyleSet (Style, WindowStyles.WS_CHILD)) {
914                                 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
915                                         border_style = FormBorderStyle.Fixed3D;
916                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
917                                         border_style = FormBorderStyle.Fixed3D;
918                                         border_static = true;
919                                 } else if (!StyleSet (Style, WindowStyles.WS_BORDER)) {
920                                         border_style = FormBorderStyle.None;
921                                 } else {
922                                         border_style = FormBorderStyle.FixedSingle;
923                                 }
924                                 title_style = TitleStyle.None;
925                                 
926                                 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
927                                         caption_height = 19;
928                                         if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
929                                                 title_style = TitleStyle.Tool;
930                                         } else {
931                                                 title_style = TitleStyle.Normal;
932                                         }
933                                 }
934
935                                 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_MDICHILD)) {
936                                         caption_height = 19;
937
938                                         if (StyleSet (Style, WindowStyles.WS_OVERLAPPEDWINDOW) ||
939                                             ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
940                                                 border_style = (FormBorderStyle) 0xFFFF;
941                                         } else {
942                                                 border_style = FormBorderStyle.None;
943                                         }
944                                 }
945
946                         } else {
947                                 title_style = TitleStyle.None;
948                                 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
949                                         if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
950                                                 title_style = TitleStyle.Tool;
951                                         } else {
952                                                 title_style = TitleStyle.Normal;
953                                         }
954                                 }
955
956                                 border_style = FormBorderStyle.None;
957
958                                 if (StyleSet (Style, WindowStyles.WS_THICKFRAME)) {
959                                         if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
960                                                 border_style = FormBorderStyle.SizableToolWindow;
961                                         } else {
962                                                 border_style = FormBorderStyle.Sizable;
963                                         }
964                                 } else {
965                                         if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
966                                                 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
967                                                         border_style = FormBorderStyle.Fixed3D;
968                                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
969                                                         border_style = FormBorderStyle.Fixed3D;
970                                                         border_static = true;
971                                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
972                                                         border_style = FormBorderStyle.FixedDialog;
973                                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
974                                                         border_style = FormBorderStyle.FixedToolWindow;
975                                                 } else if (StyleSet (Style, WindowStyles.WS_BORDER)) {
976                                                         border_style = FormBorderStyle.FixedSingle;
977                                                 }
978                                         } else {
979                                                 if (StyleSet (Style, WindowStyles.WS_BORDER)) {
980                                                         border_style = FormBorderStyle.FixedSingle;
981                                                 }
982                                         }
983                                 }
984                         }
985                 }
986
987                 private void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
988                         DeriveStyles(cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.border_static, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
989                 }
990
991                 private void SetWMStyles(Hwnd hwnd, CreateParams cp) {
992                         MotifWmHints            mwmHints;
993                         MotifFunctions          functions;
994                         MotifDecorations        decorations;
995                         int[]                   atoms;
996                         int                     atom_count;
997                         Rectangle               client_rect;
998                         Form                    form;
999                         IntPtr                  window_type;
1000                         bool                    hide_from_taskbar;
1001                         IntPtr                  transient_for_parent;
1002                         
1003                         // Windows we manage ourselves don't need WM window styles.
1004                         if (cp.HasWindowManager && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
1005                                 return;
1006                         }
1007
1008                         atoms = new int[8];
1009                         mwmHints = new MotifWmHints();
1010                         functions = 0;
1011                         decorations = 0;
1012                         window_type = _NET_WM_WINDOW_TYPE_NORMAL;
1013                         transient_for_parent = IntPtr.Zero;
1014
1015                         mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
1016                         mwmHints.functions = (IntPtr)0;
1017                         mwmHints.decorations = (IntPtr)0;
1018
1019                         form = cp.control as Form;
1020
1021                         if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
1022                                 /* tool windows get no window manager
1023                                    decorations.
1024                                 */
1025
1026                                 /* just because the window doesn't get any decorations doesn't
1027                                    mean we should disable the functions.  for instance, without
1028                                    MotifFunctions.Maximize, changing the windowstate to Maximized
1029                                    is ignored by metacity. */
1030                                 functions |= MotifFunctions.Move | MotifFunctions.Resize | MotifFunctions.Minimize | MotifFunctions.Maximize;
1031                         } else if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
1032                                 /* allow borderless window to be maximized */
1033                                 functions |= MotifFunctions.All | MotifFunctions.Resize;
1034                         } else {
1035                                 if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
1036                                         functions |= MotifFunctions.Move;
1037                                         decorations |= MotifDecorations.Title | MotifDecorations.Menu;
1038                                 }
1039
1040                                 if (StyleSet (cp.Style, WindowStyles.WS_THICKFRAME)) {
1041                                         functions |= MotifFunctions.Move | MotifFunctions.Resize;
1042                                         decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
1043                                 }
1044
1045                                 if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
1046                                         functions |= MotifFunctions.Minimize;
1047                                         decorations |= MotifDecorations.Minimize;
1048                                 }
1049
1050                                 if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
1051                                         functions |= MotifFunctions.Maximize;
1052                                         decorations |= MotifDecorations.Maximize;
1053                                 }
1054
1055                                 if (StyleSet (cp.Style, WindowStyles.WS_SIZEBOX)) {
1056                                         functions |= MotifFunctions.Resize;
1057                                         decorations |= MotifDecorations.ResizeH;
1058                                 }
1059
1060                                 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
1061                                         decorations |= MotifDecorations.Border;
1062                                 }
1063
1064                                 if (StyleSet (cp.Style, WindowStyles.WS_BORDER)) {
1065                                         decorations |= MotifDecorations.Border;
1066                                 }
1067                         
1068                                 if (StyleSet (cp.Style, WindowStyles.WS_DLGFRAME)) {
1069                                         decorations |= MotifDecorations.Border;
1070                                 }
1071
1072                                 if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
1073                                         functions |= MotifFunctions.Close;
1074                                 }
1075                                 else {
1076                                         functions &= ~(MotifFunctions.Maximize | MotifFunctions.Minimize | MotifFunctions.Close);
1077                                         decorations &= ~(MotifDecorations.Menu | MotifDecorations.Maximize | MotifDecorations.Minimize);
1078                                         if (cp.Caption == "") {
1079                                                 functions &= ~MotifFunctions.Move;
1080                                                 decorations &= ~(MotifDecorations.Title | MotifDecorations.ResizeH);
1081                                         }
1082                                 }
1083                         }
1084
1085                         if ((functions & MotifFunctions.Resize) == 0) {
1086                                 hwnd.fixed_size = true;
1087                                 Rectangle fixed_rectangle = new Rectangle (cp.X, cp.Y, cp.Width, cp.Height);
1088                                 SetWindowMinMax(hwnd.Handle, fixed_rectangle, fixed_rectangle.Size, fixed_rectangle.Size, cp);
1089                         } else {
1090                                 hwnd.fixed_size = false;
1091                         }
1092
1093                         mwmHints.functions = (IntPtr)functions;
1094                         mwmHints.decorations = (IntPtr)decorations;
1095
1096 #if debug
1097                         Console.WriteLine ("SetWMStyles ({0}, {1}) functions = {2}, decorations = {3}", hwnd, cp, functions, decorations);
1098 #endif
1099
1100                         if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
1101                                 // needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
1102                                 // and get those windows in front of their parents
1103                                 window_type = _NET_WM_WINDOW_TYPE_UTILITY;
1104                         } else {
1105                                 window_type = _NET_WM_WINDOW_TYPE_NORMAL;
1106                         }
1107                         
1108                         if (!cp.IsSet (WindowExStyles.WS_EX_APPWINDOW)) {
1109                                 hide_from_taskbar = true;
1110                         } else if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW) &&  form != null && form.Parent != null && !form.ShowInTaskbar) {
1111                                 hide_from_taskbar = true;
1112                         } else {
1113                                 hide_from_taskbar = false;
1114                         }
1115
1116                         if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
1117                                 if (form != null && !hwnd.reparented) {
1118                                         if (form.Owner != null && form.Owner.Handle != IntPtr.Zero) {
1119                                                 Hwnd owner_hwnd = Hwnd.ObjectFromHandle (form.Owner.Handle);
1120                                                 if (owner_hwnd != null)
1121                                                         transient_for_parent = owner_hwnd.whole_window;
1122                                         }
1123                                 }
1124                         } 
1125                         if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
1126                                 transient_for_parent = hwnd.parent.whole_window;
1127                         }
1128                         
1129                         FormWindowState current_state = GetWindowState (hwnd.Handle);
1130                         if (current_state == (FormWindowState)(-1))
1131                                 current_state = FormWindowState.Normal;
1132
1133                         client_rect = TranslateClientRectangleToXClientRectangle (hwnd);
1134
1135                         lock (XlibLock) {
1136                                 atom_count = 0;
1137
1138                                 atoms [0] = window_type.ToInt32 ();
1139                                 XChangeProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
1140
1141                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropertyMode.Replace, ref mwmHints, 5);
1142
1143                                 if (transient_for_parent != IntPtr.Zero) {
1144                                         XSetTransientForHint (DisplayHandle, hwnd.whole_window, transient_for_parent);
1145                                 }
1146
1147                                 MoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
1148
1149                                 if (hide_from_taskbar) {
1150                                         /* this line keeps the window from showing up in gnome's taskbar */
1151                                         atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
1152                                 }
1153                                 /* we need to add these atoms in the
1154                                  * event we're maximized, since we're
1155                                  * replacing the existing
1156                                  * _NET_WM_STATE here.  If we don't
1157                                  * add them, future calls to
1158                                  * GetWindowState will return Normal
1159                                  * for a window which is maximized. */
1160                                 if (current_state == FormWindowState.Maximized) {
1161                                         atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_HORZ.ToInt32();
1162                                         atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_VERT.ToInt32();
1163                                 }
1164                                 
1165                                 if (form != null && form.Modal) {
1166                                         atoms[atom_count++] = _NET_WM_STATE_MODAL.ToInt32 ();
1167                                 }
1168                                 
1169                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
1170
1171                                 atom_count = 0;
1172                                 IntPtr[] atom_ptrs = new IntPtr[2];
1173                                 atom_ptrs[atom_count++] = WM_DELETE_WINDOW;
1174                                 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_CONTEXTHELP)) {
1175                                         atom_ptrs[atom_count++] = _NET_WM_CONTEXT_HELP;
1176                                 }
1177
1178                                 XSetWMProtocols(DisplayHandle, hwnd.whole_window, atom_ptrs, atom_count);
1179                         }
1180                 }
1181
1182                 private void SetIcon(Hwnd hwnd, Icon icon)
1183                 {
1184                         if (icon == null) {
1185                                 // XXX
1186
1187                                 // This really needs to do whatever it
1188                                 // takes to remove the window manager
1189                                 // menu, not just delete the ICON
1190                                 // property.  This will cause metacity
1191                                 // to use the "no icon set" icon, and
1192                                 // we'll still have an icon.
1193                                 XDeleteProperty (DisplayHandle, hwnd.whole_window, _NET_WM_ICON);
1194                         }
1195                         else {
1196                                 Bitmap          bitmap;
1197                                 int             size;
1198                                 IntPtr[]        data;
1199                                 int             index;
1200
1201                                 bitmap = icon.ToBitmap();
1202                                 index = 0;
1203                                 size = bitmap.Width * bitmap.Height + 2;
1204                                 data = new IntPtr[size];
1205
1206                                 data[index++] = (IntPtr)bitmap.Width;
1207                                 data[index++] = (IntPtr)bitmap.Height;
1208
1209                                 for (int y = 0; y < bitmap.Height; y++) {
1210                                         for (int x = 0; x < bitmap.Width; x++) {
1211                                                 data[index++] = (IntPtr)bitmap.GetPixel (x, y).ToArgb ();
1212                                         }
1213                                 }
1214
1215                                 XChangeProperty (DisplayHandle, hwnd.whole_window,
1216                                                  _NET_WM_ICON, (IntPtr)Atom.XA_CARDINAL, 32,
1217                                                  PropertyMode.Replace, data, size);
1218                         }
1219                 }
1220
1221                 private void WakeupMain () {
1222                         wake.Send (new byte [] { 0xFF });
1223                 }
1224
1225                 private XEventQueue ThreadQueue(Thread thread) {
1226                         XEventQueue     queue;
1227
1228                         queue = (XEventQueue)MessageQueues[thread];
1229                         if (queue == null) {
1230                                 queue = new XEventQueue(thread);
1231                                 MessageQueues[thread] = queue;
1232                         }
1233
1234                         return queue;
1235                 }
1236
1237                 private void TranslatePropertyToClipboard(IntPtr property) {
1238                         IntPtr                  actual_atom;
1239                         int                     actual_format;
1240                         IntPtr                  nitems;
1241                         IntPtr                  bytes_after;
1242                         IntPtr                  prop = IntPtr.Zero;
1243
1244                         Clipboard.Item = null;
1245
1246                         XGetWindowProperty(DisplayHandle, FosterParent, property, IntPtr.Zero, new IntPtr (0x7fffffff), true, (IntPtr)Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1247
1248                         if ((long)nitems > 0) {
1249                                 if (property == (IntPtr)Atom.XA_STRING) {
1250                                         Clipboard.Item = Marshal.PtrToStringAnsi(prop);
1251                                 } else if (property == (IntPtr)Atom.XA_BITMAP) {
1252                                         // FIXME - convert bitmap to image
1253                                 } else if (property == (IntPtr)Atom.XA_PIXMAP) {
1254                                         // FIXME - convert pixmap to image
1255                                 } else if (property == OEMTEXT) {
1256                                         Clipboard.Item = Marshal.PtrToStringAnsi(prop);
1257                                 } else if (property == UTF8_STRING) {
1258                                         byte [] buffer = new byte [(int)nitems];
1259                                         for (int i = 0; i < (int)nitems; i++)
1260                                                 buffer [i] = Marshal.ReadByte (prop, i);
1261                                         Clipboard.Item = Encoding.UTF8.GetString (buffer);
1262                                 } else if (property == UTF16_STRING) {
1263                                         Clipboard.Item = Marshal.PtrToStringUni (prop, Encoding.Unicode.GetMaxCharCount ((int)nitems));
1264                                 } else if (property == RICHTEXTFORMAT)
1265                                         Clipboard.Item = Marshal.PtrToStringAnsi(prop);
1266                                 else if (DataFormats.ContainsFormat (property.ToInt32 ())) {
1267                                         if (DataFormats.GetFormat (property.ToInt32 ()).is_serializable) {
1268                                                 MemoryStream memory_stream = new MemoryStream ((int)nitems);
1269                                                 for (int i = 0; i < (int)nitems; i++)
1270                                                         memory_stream.WriteByte (Marshal.ReadByte (prop, i));
1271
1272                                                 memory_stream.Position = 0;
1273                                                 BinaryFormatter formatter = new BinaryFormatter ();
1274                                                 Clipboard.Item = formatter.Deserialize (memory_stream);
1275                                                 memory_stream.Close ();
1276                                         }
1277                                 }
1278
1279                                 XFree(prop);
1280                         }
1281                 }
1282
1283                 private void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
1284                         // Don't waste time
1285                         if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
1286                                 return;
1287                         }
1288
1289                         // Keep the invalid area as small as needed
1290                         if ((x + width) > hwnd.width) {
1291                                 width = hwnd.width - x;
1292                         }
1293
1294                         if ((y + height) > hwnd.height) {
1295                                 height = hwnd.height - y;
1296                         }
1297
1298                         if (client) {
1299                                 hwnd.AddInvalidArea(x, y, width, height);
1300                                 if (!hwnd.expose_pending) {
1301                                         if (!hwnd.nc_expose_pending) {
1302                                                 hwnd.Queue.Paint.Enqueue(hwnd);
1303                                         }
1304                                         hwnd.expose_pending = true;
1305                                 }
1306                         } else {
1307                                 hwnd.AddNcInvalidArea (x, y, width, height);
1308                                 
1309                                 if (!hwnd.nc_expose_pending) {
1310                                         if (!hwnd.expose_pending) {
1311                                                 hwnd.Queue.Paint.Enqueue(hwnd);
1312                                         }
1313                                         hwnd.nc_expose_pending = true;
1314                                 }
1315                         }
1316                 }
1317
1318                 private static Hwnd.Borders FrameExtents (IntPtr window)
1319                 {
1320                         IntPtr actual_atom;
1321                         int actual_format;
1322                         IntPtr nitems;
1323                         IntPtr bytes_after;
1324                         IntPtr prop = IntPtr.Zero;
1325                         Hwnd.Borders rect = new Hwnd.Borders ();
1326
1327                         XGetWindowProperty (DisplayHandle, window, _NET_FRAME_EXTENTS, IntPtr.Zero, new IntPtr (16), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1328                         if (prop != IntPtr.Zero) {
1329                                 if (nitems.ToInt32 () == 4) {
1330                                         rect.left = Marshal.ReadInt32 (prop, 0);
1331                                         rect.right = Marshal.ReadInt32 (prop, IntPtr.Size);
1332                                         rect.top = Marshal.ReadInt32 (prop, 2 * IntPtr.Size);
1333                                         rect.bottom = Marshal.ReadInt32 (prop, 3 * IntPtr.Size);
1334                                 }
1335                                 XFree (prop);
1336                         }
1337                         
1338                         return rect;
1339                 }
1340
1341                 private void AddConfigureNotify (XEvent xevent) {
1342                         Hwnd    hwnd;
1343
1344                         hwnd = Hwnd.GetObjectFromWindow(xevent.ConfigureEvent.window);
1345
1346                         // Don't waste time
1347                         if (hwnd == null || hwnd.zombie) {
1348                                 return;
1349                         }
1350                         if ((xevent.ConfigureEvent.window == hwnd.whole_window)/* && (xevent.ConfigureEvent.window == xevent.ConfigureEvent.xevent)*/) {
1351                                 if (hwnd.parent == null) {
1352                                         // The location given by the event is not reliable between different wm's, 
1353                                         // so use an alternative way of getting it.
1354                                         Point location = GetTopLevelWindowLocation (hwnd);
1355                                         hwnd.x = location.X;
1356                                         hwnd.y = location.Y;
1357                                 }
1358
1359                                 // XXX this sucks.  this isn't thread safe
1360                                 Control ctrl = Control.FromHandle (hwnd.Handle);
1361                                 Size TranslatedSize;
1362                                 if (ctrl != null) {
1363                                         TranslatedSize = TranslateXWindowSizeToWindowSize (ctrl.GetCreateParams (), xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
1364                                 } else {
1365                                         TranslatedSize = new Size (xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
1366                                 }
1367                                 hwnd.width = TranslatedSize.Width;
1368                                 hwnd.height = TranslatedSize.Height;
1369                                 hwnd.ClientRect = Rectangle.Empty;
1370
1371 #if debug
1372                                 Console.WriteLine ("AddConfigureNotify (hwnd.Handle = {1}, final hwnd.rect = {0}, reported rect={2})", new Rectangle (hwnd.x, hwnd.y, hwnd.width, hwnd.height), hwnd.Handle, new Rectangle (xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.width));
1373 #endif                  
1374                                 lock (hwnd.configure_lock) {
1375                                         if (!hwnd.configure_pending) {
1376                                                 hwnd.Queue.EnqueueLocked (xevent);
1377                                                 hwnd.configure_pending = true;
1378                                         }
1379                                 }
1380                         }
1381                         // We drop configure events for Client windows
1382                 }
1383
1384                 private void ShowCaret() {
1385                         if ((Caret.gc == IntPtr.Zero) || Caret.On) {
1386                                 return;
1387                         }
1388                         Caret.On = true;
1389
1390                         lock (XlibLock) {
1391                                 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1392                         }
1393                 }
1394
1395                 private void HideCaret() {
1396                         if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
1397                                 return;
1398                         }
1399                         Caret.On = false;
1400
1401                         lock (XlibLock) {
1402                                 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1403                         }
1404                 }
1405
1406                 private int NextTimeout (ArrayList timers, DateTime now) {
1407                         int timeout = 0; 
1408
1409                         foreach (Timer timer in timers) {
1410                                 int next = (int) (timer.Expires - now).TotalMilliseconds;
1411                                 if (next < 0) {
1412                                         return 0; // Have a timer that has already expired
1413                                 }
1414
1415                                 if (next < timeout) {
1416                                         timeout = next;
1417                                 }
1418                         }
1419                         if (timeout < Timer.Minimum) {
1420                                 timeout = Timer.Minimum;
1421                         }
1422
1423                         if (timeout > 1000)
1424                                 timeout = 1000;
1425                         return timeout;
1426                 }
1427
1428                 private void CheckTimers (ArrayList timers, DateTime now) {
1429                         int count;
1430
1431                         count = timers.Count;
1432
1433                         if (count == 0)
1434                                 return;
1435
1436                         for (int i = 0; i < timers.Count; i++) {
1437                                 Timer timer;
1438
1439                                 timer = (Timer) timers [i];
1440
1441                                 if (timer.Enabled && timer.Expires <= now && !timer.Busy) {
1442                                         // Timer ticks:
1443                                         //  - Before MainForm.OnLoad if DoEvents () is called.
1444                                         //  - After MainForm.OnLoad if not.
1445                                         //
1446                                         if (in_doevents ||
1447                                             (Application.MWFThread.Current.Context != null && 
1448                                              (Application.MWFThread.Current.Context.MainForm == null || 
1449                                               Application.MWFThread.Current.Context.MainForm.IsLoaded))) {
1450                                                 timer.Busy = true;
1451                                                 timer.Update (now);
1452                                                 timer.FireTick ();
1453                                                 timer.Busy = false;
1454                                         }
1455                                 }
1456                         }
1457                 }
1458
1459                 private void WaitForHwndMessage (Hwnd hwnd, Msg message) {
1460                         WaitForHwndMessage (hwnd, message, false);
1461
1462                 }
1463
1464                 private void WaitForHwndMessage (Hwnd hwnd, Msg message, bool process) {
1465                         MSG msg = new MSG ();
1466                         XEventQueue queue;
1467
1468                         queue = ThreadQueue(Thread.CurrentThread);
1469
1470                         queue.DispatchIdle = false;
1471
1472                         bool done = false;
1473                         string key = hwnd.Handle + ":" + message;
1474                         if (!messageHold.ContainsKey (key))     
1475                                 messageHold.Add (key, 1);
1476                         else
1477                                 messageHold[key] = ((int)messageHold[key]) + 1;
1478                         
1479                                         
1480                         do {
1481
1482                                 DebugHelper.WriteLine  ("Waiting for message " + message + " on hwnd " + String.Format("0x{0:x}", hwnd.Handle.ToInt32 ()));
1483                                 DebugHelper.Indent ();
1484                                 
1485                                 if (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
1486                                         if ((Msg)msg.message == Msg.WM_QUIT) {
1487                                                 PostQuitMessage (0);
1488                                                 done = true;
1489                                         }
1490                                         else {
1491                                                 
1492                                                 DebugHelper.WriteLine  ("PeekMessage got " + msg);
1493                                                 
1494                                                 if (msg.hwnd == hwnd.Handle) {
1495                                                         if ((Msg)msg.message == message) {
1496                                                                 if (process) {
1497                                                                         TranslateMessage (ref msg);
1498                                                                         DispatchMessage (ref msg);
1499                                                                 }
1500                                                                 break;
1501                                                         }
1502                                                         else if ((Msg)msg.message == Msg.WM_DESTROY)
1503                                                                 done = true;
1504                                                 }
1505
1506                                                 TranslateMessage (ref msg);
1507                                                 DispatchMessage (ref msg);
1508                                         }
1509                                 }
1510                                 
1511                                 done = !messageHold.ContainsKey (key) || ((int)messageHold[key] < 1) || done;
1512                         } while (!done);
1513                                                 
1514                         messageHold.Remove (key);
1515
1516                         DebugHelper.Unindent ();
1517                         DebugHelper.WriteLine  ("Finished waiting for " + key);                 
1518
1519                         queue.DispatchIdle = true;
1520
1521                 }
1522
1523                 private void MapWindow(Hwnd hwnd, WindowType windows) {
1524                         if (!hwnd.mapped) {
1525                                 Form f = Control.FromHandle(hwnd.Handle) as Form;
1526                                 if (f != null) {
1527                                         if (f.WindowState == FormWindowState.Normal) {
1528                                                 f.waiting_showwindow = true;
1529                                                 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
1530                                         }
1531                                 }
1532
1533                                 // it's possible that our Hwnd is no
1534                                 // longer valid after making that
1535                                 // SendMessage call, so check here.
1536                                 if (hwnd.zombie)
1537                                         return;
1538
1539                                 if ((windows & WindowType.Whole) != 0) {
1540                                         XMapWindow(DisplayHandle, hwnd.whole_window);
1541                                 }
1542                                 if ((windows & WindowType.Client) != 0) {
1543                                         XMapWindow(DisplayHandle, hwnd.client_window);
1544                                 }
1545
1546                                 hwnd.mapped = true;
1547
1548                                 if (f != null) {
1549                                         if (f.waiting_showwindow) {
1550                                                 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1551                                                 CreateParams cp = f.GetCreateParams();
1552                                                 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1553                                                     !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1554                                                         WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1555                                                 }
1556                                         }
1557                                 }
1558                         }
1559                 }
1560
1561                 private void UnmapWindow(Hwnd hwnd, WindowType windows) {
1562                         if (hwnd.mapped) {
1563                                 Form f = null;
1564                                 if (Control.FromHandle(hwnd.Handle) is Form) {
1565                                         f = Control.FromHandle(hwnd.Handle) as Form;
1566                                         if (f.WindowState == FormWindowState.Normal) {
1567                                                 f.waiting_showwindow = true;
1568                                                 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, IntPtr.Zero, IntPtr.Zero);
1569                                         }
1570                                 }
1571
1572                                 // it's possible that our Hwnd is no
1573                                 // longer valid after making that
1574                                 // SendMessage call, so check here.
1575                                 // FIXME: it is likely wrong, as it has already sent WM_SHOWWINDOW
1576                                 if (hwnd.zombie)
1577                                         return;
1578
1579                                 if ((windows & WindowType.Client) != 0) {
1580                                         XUnmapWindow(DisplayHandle, hwnd.client_window);
1581                                 }
1582                                 if ((windows & WindowType.Whole) != 0) {
1583                                         XUnmapWindow(DisplayHandle, hwnd.whole_window);
1584                                 }
1585
1586                                 hwnd.mapped = false;
1587
1588                                 if (f != null) {
1589                                         if (f.waiting_showwindow) {
1590                                                 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1591                                                 CreateParams cp = f.GetCreateParams();
1592                                                 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1593                                                     !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1594                                                         WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1595                                                 }
1596                                         }
1597                                 }
1598                         }
1599                 }
1600
1601                 private void UpdateMessageQueue (XEventQueue queue) {
1602                         DateTime        now;
1603                         int             pending;
1604                         Hwnd            hwnd;
1605
1606                         now = DateTime.UtcNow;
1607
1608                         lock (XlibLock) {
1609                                 pending = XPending (DisplayHandle);
1610                         }
1611
1612                         if (pending == 0) {
1613                                 if ((queue == null || queue.DispatchIdle) && Idle != null) {
1614                                         Idle (this, EventArgs.Empty);
1615                                 }
1616
1617                                 lock (XlibLock) {
1618                                         pending = XPending (DisplayHandle);
1619                                 }
1620                         }
1621
1622                         if (pending == 0) {
1623                                 int     timeout = 0;
1624
1625                                 if (queue != null) {
1626                                         if (queue.Paint.Count > 0)
1627                                                 return;
1628
1629                                         timeout = NextTimeout (queue.timer_list, now);
1630                                 }
1631
1632                                 if (timeout > 0) {
1633                                         #if __MonoCS__
1634                                         int length = pollfds.Length - 1;
1635                                         lock (wake_waiting_lock) {
1636                                                 if (wake_waiting == false) {
1637                                                         length ++;
1638                                                         wake_waiting = true;
1639                                                 }
1640                                         }
1641
1642                                         Syscall.poll (pollfds, (uint)length, timeout);
1643                                         // Clean out buffer, so we're not busy-looping on the same data
1644                                         if (length == pollfds.Length) {
1645                                                 if (pollfds[1].revents != 0)
1646                                                         wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
1647                                                 lock (wake_waiting_lock) {
1648                                                         wake_waiting = false;
1649                                                 }
1650                                         }
1651                                         #endif
1652                                         lock (XlibLock) {
1653                                                 pending = XPending (DisplayHandle);
1654                                         }
1655                                 }
1656                         }
1657
1658                         if (queue != null)
1659                                 CheckTimers (queue.timer_list, now);
1660
1661                         while (true) {
1662                                 XEvent xevent = new XEvent ();
1663
1664                                 lock (XlibLock) {
1665                                         if (XPending (DisplayHandle) == 0)
1666                                                 break;
1667
1668                                         XNextEvent (DisplayHandle, ref xevent);
1669
1670                                         if (xevent.AnyEvent.type == XEventName.KeyPress ||
1671                                             xevent.AnyEvent.type == XEventName.KeyRelease) {
1672                                                 // PreFilter() handles "shift key state updates.
1673                                                 Keyboard.PreFilter (xevent);
1674                                                 if (XFilterEvent (ref xevent, Keyboard.ClientWindow)) {
1675                                                         // probably here we could raise WM_IME_KEYDOWN and
1676                                                         // WM_IME_KEYUP, but I'm not sure it is worthy.
1677                                                         continue;
1678                                                 }
1679                                         }
1680                                         else if (XFilterEvent (ref xevent, IntPtr.Zero))
1681                                                 continue;
1682                                 }
1683
1684                                 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
1685                                 if (hwnd == null)
1686                                         continue;
1687
1688 #if debug                               
1689                                 Console.WriteLine ("UpdateMessageQueue (), got Event: {0}", xevent.ToString ());
1690 #else
1691                                 DebugHelper.WriteLine  ("UpdateMessageQueue got Event: " + xevent.ToString ());
1692 #endif
1693                                 switch (xevent.type) {
1694                                 case XEventName.Expose:
1695                                         AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
1696                                         break;
1697
1698                                 case XEventName.SelectionClear: {
1699                                         // Should we do something?
1700                                         break;
1701                                 }
1702
1703                                 case XEventName.SelectionRequest: {
1704                                         if (Dnd.HandleSelectionRequestEvent (ref xevent))
1705                                                 break;
1706                                         XEvent sel_event;
1707
1708                                         sel_event = new XEvent();
1709                                         sel_event.SelectionEvent.type = XEventName.SelectionNotify;
1710                                         sel_event.SelectionEvent.send_event = true;
1711                                         sel_event.SelectionEvent.display = DisplayHandle;
1712                                         sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
1713                                         sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
1714                                         sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
1715                                         sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
1716                                         sel_event.SelectionEvent.property = IntPtr.Zero;
1717
1718                                         IntPtr format_atom = xevent.SelectionRequestEvent.target;
1719
1720                                         // Seems that some apps support asking for supported types
1721                                         if (format_atom == TARGETS) {
1722                                                 int[]   atoms;
1723                                                 int     atom_count;
1724
1725                                                 atoms = new int[5];
1726                                                 atom_count = 0;
1727
1728                                                 if (Clipboard.IsSourceText) {
1729                                                         atoms[atom_count++] = (int)Atom.XA_STRING;
1730                                                         atoms[atom_count++] = (int)OEMTEXT;
1731                                                         atoms[atom_count++] = (int)UTF8_STRING;
1732                                                         atoms[atom_count++] = (int)UTF16_STRING;
1733                                                         atoms[atom_count++] = (int)RICHTEXTFORMAT;
1734                                                 } else if (Clipboard.IsSourceImage) {
1735                                                         atoms[atom_count++] = (int)Atom.XA_PIXMAP;
1736                                                         atoms[atom_count++] = (int)Atom.XA_BITMAP;
1737                                                 } else {
1738                                                         // FIXME - handle other types
1739                                                 }
1740
1741                                                 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, 
1742                                                                 (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
1743                                                 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1744                                         } else if (format_atom == (IntPtr)RICHTEXTFORMAT) {
1745                                                 string rtf_text = Clipboard.GetRtfText ();
1746                                                 if (rtf_text != null) {
1747                                                         // The RTF spec mentions that ascii is enough to contain it
1748                                                         Byte [] bytes = Encoding.ASCII.GetBytes (rtf_text);
1749                                                         int buflen = bytes.Length;
1750                                                         IntPtr buffer = Marshal.AllocHGlobal (buflen);
1751
1752                                                         for (int i = 0; i < buflen; i++)
1753                                                                 Marshal.WriteByte (buffer, i, bytes[i]);
1754
1755                                                         XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
1756                                                                         (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1757                                                         sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1758                                                         Marshal.FreeHGlobal(buffer);
1759                                                 }
1760                                         } else if (Clipboard.IsSourceText) {
1761                                                 IntPtr  buffer = IntPtr.Zero;
1762                                                 int     buflen;
1763                                                 Encoding encoding = null;
1764
1765                                                 buflen = 0;
1766
1767                                                 // Select an encoding depending on the target
1768                                                 IntPtr target_atom = xevent.SelectionRequestEvent.target;
1769                                                 if (target_atom == (IntPtr)Atom.XA_STRING || target_atom == OEMTEXT)
1770                                                         // FIXME - EOMTEXT should encode into ISO2022
1771                                                         encoding = Encoding.ASCII;
1772                                                 else if (target_atom == UTF16_STRING)
1773                                                         encoding = Encoding.Unicode;
1774                                                 else if (target_atom == UTF8_STRING)
1775                                                         encoding = Encoding.UTF8;
1776
1777                                                 if (encoding != null) {
1778                                                         Byte [] bytes;
1779
1780                                                         bytes = encoding.GetBytes (Clipboard.GetPlainText ());
1781                                                         buffer = Marshal.AllocHGlobal (bytes.Length);
1782                                                         buflen = bytes.Length;
1783
1784                                                         for (int i = 0; i < buflen; i++)
1785                                                                 Marshal.WriteByte (buffer, i, bytes [i]);
1786                                                 }
1787
1788                                                 if (buffer != IntPtr.Zero) {
1789                                                         XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1790                                                         sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1791                                                         Marshal.FreeHGlobal(buffer);
1792                                                 }
1793                                         } else if (Clipboard.GetSource (format_atom.ToInt32 ()) != null) { // check if we have an available value of this format
1794                                                 if (DataFormats.GetFormat (format_atom.ToInt32 ()).is_serializable) {
1795                                                         object serializable = Clipboard.GetSource (format_atom.ToInt32 ());
1796
1797                                                         BinaryFormatter formatter = new BinaryFormatter ();
1798                                                         MemoryStream memory_stream = new MemoryStream ();
1799                                                         formatter.Serialize (memory_stream, serializable);
1800
1801                                                         int buflen = (int)memory_stream.Length;
1802                                                         IntPtr buffer = Marshal.AllocHGlobal (buflen);
1803                                                         memory_stream.Position = 0;
1804                                                         for (int i = 0; i < buflen; i++)
1805                                                                 Marshal.WriteByte (buffer, i, (byte)memory_stream.ReadByte ());
1806                                                         memory_stream.Close ();
1807
1808                                                         XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target,
1809                                                                         8, PropertyMode.Replace, buffer, buflen);
1810                                                         sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1811                                                         Marshal.FreeHGlobal (buffer);
1812                                                 }
1813
1814                                         } else if (Clipboard.IsSourceImage) {
1815                                                 if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1816                                                         // FIXME - convert image and store as property
1817                                                 } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1818                                                         // FIXME - convert image and store as property
1819                                                 }
1820                                         }
1821
1822                                         XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
1823                                         break;
1824                                 }
1825
1826                                 case XEventName.SelectionNotify: {
1827                                         if (Clipboard.Enumerating) {
1828                                                 Clipboard.Enumerating = false;
1829                                                 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1830                                                         XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
1831                                                         if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
1832                                                                 Clipboard.Formats.Add(xevent.SelectionEvent.property);
1833                                                                 #if DriverDebugExtra
1834                                                                 Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
1835                                                                 #endif
1836                                                         }
1837                                                 }
1838                                         } else if (Clipboard.Retrieving) {
1839                                                 Clipboard.Retrieving = false;
1840                                                 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1841                                                         TranslatePropertyToClipboard(xevent.SelectionEvent.property);
1842                                                 } else {
1843                                                         Clipboard.ClearSources ();
1844                                                         Clipboard.Item = null;
1845                                                 }
1846                                         } else {
1847                                                 Dnd.HandleSelectionNotifyEvent (ref xevent);
1848                                         }
1849                                         break;
1850                                 }
1851
1852                                 case XEventName.KeyRelease:
1853                                         if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
1854                                                 XEvent nextevent = new XEvent ();
1855
1856                                                 XPeekEvent (DisplayHandle, ref nextevent);
1857
1858                                                 if (nextevent.type == XEventName.KeyPress &&
1859                                                     nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
1860                                                     nextevent.KeyEvent.time == xevent.KeyEvent.time) {
1861                                                         continue;
1862                                                 }
1863                                         }
1864                                         goto case XEventName.KeyPress;
1865                                         
1866                                 case XEventName.MotionNotify: {
1867                                         XEvent peek;
1868
1869                                         /* we can't do motion compression across threads, so just punt if we don't match up */
1870                                         if (Thread.CurrentThread == hwnd.Queue.Thread && hwnd.Queue.Count > 0) {
1871                                                 peek = hwnd.Queue.Peek();
1872                                                 if (peek.AnyEvent.type == XEventName.MotionNotify) {
1873                                                         continue;
1874                                                 }
1875                                         }
1876                                         goto case XEventName.KeyPress;
1877                                 }
1878
1879                                 case XEventName.KeyPress:
1880                                         hwnd.Queue.EnqueueLocked (xevent);
1881                                         /* Process KeyPresses immediately. Otherwise multiple Compose messages as a result of a
1882                                          * single physical keypress are not processed correctly */
1883                                         return;
1884                                 case XEventName.ButtonPress:
1885                                 case XEventName.ButtonRelease:
1886                                 case XEventName.EnterNotify:
1887                                 case XEventName.LeaveNotify:
1888                                 case XEventName.CreateNotify:
1889                                 case XEventName.DestroyNotify:
1890                                 case XEventName.FocusIn:
1891                                 case XEventName.FocusOut:
1892                                 case XEventName.ClientMessage:
1893                                 case XEventName.ReparentNotify:
1894                                 case XEventName.MapNotify:
1895                                 case XEventName.UnmapNotify:
1896                                         hwnd.Queue.EnqueueLocked (xevent);
1897                                         break;
1898
1899                                 case XEventName.ConfigureNotify:
1900                                         AddConfigureNotify(xevent);
1901                                         break;
1902
1903                                 case XEventName.PropertyNotify:
1904 #if debug
1905                                         Console.WriteLine ("UpdateMessageQueue (), got Event: {0}", xevent.ToString ());
1906 #endif
1907                                         if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
1908                                                 IntPtr  actual_atom;
1909                                                 int     actual_format;
1910                                                 IntPtr  nitems;
1911                                                 IntPtr  bytes_after;
1912                                                 IntPtr  prop = IntPtr.Zero;
1913                                                 IntPtr  prev_active;
1914
1915                                                 prev_active = ActiveWindow;
1916                                                 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);
1917                                                 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
1918                                                         ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));                                                       
1919                                                         XFree(prop);
1920
1921                                                         DebugHelper.WriteLine ("PropertyNotify: _NET_ACTIVE_WINDOW: previous = 0x{0:x}, new = 0x{1:x}", prev_active.ToInt32 (), ActiveWindow.ToInt32 ());
1922                                                         
1923                                                         if (prev_active != ActiveWindow) {
1924                                                                 if (prev_active != IntPtr.Zero) {
1925                                                                         PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
1926                                                                 }
1927                                                                 if (ActiveWindow != IntPtr.Zero) {
1928                                                                         PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
1929                                                                 }
1930                                                         }
1931                                                         if (ModalWindows.Count == 0) {
1932                                                                 break;
1933                                                         } else {
1934                                                                 // Modality Handling
1935                                                                 // 
1936                                                                 // If there is a modal window on the stack and the new active 
1937                                                                 // window is MWF window, but not the modal one and not a non-modal 
1938                                                                 // child of the modal one, switch back to the modal window.
1939                                                                 //
1940                                                                 // To identify if a non-modal form is child of a modal form 
1941                                                                 // we match their ApplicationContexts, which will be the same.
1942                                                                 // This is because each modal form runs the loop with a 
1943                                                                 // new ApplicationContext, which is inherited by the non-modal 
1944                                                                 // forms.
1945
1946                                                                 Form activeForm = Control.FromHandle (ActiveWindow) as Form;
1947                                                                 if (activeForm != null) {
1948                                                                         Form modalForm = Control.FromHandle ((IntPtr)ModalWindows.Peek()) as Form;
1949                                                                         if (ActiveWindow != (IntPtr)ModalWindows.Peek() && 
1950                                                                             (modalForm == null || activeForm.context == modalForm.context)) {
1951                                                                                 Activate((IntPtr)ModalWindows.Peek());
1952                                                                         }
1953                                                                 }
1954                                                                 break;
1955                                                         }
1956                                                 }
1957                                         }
1958                                         else if (xevent.PropertyEvent.atom == _NET_WM_STATE) {
1959                                                 // invalidate our cache - we'll query again the next time someone does GetWindowState.
1960                                                 hwnd.cached_window_state = (FormWindowState)(-1);
1961                                                 PostMessage (hwnd.Handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
1962                                         }
1963                                         break;
1964
1965                                 }
1966                         }
1967                 }
1968
1969                 private IntPtr GetMousewParam(int Delta) {
1970                         int     result = 0;
1971
1972                         if ((MouseState & MouseButtons.Left) != 0) {
1973                                 result |= (int)MsgButtons.MK_LBUTTON;
1974                         }
1975
1976                         if ((MouseState & MouseButtons.Middle) != 0) {
1977                                 result |= (int)MsgButtons.MK_MBUTTON;
1978                         }
1979
1980                         if ((MouseState & MouseButtons.Right) != 0) {
1981                                 result |= (int)MsgButtons.MK_RBUTTON;
1982                         }
1983
1984                         Keys mods = ModifierKeys;
1985                         if ((mods & Keys.Control) != 0) {
1986                                 result |= (int)MsgButtons.MK_CONTROL;
1987                         }
1988
1989                         if ((mods & Keys.Shift) != 0) {
1990                                 result |= (int)MsgButtons.MK_SHIFT;
1991                         }
1992
1993                         result |= Delta << 16;
1994
1995                         return (IntPtr)result;
1996                 }
1997                 private IntPtr XGetParent(IntPtr handle) {
1998                         IntPtr  Root;
1999                         IntPtr  Parent;
2000                         IntPtr  Children;
2001                         int     ChildCount;
2002
2003                         lock (XlibLock) {
2004                                 XQueryTree(DisplayHandle, handle, out Root, out Parent, out Children, out ChildCount);
2005                         }
2006
2007                         if (Children!=IntPtr.Zero) {
2008                                 lock (XlibLock) {
2009                                         XFree(Children);
2010                                 }
2011                         }
2012                         return Parent;
2013                 }
2014
2015                 private int HandleError (IntPtr display, ref XErrorEvent error_event)
2016                 {
2017                         // we need to workaround a problem with the
2018                         // ordering of destruction of Drawables and
2019                         // Pictures that exists between cairo and
2020                         // RENDER on the server.
2021                         if (error_event.request_code == (XRequest)render_major_opcode
2022                             && error_event.minor_code == 7 /* X_RenderFreePicture from render.h */
2023                             && error_event.error_code == render_first_error + 1 /* BadPicture from render.h */) {
2024                                 return 0;
2025                         }
2026
2027                         if (ErrorExceptions) {
2028                                 XUngrabPointer (display, IntPtr.Zero);
2029                                 throw new XException (error_event.display, error_event.resourceid,
2030                                                       error_event.serial, error_event.error_code,
2031                                                       error_event.request_code, error_event.minor_code);
2032                         } else {
2033                                 Console.WriteLine("X11 Error encountered: {0}{1}\n",
2034                                                   XException.GetMessage (error_event.display, error_event.resourceid,
2035                                                                          error_event.serial, error_event.error_code,
2036                                                                          error_event.request_code, error_event.minor_code),
2037                                                   Environment.StackTrace);
2038                         }
2039                         return 0;
2040                 }
2041
2042                 private void AccumulateDestroyedHandles (Control c, ArrayList list)
2043                 {
2044                         DebugHelper.Enter ();
2045                         if (c != null) {
2046                                 
2047                                 Control[] controls = c.Controls.GetAllControls ();
2048                                 
2049                                 DebugHelper.WriteLine  ("Checking control:0x{0:x}", c.IsHandleCreated ? c.Handle.ToInt32() : 0);
2050
2051                                 if (c.IsHandleCreated && !c.IsDisposed) {
2052                                         Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
2053
2054                                         #if DriverDebug || DriverDebugDestroy
2055                                         Console.WriteLine (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
2056                                         Console.WriteLine (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
2057                                         #endif
2058
2059                                         list.Add (hwnd);
2060                                         CleanupCachedWindows (hwnd);
2061                                 }
2062
2063                                 for (int  i = 0; i < controls.Length; i ++) {
2064                                         AccumulateDestroyedHandles (controls[i], list);
2065                                 }                                
2066                         }
2067                         DebugHelper.Leave ();
2068                 }
2069
2070                 void CleanupCachedWindows (Hwnd hwnd)
2071                 {
2072                         if (ActiveWindow == hwnd.Handle) {
2073                                 SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
2074                                 ActiveWindow = IntPtr.Zero;
2075                         }
2076
2077                         if (FocusWindow == hwnd.Handle) {
2078                                 SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
2079                                 FocusWindow = IntPtr.Zero;
2080                         }
2081
2082                         if (Grab.Hwnd == hwnd.Handle) {
2083                                 Grab.Hwnd = IntPtr.Zero;
2084                                 Grab.Confined = false;
2085                         }
2086
2087                         DestroyCaret (hwnd.Handle);
2088                 }
2089
2090                 private void PerformNCCalc(Hwnd hwnd) {
2091                         XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
2092                         IntPtr                          ptr;
2093                         Rectangle                       rect;
2094
2095                         rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
2096
2097                         ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
2098                         ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
2099
2100                         ncp.rgrc1.left = rect.Left;
2101                         ncp.rgrc1.top = rect.Top;
2102                         ncp.rgrc1.right = rect.Right;
2103                         ncp.rgrc1.bottom = rect.Bottom;
2104
2105                         Marshal.StructureToPtr(ncp, ptr, true);
2106                         NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
2107                         ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
2108                         Marshal.FreeHGlobal(ptr);
2109
2110
2111                         rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
2112                         hwnd.ClientRect = rect;
2113                 
2114                         rect = TranslateClientRectangleToXClientRectangle (hwnd);
2115
2116                         if (hwnd.visible) {
2117                                 MoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
2118                         }
2119
2120                         AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
2121                 }
2122                 #endregion      // Private Methods
2123
2124                 #region Callbacks
2125                 private void MouseHover(object sender, EventArgs e) {
2126                         XEvent  xevent;
2127                         Hwnd    hwnd;
2128
2129                         HoverState.Timer.Enabled = false;
2130
2131                         if (HoverState.Window != IntPtr.Zero) {
2132                                 hwnd = Hwnd.GetObjectFromWindow(HoverState.Window);
2133                                 if (hwnd != null) {
2134                                         xevent = new XEvent ();
2135
2136                                         xevent.type = XEventName.ClientMessage;
2137                                         xevent.ClientMessageEvent.display = DisplayHandle;
2138                                         xevent.ClientMessageEvent.window = HoverState.Window;
2139                                         xevent.ClientMessageEvent.message_type = HoverState.Atom;
2140                                         xevent.ClientMessageEvent.format = 32;
2141                                         xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
2142
2143                                         hwnd.Queue.EnqueueLocked (xevent);
2144
2145                                         WakeupMain ();
2146                                 }
2147                         }
2148                 }
2149
2150                 private void CaretCallback(object sender, EventArgs e) {
2151                         if (Caret.Paused) {
2152                                 return;
2153                         }
2154                         Caret.On = !Caret.On;
2155
2156                         XDrawLine(DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
2157                 }
2158                 #endregion      // Callbacks
2159
2160                 #region Public Properties
2161
2162                 internal override int CaptionHeight {
2163                         get {
2164                                 return 19;
2165                         }
2166                 }
2167
2168                 internal override  Size CursorSize {
2169                         get {
2170                                 int     x;
2171                                 int     y;
2172
2173                                 if (XQueryBestCursor(DisplayHandle, RootWindow, 32, 32, out x, out y) != 0) {
2174                                         return new Size(x, y);
2175                                 } else {
2176                                         return new Size(16, 16);
2177                                 }
2178                         }
2179                 } 
2180
2181                 internal override  bool DragFullWindows {
2182                         get {
2183                                 return true;
2184                         }
2185                 } 
2186
2187                 internal override  Size DragSize {
2188                         get {
2189                                 return new Size(4, 4);
2190                         }
2191                 }
2192
2193                 internal override  Size FrameBorderSize { 
2194                         get {
2195                                 return new Size (4, 4);
2196                         }
2197                 }
2198
2199                 internal override  Size IconSize {
2200                         get {
2201                                 IntPtr          list;
2202                                 XIconSize       size;
2203                                 int             count;
2204
2205                                 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2206                                         long            current;
2207                                         int             largest;
2208
2209                                         current = (long)list;
2210                                         largest = 0;
2211
2212                                         size = new XIconSize();
2213
2214                                         for (int i = 0; i < count; i++) {
2215                                                 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2216                                                 current += Marshal.SizeOf(size);
2217
2218                                                 // Look for our preferred size
2219                                                 if (size.min_width == 32) {
2220                                                         XFree(list);
2221                                                         return new Size(32, 32);
2222                                                 }
2223
2224                                                 if (size.max_width == 32) {
2225                                                         XFree(list);
2226                                                         return new Size(32, 32);
2227                                                 }
2228
2229                                                 if (size.min_width < 32 && size.max_width > 32) {
2230                                                         int     x;
2231
2232                                                         // check if we can fit one
2233                                                         x = size.min_width;
2234                                                         while (x < size.max_width) {
2235                                                                 x += size.width_inc;
2236                                                                 if (x == 32) {
2237                                                                         XFree(list);
2238                                                                         return new Size(32, 32);
2239                                                                 }
2240                                                         }
2241                                                 }
2242
2243                                                 if (largest < size.max_width) {
2244                                                         largest = size.max_width;
2245                                                 }
2246                                         }
2247
2248                                         // We didn't find a match or we wouldn't be here
2249                                         return new Size(largest, largest);
2250
2251                                 } else {
2252                                         return new Size(32, 32);
2253                                 }
2254                         }
2255                 } 
2256
2257                 internal override int KeyboardSpeed {
2258                         get{
2259                                 //
2260                                 // A lot harder: need to do:
2261                                 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58)       = 1
2262                                 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58)        = 0x080517a8
2263                                 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58)                   = 0
2264                                 //
2265                                 // And from that we can tell the repetition rate
2266                                 //
2267                                 // Notice, the values must map to:
2268                                 //   [0, 31] which maps to 2.5 to 30 repetitions per second.
2269                                 //
2270                                 return 0;
2271                         }
2272                 }
2273
2274                 internal override int KeyboardDelay {
2275                         get {
2276                                 //
2277                                 // Return values must range from 0 to 4, 0 meaning 250ms,
2278                                 // and 4 meaning 1000 ms.
2279                                 //
2280                                 return 1; // ie, 500 ms
2281                         }
2282                 } 
2283
2284                 internal override  Size MaxWindowTrackSize {
2285                         get {
2286                                 return new Size (WorkingArea.Width, WorkingArea.Height);
2287                         }
2288                 }
2289
2290                 internal override bool MenuAccessKeysUnderlined {
2291                         get {
2292                                 return false;
2293                         }
2294                 }
2295
2296                 internal override  Size MinimizedWindowSpacingSize {
2297                         get {
2298                                 return new Size(1, 1);
2299                         }
2300                 } 
2301
2302                 internal override  Size MinimumWindowSize {
2303                         get {
2304                                 return new Size(110, 22);
2305                         }
2306                 } 
2307
2308                 internal override Size MinimumFixedToolWindowSize {
2309                         get { return new Size (27, 22); }
2310                 }
2311
2312                 internal override Size MinimumSizeableToolWindowSize {
2313                         get { return new Size (37, 22); }
2314                 }
2315
2316                 internal override Size MinimumNoBorderWindowSize {
2317                         get { return new Size (2, 2); }
2318                 }
2319                 
2320                 internal override Keys ModifierKeys {
2321                         get {
2322                                 return Keyboard.ModifierKeys;
2323                         }
2324                 }
2325
2326                 internal override  Size SmallIconSize {
2327                         get {
2328                                 IntPtr          list;
2329                                 XIconSize       size;
2330                                 int             count;
2331
2332                                 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2333                                         long            current;
2334                                         int             smallest;
2335
2336                                         current = (long)list;
2337                                         smallest = 0;
2338
2339                                         size = new XIconSize();
2340
2341                                         for (int i = 0; i < count; i++) {
2342                                                 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2343                                                 current += Marshal.SizeOf(size);
2344
2345                                                 // Look for our preferred size
2346                                                 if (size.min_width == 16) {
2347                                                         XFree(list);
2348                                                         return new Size(16, 16);
2349                                                 }
2350
2351                                                 if (size.max_width == 16) {
2352                                                         XFree(list);
2353                                                         return new Size(16, 16);
2354                                                 }
2355
2356                                                 if (size.min_width < 16 && size.max_width > 16) {
2357                                                         int     x;
2358
2359                                                         // check if we can fit one
2360                                                         x = size.min_width;
2361                                                         while (x < size.max_width) {
2362                                                                 x += size.width_inc;
2363                                                                 if (x == 16) {
2364                                                                         XFree(list);
2365                                                                         return new Size(16, 16);
2366                                                                 }
2367                                                         }
2368                                                 }
2369
2370                                                 if (smallest == 0 || smallest > size.min_width) {
2371                                                         smallest = size.min_width;
2372                                                 }
2373                                         }
2374
2375                                         // We didn't find a match or we wouldn't be here
2376                                         return new Size(smallest, smallest);
2377
2378                                 } else {
2379                                         return new Size(16, 16);
2380                                 }
2381                         }
2382                 } 
2383
2384                 internal override  int MouseButtonCount {
2385                         get {
2386                                 return 3;
2387                         }
2388                 } 
2389
2390                 internal override  bool MouseButtonsSwapped {
2391                         get {
2392                                 return false;   // FIXME - how to detect?
2393                         }
2394                 } 
2395
2396                 internal override Point MousePosition {
2397                         get {
2398                                 return mouse_position;
2399                         }
2400                 }
2401
2402                 internal override Size MouseHoverSize {
2403                         get {
2404                                 return new Size (1, 1);
2405                         }
2406                 }
2407
2408                 internal override int MouseHoverTime {
2409                         get {
2410                                 return HoverState.Interval;
2411                         }
2412                 }
2413
2414
2415
2416                 internal override  bool MouseWheelPresent {
2417                         get {
2418                                 return true;    // FIXME - how to detect?
2419                         }
2420                 } 
2421
2422                 internal override MouseButtons MouseButtons {
2423                         get {
2424                                 return MouseState;
2425                         }
2426                 }
2427
2428                 internal override  Rectangle VirtualScreen {
2429                         get {
2430                                 IntPtr                  actual_atom;
2431                                 int                     actual_format;
2432                                 IntPtr                  nitems;
2433                                 IntPtr                  bytes_after;
2434                                 IntPtr                  prop = IntPtr.Zero;
2435                                 int                     width;
2436                                 int                     height;
2437
2438                                 XGetWindowProperty(DisplayHandle, RootWindow, _NET_DESKTOP_GEOMETRY, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2439                                 if ((long)nitems < 2)
2440                                         goto failsafe;
2441
2442                                 width = Marshal.ReadIntPtr(prop, 0).ToInt32();
2443                                 height = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
2444
2445                                 XFree(prop);
2446
2447                                 return new Rectangle(0, 0, width, height);
2448
2449                         failsafe:
2450                                 XWindowAttributes       attributes=new XWindowAttributes();
2451
2452                                 lock (XlibLock) {
2453                                         XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2454                                 }
2455
2456                                 return new Rectangle(0, 0, attributes.width, attributes.height);
2457                         }
2458                 } 
2459
2460                 internal override  Rectangle WorkingArea {
2461                         get {
2462                                 IntPtr                  actual_atom;
2463                                 int                     actual_format;
2464                                 IntPtr                  nitems;
2465                                 IntPtr                  bytes_after;
2466                                 IntPtr                  prop = IntPtr.Zero;
2467                                 int                     width;
2468                                 int                     height;
2469                                 int                     current_desktop;
2470                                 int                     x;
2471                                 int                     y;
2472
2473                                 XGetWindowProperty(DisplayHandle, RootWindow, _NET_CURRENT_DESKTOP, IntPtr.Zero, new IntPtr(1), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2474                                 if ((long)nitems < 1) {
2475                                         goto failsafe;
2476                                 }
2477
2478                                 current_desktop = Marshal.ReadIntPtr(prop, 0).ToInt32();
2479                                 XFree(prop);
2480
2481                                 XGetWindowProperty(DisplayHandle, RootWindow, _NET_WORKAREA, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2482                                 if ((long)nitems < 4 * current_desktop) {
2483                                         goto failsafe;
2484                                 }
2485
2486                                 x = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop).ToInt32();
2487                                 y = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size).ToInt32();
2488                                 width = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 2).ToInt32();
2489                                 height = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 3).ToInt32();
2490                                 XFree(prop);
2491
2492                                 return new Rectangle(x, y, width, height);
2493
2494                         failsafe:
2495                                 XWindowAttributes       attributes=new XWindowAttributes();
2496
2497                                 lock (XlibLock) {
2498                                         XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2499                                 }
2500
2501                                 return new Rectangle(0, 0, attributes.width, attributes.height);
2502                         }
2503                 }
2504
2505                 internal override bool ThemesEnabled {
2506                         get {
2507                                 return XplatUIX11.themes_enabled;
2508                         }
2509                 }
2510  
2511
2512                 #endregion      // Public properties
2513
2514                 #region Public Static Methods
2515                 internal override void RaiseIdle (EventArgs e)
2516                 {
2517                         if (Idle != null)
2518                                 Idle (this, e);
2519                 }
2520                 
2521                 internal override IntPtr InitializeDriver() {
2522                         lock (this) {
2523                                 if (DisplayHandle==IntPtr.Zero) {
2524                                         SetDisplay(XOpenDisplay(IntPtr.Zero));
2525                                 }
2526                         }
2527                         return IntPtr.Zero;
2528                 }
2529
2530                 internal override void ShutdownDriver(IntPtr token) {
2531                         lock (this) {
2532                                 if (DisplayHandle!=IntPtr.Zero) {
2533                                         XCloseDisplay(DisplayHandle);
2534                                         DisplayHandle=IntPtr.Zero;
2535                                 }
2536                         }
2537                 }
2538
2539                 internal override void EnableThemes() {
2540                         themes_enabled = true;
2541                 }
2542
2543
2544                 internal override void Activate(IntPtr handle) {
2545                         Hwnd hwnd;
2546
2547                         hwnd = Hwnd.ObjectFromHandle(handle);
2548
2549                         if (hwnd != null) {
2550                                 lock (XlibLock) {
2551                                         if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
2552                                                 SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
2553                                                 XEventQueue q = null;
2554                                                 lock (unattached_timer_list) {
2555                                                         foreach (Timer t in unattached_timer_list) {
2556                                                                 if (q == null)
2557                                                                         q= (XEventQueue) MessageQueues [Thread.CurrentThread];
2558                                                                 t.thread = q.Thread;
2559                                                                 q.timer_list.Add (t);
2560                                                         }
2561                                                         unattached_timer_list.Clear ();
2562                                                 }
2563                                         }
2564 //                                      else {
2565 //                                              XRaiseWindow(DisplayHandle, handle);
2566 //                                      }
2567                                 }
2568                         }
2569                 }
2570
2571                 internal override void AudibleAlert() {
2572                         XBell(DisplayHandle, 0);
2573                         return;
2574                 }
2575
2576
2577                 internal override void CaretVisible(IntPtr handle, bool visible) {
2578                         if (Caret.Hwnd == handle) {
2579                                 if (visible) {
2580                                         if (!Caret.Visible) {
2581                                                 Caret.Visible = true;
2582                                                 ShowCaret();
2583                                                 Caret.Timer.Start();
2584                                         }
2585                                 } else {
2586                                         Caret.Visible = false;
2587                                         Caret.Timer.Stop();
2588                                         HideCaret();
2589                                 }
2590                         }
2591                 }
2592
2593                 internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect) {
2594                         WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
2595                         return true;
2596                 }
2597
2598                 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
2599                         int     dest_x_return;
2600                         int     dest_y_return;
2601                         IntPtr  child;
2602                         Hwnd    hwnd;
2603
2604                         hwnd = Hwnd.ObjectFromHandle(handle);
2605
2606                         lock (XlibLock) {
2607                                 XTranslateCoordinates(DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
2608                         }
2609
2610                         x = dest_x_return;
2611                         y = dest_y_return;
2612                 }
2613
2614                 internal override int[] ClipboardAvailableFormats(IntPtr handle) {
2615                         DataFormats.Format      f;
2616                         int[]                   result;
2617
2618                         f = DataFormats.Format.List;
2619
2620                         if (XGetSelectionOwner(DisplayHandle, CLIPBOARD) == IntPtr.Zero) {
2621                                 return null;
2622                         }
2623
2624                         Clipboard.Formats = new ArrayList();
2625
2626                         while (f != null) {
2627                                 XConvertSelection(DisplayHandle, CLIPBOARD, (IntPtr)f.Id, (IntPtr)f.Id, FosterParent, IntPtr.Zero);
2628
2629                                 Clipboard.Enumerating = true;
2630                                 while (Clipboard.Enumerating) {
2631                                         UpdateMessageQueue(null);
2632                                 }
2633                                 f = f.Next;
2634                         }
2635
2636                         result = new int[Clipboard.Formats.Count];
2637
2638                         for (int i = 0; i < Clipboard.Formats.Count; i++) {
2639                                 result[i] = ((IntPtr)Clipboard.Formats[i]).ToInt32 ();
2640                         }
2641
2642                         Clipboard.Formats = null;
2643                         return result;
2644                 }
2645
2646                 internal override void ClipboardClose(IntPtr handle) {
2647                         if (handle != ClipMagic) {
2648                                 throw new ArgumentException("handle is not a valid clipboard handle");
2649                         }
2650                         return;
2651                 }
2652
2653                 internal override int ClipboardGetID(IntPtr handle, string format) {
2654                         if (handle != ClipMagic) {
2655                                 throw new ArgumentException("handle is not a valid clipboard handle");
2656                         }
2657
2658                         if (format == "Text" ) return (int)Atom.XA_STRING;
2659                         else if (format == "Bitmap" ) return (int)Atom.XA_BITMAP;
2660                         //else if (format == "MetaFilePict" ) return 3;
2661                         //else if (format == "SymbolicLink" ) return 4;
2662                         //else if (format == "DataInterchangeFormat" ) return 5;
2663                         //else if (format == "Tiff" ) return 6;
2664                         else if (format == "OEMText" ) return OEMTEXT.ToInt32();
2665                         else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP;
2666                         else if (format == "Palette" ) return (int)Atom.XA_COLORMAP;    // Useless
2667                         //else if (format == "PenData" ) return 10;
2668                         //else if (format == "RiffAudio" ) return 11;
2669                         //else if (format == "WaveAudio" ) return 12;
2670                         else if (format == "UnicodeText" ) return UTF16_STRING.ToInt32();
2671                         //else if (format == "EnhancedMetafile" ) return 14;
2672                         //else if (format == "FileDrop" ) return 15;
2673                         //else if (format == "Locale" ) return 16;
2674                         else if (format == "Rich Text Format") return RICHTEXTFORMAT.ToInt32 ();
2675
2676                         return XInternAtom(DisplayHandle, format, false).ToInt32();
2677                 }
2678
2679                 internal override IntPtr ClipboardOpen(bool primary_selection) {
2680                         if (!primary_selection)
2681                                 ClipMagic = CLIPBOARD;
2682                         else
2683                                 ClipMagic = PRIMARY;
2684                         return ClipMagic;
2685                 }
2686
2687                 internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
2688                         XConvertSelection(DisplayHandle, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);
2689
2690                         Clipboard.Retrieving = true;
2691                         while (Clipboard.Retrieving) {
2692                                 UpdateMessageQueue(null);
2693                         }
2694
2695                         return Clipboard.Item;
2696                 }
2697
2698                 internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) {
2699                         Clipboard.Converter = converter;
2700
2701                         if (obj != null) {
2702                                 Clipboard.AddSource (type, obj);
2703                                 XSetSelectionOwner(DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
2704                         } else {
2705                                 // Clearing the selection
2706                                 Clipboard.ClearSources ();
2707                                 XSetSelectionOwner(DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
2708                         }
2709                 }
2710
2711                 internal override void CreateCaret (IntPtr handle, int width, int height)
2712                 {
2713                         XGCValues       gc_values;
2714                         Hwnd            hwnd;
2715
2716                         hwnd = Hwnd.ObjectFromHandle(handle);
2717
2718                         if (Caret.Hwnd != IntPtr.Zero) {
2719                                 DestroyCaret(Caret.Hwnd);
2720                         }
2721
2722                         Caret.Hwnd = handle;
2723                         Caret.Window = hwnd.client_window;
2724                         Caret.Width = width;
2725                         Caret.Height = height;
2726                         Caret.Visible = false;
2727                         Caret.On = false;
2728
2729                         gc_values = new XGCValues();
2730                         gc_values.line_width = width;
2731
2732                         Caret.gc = XCreateGC(DisplayHandle, Caret.Window, new IntPtr ((int)GCFunction.GCLineWidth), ref gc_values);
2733                         if (Caret.gc == IntPtr.Zero) {
2734                                 Caret.Hwnd = IntPtr.Zero;
2735                                 return;
2736                         }
2737
2738                         XSetFunction(DisplayHandle, Caret.gc, GXFunction.GXinvert);
2739                 }
2740
2741                 internal override IntPtr CreateWindow (CreateParams cp)
2742                 {
2743                         XSetWindowAttributes    Attributes;
2744                         Hwnd                    hwnd;
2745                         Hwnd                    parent_hwnd = null;
2746                         int                     X;
2747                         int                     Y;
2748                         int                     Width;
2749                         int                     Height;
2750                         IntPtr                  ParentHandle;
2751                         IntPtr                  WholeWindow;
2752                         IntPtr                  ClientWindow;
2753                         SetWindowValuemask      ValueMask;
2754                         int[]                   atoms;
2755
2756                         hwnd = new Hwnd();
2757
2758                         Attributes = new XSetWindowAttributes();
2759                         X = cp.X;
2760                         Y = cp.Y;
2761                         Width = cp.Width;
2762                         Height = cp.Height;
2763
2764                         if (Width<1) Width=1;
2765                         if (Height<1) Height=1;
2766
2767                         if (cp.Parent != IntPtr.Zero) {
2768                                 parent_hwnd = Hwnd.ObjectFromHandle(cp.Parent);
2769                                 ParentHandle = parent_hwnd.client_window;
2770                         } else {
2771                                 if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
2772                                         // We need to use our foster parent window until this poor child gets it's parent assigned
2773                                         ParentHandle=FosterParent;
2774                                 } else {
2775                                         ParentHandle=RootWindow;
2776                                 }
2777                         }
2778
2779                         // Set the default location location for forms.
2780                         Point next;
2781                         if (cp.control is Form) {
2782                                 next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
2783                                 X = next.X;
2784                                 Y = next.Y;
2785                         }
2786                         ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
2787
2788                         Attributes.bit_gravity = Gravity.NorthWestGravity;
2789                         Attributes.win_gravity = Gravity.NorthWestGravity;
2790
2791                         // Save what's under the toolwindow
2792                         if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
2793                                 Attributes.save_under = true;
2794                                 ValueMask |= SetWindowValuemask.SaveUnder;
2795                         }
2796
2797
2798                         // If we're a popup without caption we override the WM
2799                         if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && !StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
2800                                 Attributes.override_redirect = true;
2801                                 ValueMask |= SetWindowValuemask.OverrideRedirect;
2802                         }
2803
2804                         hwnd.x = X;
2805                         hwnd.y = Y;
2806                         hwnd.width = Width;
2807                         hwnd.height = Height;
2808                         hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
2809                         hwnd.initial_style = cp.WindowStyle;
2810                         hwnd.initial_ex_style = cp.WindowExStyle;
2811
2812                         if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
2813                                 hwnd.enabled = false;
2814                         }
2815
2816                         ClientWindow = IntPtr.Zero;
2817
2818                         Size XWindowSize = TranslateWindowSizeToXWindowSize (cp);
2819                         Rectangle XClientRect = TranslateClientRectangleToXClientRectangle (hwnd, cp.control);
2820                                 
2821                         lock (XlibLock) {
2822                                 WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, XWindowSize.Width, XWindowSize.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, new UIntPtr ((uint)ValueMask), ref Attributes);
2823                                 if (WholeWindow != IntPtr.Zero) {
2824                                         ValueMask &= ~(SetWindowValuemask.OverrideRedirect | SetWindowValuemask.SaveUnder);
2825
2826                                         if (CustomVisual != IntPtr.Zero && CustomColormap != IntPtr.Zero) {
2827                                                 ValueMask = SetWindowValuemask.ColorMap;
2828                                                 Attributes.colormap = CustomColormap;
2829                                         }
2830                                         ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, XClientRect.X, XClientRect.Y, XClientRect.Width, XClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, new UIntPtr ((uint)ValueMask), ref Attributes);
2831                                 }
2832                         }
2833
2834                         if ((WholeWindow == IntPtr.Zero) || (ClientWindow == IntPtr.Zero)) {
2835                                 throw new Exception("Could not create X11 windows");
2836                         }
2837
2838                         hwnd.Queue = ThreadQueue(Thread.CurrentThread);
2839                         hwnd.WholeWindow = WholeWindow;
2840                         hwnd.ClientWindow = ClientWindow;
2841
2842                         #if DriverDebug || DriverDebugCreate
2843                                 Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}, Style {3}, ExStyle {4}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, (WindowStyles)cp.Style, (WindowExStyles)cp.ExStyle);
2844                         #endif
2845                         
2846                         if (!StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
2847                                 if ((X != unchecked((int)0x80000000)) && (Y != unchecked((int)0x80000000))) {
2848                                         XSizeHints      hints;
2849
2850                                         hints = new XSizeHints();
2851                                         hints.x = X;
2852                                         hints.y = Y;
2853                                         hints.flags = (IntPtr)(XSizeHintsFlags.USPosition | XSizeHintsFlags.PPosition);
2854                                         XSetWMNormalHints(DisplayHandle, WholeWindow, ref hints);
2855                                 }
2856                         }
2857
2858                         lock (XlibLock) {
2859                                 XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
2860                                 if (hwnd.whole_window != hwnd.client_window)
2861                                         XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
2862                         }
2863
2864                         if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST)) {
2865                                 atoms = new int[2];
2866                                 atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
2867                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
2868
2869                                 XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
2870                         }
2871
2872                         SetWMStyles(hwnd, cp);
2873                         
2874                         // set the group leader
2875                         XWMHints wm_hints = new XWMHints ();
2876                         
2877                         wm_hints.flags = (IntPtr)(XWMHintsFlags.InputHint | XWMHintsFlags.StateHint | XWMHintsFlags.WindowGroupHint);
2878                         wm_hints.input = !StyleSet (cp.Style, WindowStyles.WS_DISABLED);
2879                         wm_hints.initial_state = StyleSet (cp.Style, WindowStyles.WS_MINIMIZE) ? XInitialState.IconicState : XInitialState.NormalState;
2880                         
2881                         if (ParentHandle != RootWindow) {
2882                                 wm_hints.window_group = hwnd.whole_window;
2883                         } else {
2884                                 wm_hints.window_group = ParentHandle;
2885                         }
2886                         
2887                         lock (XlibLock) {
2888                                 XSetWMHints(DisplayHandle, hwnd.whole_window, ref wm_hints );
2889                         }
2890
2891                         if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
2892                                 SetWindowState(hwnd.Handle, FormWindowState.Minimized);
2893                         } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
2894                                 SetWindowState(hwnd.Handle, FormWindowState.Maximized);
2895                         }
2896
2897                         // for now make all windows dnd enabled
2898                         Dnd.SetAllowDrop (hwnd, true);
2899
2900                         // Set caption/window title
2901                         Text(hwnd.Handle, cp.Caption);
2902
2903                         SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
2904                         SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
2905
2906                         if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
2907                                 hwnd.visible = true;
2908                                 MapWindow(hwnd, WindowType.Both);
2909                                 if (!(Control.FromHandle(hwnd.Handle) is Form))
2910                                         SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
2911                         }
2912
2913                         return hwnd.Handle;
2914                 }
2915
2916                 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
2917                         CreateParams create_params = new CreateParams();
2918
2919                         create_params.Caption = "";
2920                         create_params.X = X;
2921                         create_params.Y = Y;
2922                         create_params.Width = Width;
2923                         create_params.Height = Height;
2924
2925                         create_params.ClassName=XplatUI.DefaultClassName;
2926                         create_params.ClassStyle = 0;
2927                         create_params.ExStyle=0;
2928                         create_params.Parent=IntPtr.Zero;
2929                         create_params.Param=0;
2930
2931                         return CreateWindow(create_params);
2932                 }
2933
2934                 internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
2935                         IntPtr  cursor;
2936                         Bitmap  cursor_bitmap;
2937                         Bitmap  cursor_mask;
2938                         Byte[]  cursor_bits;
2939                         Byte[]  mask_bits;
2940                         Color   c_pixel;
2941                         Color   m_pixel;
2942                         int     width;
2943                         int     height;
2944                         IntPtr  cursor_pixmap;
2945                         IntPtr  mask_pixmap;
2946                         XColor  fg;
2947                         XColor  bg;
2948                         bool    and;
2949                         bool    xor;
2950
2951                         if (XQueryBestCursor(DisplayHandle, RootWindow, bitmap.Width, bitmap.Height, out width, out height) == 0) {
2952                                 return IntPtr.Zero;
2953                         }
2954
2955                         // Win32 only allows creation cursors of a certain size
2956                         if ((bitmap.Width != width) || (bitmap.Width != height)) {
2957                                 cursor_bitmap = new Bitmap(bitmap, new Size(width, height));
2958                                 cursor_mask = new Bitmap(mask, new Size(width, height));
2959                         } else {
2960                                 cursor_bitmap = bitmap;
2961                                 cursor_mask = mask;
2962                         }
2963
2964                         width = cursor_bitmap.Width;
2965                         height = cursor_bitmap.Height;
2966
2967                         cursor_bits = new Byte[(width / 8) * height];
2968                         mask_bits = new Byte[(width / 8) * height];
2969
2970                         for (int y = 0; y < height; y++) {
2971                                 for (int x = 0; x < width; x++) {
2972                                         c_pixel = cursor_bitmap.GetPixel(x, y);
2973                                         m_pixel = cursor_mask.GetPixel(x, y);
2974
2975                                         and = c_pixel == cursor_pixel;
2976                                         xor = m_pixel == mask_pixel;
2977
2978                                         if (!and && !xor) {
2979                                                 // Black
2980                                                 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));       // The bit already is 0
2981                                                 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2982                                         } else if (and && !xor) {
2983                                                 // White
2984                                                 cursor_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2985                                                 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2986 #if notneeded
2987                                         } else if (and && !xor) {
2988                                                 // Screen
2989                                         } else if (and && xor) {
2990                                                 // Inverse Screen
2991
2992                                                 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
2993                                                 // we want both to be 0 so nothing to be done
2994                                                 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
2995                                                 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
2996 #endif
2997                                         }
2998                                 }
2999                         }
3000
3001                         cursor_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3002                         mask_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3003                         fg = new XColor();
3004                         bg = new XColor();
3005
3006                         fg.pixel = XWhitePixel(DisplayHandle, ScreenNo);
3007                         fg.red = (ushort)65535;
3008                         fg.green = (ushort)65535;
3009                         fg.blue = (ushort)65535;
3010
3011                         bg.pixel = XBlackPixel(DisplayHandle, ScreenNo);
3012
3013                         cursor = XCreatePixmapCursor(DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
3014
3015                         XFreePixmap(DisplayHandle, cursor_pixmap);
3016                         XFreePixmap(DisplayHandle, mask_pixmap);
3017
3018                         return cursor;
3019                 }
3020
3021                 internal override Bitmap DefineStdCursorBitmap (StdCursor id) {
3022                         CursorFontShape shape;
3023                         string name;
3024                         IntPtr theme;
3025                         int size;
3026                         Bitmap bmp = null;
3027                         
3028                         try {
3029                                 shape = StdCursorToFontShape (id);
3030                                 name = shape.ToString ().Replace ("XC_", string.Empty);
3031                                 size = XcursorGetDefaultSize (DisplayHandle);
3032                                 theme = XcursorGetTheme (DisplayHandle);
3033                                 IntPtr images_ptr = XcursorLibraryLoadImages (name, theme, size);
3034 #if debug
3035                                 Console.WriteLine ("DefineStdCursorBitmap, id={0}, #id={1}, name{2}, size={3}, theme: {4}, images_ptr={5}", id, (int) id, name, size, Marshal.PtrToStringAnsi (theme), images_ptr);
3036 #endif
3037
3038                                 if (images_ptr == IntPtr.Zero) {
3039                                         return null;
3040                                 }
3041
3042                                 XcursorImages images = (XcursorImages) Marshal.PtrToStructure (images_ptr, typeof (XcursorImages));
3043 #if debug
3044                                 Console.WriteLine ("DefineStdCursorBitmap, cursor has {0} images", images.nimage);
3045 #endif
3046
3047                                 if (images.nimage > 0) {                        
3048                                         // We only care about the first image.
3049                                         XcursorImage image = (XcursorImage)Marshal.PtrToStructure (Marshal.ReadIntPtr (images.images), typeof (XcursorImage));
3050                                         
3051 #if debug
3052                                         Console.WriteLine ("DefineStdCursorBitmap, loaded image <size={0}, height={1}, width={2}, xhot={3}, yhot={4}, pixels={5}", image.size, image.height, image.width, image.xhot, image.yhot, image.pixels);
3053 #endif
3054                                         // A sanity check
3055                                         if (image.width <= short.MaxValue && image.height <= short.MaxValue) {
3056                                                 int [] pixels = new int [image.width * image.height];
3057                                                 Marshal.Copy (image.pixels, pixels, 0, pixels.Length);
3058                                                 bmp = new Bitmap (image.width, image.height);
3059                                                 for (int w = 0; w < image.width; w++) {
3060                                                         for (int h = 0; h < image.height; h++) {
3061                                                                 bmp.SetPixel (w, h, Color.FromArgb (pixels [h * image.width + w]));
3062                                                         }
3063                                                 }
3064                                         }
3065                                 }
3066                                 
3067                                 XcursorImagesDestroy (images_ptr);
3068                                 
3069                         } catch (DllNotFoundException ex) {
3070                                 Console.WriteLine ("Could not load libXcursor: " + ex.Message + " (" + ex.GetType ().Name + ")");
3071                                 return null;
3072                         }
3073                         
3074                         return bmp;
3075                 }
3076
3077                 
3078                 internal override IntPtr DefineStdCursor(StdCursor id) {
3079                         CursorFontShape shape;
3080                         IntPtr          cursor;
3081
3082                         shape = StdCursorToFontShape (id);
3083
3084                         lock (XlibLock) {
3085                                 cursor = XCreateFontCursor(DisplayHandle, shape);
3086                         }
3087                         return cursor;
3088                 }
3089
3090                 internal static CursorFontShape StdCursorToFontShape (StdCursor id) {
3091                         CursorFontShape shape;
3092                         // FIXME - define missing shapes
3093
3094                         switch (id) {
3095                                 case StdCursor.AppStarting: {
3096                                         shape = CursorFontShape.XC_watch;
3097                                         break;
3098                                 }
3099
3100                                 case StdCursor.Arrow: {
3101                                         shape = CursorFontShape.XC_top_left_arrow;
3102                                         break;
3103                                 }
3104
3105                                 case StdCursor.Cross: {
3106                                         shape = CursorFontShape.XC_crosshair;
3107                                         break;
3108                                 }
3109
3110                                 case StdCursor.Default: {
3111                                         shape = CursorFontShape.XC_top_left_arrow;
3112                                         break;
3113                                 }
3114
3115                                 case StdCursor.Hand: {
3116                                         shape = CursorFontShape.XC_hand1;
3117                                         break;
3118                                 }
3119
3120                                 case StdCursor.Help: {
3121                                         shape = CursorFontShape.XC_question_arrow;
3122                                         break;
3123                                 }
3124
3125                                 case StdCursor.HSplit: {
3126                                         shape = CursorFontShape.XC_sb_v_double_arrow; 
3127                                         break;
3128                                 }
3129
3130                                 case StdCursor.IBeam: {
3131                                         shape = CursorFontShape.XC_xterm; 
3132                                         break;
3133                                 }
3134
3135                                 case StdCursor.No: {
3136                                         shape = CursorFontShape.XC_circle; 
3137                                         break;
3138                                 }
3139
3140                                 case StdCursor.NoMove2D: {
3141                                         shape = CursorFontShape.XC_fleur; 
3142                                         break;
3143                                 }
3144
3145                                 case StdCursor.NoMoveHoriz: {
3146                                         shape = CursorFontShape.XC_fleur; 
3147                                         break;
3148                                 }
3149
3150                                 case StdCursor.NoMoveVert: {
3151                                         shape = CursorFontShape.XC_fleur; 
3152                                         break;
3153                                 }
3154
3155                                 case StdCursor.PanEast: {
3156                                         shape = CursorFontShape.XC_fleur; 
3157                                         break;
3158                                 }
3159
3160                                 case StdCursor.PanNE: {
3161                                         shape = CursorFontShape.XC_fleur; 
3162                                         break;
3163                                 }
3164
3165                                 case StdCursor.PanNorth: {
3166                                         shape = CursorFontShape.XC_fleur; 
3167                                         break;
3168                                 }
3169
3170                                 case StdCursor.PanNW: {
3171                                         shape = CursorFontShape.XC_fleur; 
3172                                         break;
3173                                 }
3174
3175                                 case StdCursor.PanSE: {
3176                                         shape = CursorFontShape.XC_fleur; 
3177                                         break;
3178                                 }
3179
3180                                 case StdCursor.PanSouth: {
3181                                         shape = CursorFontShape.XC_fleur; 
3182                                         break;
3183                                 }
3184
3185                                 case StdCursor.PanSW: {
3186                                         shape = CursorFontShape.XC_fleur; 
3187                                         break;
3188                                 }
3189
3190                                 case StdCursor.PanWest: {
3191                                         shape = CursorFontShape.XC_sizing; 
3192                                         break;
3193                                 }
3194
3195                                 case StdCursor.SizeAll: {
3196                                         shape = CursorFontShape.XC_fleur; 
3197                                         break;
3198                                 }
3199
3200                                 case StdCursor.SizeNESW: {
3201                                         shape = CursorFontShape.XC_top_right_corner; 
3202                                         break;
3203                                 }
3204
3205                                 case StdCursor.SizeNS: {
3206                                         shape = CursorFontShape.XC_sb_v_double_arrow;
3207                                         break;
3208                                 }
3209
3210                                 case StdCursor.SizeNWSE: {
3211                                         shape = CursorFontShape.XC_top_left_corner; 
3212                                         break;
3213                                 }
3214
3215                                 case StdCursor.SizeWE: {
3216                                         shape = CursorFontShape.XC_sb_h_double_arrow; 
3217                                         break;
3218                                 }
3219
3220                                 case StdCursor.UpArrow: {
3221                                         shape = CursorFontShape.XC_center_ptr; 
3222                                         break;
3223                                 }
3224
3225                                 case StdCursor.VSplit: {
3226                                         shape = CursorFontShape.XC_sb_h_double_arrow;
3227                                         break;
3228                                 }
3229
3230                                 case StdCursor.WaitCursor: {
3231                                         shape = CursorFontShape.XC_watch; 
3232                                         break;
3233                                 }
3234
3235                                 default: {
3236                                         shape = (CursorFontShape) 0;
3237                                         break;
3238                                 }
3239                         }
3240                         
3241                         return shape;
3242                 }
3243
3244                 internal override IntPtr DefWndProc(ref Message msg) {
3245                         switch ((Msg)msg.Msg) {
3246                                 
3247                                 case Msg.WM_IME_COMPOSITION:
3248                                         string s = Keyboard.GetCompositionString ();
3249                                         foreach (char c in s)
3250                                                 SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
3251                                         return IntPtr.Zero;
3252
3253                                 case Msg.WM_IME_CHAR:
3254                                         // On Windows API it sends two WM_CHAR messages for each byte, but
3255                                         // I wonder if it is worthy to emulate it (also no idea how to 
3256                                         // reconstruct those bytes into chars).
3257                                         SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
3258                                         return IntPtr.Zero;
3259
3260                                 case Msg.WM_PAINT: {
3261                                         Hwnd hwnd;
3262
3263                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3264                                         if (hwnd != null) {
3265                                                 hwnd.expose_pending = false;
3266                                         }
3267
3268                                         return IntPtr.Zero;
3269                                 }
3270
3271                                 case Msg.WM_NCPAINT: {
3272                                         Hwnd hwnd;
3273
3274                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3275                                         if (hwnd != null) {
3276                                                 hwnd.nc_expose_pending = false;
3277                                         }
3278
3279                                         return IntPtr.Zero;
3280                                 }
3281
3282                                 case Msg.WM_NCCALCSIZE: {
3283                                         Hwnd hwnd;
3284
3285                                         if (msg.WParam == (IntPtr)1) {
3286                                                 hwnd = Hwnd.GetObjectFromWindow (msg.HWnd);
3287                                                 
3288                                                 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
3289                                                 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
3290
3291                                                 // Add all the stuff X is supposed to draw.
3292                                                 Control ctrl = Control.FromHandle (hwnd.Handle);
3293                                                 
3294                                                 if (ctrl != null) {
3295                                                         Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
3296                                                         
3297                                                         ncp.rgrc1.top += rect.top;
3298                                                         ncp.rgrc1.bottom -= rect.bottom;
3299                                                         ncp.rgrc1.left += rect.left;
3300                                                         ncp.rgrc1.right -= rect.right;
3301                                                         
3302                                                         Marshal.StructureToPtr (ncp, msg.LParam, true);
3303                                                 }
3304                                         }
3305
3306                                         return IntPtr.Zero;
3307                                 }
3308
3309                                 case Msg.WM_CONTEXTMENU: {
3310                                         Hwnd hwnd;
3311
3312                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3313
3314                                         if ((hwnd != null) && (hwnd.parent != null)) {
3315                                                 SendMessage(hwnd.parent.client_window, Msg.WM_CONTEXTMENU, msg.WParam, msg.LParam);
3316                                         }
3317                                         return IntPtr.Zero;
3318                                 }
3319
3320                                 case Msg.WM_MOUSEWHEEL: {
3321                                         Hwnd hwnd;
3322
3323                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3324
3325                                         if ((hwnd != null) && (hwnd.parent != null)) {
3326                                                 SendMessage(hwnd.parent.client_window, Msg.WM_MOUSEWHEEL, msg.WParam, msg.LParam);
3327                                                 if (msg.Result == IntPtr.Zero) {
3328                                                         return IntPtr.Zero;
3329                                                 }
3330                                         }
3331                                         return IntPtr.Zero;
3332                                 }
3333
3334                                 case Msg.WM_SETCURSOR: {
3335                                         Hwnd    hwnd;
3336
3337                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3338                                         if (hwnd == null)
3339                                                 break; // not sure how this happens, but it does
3340
3341                                         // Pass to parent window first
3342                                         while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
3343                                                 hwnd = hwnd.parent;
3344                                                 msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
3345                                         }
3346
3347                                         if (msg.Result == IntPtr.Zero) {
3348                                                 IntPtr handle;
3349
3350                                                 switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
3351                                                         case HitTest.HTBOTTOM:          handle = Cursors.SizeNS.handle; break;
3352                                                         case HitTest.HTBORDER:          handle = Cursors.SizeNS.handle; break;
3353                                                         case HitTest.HTBOTTOMLEFT:      handle = Cursors.SizeNESW.handle; break;
3354                                                         case HitTest.HTBOTTOMRIGHT:     handle = Cursors.SizeNWSE.handle; break;
3355                                                         case HitTest.HTERROR:           if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
3356                                                                                                 AudibleAlert();
3357                                                                                         }
3358                                                                                         handle = Cursors.Default.handle;
3359                                                                                         break;
3360
3361                                                         case HitTest.HTHELP:            handle = Cursors.Help.handle; break;
3362                                                         case HitTest.HTLEFT:            handle = Cursors.SizeWE.handle; break;
3363                                                         case HitTest.HTRIGHT:           handle = Cursors.SizeWE.handle; break;
3364                                                         case HitTest.HTTOP:             handle = Cursors.SizeNS.handle; break;
3365                                                         case HitTest.HTTOPLEFT:         handle = Cursors.SizeNWSE.handle; break;
3366                                                         case HitTest.HTTOPRIGHT:        handle = Cursors.SizeNESW.handle; break;
3367
3368                                                         #if SameAsDefault
3369                                                         case HitTest.HTGROWBOX:
3370                                                         case HitTest.HTSIZE:
3371                                                         case HitTest.HTZOOM:
3372                                                         case HitTest.HTVSCROLL:
3373                                                         case HitTest.HTSYSMENU:
3374                                                         case HitTest.HTREDUCE:
3375                                                         case HitTest.HTNOWHERE:
3376                                                         case HitTest.HTMAXBUTTON:
3377                                                         case HitTest.HTMINBUTTON:
3378                                                         case HitTest.HTMENU:
3379                                                         case HitTest.HSCROLL:
3380                                                         case HitTest.HTBOTTOM:
3381                                                         case HitTest.HTCAPTION:
3382                                                         case HitTest.HTCLIENT:
3383                                                         case HitTest.HTCLOSE:
3384                                                         #endif
3385                                                         default: handle = Cursors.Default.handle; break;
3386                                                 }
3387                                                 SetCursor(msg.HWnd, handle);
3388                                         }
3389                                         return (IntPtr)1;
3390                                 }
3391                         }
3392                         return IntPtr.Zero;
3393                 }
3394
3395                 internal override void DestroyCaret(IntPtr handle) {
3396                         if (Caret.Hwnd == handle) {
3397                                 if (Caret.Visible) {
3398                                         HideCaret ();
3399                                         Caret.Timer.Stop();
3400                                 }
3401                                 if (Caret.gc != IntPtr.Zero) {
3402                                         XFreeGC(DisplayHandle, Caret.gc);
3403                                         Caret.gc = IntPtr.Zero;
3404                                 }
3405                                 Caret.Hwnd = IntPtr.Zero;
3406                                 Caret.Visible = false;
3407                                 Caret.On = false;
3408                         }
3409                 }
3410
3411                 internal override void DestroyCursor(IntPtr cursor) {
3412                         lock (XlibLock) {
3413                                 XFreeCursor(DisplayHandle, cursor);
3414                         }
3415                 }
3416
3417                 internal override void DestroyWindow(IntPtr handle) {
3418                         Hwnd    hwnd;
3419                         hwnd = Hwnd.ObjectFromHandle(handle);
3420                         
3421                         // The window should never ever be a zombie here, since we should
3422                         // wait until it's completely dead before returning from 
3423                         // "destroying" calls, but just in case....
3424                         if (hwnd == null || hwnd.zombie) {
3425                                 #if DriverDebug || DriverDebugDestroy
3426                                         Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
3427                                 #endif
3428                                 return;
3429                         }
3430
3431                         #if DriverDebug || DriverDebugDestroy
3432                                 Console.WriteLine("Destroying window {0}", XplatUI.Window(hwnd.client_window));
3433                         #endif
3434
3435                         SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
3436                                 
3437                         CleanupCachedWindows (hwnd);
3438
3439                         ArrayList windows = new ArrayList ();
3440
3441                         AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
3442
3443
3444                         foreach (Hwnd h in windows) {
3445                                 SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
3446                                 h.zombie = true;                                
3447                         }
3448
3449                         lock (XlibLock) {
3450                                 if (hwnd.whole_window != IntPtr.Zero) {
3451                                         #if DriverDebug || DriverDebugDestroy
3452                                         Console.WriteLine ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
3453                                         #endif
3454                                         Keyboard.DestroyICForWindow (hwnd.whole_window);
3455                                         XDestroyWindow(DisplayHandle, hwnd.whole_window);
3456                                 }
3457                                 else if (hwnd.client_window != IntPtr.Zero) {
3458                                         #if DriverDebug || DriverDebugDestroy
3459                                         Console.WriteLine ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
3460                                         #endif
3461                                         Keyboard.DestroyICForWindow (hwnd.client_window);
3462                                         XDestroyWindow(DisplayHandle, hwnd.client_window);
3463                                 }
3464
3465                         }
3466                 }
3467
3468                 internal override IntPtr DispatchMessage(ref MSG msg) {
3469                         return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
3470                 }
3471
3472                 IntPtr GetReversibleScreenGC (Color backColor)
3473                 {
3474                         XGCValues       gc_values;
3475                         IntPtr          gc;
3476                         uint pixel;
3477
3478                         XColor xcolor = new XColor();
3479                         xcolor.red = (ushort)(backColor.R * 257);
3480                         xcolor.green = (ushort)(backColor.G * 257);
3481                         xcolor.blue = (ushort)(backColor.B * 257);
3482                         XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3483                         pixel = (uint)xcolor.pixel.ToInt32();
3484
3485
3486                         gc_values = new XGCValues();
3487
3488                         gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3489                         gc_values.foreground = (IntPtr)pixel;
3490
3491                         gc = XCreateGC(DisplayHandle, RootWindow, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCForeground)), ref gc_values);
3492                         XSetForeground(DisplayHandle, gc, (UIntPtr)pixel);
3493                         XSetFunction(DisplayHandle,   gc, GXFunction.GXxor);
3494
3495                         return gc;
3496                 }
3497
3498                 IntPtr GetReversibleControlGC (Control control, int line_width)
3499                 {
3500                         XGCValues       gc_values;
3501                         IntPtr          gc;
3502
3503                         gc_values = new XGCValues();
3504
3505                         gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3506                         gc_values.line_width = line_width;
3507                         gc_values.foreground = XBlackPixel(DisplayHandle, ScreenNo);
3508
3509                         // This logic will give us true rubber bands: (libsx, SANE_XOR)
3510                         //mask = foreground ^ background; 
3511                         //XSetForeground(DisplayHandle, gc, 0xffffffff);
3512                         //XSetBackground(DisplayHandle, gc, background);
3513                         //XSetFunction(DisplayHandle,   gc, GXxor);
3514                         //XSetPlaneMask(DisplayHandle,  gc, mask);
3515
3516
3517                         gc = XCreateGC(DisplayHandle, control.Handle, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
3518                         uint foreground;
3519                         uint background;
3520
3521                         XColor xcolor = new XColor();
3522
3523                         xcolor.red = (ushort)(control.ForeColor.R * 257);
3524                         xcolor.green = (ushort)(control.ForeColor.G * 257);
3525                         xcolor.blue = (ushort)(control.ForeColor.B * 257);
3526                         XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3527                         foreground = (uint)xcolor.pixel.ToInt32();
3528
3529                         xcolor.red = (ushort)(control.BackColor.R * 257);
3530                         xcolor.green = (ushort)(control.BackColor.G * 257);
3531                         xcolor.blue = (ushort)(control.BackColor.B * 257);
3532                         XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3533                         background = (uint)xcolor.pixel.ToInt32();
3534
3535                         uint mask = foreground ^ background; 
3536
3537                         XSetForeground(DisplayHandle, gc, (UIntPtr)0xffffffff);
3538                         XSetBackground(DisplayHandle, gc, (UIntPtr)background);
3539                         XSetFunction(DisplayHandle,   gc, GXFunction.GXxor);
3540                         XSetPlaneMask(DisplayHandle,  gc, (IntPtr)mask);
3541
3542                         return gc;
3543                 }
3544
3545                 internal override void DrawReversibleLine(Point start, Point end, Color backColor)
3546                 {
3547                         if (backColor.GetBrightness() < 0.5)
3548                                 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3549
3550                         IntPtr gc = GetReversibleScreenGC (backColor);
3551
3552                         XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
3553
3554                         XFreeGC(DisplayHandle, gc);
3555                 }
3556
3557                 internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
3558                 {
3559                         if (backColor.GetBrightness() < 0.5)
3560                                 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3561
3562                         IntPtr gc = GetReversibleScreenGC (backColor);
3563
3564                         if (rectangle.Width < 0) {
3565                                 rectangle.X += rectangle.Width;
3566                                 rectangle.Width = -rectangle.Width;
3567                         }
3568                         if (rectangle.Height < 0) {
3569                                 rectangle.Y += rectangle.Height;
3570                                 rectangle.Height = -rectangle.Height;
3571                         }
3572
3573                         int line_width = 1;
3574                         GCLineStyle line_style = GCLineStyle.LineSolid;
3575                         GCCapStyle cap_style = GCCapStyle.CapButt;
3576                         GCJoinStyle join_style = GCJoinStyle.JoinMiter;
3577
3578                         switch (style) {
3579                         case FrameStyle.Dashed:
3580                                 line_style = GCLineStyle.LineOnOffDash;
3581                                 break;
3582                         case FrameStyle.Thick:
3583                                 line_width = 2;
3584                                 break;
3585                         }
3586
3587                         XSetLineAttributes (DisplayHandle, gc, line_width, line_style, cap_style, join_style);
3588
3589                         XDrawRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3590
3591                         XFreeGC(DisplayHandle, gc);
3592                 }
3593
3594                 internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor) 
3595                 {
3596                         if (backColor.GetBrightness() < 0.5)
3597                                 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3598
3599                         IntPtr gc = GetReversibleScreenGC (backColor);
3600
3601                         if (rectangle.Width < 0) {
3602                                 rectangle.X += rectangle.Width;
3603                                 rectangle.Width = -rectangle.Width;
3604                         }
3605                         if (rectangle.Height < 0) {
3606                                 rectangle.Y += rectangle.Height;
3607                                 rectangle.Height = -rectangle.Height;
3608                         }
3609                         XFillRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3610
3611                         XFreeGC(DisplayHandle, gc);
3612                 }
3613
3614                 internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width)
3615                 {
3616                         IntPtr          gc;
3617                         Control control = Control.FromHandle(handle);
3618
3619                         gc = GetReversibleControlGC (control, line_width);
3620
3621                         if ((rect.Width > 0) && (rect.Height > 0)) {
3622                                 XDrawRectangle(DisplayHandle, control.Handle, gc, rect.Left, rect.Top, rect.Width, rect.Height);
3623                         } else {
3624                                 if (rect.Width > 0) {
3625                                         XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.Right, rect.Y);
3626                                 } else {
3627                                         XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.X, rect.Bottom);
3628                                 }
3629                         }
3630                         XFreeGC(DisplayHandle, gc);
3631                 }
3632
3633                 internal override void DoEvents() {
3634                         DebugHelper.Enter ();
3635
3636                         MSG     msg = new MSG ();
3637                         XEventQueue queue;
3638
3639                         if (OverrideCursorHandle != IntPtr.Zero) {
3640                                 OverrideCursorHandle = IntPtr.Zero;
3641                         }
3642
3643                         queue = ThreadQueue(Thread.CurrentThread);
3644
3645                         queue.DispatchIdle = false;
3646                         in_doevents = true;
3647
3648                         while (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
3649                                 TranslateMessage (ref msg);
3650                                 DispatchMessage (ref msg);
3651
3652                                 string key = msg.hwnd + ":" + msg.message;                              
3653                                 if (messageHold[key] != null) {
3654                                         messageHold[key] = ((int)messageHold[key]) - 1;
3655                                         DebugHelper.WriteLine  ("Got " + msg + " for " + key);
3656                                 }
3657                         }
3658
3659                         in_doevents = false;
3660                         queue.DispatchIdle = true;
3661
3662                         DebugHelper.Leave ();
3663                 }
3664
3665                 internal override void EnableWindow(IntPtr handle, bool Enable) {
3666                         Hwnd    hwnd;
3667
3668                         hwnd = Hwnd.ObjectFromHandle(handle);
3669                         if (hwnd != null) {
3670                                 hwnd.Enabled = Enable;
3671                         }
3672                 }
3673
3674                 internal override void EndLoop(Thread thread) {
3675                         // This is where we one day will shut down the loop for the thread
3676                 }
3677
3678                 internal override IntPtr GetActive() {
3679                         IntPtr  actual_atom;
3680                         int     actual_format;
3681                         IntPtr  nitems;
3682                         IntPtr  bytes_after;
3683                         IntPtr  prop = IntPtr.Zero;
3684                         IntPtr  active = IntPtr.Zero;
3685
3686                         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);
3687                         if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
3688                                 active = (IntPtr)Marshal.ReadInt32(prop);
3689                                 XFree(prop);
3690                         }
3691
3692                         if (active != IntPtr.Zero) {
3693                                 Hwnd    hwnd;
3694
3695                                 hwnd = Hwnd.GetObjectFromWindow(active);
3696                                 if (hwnd != null) {
3697                                         active = hwnd.Handle;
3698                                 } else {
3699                                         active = IntPtr.Zero;
3700                                 }
3701                         }
3702                         return active;
3703                 }
3704
3705                 internal override Region GetClipRegion(IntPtr handle) {
3706                         Hwnd    hwnd;
3707
3708                         hwnd = Hwnd.ObjectFromHandle(handle);
3709                         if (hwnd != null) {
3710                                 return hwnd.UserClip;
3711                         }
3712
3713                         return null;
3714                 }
3715
3716                 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
3717                         width = 20;
3718                         height = 20;
3719                         hotspot_x = 0;
3720                         hotspot_y = 0;
3721                 }
3722
3723                 internal override void GetDisplaySize(out Size size) {
3724                         XWindowAttributes       attributes=new XWindowAttributes();
3725
3726                         lock (XlibLock) {
3727                                 // FIXME - use _NET_WM messages instead?
3728                                 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
3729                         }
3730
3731                         size = new Size(attributes.width, attributes.height);
3732                 }
3733
3734                 internal override SizeF GetAutoScaleSize(Font font) {
3735                         Graphics        g;
3736                         float           width;
3737                         string          magic_string = "The quick brown fox jumped over the lazy dog.";
3738                         double          magic_number = 44.549996948242189;
3739
3740                         g = Graphics.FromHwnd(FosterParent);
3741
3742                         width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
3743                         return new SizeF(width, font.Height);
3744                 }
3745
3746                 internal override IntPtr GetParent(IntPtr handle) {
3747                         Hwnd    hwnd;
3748
3749                         hwnd = Hwnd.ObjectFromHandle(handle);
3750                         if (hwnd != null && hwnd.parent != null) {
3751                                 return hwnd.parent.Handle;
3752                         }
3753                         return IntPtr.Zero;
3754                 }
3755                 
3756                 // This is a nop on win32 and x11
3757                 internal override IntPtr GetPreviousWindow(IntPtr handle) {
3758                         return handle;
3759                 }
3760
3761                 internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
3762                         IntPtr  use_handle;
3763                         IntPtr  root;
3764                         IntPtr  child;
3765                         int     root_x;
3766                         int     root_y;
3767                         int     win_x;
3768                         int     win_y;
3769                         int     keys_buttons;
3770
3771                         if (handle != IntPtr.Zero) {
3772                                 use_handle = Hwnd.ObjectFromHandle(handle).client_window;
3773                         } else {
3774                                 use_handle = RootWindow;
3775                         }
3776
3777                         lock (XlibLock) {
3778                                 QueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
3779                         }
3780
3781                         if (handle != IntPtr.Zero) {
3782                                 x = win_x;
3783                                 y = win_y;
3784                         } else {
3785                                 x = root_x;
3786                                 y = root_y;
3787                         }
3788                 }
3789
3790                 internal override IntPtr GetFocus() {
3791                         return FocusWindow;
3792                 }
3793
3794
3795                 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent) {
3796                         FontFamily ff = font.FontFamily;
3797                         ascent = ff.GetCellAscent (font.Style);
3798                         descent = ff.GetCellDescent (font.Style);
3799                         return true;
3800                 }
3801
3802                 internal override Point GetMenuOrigin(IntPtr handle) {
3803                         Hwnd    hwnd;
3804
3805                         hwnd = Hwnd.ObjectFromHandle(handle);
3806
3807                         if (hwnd != null) {
3808                                 return hwnd.MenuOrigin;
3809                         }
3810                         return Point.Empty;
3811                 }
3812
3813                 [MonoTODO("Implement filtering")]
3814                 internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax) {
3815                         XEvent  xevent;
3816                         bool    client;
3817                         Hwnd    hwnd;
3818
3819                         ProcessNextMessage:
3820
3821                         if (((XEventQueue)queue_id).Count > 0) {
3822                                 xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3823                         } else {
3824                                 UpdateMessageQueue ((XEventQueue)queue_id);
3825
3826                                 if (((XEventQueue)queue_id).Count > 0) {
3827                                         xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3828                                 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
3829                                         xevent = ((XEventQueue)queue_id).Paint.Dequeue();
3830                                 } else {
3831                                         msg.hwnd= IntPtr.Zero;
3832                                         msg.message = Msg.WM_ENTERIDLE;
3833                                         return true;
3834                                 }
3835                         }
3836
3837                         hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
3838
3839 #if DriverDebugDestroy                  
3840                         if (hwnd != null)
3841                                 if (hwnd.zombie)
3842                                         Console.WriteLine ( "GetMessage zombie, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
3843                                 else    
3844                                         Console.WriteLine ( "GetMessage, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
3845 #endif
3846                         // Handle messages for windows that are already or are about to be destroyed.
3847
3848                         // we need a special block for this because unless we remove the hwnd from the paint
3849                         // queue it will always stay there (since we don't handle the expose), and we'll
3850                         // effectively loop infinitely trying to repaint a non-existant window.
3851                         if (hwnd != null && hwnd.zombie && xevent.type == XEventName.Expose) {
3852                                 hwnd.expose_pending = hwnd.nc_expose_pending = false;
3853                                 hwnd.Queue.Paint.Remove (hwnd);
3854                                 goto ProcessNextMessage;
3855                         }
3856
3857                         // We need to make sure we only allow DestroyNotify events through for zombie
3858                         // hwnds, since much of the event handling code makes requests using the hwnd's
3859                         // client_window, and that'll result in BadWindow errors if there's some lag
3860                         // between the XDestroyWindow call and the DestroyNotify event.
3861                         if (hwnd == null || hwnd.zombie && xevent.AnyEvent.type != XEventName.ClientMessage) {
3862                                 #if DriverDebug || DriverDebugDestroy
3863                                         Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
3864                                 #endif
3865                                 goto ProcessNextMessage;
3866                         }
3867
3868
3869                         // If we get here, that means the window is no more but there are Client Messages
3870                         // to be processed, probably a Posted message (for instance, an WM_ACTIVATE message) 
3871                         // We don't want anything else to run but the ClientMessage block, so reset all hwnd
3872                         // properties that might cause other processing to occur.
3873                         if (hwnd.zombie) {
3874                                 hwnd.resizing_or_moving = false;
3875                         }
3876
3877                         if (hwnd.client_window == xevent.AnyEvent.window) {
3878                                 client = true;
3879                                 //Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
3880                         } else {
3881                                 client = false;
3882                                 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
3883                         }
3884
3885                         msg.hwnd = hwnd.Handle;
3886
3887                         // Windows sends WM_ENTERSIZEMOVE when a form resize/move operation starts and WM_EXITSIZEMOVE 
3888                         // when it is done. The problem in X11 is that there is no concept of start-end of a moving/sizing.
3889                         // Configure events ("this window has resized/moved") are sent for each step of the resize. We send a
3890                         // WM_ENTERSIZEMOVE when we get the first Configure event. The problem is the WM_EXITSIZEMOVE.
3891                         // 
3892                         //  - There is no way for us to know which is the last Configure event. We can't traverse the events 
3893                         //    queue, because the next configure event might not be pending yet.
3894                         //  - We can't get ButtonPress/Release events for the window decorations, because they are not part 
3895                         //    of the window(s) we manage.
3896                         //  - We can't rely on the mouse state to change to "up" before the last Configure event. It doesn't.
3897                         // 
3898                         // We are almost 100% guaranteed to get another event (e.g Expose or other), but we can't know for sure 
3899                         // which, so we have here to check if the mouse buttons state is "up" and send the WM_EXITSIZEMOVE
3900                         //
3901                         if (hwnd.resizing_or_moving) {
3902                                 int root_x, root_y, win_x, win_y, keys_buttons;
3903                                 IntPtr  root, child;
3904                                 XQueryPointer (DisplayHandle, hwnd.Handle, out root, out child, out root_x, out root_y, 
3905                                                out win_x, out win_y, out keys_buttons);
3906                                 if ((keys_buttons & (int)MouseKeyMasks.Button1Mask) == 0 &&
3907                                     (keys_buttons & (int)MouseKeyMasks.Button2Mask) == 0 &&
3908                                     (keys_buttons & (int)MouseKeyMasks.Button3Mask) == 0) {
3909                                         hwnd.resizing_or_moving = false;
3910                                         SendMessage (hwnd.Handle, Msg.WM_EXITSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
3911                                 }
3912                         }
3913
3914                         //
3915                         // If you add a new event to this switch make sure to add it in
3916                         // UpdateMessage also unless it is not coming through the X event system.
3917                         //
3918                         switch(xevent.type) {
3919                                 case XEventName.KeyPress: {
3920                                         Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
3921
3922                                         // F1 key special case - WM_HELP sending
3923                                         if (msg.wParam == (IntPtr)VirtualKeys.VK_F1 || msg.wParam == (IntPtr)VirtualKeys.VK_HELP) {
3924                                                 // Send wM_HELP and then return it as a keypress message in
3925                                                 // case it needs to be preproccessed.
3926                                                 HELPINFO helpInfo = new HELPINFO ();
3927                                                 GetCursorPos (IntPtr.Zero, out helpInfo.MousePos.x, out helpInfo.MousePos.y);
3928                                                 IntPtr helpInfoPtr = Marshal.AllocHGlobal (Marshal.SizeOf (helpInfo));
3929                                                 Marshal.StructureToPtr (helpInfo, helpInfoPtr, true);
3930                                                 NativeWindow.WndProc (FocusWindow, Msg.WM_HELP, IntPtr.Zero, helpInfoPtr);
3931                                                 Marshal.FreeHGlobal (helpInfoPtr);
3932                                         }
3933                                         break;
3934                                 }
3935
3936                                 case XEventName.KeyRelease: {
3937                                         Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
3938                                         break;
3939                                 }
3940
3941                                 case XEventName.ButtonPress: {
3942                                         switch(xevent.ButtonEvent.button) {
3943                                                 case 1: {
3944                                                         MouseState |= MouseButtons.Left;
3945                                                         if (client) {
3946                                                                 msg.message = Msg.WM_LBUTTONDOWN;
3947                                                                 msg.wParam = GetMousewParam (0);
3948                                                         } else {
3949                                                                 msg.message = Msg.WM_NCLBUTTONDOWN;
3950                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
3951                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
3952                                                         }
3953                                                         break;
3954                                                 }
3955
3956                                                 case 2: {
3957                                                         MouseState |= MouseButtons.Middle;
3958                                                         if (client) {
3959                                                                 msg.message = Msg.WM_MBUTTONDOWN;
3960                                                                 msg.wParam = GetMousewParam (0);
3961                                                         } else {
3962                                                                 msg.message = Msg.WM_NCMBUTTONDOWN;
3963                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
3964                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
3965                                                         }
3966                                                         break;
3967                                                 }
3968
3969                                                 case 3: {
3970                                                         MouseState |= MouseButtons.Right;
3971                                                         if (client) {
3972                                                                 msg.message = Msg.WM_RBUTTONDOWN;
3973                                                                 msg.wParam = GetMousewParam (0);
3974                                                         } else {
3975                                                                 msg.message = Msg.WM_NCRBUTTONDOWN;
3976                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
3977                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
3978                                                         }
3979                                                         break;
3980                                                 }
3981
3982                                                 case 4: {
3983                                                         msg.hwnd = FocusWindow;
3984                                                         msg.message=Msg.WM_MOUSEWHEEL;
3985                                                         msg.wParam=GetMousewParam(120);
3986                                                         break;
3987                                                 }
3988
3989                                                 case 5: {
3990                                                         msg.hwnd = FocusWindow;
3991                                                         msg.message=Msg.WM_MOUSEWHEEL;
3992                                                         msg.wParam=GetMousewParam(-120);
3993                                                         break;
3994                                                 }
3995
3996                                         }
3997
3998                                         msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
3999                                         mouse_position.X = xevent.ButtonEvent.x;
4000                                         mouse_position.Y = xevent.ButtonEvent.y;
4001
4002                                         if (!hwnd.Enabled) {
4003                                                 IntPtr dummy;
4004
4005                                                 msg.hwnd = hwnd.EnabledHwnd;
4006                                                 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);
4007                                                 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4008                                         }
4009
4010                                         if (Grab.Hwnd != IntPtr.Zero) {
4011                                                 msg.hwnd = Grab.Hwnd;
4012                                         }
4013
4014                                         if (ClickPending.Pending && ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message))) {
4015                                                 // Looks like a genuine double click, clicked twice on the same spot with the same keys
4016                                                 switch(xevent.ButtonEvent.button) {
4017                                                         case 1: {
4018                                                                 msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
4019                                                                 break;
4020                                                         }
4021
4022                                                         case 2: {
4023                                                                 msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
4024                                                                 break;
4025                                                         }
4026
4027                                                         case 3: {
4028                                                                 msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
4029                                                                 break;
4030                                                         }
4031                                                 }
4032                                                 ClickPending.Pending = false;
4033                                         } else {
4034                                                 ClickPending.Pending = true;
4035                                                 ClickPending.Hwnd = msg.hwnd;
4036                                                 ClickPending.Message = msg.message;
4037                                                 ClickPending.wParam = msg.wParam;
4038                                                 ClickPending.lParam = msg.lParam;
4039                                                 ClickPending.Time = (long)xevent.ButtonEvent.time;
4040                                         }
4041                                         
4042                                         if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN) {
4043                                                 SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
4044                                         }
4045                                         
4046                                         break;
4047                                 }
4048
4049                                 case XEventName.ButtonRelease: {
4050                                         switch(xevent.ButtonEvent.button) {
4051                                                 case 1: {
4052                                                         if (client) {
4053                                                                 msg.message = Msg.WM_LBUTTONUP;
4054                                                         } else {
4055                                                                 msg.message = Msg.WM_NCLBUTTONUP;
4056                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4057                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4058                                                         }
4059                                                         MouseState &= ~MouseButtons.Left;
4060                                                         msg.wParam = GetMousewParam (0);
4061                                                         break;
4062                                                 }
4063
4064                                                 case 2: {
4065                                                         if (client) {
4066                                                                 msg.message = Msg.WM_MBUTTONUP;
4067                                                         } else {
4068                                                                 msg.message = Msg.WM_NCMBUTTONUP;
4069                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4070                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4071                                                         }
4072                                                         MouseState &= ~MouseButtons.Middle;
4073                                                         msg.wParam = GetMousewParam (0);
4074                                                         break;
4075                                                 }
4076
4077                                                 case 3: {
4078                                                         if (client) {
4079                                                                 msg.message = Msg.WM_RBUTTONUP;
4080                                                         } else {
4081                                                                 msg.message = Msg.WM_NCRBUTTONUP;
4082                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4083                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4084                                                         }
4085                                                         MouseState &= ~MouseButtons.Right;
4086                                                         msg.wParam = GetMousewParam (0);
4087                                                         break;
4088                                                 }
4089
4090                                                 case 4: {
4091                                                         goto ProcessNextMessage;
4092                                                 }
4093
4094                                                 case 5: {
4095                                                         goto ProcessNextMessage;
4096                                                 }
4097                                         }
4098
4099                                         if (!hwnd.Enabled) {
4100                                                 IntPtr dummy;
4101
4102                                                 msg.hwnd = hwnd.EnabledHwnd;
4103                                                 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);
4104                                                 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4105                                         }
4106
4107                                         if (Grab.Hwnd != IntPtr.Zero) {
4108                                                 msg.hwnd = Grab.Hwnd;
4109                                         }
4110
4111                                         msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
4112                                         mouse_position.X = xevent.ButtonEvent.x;
4113                                         mouse_position.Y = xevent.ButtonEvent.y;
4114
4115                                         // Win32 splurts MouseMove events all over the place, regardless of whether the mouse is actually moving or
4116                                         // not, especially after mousedown and mouseup. To support apps relying on mousemove events between and after 
4117                                         // mouse clicks to repaint or whatever, we generate a mousemove event here. *sigh*
4118                                         if (msg.message == Msg.WM_LBUTTONUP || msg.message == Msg.WM_MBUTTONUP || msg.message == Msg.WM_RBUTTONUP) {
4119                                                 XEvent motionEvent = new XEvent ();
4120                                                 motionEvent.type = XEventName.MotionNotify;
4121                                                 motionEvent.MotionEvent.display = DisplayHandle;
4122                                                 motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4123                                                 motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4124                                                 motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4125                                                 hwnd.Queue.EnqueueLocked (motionEvent);
4126                                         }
4127                                         break;
4128                                 }
4129
4130                                 case XEventName.MotionNotify: {
4131                                         if (client) {
4132                                                 #if DriverDebugExtra
4133                                                         Console.WriteLine("GetMessage(): Window {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
4134                                                 #endif
4135
4136                                                 if (Grab.Hwnd != IntPtr.Zero) {
4137                                                         msg.hwnd = Grab.Hwnd;
4138                                                 } else {
4139                                                         if (hwnd.Enabled) {
4140                                                                 NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
4141                                                         }
4142                                                 }
4143
4144                                                 if (xevent.MotionEvent.is_hint != 0)
4145                                                 {
4146                                                         IntPtr root, child;
4147                                                         int mask;
4148                                                         XQueryPointer (DisplayHandle, xevent.AnyEvent.window,
4149                                                                                         out root, out child,
4150                                                                                         out xevent.MotionEvent.x_root, 
4151                                                                                         out xevent.MotionEvent.y_root,
4152                                                                                         out xevent.MotionEvent.x,      
4153                                                                                         out xevent.MotionEvent.y, out mask);
4154                                                 }
4155
4156                                                 msg.message = Msg.WM_MOUSEMOVE;
4157                                                 msg.wParam = GetMousewParam(0);
4158                                                 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
4159
4160                                                 if (!hwnd.Enabled) {
4161                                                         IntPtr dummy;
4162
4163                                                         msg.hwnd = hwnd.EnabledHwnd;
4164                                                         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);
4165                                                         msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4166                                                 }
4167
4168                                                 mouse_position.X = xevent.MotionEvent.x;
4169                                                 mouse_position.Y = xevent.MotionEvent.y;
4170
4171                                                 if ((HoverState.Timer.Enabled) &&
4172                                                     (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
4173                                                     ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
4174                                                     ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
4175                                                     ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
4176                                                         HoverState.Timer.Stop();
4177                                                         HoverState.Timer.Start();
4178                                                         HoverState.X = mouse_position.X;
4179                                                         HoverState.Y = mouse_position.Y;
4180                                                 }
4181
4182                                                 break;
4183                                         } else {
4184                                                 HitTest ht;
4185                                                 IntPtr dummy;
4186
4187                                                 #if DriverDebugExtra
4188                                                         Console.WriteLine("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
4189                                                 #endif
4190                                                 msg.message = Msg.WM_NCMOUSEMOVE;
4191
4192                                                 if (!hwnd.Enabled) {
4193                                                         msg.hwnd = hwnd.EnabledHwnd;
4194                                                         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);
4195                                                         msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4196                                                 }
4197
4198                                                 ht = NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4199                                                 NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
4200
4201                                                 mouse_position.X = xevent.MotionEvent.x;
4202                                                 mouse_position.Y = xevent.MotionEvent.y;
4203                                         }
4204
4205                                         break;
4206                                 }
4207
4208                                 case XEventName.EnterNotify: {
4209                                         if (!hwnd.Enabled) {
4210                                                 goto ProcessNextMessage;
4211                                         }
4212                                         if (xevent.CrossingEvent.mode == NotifyMode.NotifyGrab || xevent.AnyEvent.window != hwnd.client_window) {
4213                                                 goto ProcessNextMessage;
4214                                         }
4215                                         if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) { // Pseudo motion caused by grabbing
4216                                                 if (LastPointerWindow == xevent.AnyEvent.window)
4217                                                         goto ProcessNextMessage;
4218
4219                                                 if (LastPointerWindow != IntPtr.Zero) {
4220                                                         Point enter_loc = new Point (xevent.ButtonEvent.x, xevent.ButtonEvent.y);
4221
4222                                                         // We need this due to EnterNotify being fired on all the parent controls
4223                                                         // of the Control being grabbed, and obviously in that scenario we are not
4224                                                         // actuallty entering them
4225                                                         Control ctrl = Control.FromHandle (hwnd.client_window);
4226                                                         foreach (Control child_control in ctrl.Controls.GetAllControls ())
4227                                                                 if (child_control.Bounds.Contains (enter_loc))
4228                                                                         goto ProcessNextMessage;
4229
4230                                                         // A MouseLeave/LeaveNotify event is sent to the previous window
4231                                                         // until the mouse is ungrabbed, not when actually leaving its bounds
4232                                                         int x = xevent.CrossingEvent.x_root;
4233                                                         int y = xevent.CrossingEvent.y_root;
4234                                                         ScreenToClient (LastPointerWindow, ref x, ref y);
4235
4236                                                         XEvent leaveEvent = new XEvent ();
4237                                                         leaveEvent.type = XEventName.LeaveNotify;
4238                                                         leaveEvent.CrossingEvent.display = DisplayHandle;
4239                                                         leaveEvent.CrossingEvent.window = LastPointerWindow;
4240                                                         leaveEvent.CrossingEvent.x = x;
4241                                                         leaveEvent.CrossingEvent.y = y;
4242                                                         leaveEvent.CrossingEvent.mode = NotifyMode.NotifyNormal;
4243                                                         Hwnd last_pointer_hwnd = Hwnd.ObjectFromHandle (LastPointerWindow);
4244                                                         last_pointer_hwnd.Queue.EnqueueLocked (leaveEvent);
4245                                                 }
4246                                         }
4247
4248                                         LastPointerWindow = xevent.AnyEvent.window;
4249
4250                                         msg.message = Msg.WM_MOUSE_ENTER;
4251                                         HoverState.X = xevent.CrossingEvent.x;
4252                                         HoverState.Y = xevent.CrossingEvent.y;
4253                                         HoverState.Timer.Enabled = true;
4254                                         HoverState.Window = xevent.CrossingEvent.window;
4255
4256                                         // Win32 sends a WM_MOUSEMOVE after mouse enter
4257                                         XEvent motionEvent = new XEvent ();
4258                                         motionEvent.type = XEventName.MotionNotify;
4259                                         motionEvent.MotionEvent.display = DisplayHandle;
4260                                         motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4261                                         motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4262                                         motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4263                                         hwnd.Queue.EnqueueLocked (motionEvent);
4264                                         break;
4265                                 }
4266
4267                                 case XEventName.LeaveNotify: {
4268                                         if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) {
4269                                                 WindowUngrabbed (hwnd.Handle);
4270                                                 goto ProcessNextMessage;
4271                                         }
4272                                         if (!hwnd.Enabled) {
4273                                                 goto ProcessNextMessage;
4274                                         }
4275                                         if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
4276                                                 goto ProcessNextMessage;
4277                                         }
4278                                         // If a grab is taking place, ignore it - we handle it in EnterNotify
4279                                         if (Grab.Hwnd != IntPtr.Zero)
4280                                                 goto ProcessNextMessage;
4281
4282                                         // Reset the cursor explicitly on X11.
4283                                         // X11 remembers the last set cursor for the window and in cases where 
4284                                         // the control won't get a WM_SETCURSOR X11 will restore the last 
4285                                         // known cursor, which we don't want.
4286                                         // 
4287                                         SetCursor (hwnd.client_window, IntPtr.Zero);
4288
4289                                         msg.message=Msg.WM_MOUSELEAVE;
4290                                         HoverState.Timer.Enabled = false;
4291                                         HoverState.Window = IntPtr.Zero;
4292                                         break;
4293                                 }
4294
4295                                 #if later
4296                                 case XEventName.CreateNotify: {
4297                                         if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
4298                                                 msg.message = WM_CREATE;
4299                                                 // Set up CreateStruct
4300                                         } else {
4301                                                 goto ProcessNextMessage;
4302                                         }
4303                                         break;
4304                                 }
4305                                 #endif
4306
4307
4308                                 case XEventName.ReparentNotify: {
4309                                         if (hwnd.parent == null) {      // Toplevel
4310                                                 if ((xevent.ReparentEvent.parent != IntPtr.Zero) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
4311                                                         hwnd.Reparented = true;
4312
4313                                                         // The location given by the event is not reliable between different wm's, 
4314                                                         // so use an alternative way of getting it.
4315                                                         Point location = GetTopLevelWindowLocation (hwnd);
4316                                                         hwnd.X = location.X;
4317                                                         hwnd.Y = location.Y;
4318
4319                                                         if (hwnd.opacity != 0xffffffff) {
4320                                                                 IntPtr opacity;
4321
4322                                                                 opacity = (IntPtr)(Int32)hwnd.opacity;
4323                                                                 XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
4324                                                         }
4325                                                         SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, msg.wParam, msg.lParam);
4326                                                         goto ProcessNextMessage;
4327                                                 } else {
4328                                                         hwnd.Reparented = false;
4329                                                         goto ProcessNextMessage;
4330                                                 }
4331                                         }
4332                                         goto ProcessNextMessage;
4333                                 }
4334
4335                                 case XEventName.ConfigureNotify: {
4336                                         if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {        // Ignore events for children (SubstructureNotify) and client areas
4337                                                 #if DriverDebugExtra
4338                                                         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);
4339                                                 #endif
4340
4341                                                 lock (hwnd.configure_lock) {
4342                                                         Form form = Control.FromHandle (hwnd.client_window) as Form;
4343                                                         if (form != null && !hwnd.resizing_or_moving) {
4344                                                                 if (hwnd.x != form.Bounds.X || hwnd.y != form.Bounds.Y) {
4345                                                                         SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_MOVE, IntPtr.Zero);
4346                                                                         hwnd.resizing_or_moving = true;
4347                                                                 } else if (hwnd.width != form.Bounds.Width || hwnd.height != form.Bounds.Height) {
4348                                                                         SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_SIZE, IntPtr.Zero);
4349                                                                         hwnd.resizing_or_moving = true;
4350                                                                 }
4351                                                                 if (hwnd.resizing_or_moving)
4352                                                                         SendMessage (form.Handle, Msg.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
4353                                                         }
4354         
4355                                                         SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4356                                                         hwnd.configure_pending = false;
4357         
4358                                                         // We need to adjust our client window to track the resize of whole_window
4359                                                         if (hwnd.whole_window != hwnd.client_window)
4360                                                                 PerformNCCalc(hwnd);
4361                                                 }
4362                                         }
4363                                         goto ProcessNextMessage;
4364                                 }
4365
4366                                 case XEventName.FocusIn: {
4367                                         // We received focus. We use X11 focus only to know if the app window does or does not have focus
4368                                         // We do not track the actual focussed window via it. Instead, this is done via FocusWindow internally
4369                                         // Receiving focus means we've gotten activated and therefore we need to let the actual FocusWindow know 
4370                                         // about it having focus again
4371                                         if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4372                                                 goto ProcessNextMessage;
4373                                         }
4374
4375                                         
4376                                         if (FocusWindow == IntPtr.Zero) {
4377                                                 Control c = Control.FromHandle (hwnd.client_window);
4378
4379                                                 if (c == null)
4380                                                         goto ProcessNextMessage;                                                
4381                                                 Form form = c.FindForm ();
4382                                                 if (form == null)
4383                                                         goto ProcessNextMessage;
4384                                         
4385                                                 if (ActiveWindow != form.Handle) {
4386                                                         ActiveWindow = form.Handle;
4387                                                         SendMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr) WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
4388                                                 }
4389                                                 goto ProcessNextMessage;
4390                                         }
4391                                         SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
4392                                         Keyboard.FocusIn (FocusWindow);
4393                                         goto ProcessNextMessage;
4394                                 }
4395
4396                                 case XEventName.FocusOut: {
4397                                         // Se the comment for our FocusIn handler
4398                                         if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4399                                                 goto ProcessNextMessage;
4400                                         }
4401
4402                                         while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
4403                                                 SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
4404                                         }
4405
4406                                         Keyboard.FocusOut(hwnd.client_window);
4407                                         SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
4408                                         goto ProcessNextMessage;
4409                                 }
4410
4411                                 // We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
4412                                 // in case we break a scenario not taken into account in the tests
4413                                 case XEventName.MapNotify: {
4414                                         /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
4415                                                 hwnd.mapped = true;
4416                                                 msg.message = Msg.WM_SHOWWINDOW;
4417                                                 msg.wParam = (IntPtr) 1;
4418                                                 // XXX we're missing the lParam..
4419                                                 break;
4420                                         }*/
4421                                         goto ProcessNextMessage;
4422                                 }
4423
4424                                 case XEventName.UnmapNotify: {
4425                                         /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
4426                                                 hwnd.mapped = false;
4427                                                 msg.message = Msg.WM_SHOWWINDOW;
4428                                                 msg.wParam = (IntPtr) 0;
4429                                                 // XXX we're missing the lParam..
4430                                                 break;
4431                                         }*/
4432                                         goto ProcessNextMessage;
4433                                 }
4434
4435                                 case XEventName.Expose: {
4436                                         if (!hwnd.Mapped) {
4437                                                 if (client) {
4438                                                         hwnd.expose_pending = false;
4439                                                 } else {
4440                                                         hwnd.nc_expose_pending = false;
4441                                                 }
4442                                                 goto ProcessNextMessage;
4443                                         }
4444
4445                                         if (client) {
4446                                                 if (!hwnd.expose_pending) {
4447                                                         goto ProcessNextMessage;
4448                                                 }
4449                                         } else {
4450                                                 if (!hwnd.nc_expose_pending) {
4451                                                         goto ProcessNextMessage;
4452                                                 }
4453
4454                                                 switch (hwnd.border_style) {
4455                                                         case FormBorderStyle.Fixed3D: {
4456                                                                 Graphics g;
4457
4458                                                                 g = Graphics.FromHwnd(hwnd.whole_window);
4459                                                                 if (hwnd.border_static)
4460                                                                         ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.SunkenOuter);
4461                                                                 else
4462                                                                         ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
4463                                                                 g.Dispose();
4464                                                                 break;
4465                                                         }
4466
4467                                                         case FormBorderStyle.FixedSingle: {
4468                                                                 Graphics g;
4469
4470                                                                 g = Graphics.FromHwnd(hwnd.whole_window);
4471                                                                 ControlPaint.DrawBorder(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
4472                                                                 g.Dispose();
4473                                                                 break;
4474                                                         }
4475                                                 }
4476                                                 #if DriverDebugExtra
4477                                                         Console.WriteLine("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4478                                                 #endif
4479
4480                                                 Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4481                                                 Region region = new Region (rect);
4482                                                 IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
4483                                                 msg.message = Msg.WM_NCPAINT;
4484                                                 msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
4485                                                 msg.refobject = region;
4486                                                 break;
4487                                         }
4488                                         #if DriverDebugExtra
4489                                                 Console.WriteLine("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4490                                         #endif
4491                                         if (Caret.Visible == true) {
4492                                                 Caret.Paused = true;
4493                                                 HideCaret();
4494                                         }
4495
4496                                         if (Caret.Visible == true) {
4497                                                 ShowCaret();
4498                                                 Caret.Paused = false;
4499                                         }
4500                                         msg.message = Msg.WM_PAINT;
4501                                         break;
4502                                 }
4503
4504                                 case XEventName.DestroyNotify: {
4505
4506                                         // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
4507                                         hwnd = Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
4508
4509                                         // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
4510                                         if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
4511                                                 CleanupCachedWindows (hwnd);
4512
4513                                                 #if DriverDebugDestroy
4514                                                         Console.WriteLine("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
4515                                                 #endif
4516
4517                                                 msg.hwnd = hwnd.client_window;
4518                                                 msg.message=Msg.WM_DESTROY;
4519                                                 hwnd.Dispose();
4520                                         } else {
4521                                                 goto ProcessNextMessage;
4522                                         }
4523
4524                                         break;
4525                                 }
4526
4527                                 case XEventName.ClientMessage: {
4528                                         if (Dnd.HandleClientMessage (ref xevent)) {
4529                                                 goto ProcessNextMessage;
4530                                         }
4531
4532                                         if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
4533                                                 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
4534                                                 goto ProcessNextMessage;
4535                                         }
4536
4537                                         if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
4538                                                 msg.message = Msg.WM_MOUSEHOVER;
4539                                                 msg.wParam = GetMousewParam(0);
4540                                                 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
4541                                                 return true;
4542                                         }
4543
4544                                         if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {                                               
4545                                                 DebugHelper.Indent ();
4546                                                 DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
4547                                                 DebugHelper.Unindent ();
4548                                                 msg.hwnd = xevent.ClientMessageEvent.ptr1;
4549                                                 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
4550                                                 msg.wParam = xevent.ClientMessageEvent.ptr3;
4551                                                 msg.lParam = xevent.ClientMessageEvent.ptr4;
4552                                                 if (msg.message == (Msg)Msg.WM_QUIT)
4553                                                         return false;
4554                                                 else
4555                                                         return true;
4556                                         }
4557
4558                                         if  (xevent.ClientMessageEvent.message_type == _XEMBED) {
4559 #if DriverDebugXEmbed
4560                                                 Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
4561 #endif
4562
4563                                                 if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
4564                                                         XSizeHints hints = new XSizeHints();
4565                                                         IntPtr dummy;
4566
4567                                                         XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
4568
4569                                                         hwnd.width = hints.max_width;
4570                                                         hwnd.height = hints.max_height;
4571                                                         hwnd.ClientRect = Rectangle.Empty;
4572                                                         SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4573                                                 }
4574                                         }
4575
4576                                         if  (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
4577                                                 if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
4578                                                         SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
4579                                                         msg.message = Msg.WM_CLOSE;
4580                                                         return true;
4581                                                 }
4582
4583                                                 // We should not get this, but I'll leave the code in case we need it in the future
4584                                                 if (xevent.ClientMessageEvent.ptr1 == WM_TAKE_FOCUS) {
4585                                                         goto ProcessNextMessage;
4586                                                 }
4587                                         }
4588                                         goto ProcessNextMessage;
4589                                 }
4590
4591                                 default: {
4592                                         goto ProcessNextMessage;
4593                                 }
4594                         }
4595
4596                         return true;
4597                 }
4598
4599                 private HitTest NCHitTest (Hwnd hwnd, int x, int y)
4600                 {
4601                         // The hit test is sent in screen coordinates
4602                         IntPtr dummy;
4603                         int screen_x, screen_y;
4604                         XTranslateCoordinates (DisplayHandle, hwnd.WholeWindow, RootWindow, x, y, out screen_x, out screen_y, out dummy);
4605                         return (HitTest) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, 
4606                                                                (IntPtr) (screen_y << 16 | screen_x & 0xFFFF));
4607                 }
4608
4609                 internal override bool GetText(IntPtr handle, out string text) {
4610
4611                         lock (XlibLock) {
4612                                 IntPtr actual_atom;
4613                                 int actual_format;
4614                                 IntPtr nitems;
4615                                 IntPtr bytes_after;
4616                                 IntPtr prop = IntPtr.Zero;
4617
4618                                 XGetWindowProperty(DisplayHandle, handle,
4619                                                    _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
4620                                                    UTF8_STRING, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
4621
4622                                 if ((long)nitems > 0 && prop != IntPtr.Zero) {
4623                                         text = Marshal.PtrToStringUni (prop, (int)nitems);
4624                                         XFree (prop);
4625                                         return true;
4626                                 }
4627                                 else {
4628                                         // fallback on the non-_NET property
4629                                         IntPtr  textptr;
4630
4631                                         textptr = IntPtr.Zero;
4632
4633                                         XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
4634                                         if (textptr != IntPtr.Zero) {
4635                                                 text = Marshal.PtrToStringAnsi(textptr);
4636                                                 XFree(textptr);
4637                                                 return true;
4638                                         } else {
4639                                                 text = "";
4640                                                 return false;
4641                                         }
4642                                 }
4643                         }
4644                 }
4645
4646                 internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
4647                         Hwnd            hwnd;
4648
4649                         hwnd = Hwnd.ObjectFromHandle(handle);
4650
4651                         if (hwnd != null) {
4652                                 x = hwnd.x;
4653                                 y = hwnd.y;
4654                                 width = hwnd.width;
4655                                 height = hwnd.height;
4656
4657                                 PerformNCCalc(hwnd);
4658
4659                                 client_width = hwnd.ClientRect.Width;
4660                                 client_height = hwnd.ClientRect.Height;
4661
4662                                 return;
4663                         }
4664
4665                         // Should we throw an exception or fail silently?
4666                         // throw new ArgumentException("Called with an invalid window handle", "handle");
4667
4668                         x = 0;
4669                         y = 0;
4670                         width = 0;
4671                         height = 0;
4672                         client_width = 0;
4673                         client_height = 0;
4674                 }
4675
4676                 internal override FormWindowState GetWindowState(IntPtr handle) {
4677                         Hwnd                    hwnd;
4678
4679                         hwnd = Hwnd.ObjectFromHandle(handle);
4680
4681                         if (hwnd.cached_window_state == (FormWindowState)(-1))
4682                                 hwnd.cached_window_state = UpdateWindowState (handle);
4683
4684                         return hwnd.cached_window_state;
4685                 }
4686
4687                 private FormWindowState UpdateWindowState (IntPtr handle) {
4688                         IntPtr                  actual_atom;
4689                         int                     actual_format;
4690                         IntPtr                  nitems;
4691                         IntPtr                  bytes_after;
4692                         IntPtr                  prop = IntPtr.Zero;
4693                         IntPtr                  atom;
4694                         int                     maximized;
4695                         bool                    minimized;
4696                         XWindowAttributes       attributes;
4697                         Hwnd                    hwnd;
4698
4699                         hwnd = Hwnd.ObjectFromHandle(handle);
4700
4701                         maximized = 0;
4702                         minimized = false;
4703                         XGetWindowProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
4704                         if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
4705                                 for (int i = 0; i < (long)nitems; i++) {
4706                                         atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
4707                                         if ((atom == _NET_WM_STATE_MAXIMIZED_HORZ) || (atom == _NET_WM_STATE_MAXIMIZED_VERT)) {
4708                                                 maximized++;
4709                                         } else if (atom == _NET_WM_STATE_HIDDEN) {
4710                                                 minimized = true;
4711                                         }
4712                                 }
4713                                 XFree(prop);
4714                         }
4715
4716                         if (minimized) {
4717                                 return FormWindowState.Minimized;
4718                         } else if (maximized == 2) {
4719                                 return FormWindowState.Maximized;
4720                         }
4721
4722                         attributes = new XWindowAttributes();
4723                         XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4724                         if (attributes.map_state == MapState.IsUnmapped) {
4725                                 return (FormWindowState)(-1);
4726                         }
4727
4728
4729                         return FormWindowState.Normal;
4730                 }
4731
4732                 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea) {
4733                         handle = Grab.Hwnd;
4734                         GrabConfined = Grab.Confined;
4735                         GrabArea = Grab.Area;
4736                 }
4737
4738                 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
4739                         Hwnd    hwnd;
4740                         IntPtr  confine_to_window;
4741
4742                         confine_to_window = IntPtr.Zero;
4743
4744                         if (confine_to_handle != IntPtr.Zero) {
4745                                 XWindowAttributes       attributes = new XWindowAttributes();
4746
4747                                 hwnd = Hwnd.ObjectFromHandle(confine_to_handle);
4748
4749                                 lock (XlibLock) {
4750                                         XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4751                                 }
4752                                 Grab.Area.X = attributes.x;
4753                                 Grab.Area.Y = attributes.y;
4754                                 Grab.Area.Width = attributes.width;
4755                                 Grab.Area.Height = attributes.height;
4756                                 Grab.Confined = true;
4757                                 confine_to_window = hwnd.client_window;
4758                         }
4759
4760                         Grab.Hwnd = handle;
4761
4762                         hwnd = Hwnd.ObjectFromHandle(handle);
4763
4764                         lock (XlibLock) {
4765                                 XGrabPointer(DisplayHandle, hwnd.client_window, false, 
4766                                         EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
4767                                         EventMask.ButtonReleaseMask | EventMask.PointerMotionMask | 
4768                                         EventMask.PointerMotionHintMask | EventMask.LeaveWindowMask,
4769                                         GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
4770                         }
4771                 }
4772
4773                 internal override void UngrabWindow(IntPtr hwnd) {
4774                         lock (XlibLock) {
4775                                 XUngrabPointer(DisplayHandle, IntPtr.Zero);
4776                                 XFlush(DisplayHandle);
4777                         }
4778                         WindowUngrabbed (hwnd);                 
4779                 }
4780                 
4781                 private void WindowUngrabbed (IntPtr hwnd) {
4782                         bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
4783                         
4784                         Grab.Hwnd = IntPtr.Zero;
4785                         Grab.Confined = false;
4786                         
4787                         if (was_grabbed) {
4788                                 // lparam should be the handle to the window gaining the mouse capture,
4789                                 // but X doesn't seem to give us that information.
4790                                 // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
4791                                 // X will send a NotifyUngrab, but since it comes late sometimes we're
4792                                 // calling WindowUngrabbed directly from UngrabWindow in order to send
4793                                 // this WM right away.
4794                                 SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
4795                         }
4796                 }
4797
4798                 internal override void HandleException(Exception e) {
4799                         StackTrace st = new StackTrace(e, true);
4800                         Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
4801                         Console.WriteLine("{0}{1}", e.Message, st.ToString());
4802                 }
4803
4804                 internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
4805                         Hwnd    hwnd;
4806
4807                         hwnd = Hwnd.ObjectFromHandle(handle);
4808
4809                         if (clear) {
4810                                 AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
4811                         } else {
4812                                 AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
4813                         }
4814                 }
4815
4816                 internal override void InvalidateNC (IntPtr handle) {
4817                         Hwnd    hwnd;
4818
4819                         hwnd = Hwnd.ObjectFromHandle(handle);
4820
4821                         AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
4822                 }
4823
4824                 internal override bool IsEnabled(IntPtr handle) {
4825                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4826                         return (hwnd != null && hwnd.Enabled);
4827                 }
4828                 
4829                 internal override bool IsVisible(IntPtr handle) {
4830                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4831                         return (hwnd != null && hwnd.visible);
4832                 }
4833
4834                 internal override void KillTimer(Timer timer) {
4835                         XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
4836
4837                         if (queue == null) {
4838                                 // This isn't really an error, MS doesn't start the timer if
4839                                 // it has no assosciated queue. In this case, remove the timer
4840                                 // from the list of unattached timers (if it was enabled).
4841                                 lock (unattached_timer_list) {
4842                                         if (unattached_timer_list.Contains (timer))
4843                                                 unattached_timer_list.Remove (timer);
4844                                 }
4845                                 return;
4846                         }
4847                         queue.timer_list.Remove (timer);
4848                 }
4849
4850                 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
4851                         int     dest_x_return;
4852                         int     dest_y_return;
4853                         IntPtr  child;
4854                         Hwnd    hwnd;
4855
4856                         hwnd = Hwnd.ObjectFromHandle(handle);
4857
4858                         lock (XlibLock) {
4859                                 XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
4860                         }
4861
4862                         x = dest_x_return;
4863                         y = dest_y_return;
4864                 }
4865
4866                 internal override void OverrideCursor(IntPtr cursor)
4867                 {
4868                         if (Grab.Hwnd != IntPtr.Zero) {
4869                                 XChangeActivePointerGrab (DisplayHandle,
4870                                                 EventMask.ButtonMotionMask |
4871                                                 EventMask.PointerMotionMask |
4872                                                 EventMask.PointerMotionHintMask |
4873                                                 EventMask.ButtonPressMask |
4874                                                 EventMask.ButtonReleaseMask,
4875                                                 cursor, IntPtr.Zero);
4876                                 return;
4877                         }
4878
4879                         OverrideCursorHandle = cursor;
4880                 }
4881
4882                 internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client) {
4883                         PaintEventArgs  paint_event;
4884                         Hwnd            hwnd;
4885                         Hwnd            paint_hwnd;
4886                         
4887                         // 
4888                         // handle  (and paint_hwnd) refers to the window that is should be painted.
4889                         // msg.HWnd (and hwnd) refers to the window that got the paint message.
4890                         // 
4891                         
4892                         hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
4893                         if (msg.HWnd == handle) {
4894                                 paint_hwnd = hwnd;
4895                         } else {
4896                                 paint_hwnd = Hwnd.ObjectFromHandle (handle);
4897                         }
4898         
4899                         if (Caret.Visible == true) {
4900                                 Caret.Paused = true;
4901                                 HideCaret();
4902                         }
4903
4904                         Graphics dc;
4905
4906                         if (client) {
4907                                 dc = Graphics.FromHwnd (paint_hwnd.client_window);
4908
4909                                 Region clip_region = new Region ();
4910                                 clip_region.MakeEmpty();
4911
4912                                 foreach (Rectangle r in hwnd.ClipRectangles) {
4913                                         clip_region.Union (r);
4914                                 }
4915
4916                                 if (hwnd.UserClip != null) {
4917                                         clip_region.Intersect(hwnd.UserClip);
4918                                 }
4919
4920                                 dc.Clip = clip_region;
4921                                 paint_event = new PaintEventArgs(dc, hwnd.Invalid);
4922                                 hwnd.expose_pending = false;
4923
4924                                 hwnd.ClearInvalidArea();
4925
4926                                 hwnd.drawing_stack.Push (paint_event);
4927                                 hwnd.drawing_stack.Push (dc);
4928
4929                                 return paint_event;
4930                         } else {
4931                                 dc = Graphics.FromHwnd (paint_hwnd.whole_window);
4932
4933                                 if (!hwnd.nc_invalid.IsEmpty) {
4934                                         dc.SetClip (hwnd.nc_invalid);
4935                                         paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
4936                                 } else {
4937                                         paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
4938                                 }
4939                                 hwnd.nc_expose_pending = false;
4940
4941                                 hwnd.ClearNcInvalidArea ();
4942
4943                                 hwnd.drawing_stack.Push (paint_event);
4944                                 hwnd.drawing_stack.Push (dc);
4945
4946                                 return paint_event;
4947                         }
4948                 }
4949
4950                 internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client) {
4951                         Hwnd    hwnd;
4952
4953                         hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
4954
4955                         Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
4956                         dc.Flush();
4957                         dc.Dispose();
4958                         
4959                         PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
4960                         pe.SetGraphics (null);
4961                         pe.Dispose ();
4962
4963                         if (Caret.Visible == true) {
4964                                 ShowCaret();
4965                                 Caret.Paused = false;
4966                         }
4967                 }
4968
4969                 [MonoTODO("Implement filtering and PM_NOREMOVE")]
4970                 internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
4971                         XEventQueue queue = (XEventQueue) queue_id;
4972                         bool    pending;
4973
4974                         if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
4975                                 throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet");    // FIXME - Implement PM_NOREMOVE flag
4976                         }
4977
4978                         pending = false;
4979                         if (queue.Count > 0) {
4980                                 pending = true;
4981                         } else {
4982                                 // Only call UpdateMessageQueue if real events are pending 
4983                                 // otherwise we go to sleep on the socket
4984                                 if (XPending(DisplayHandle) != 0) {
4985                                         UpdateMessageQueue((XEventQueue)queue_id);
4986                                         pending = true;
4987                                 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
4988                                         pending = true;
4989                                 }
4990                         }
4991
4992                         CheckTimers(queue.timer_list, DateTime.UtcNow);
4993
4994                         if (!pending) {
4995                                 return false;
4996                         }
4997                         return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
4998                 }
4999
5000                 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam) {
5001                         XEvent xevent = new XEvent ();
5002                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5003
5004                         xevent.type = XEventName.ClientMessage;
5005                         xevent.ClientMessageEvent.display = DisplayHandle;
5006
5007                         if (hwnd != null) {
5008                                 xevent.ClientMessageEvent.window = hwnd.whole_window;
5009                         } else {
5010                                 xevent.ClientMessageEvent.window = IntPtr.Zero;
5011                         }
5012
5013                         xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
5014                         xevent.ClientMessageEvent.format = 32;
5015                         xevent.ClientMessageEvent.ptr1 = handle;
5016                         xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
5017                         xevent.ClientMessageEvent.ptr3 = wparam;
5018                         xevent.ClientMessageEvent.ptr4 = lparam;
5019
5020                         if (hwnd != null)
5021                                 hwnd.Queue.EnqueueLocked (xevent);
5022                         else
5023                                 ThreadQueue(Thread.CurrentThread).EnqueueLocked (xevent);
5024
5025                         return true;
5026                 }
5027
5028                 internal override void PostQuitMessage(int exitCode) {
5029                         ApplicationContext ctx = Application.MWFThread.Current.Context;
5030                         Form f = ctx != null ? ctx.MainForm : null;
5031                         if (f != null)
5032                                 PostMessage (Application.MWFThread.Current.Context.MainForm.window.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5033                         else
5034                                 PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5035                         XFlush(DisplayHandle);
5036                 }
5037
5038                 internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
5039                 {
5040                         // TODO
5041                 }
5042
5043                 internal override void RequestNCRecalc(IntPtr handle) {
5044                         Hwnd                            hwnd;
5045
5046                         hwnd = Hwnd.ObjectFromHandle(handle);
5047
5048                         if (hwnd == null) {
5049                                 return;
5050                         }
5051
5052                         PerformNCCalc(hwnd);
5053                         SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5054                         InvalidateNC(handle);
5055                 }
5056
5057                 internal override void ResetMouseHover(IntPtr handle) {
5058                         Hwnd    hwnd;
5059
5060                         hwnd = Hwnd.ObjectFromHandle(handle);
5061                         if (hwnd == null) {
5062                                 return;
5063                         }
5064
5065                         HoverState.Timer.Enabled = true;
5066                         HoverState.X = mouse_position.X;
5067                         HoverState.Y = mouse_position.Y;
5068                         HoverState.Window = handle;
5069                 }
5070
5071
5072                 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
5073                         int     dest_x_return;
5074                         int     dest_y_return;
5075                         IntPtr  child;
5076                         Hwnd    hwnd;
5077
5078                         hwnd = Hwnd.ObjectFromHandle(handle);
5079
5080                         lock (XlibLock) {
5081                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
5082                         }
5083
5084                         x = dest_x_return;
5085                         y = dest_y_return;
5086                 }
5087
5088                 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
5089                         int     dest_x_return;
5090                         int     dest_y_return;
5091                         IntPtr  child;
5092                         Hwnd    hwnd;
5093
5094                         hwnd = Hwnd.ObjectFromHandle(handle);
5095
5096                         lock (XlibLock) {
5097                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
5098                         }
5099
5100                         Form form = Control.FromHandle (handle) as Form;
5101                         if (form != null && form.window_manager != null) {
5102                                 dest_y_return -= form.window_manager.TitleBarHeight;
5103                         }
5104
5105                         x = dest_x_return;
5106                         y = dest_y_return;
5107                 }
5108
5109                 bool GraphicsExposePredicate (IntPtr display, ref XEvent xevent, IntPtr arg)
5110                 {
5111                         return (xevent.type == XEventName.GraphicsExpose || xevent.type == XEventName.NoExpose) &&
5112                                 arg == xevent.GraphicsExposeEvent.drawable;
5113                 }
5114
5115                 delegate bool EventPredicate (IntPtr display, ref XEvent xevent, IntPtr arg);
5116
5117                 void ProcessGraphicsExpose (Hwnd hwnd)
5118                 {
5119                         XEvent xevent = new XEvent ();
5120                         IntPtr handle = Hwnd.HandleFromObject (hwnd);
5121                         EventPredicate predicate = GraphicsExposePredicate;
5122
5123                         for (;;) {
5124                                 XIfEvent (Display, ref xevent, predicate, handle);
5125                                 if (xevent.type != XEventName.GraphicsExpose)
5126                                         break;
5127
5128                                 AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.GraphicsExposeEvent.x, xevent.GraphicsExposeEvent.y,
5129                                                 xevent.GraphicsExposeEvent.width, xevent.GraphicsExposeEvent.height);
5130
5131                                 if (xevent.GraphicsExposeEvent.count == 0)
5132                                         break;
5133                         }
5134                 }
5135
5136                 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children) {
5137                         Hwnd            hwnd;
5138                         IntPtr          gc;
5139                         XGCValues       gc_values;
5140
5141                         hwnd = Hwnd.ObjectFromHandle(handle);
5142
5143                         Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
5144                         if (!r.IsEmpty) {
5145                                 /* We have an invalid area in the window we're scrolling. 
5146                                    Adjust our stored invalid rectangle to to match the scrolled amount */
5147
5148                                 r.X += XAmount;
5149                                 r.Y += YAmount;
5150
5151                                 if (r.X < 0) {
5152                                         r.Width += r.X;
5153                                         r.X =0;
5154                                 }
5155
5156                                 if (r.Y < 0) {
5157                                         r.Height += r.Y;
5158                                         r.Y =0;
5159                                 }
5160
5161                                 if (area.Contains (hwnd.Invalid))
5162                                         hwnd.ClearInvalidArea ();
5163                                 hwnd.AddInvalidArea(r);
5164                         }
5165
5166                         gc_values = new XGCValues();
5167
5168                         if (with_children) {
5169                                 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
5170                         }
5171
5172                         gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
5173
5174                         Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
5175                         visible_rect.Intersect (area);
5176
5177                         Rectangle dest_rect = visible_rect;
5178                         dest_rect.Y += YAmount;
5179                         dest_rect.X += XAmount;
5180                         dest_rect.Intersect (area);
5181
5182                         Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
5183                         XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y, 
5184                                         dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
5185
5186                         Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
5187                         AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
5188
5189                         ProcessGraphicsExpose (hwnd);
5190
5191                         XFreeGC(DisplayHandle, gc);
5192                 }
5193
5194                 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children) {
5195                         Hwnd            hwnd;
5196                         Rectangle       rect;
5197
5198                         hwnd = Hwnd.GetObjectFromWindow(handle);
5199
5200                         rect = hwnd.ClientRect;
5201                         rect.X = 0;
5202                         rect.Y = 0;
5203                         ScrollWindow(handle, rect, XAmount, YAmount, with_children);
5204                 }
5205
5206                 Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
5207                 {
5208                         Rectangle dirty_area = total_area;
5209
5210                         if (YAmount > 0)
5211                                 dirty_area.Height -= valid_area.Height;
5212                         else if (YAmount < 0) {
5213                                 dirty_area.Height -= valid_area.Height;
5214                                 dirty_area.Y += valid_area.Height;
5215                         }
5216
5217                         if (XAmount > 0)
5218                                 dirty_area.Width -= valid_area.Width;
5219                         else if (XAmount < 0) {
5220                                 dirty_area.Width -= valid_area.Width;
5221                                 dirty_area.X += valid_area.Width;
5222                         }
5223
5224                         return dirty_area;
5225                 }
5226
5227                 Rectangle GetTotalVisibleArea (IntPtr handle)
5228                 {
5229                         Control c = Control.FromHandle (handle);
5230
5231                         Rectangle visible_area = c.ClientRectangle;
5232                         visible_area.Location = c.PointToScreen (Point.Empty);
5233
5234                         for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
5235                                 if (!parent.IsHandleCreated || !parent.Visible)
5236                                         return visible_area; // Non visible, not need to finish computations
5237
5238                                 Rectangle r = parent.ClientRectangle;
5239                                 r.Location = parent.PointToScreen (Point.Empty);
5240
5241                                 visible_area.Intersect (r);
5242                         }
5243
5244                         visible_area.Location = c.PointToClient (visible_area.Location);
5245                         return visible_area;
5246                 }
5247
5248                 internal override void SendAsyncMethod (AsyncMethodData method) {
5249                         Hwnd    hwnd;
5250                         XEvent  xevent = new XEvent ();
5251
5252                         hwnd = Hwnd.ObjectFromHandle(method.Handle);
5253
5254                         xevent.type = XEventName.ClientMessage;
5255                         xevent.ClientMessageEvent.display = DisplayHandle;
5256                         xevent.ClientMessageEvent.window = method.Handle;
5257                         xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
5258                         xevent.ClientMessageEvent.format = 32;
5259                         xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
5260
5261                         hwnd.Queue.EnqueueLocked (xevent);
5262
5263                         WakeupMain ();
5264                 }
5265
5266                 delegate IntPtr WndProcDelegate (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam);
5267
5268                 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
5269                 {
5270                         Hwnd    h;
5271                         h = Hwnd.ObjectFromHandle(hwnd);
5272
5273                         if (h != null && h.queue != ThreadQueue (Thread.CurrentThread)) {
5274                                 AsyncMethodResult       result;
5275                                 AsyncMethodData         data;
5276
5277                                 result = new AsyncMethodResult ();
5278                                 data = new AsyncMethodData ();
5279
5280                                 data.Handle = hwnd;
5281                                 data.Method = new WndProcDelegate (NativeWindow.WndProc);
5282                                 data.Args = new object[] { hwnd, message, wParam, lParam };
5283                                 data.Result = result;
5284                                 
5285                                 SendAsyncMethod (data);
5286                                 #if DriverDebug || DriverDebugThreads
5287                                 Console.WriteLine ("Sending {0} message across.", message);
5288                                 #endif
5289
5290                                 return IntPtr.Zero;
5291                         }
5292                         string key = hwnd + ":" + message;
5293                         if (messageHold[key] != null)
5294                                 messageHold[key] = ((int)messageHold[key]) - 1;
5295                         return NativeWindow.WndProc(hwnd, message, wParam, lParam);
5296                 }
5297
5298                 internal override int SendInput(IntPtr handle, Queue keys) { 
5299                         if (handle == IntPtr.Zero)
5300                                 return 0;
5301
5302                         int count = keys.Count;
5303                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5304
5305                         while (keys.Count > 0) {
5306                         
5307                                 MSG msg = (MSG)keys.Dequeue();
5308
5309                                 XEvent xevent = new XEvent ();
5310
5311                                 xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
5312                                 xevent.KeyEvent.display = DisplayHandle;
5313
5314                                 if (hwnd != null) {
5315                                         xevent.KeyEvent.window = hwnd.whole_window;
5316                                 } else {
5317                                         xevent.KeyEvent.window = IntPtr.Zero;
5318                                 }
5319
5320                                 xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
5321
5322                                 hwnd.Queue.EnqueueLocked (xevent);
5323                         }
5324                         return count;
5325                 }
5326
5327                 internal override void SetAllowDrop (IntPtr handle, bool value)
5328                 {
5329                         // We allow drop on all windows
5330                 }
5331
5332                 internal override DragDropEffects StartDrag (IntPtr handle, object data,
5333                                 DragDropEffects allowed_effects)
5334                 {
5335                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5336
5337                         if (hwnd == null)
5338                                 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
5339
5340                         return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
5341                 }
5342
5343                 internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style) {
5344                         Form form = Control.FromHandle (handle) as Form;
5345                         if (form != null && form.window_manager == null) {
5346                                 CreateParams cp = form.GetCreateParams ();
5347                                 if (border_style == FormBorderStyle.FixedToolWindow ||
5348                                      border_style == FormBorderStyle.SizableToolWindow || 
5349                                      cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
5350                                         form.window_manager = new ToolWindowManager (form);
5351                                 }
5352                         }
5353                         
5354                         RequestNCRecalc(handle);
5355                 }
5356
5357                 internal override void SetCaretPos(IntPtr handle, int x, int y) {
5358                         if (Caret.Hwnd == handle) {
5359                                 Caret.Timer.Stop();
5360                                 HideCaret();
5361
5362                                 Caret.X = x;
5363                                 Caret.Y = y;
5364
5365                                 Keyboard.SetCaretPos (Caret, handle, x, y);
5366
5367                                 if (Caret.Visible == true) {
5368                                         ShowCaret();
5369                                         Caret.Timer.Start();
5370                                 }
5371                         }
5372                 }
5373
5374                 internal override void SetClipRegion(IntPtr handle, Region region) {
5375                         Hwnd    hwnd;
5376
5377                         hwnd = Hwnd.ObjectFromHandle(handle);
5378                         if (hwnd == null) {
5379                                 return;
5380                         }
5381
5382                         hwnd.UserClip = region;
5383                 }
5384
5385                 internal override void SetCursor(IntPtr handle, IntPtr cursor) {
5386                         Hwnd    hwnd;
5387
5388                         if (OverrideCursorHandle == IntPtr.Zero) {
5389                                 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
5390                                         return;
5391                                 }
5392
5393                                 LastCursorHandle = cursor;
5394                                 LastCursorWindow = handle;
5395
5396                                 hwnd = Hwnd.ObjectFromHandle(handle);
5397                                 lock (XlibLock) {
5398                                         if (cursor != IntPtr.Zero) {
5399                                                 XDefineCursor(DisplayHandle, hwnd.whole_window, cursor);
5400                                         } else {
5401                                                 XUndefineCursor(DisplayHandle, hwnd.whole_window);
5402                                         }
5403                                         XFlush(DisplayHandle);
5404                                 }
5405                                 return;
5406                         }
5407
5408                         hwnd = Hwnd.ObjectFromHandle(handle);
5409                         lock (XlibLock) {
5410                                 XDefineCursor(DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
5411                         }
5412                 }
5413
5414                 private void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
5415                                            out int root_x, out int root_y, out int child_x, out int child_y,
5416                                            out int mask)
5417                 {
5418                         /* this code was written with the help of
5419                         glance at gdk.  I never would have realized we
5420                         needed a loop in order to traverse down in the
5421                         hierarchy.  I would have assumed you'd get the
5422                         most deeply nested child and have to do
5423                         XQueryTree to move back up the hierarchy..
5424                         stupid me, of course. */
5425                         IntPtr c;
5426
5427                         XGrabServer (display);
5428
5429                         XQueryPointer(display, w, out root, out c,
5430                                       out root_x, out root_y, out child_x, out child_y,
5431                                       out mask);
5432
5433                         if (root != w)
5434                                 c = root;
5435
5436                         IntPtr child_last = IntPtr.Zero;
5437                         while (c != IntPtr.Zero) {
5438                                 child_last = c;
5439                                 XQueryPointer(display, c, out root, out c,
5440                                               out root_x, out root_y, out child_x, out child_y,
5441                                               out mask);
5442                         }
5443                         XUngrabServer (display);
5444                         XFlush (display);
5445
5446                         child = child_last;
5447                 }
5448
5449                 internal override void SetCursorPos(IntPtr handle, int x, int y) {
5450                         if (handle == IntPtr.Zero) {
5451                                 lock (XlibLock) {
5452                                         IntPtr root, child;
5453                                         int root_x, root_y, child_x, child_y, mask;
5454
5455                                         /* we need to do a
5456                                          * QueryPointer before warping
5457                                          * because if the warp is on
5458                                          * the RootWindow, the x/y are
5459                                          * relative to the current
5460                                          * mouse position
5461                                          */
5462                                         QueryPointer (DisplayHandle, RootWindow,
5463                                                       out root,
5464                                                       out child,
5465                                                       out root_x, out root_y,
5466                                                       out child_x, out child_y,
5467                                                       out mask);
5468
5469                                         XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x - root_x, y - root_y);
5470
5471                                         XFlush (DisplayHandle);
5472
5473                                         /* then we need to a
5474                                          * QueryPointer after warping
5475                                          * to manually generate a
5476                                          * motion event for the window
5477                                          * we move into.
5478                                          */
5479                                         QueryPointer (DisplayHandle, RootWindow,
5480                                                       out root,
5481                                                       out child,
5482                                                       out root_x, out root_y,
5483                                                       out child_x, out child_y,
5484                                                       out mask);
5485
5486                                         Hwnd child_hwnd = Hwnd.ObjectFromHandle(child);
5487                                         if (child_hwnd == null) {
5488                                                 return;
5489                                         }
5490
5491                                         XEvent xevent = new XEvent ();
5492
5493                                         xevent.type = XEventName.MotionNotify;
5494                                         xevent.MotionEvent.display = DisplayHandle;
5495                                         xevent.MotionEvent.window = child_hwnd.client_window;
5496                                         xevent.MotionEvent.root = RootWindow;
5497                                         xevent.MotionEvent.x = child_x;
5498                                         xevent.MotionEvent.y = child_y;
5499                                         xevent.MotionEvent.x_root = root_x;
5500                                         xevent.MotionEvent.y_root = root_y;
5501                                         xevent.MotionEvent.state = mask;
5502
5503                                         child_hwnd.Queue.EnqueueLocked (xevent);
5504                                 }
5505                         } else {
5506                                 Hwnd    hwnd;
5507
5508                                 hwnd = Hwnd.ObjectFromHandle(handle);
5509                                 lock (XlibLock) {
5510                                         XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
5511                                 }
5512                         }
5513                 }
5514
5515                 internal override void SetFocus(IntPtr handle) {
5516                         Hwnd    hwnd;
5517                         IntPtr  prev_focus_window;
5518
5519                         hwnd = Hwnd.ObjectFromHandle(handle);
5520
5521                         if (hwnd.client_window == FocusWindow) {
5522                                 return;
5523                         }
5524
5525                         // Win32 doesn't do anything if disabled
5526                         if (!hwnd.enabled)
5527                                 return;
5528
5529                         prev_focus_window = FocusWindow;
5530                         FocusWindow = hwnd.client_window;
5531
5532                         if (prev_focus_window != IntPtr.Zero) {
5533                                 SendMessage(prev_focus_window, Msg.WM_KILLFOCUS, FocusWindow, IntPtr.Zero);
5534                         }
5535                         SendMessage(FocusWindow, Msg.WM_SETFOCUS, prev_focus_window, IntPtr.Zero);
5536                         Keyboard.FocusIn (FocusWindow);
5537
5538                         //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
5539                 }
5540
5541                 internal override void SetIcon(IntPtr handle, Icon icon) {
5542                         Hwnd    hwnd;
5543
5544                         hwnd = Hwnd.ObjectFromHandle(handle);
5545                         if (hwnd != null) {
5546                                 SetIcon(hwnd, icon);
5547                         }
5548                 }
5549
5550                 internal override void SetMenu(IntPtr handle, Menu menu) {
5551                         Hwnd    hwnd;
5552
5553                         hwnd = Hwnd.ObjectFromHandle(handle);
5554                         hwnd.menu = menu;
5555
5556                         RequestNCRecalc(handle);
5557                 }
5558
5559                 internal override void SetModal(IntPtr handle, bool Modal) {
5560                         if (Modal) {
5561                                 ModalWindows.Push(handle);
5562                         } else {
5563                                 if (ModalWindows.Contains(handle)) {
5564                                         ModalWindows.Pop();
5565                                 }
5566                                 if (ModalWindows.Count > 0) {
5567                                         Activate((IntPtr)ModalWindows.Peek());
5568                                 }
5569                         }
5570
5571                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5572                         Control ctrl = Control.FromHandle (handle);
5573                         SetWMStyles (hwnd, ctrl.GetCreateParams ());
5574                 }
5575
5576                 internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
5577                         Hwnd    hwnd;
5578
5579                         hwnd = Hwnd.ObjectFromHandle(handle);
5580                         hwnd.parent = Hwnd.ObjectFromHandle(parent);
5581
5582                         lock (XlibLock) {
5583                                 #if DriverDebug || DriverDebugParent
5584                                         Console.WriteLine("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
5585                                 #endif
5586                                 XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent == null ? FosterParent : hwnd.parent.client_window, hwnd.x, hwnd.y);
5587                         }
5588
5589                         return IntPtr.Zero;
5590                 }
5591
5592                 internal override void SetTimer (Timer timer) {
5593                         XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5594
5595                         if (queue == null) {
5596                                 // This isn't really an error, MS doesn't start the timer if
5597                                 // it has no assosciated queue at this stage (it will be
5598                                 // enabled when a window is activated).
5599                                 unattached_timer_list.Add (timer);
5600                                 return;
5601                         }
5602                         queue.timer_list.Add (timer);
5603                         WakeupMain ();
5604                 }
5605
5606                 internal override bool SetTopmost(IntPtr handle, bool enabled) {
5607
5608                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5609
5610                         if (enabled) {
5611                                 lock (XlibLock) {
5612                                         if (hwnd.Mapped) {
5613                                                 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_ADD, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5614                                         } else {
5615                                                 int[] atoms = new int[8];
5616                                                 atoms[0] = _NET_WM_STATE_ABOVE.ToInt32();
5617                                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5618                                         }
5619                                 }
5620                         } else {
5621                                 lock (XlibLock) {
5622                                         if (hwnd.Mapped)
5623                                                 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_REMOVE, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5624                                         else
5625                                                 XDeleteProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE);
5626                                 }
5627                         }
5628                         return true;
5629                 }
5630
5631                 internal override bool SetOwner(IntPtr handle, IntPtr handle_owner) {
5632                         Hwnd hwnd;
5633                         Hwnd hwnd_owner;
5634
5635                         hwnd = Hwnd.ObjectFromHandle(handle);
5636
5637                         if (handle_owner != IntPtr.Zero) {
5638                                 hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
5639                                 lock (XlibLock) {
5640                                         int[]   atoms;
5641
5642                                         atoms = new int[8];
5643
5644                                         atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
5645                                         XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5646
5647                                         if (hwnd_owner != null) {
5648                                                 XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
5649                                         } else {
5650                                                 XSetTransientForHint(DisplayHandle, hwnd.whole_window, RootWindow);
5651                                         }
5652                                 }
5653                         } else {
5654                                 lock (XlibLock) {
5655                                         XDeleteProperty(DisplayHandle, hwnd.whole_window, (IntPtr)Atom.XA_WM_TRANSIENT_FOR);
5656                                 }
5657                         }
5658                         return true;
5659                 }
5660
5661                 internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
5662                 {
5663                         Hwnd    hwnd;
5664
5665                         hwnd = Hwnd.ObjectFromHandle(handle);
5666                         hwnd.visible = visible;
5667
5668                         lock (XlibLock) {
5669                                 if (visible) {
5670                                         MapWindow(hwnd, WindowType.Both);
5671
5672                                         if (Control.FromHandle(handle) is Form) {
5673                                                 FormWindowState s;
5674
5675                                                 s = ((Form)Control.FromHandle(handle)).WindowState;
5676
5677                                                 switch(s) {
5678                                                         case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
5679                                                         case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
5680                                                 }
5681                                         }
5682
5683                                         SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5684                                 }
5685                                 else {
5686                                         UnmapWindow(hwnd, WindowType.Both);
5687                                 }
5688                         }
5689                         return true;
5690                 }
5691
5692                 internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
5693                         Control ctrl = Control.FromHandle (handle);
5694                         SetWindowMinMax (handle, maximized, min, max, ctrl != null ? ctrl.GetCreateParams () : null);
5695                 }
5696
5697                 internal void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max, CreateParams cp)
5698                 {
5699                         Hwnd            hwnd;
5700                         XSizeHints      hints;
5701                         IntPtr          dummy;
5702
5703                         hwnd = Hwnd.ObjectFromHandle(handle);
5704                         if (hwnd == null) {
5705                                 return;
5706                         }
5707
5708                         min.Width = Math.Max (min.Width, SystemInformation.MinimumWindowSize.Width);
5709                         min.Height = Math.Max (min.Height, SystemInformation.MinimumWindowSize.Height);
5710                         
5711                         hints = new XSizeHints();
5712
5713                         XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
5714                         if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
5715                                 if (cp != null)
5716                                         min = TranslateWindowSizeToXWindowSize (cp, min);
5717                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
5718                                 hints.min_width = min.Width;
5719                                 hints.min_height = min.Height;
5720                         }
5721
5722                         if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
5723                                 if (cp != null)
5724                                         max = TranslateWindowSizeToXWindowSize (cp, max);
5725                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
5726                                 hints.max_width = max.Width;
5727                                 hints.max_height = max.Height;
5728                         }
5729
5730                         if (hints.flags != IntPtr.Zero) {
5731                                 // The Metacity team has decided that they won't care about this when clicking the maximize icon, 
5732                                 // they will maximize the window to fill the screen/parent no matter what.
5733                                 // http://bugzilla.ximian.com/show_bug.cgi?id=80021
5734                                 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
5735                         }
5736
5737                         if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
5738                                 if (cp != null)
5739                                         maximized.Size = TranslateWindowSizeToXWindowSize (cp);
5740                                 hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
5741                                 hints.x = maximized.X;
5742                                 hints.y = maximized.Y;
5743                                 hints.width = maximized.Width;
5744                                 hints.height = maximized.Height;
5745
5746                                 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
5747                                 XSetZoomHints(DisplayHandle, hwnd.whole_window, ref hints);
5748                         }
5749                 }
5750
5751
5752                 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
5753                         Hwnd            hwnd;
5754
5755                         hwnd = Hwnd.ObjectFromHandle(handle);
5756
5757                         if (hwnd == null) {
5758                                 return;
5759                         }
5760
5761                         // Win32 automatically changes negative width/height to 0.
5762                         if (width < 0)
5763                                 width = 0;
5764                         if (height < 0)
5765                                 height = 0;
5766                                 
5767                         // X requires a sanity check for width & height; otherwise it dies
5768                         if (hwnd.zero_sized && width > 0 && height > 0) {
5769                                 if (hwnd.visible) {
5770                                         MapWindow(hwnd, WindowType.Whole);
5771                                 }
5772                                 hwnd.zero_sized = false;
5773                         }
5774
5775                         if ((width < 1) || (height < 1)) {
5776                                 hwnd.zero_sized = true;
5777                                 UnmapWindow(hwnd, WindowType.Whole);
5778                         }
5779
5780                         // Save a server roundtrip (and prevent a feedback loop)
5781                         if ((hwnd.x == x) && (hwnd.y == y) && 
5782                                 (hwnd.width == width) && (hwnd.height == height)) {
5783                                 return;
5784                         }
5785
5786                         if (!hwnd.zero_sized) {
5787                                 //Hack?
5788                                 hwnd.x = x;
5789                                 hwnd.y = y;
5790                                 hwnd.width = width;
5791                                 hwnd.height = height;
5792                                 SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5793
5794                                 if (hwnd.fixed_size) {
5795                                         SetWindowMinMax(handle, Rectangle.Empty, new Size(width, height), new Size(width, height));
5796                                 }
5797
5798                                 lock (XlibLock) {
5799                                         Control ctrl = Control.FromHandle (handle);
5800                                         Size TranslatedSize = TranslateWindowSizeToXWindowSize (ctrl.GetCreateParams (), new Size (width, height));
5801                                         MoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, TranslatedSize.Width, TranslatedSize.Height);
5802                                         PerformNCCalc(hwnd);
5803                                 }
5804                         }
5805
5806                         // Update our position/size immediately, so
5807                         // that future calls to SetWindowPos aren't
5808                         // kept from calling XMoveResizeWindow (by the
5809                         // "Save a server roundtrip" block above).
5810                         hwnd.x = x;
5811                         hwnd.y = y;
5812                         hwnd.width = width;
5813                         hwnd.height = height;
5814                         hwnd.ClientRect = Rectangle.Empty;
5815                 }
5816
5817                 internal override void SetWindowState(IntPtr handle, FormWindowState state) {
5818                         FormWindowState current_state;
5819                         Hwnd            hwnd;
5820
5821                         hwnd = Hwnd.ObjectFromHandle(handle);
5822
5823                         current_state = GetWindowState(handle);
5824
5825                         if (current_state == state) {
5826                                 return;
5827                         }
5828
5829                         switch(state) {
5830                                 case FormWindowState.Normal: {
5831                                         lock (XlibLock) {
5832                                                 if (current_state == FormWindowState.Minimized) {
5833                                                         MapWindow(hwnd, WindowType.Both);
5834                                                 } else if (current_state == FormWindowState.Maximized) {
5835                                                         SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
5836                                                 }
5837                                         }
5838                                         Activate(handle);
5839                                         return;
5840                                 }
5841
5842                                 case FormWindowState.Minimized: {
5843                                         lock (XlibLock) {
5844                                                 if (current_state == FormWindowState.Maximized) {
5845                                                         SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
5846                                                 }
5847                                                 XIconifyWindow(DisplayHandle, hwnd.whole_window, ScreenNo);
5848                                         }
5849                                         return;
5850                                 }
5851
5852                                 case FormWindowState.Maximized: {
5853                                         lock (XlibLock) {
5854                                                 if (current_state == FormWindowState.Minimized) {
5855                                                         MapWindow(hwnd, WindowType.Both);
5856                                                 }
5857
5858                                                 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)1 /* Add */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
5859                                         }
5860                                         Activate(handle);
5861                                         return;
5862                                 }
5863                         }
5864                 }
5865
5866                 internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
5867                         Hwnd    hwnd;
5868
5869                         hwnd = Hwnd.ObjectFromHandle(handle);
5870                         SetHwndStyles(hwnd, cp);
5871                         SetWMStyles(hwnd, cp);
5872                 }
5873
5874                 internal override double GetWindowTransparency(IntPtr handle)
5875                 {
5876                         return 1.0;
5877                 }
5878
5879                 internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
5880                         Hwnd    hwnd;
5881                         IntPtr  opacity;
5882
5883                         hwnd = Hwnd.ObjectFromHandle(handle);
5884
5885                         if (hwnd == null) {
5886                                 return;
5887                         }
5888
5889                         hwnd.opacity = (uint)(0xffffffff * transparency);
5890                         opacity = (IntPtr)((int)hwnd.opacity);
5891
5892                         IntPtr w = hwnd.whole_window;
5893                         if (hwnd.reparented)
5894                                 w = XGetParent (hwnd.whole_window);
5895                         XChangeProperty(DisplayHandle, w, _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
5896                 }
5897
5898                 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom) {
5899                         Hwnd    hwnd = Hwnd.ObjectFromHandle(handle);
5900
5901                         if (!hwnd.mapped) {
5902                                 return false;
5903                         }
5904
5905                         if (top) {
5906                                 lock (XlibLock) {
5907                                         XRaiseWindow(DisplayHandle, hwnd.whole_window);
5908                                 }
5909                                 return true;
5910                         } else if (!bottom) {
5911                                 Hwnd    after_hwnd = null;
5912
5913                                 if (after_handle != IntPtr.Zero) {
5914                                         after_hwnd = Hwnd.ObjectFromHandle(after_handle);
5915                                 }
5916
5917                                 XWindowChanges  values = new XWindowChanges();
5918
5919                                 if (after_hwnd == null) {
5920                                         // Work around metacity 'issues'
5921                                         int[]   atoms;
5922
5923                                         atoms = new int[2];
5924                                         atoms[0] = unixtime();
5925                                         XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_USER_TIME, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, atoms, 1);
5926
5927                                         XRaiseWindow(DisplayHandle, hwnd.whole_window);
5928                                         SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
5929                                         return true;
5930                                         //throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
5931                                 }
5932
5933                                 values.sibling = after_hwnd.whole_window;
5934                                 values.stack_mode = StackMode.Below;
5935
5936                                 lock (XlibLock) {
5937                                         XConfigureWindow(DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
5938                                 }
5939                         } else {
5940                                 // Bottom
5941                                 lock (XlibLock) {
5942                                         XLowerWindow(DisplayHandle, hwnd.whole_window);
5943                                 }
5944                                 return true;
5945                         }
5946                         return false;
5947                 }
5948
5949                 internal override void ShowCursor(bool show) {
5950                         ;       // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
5951                 }
5952
5953                 internal override object StartLoop(Thread thread) {
5954                         XEventQueue q = ThreadQueue(thread);
5955                         return q;
5956                 }
5957
5958                 internal override TransparencySupport SupportsTransparency() {
5959                         // We need to check if the x compositing manager is running
5960                         return TransparencySupport.Set;
5961                 }
5962
5963                 internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {
5964                         GetSystrayManagerWindow();
5965
5966                         if (SystrayMgrWindow != IntPtr.Zero) {
5967                                 XSizeHints      size_hints;
5968                                 Hwnd            hwnd;
5969
5970                                 hwnd = Hwnd.ObjectFromHandle(handle);
5971                                 #if DriverDebug
5972                                         Console.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
5973                                 #endif
5974
5975                                 // Oh boy.
5976                                 if (hwnd.client_window != hwnd.whole_window) {
5977                                         Keyboard.DestroyICForWindow (hwnd.client_window);
5978                                         XDestroyWindow(DisplayHandle, hwnd.client_window);
5979                                         hwnd.client_window = hwnd.whole_window;
5980                                 }       
5981
5982                                 /* by virtue of the way the tests are ordered when determining if it's PAINT
5983                                    or NCPAINT, client_window == whole_window will always be PAINT.  So, if we're
5984                                    waiting on an nc_expose, drop it and remove the hwnd from the list (unless
5985                                    there's a pending expose). */
5986                                 if (hwnd.nc_expose_pending) {
5987                                         hwnd.nc_expose_pending = false;
5988                                         if (!hwnd.expose_pending)
5989                                                 hwnd.Queue.Paint.Remove (hwnd);
5990                                 }
5991
5992                                 size_hints = new XSizeHints();
5993
5994                                 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
5995
5996                                 size_hints.min_width = 24;
5997                                 size_hints.min_height = 24;
5998                                 size_hints.max_width = 24;
5999                                 size_hints.max_height = 24;
6000                                 size_hints.base_width = 24;
6001                                 size_hints.base_height = 24;
6002
6003                                 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
6004
6005                                 int[] atoms = new int[2];
6006                                 atoms [0] = 1;                  // Version 1
6007                                 atoms [1] = 1;                  // we want to be mapped
6008
6009                                 // This line cost me 3 days...
6010                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _XEMBED_INFO, _XEMBED_INFO, 32, PropertyMode.Replace, atoms, 2);
6011
6012                                 // Need to pick some reasonable defaults
6013                                 tt = new ToolTip();
6014                                 tt.AutomaticDelay = 350;
6015                                 tt.InitialDelay = 250;
6016                                 tt.ReshowDelay = 250;
6017                                 tt.ShowAlways = true;
6018
6019                                 if ((tip != null) && (tip != string.Empty)) {
6020                                         tt.SetToolTip(Control.FromHandle(handle), tip);
6021                                         tt.Active = true;
6022                                 } else {
6023                                         tt.Active = false;
6024                                 }
6025
6026                                 SendNetClientMessage(SystrayMgrWindow, _NET_SYSTEM_TRAY_OPCODE, IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
6027
6028                                 return true;
6029                         }
6030                         tt = null;
6031                         return false;
6032                 }
6033
6034                 internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt) {
6035                         Control control;
6036
6037                         control = Control.FromHandle(handle);
6038                         if (control != null && tt != null) {
6039                                 tt.SetToolTip(control, tip);
6040                                 tt.Active = true;
6041                                 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6042                                 return true;
6043                         } else {
6044                                 return false;
6045                         }
6046                 }
6047
6048                 internal override void SystrayRemove(IntPtr handle, ref ToolTip tt) {
6049
6050                         SetVisible (handle, false, false);
6051
6052                         // The caller can now re-dock it later...
6053                         if (tt != null) {
6054                                 tt.Dispose();
6055                                 tt = null;
6056                         }
6057                 }
6058
6059 #if NET_2_0
6060                 internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
6061                 {
6062                         ThemeEngine.Current.ShowBalloonWindow (handle, timeout, title, text, icon);
6063                         SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);    
6064                 }
6065 #endif
6066
6067                 internal override bool Text(IntPtr handle, string text) {
6068                         Hwnd    hwnd;
6069
6070                         hwnd = Hwnd.ObjectFromHandle(handle);
6071
6072                         lock (XlibLock) {
6073                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UTF8_STRING, 8,
6074                                                 PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
6075
6076                                 // XXX this has problems with UTF8.
6077                                 // we need to either use the actual
6078                                 // text if it's latin-1, or convert it
6079                                 // to compound text if it's in a
6080                                 // different charset.
6081                                 XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
6082                         }
6083                         return true;
6084                 }
6085
6086                 internal override bool TranslateMessage(ref MSG msg) {
6087                         return Keyboard.TranslateMessage (ref msg);
6088                 }
6089
6090                 internal override void UpdateWindow(IntPtr handle) {
6091                         Hwnd    hwnd;
6092
6093                         hwnd = Hwnd.ObjectFromHandle(handle);
6094
6095                         if (!hwnd.visible || !hwnd.expose_pending || !hwnd.Mapped) {
6096                                 return;
6097                         }
6098
6099                         SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6100                         hwnd.Queue.Paint.Remove(hwnd);
6101                 }
6102
6103                 internal override void CreateOffscreenDrawable (IntPtr handle,
6104                                                                 int width, int height,
6105                                                                 out object offscreen_drawable)
6106                 {
6107                         IntPtr root_out;
6108                         int x_out, y_out, width_out, height_out, border_width_out, depth_out;
6109
6110                         XGetGeometry (DisplayHandle, handle,
6111                                       out root_out,
6112                                       out x_out, out y_out,
6113                                       out width_out, out height_out,
6114                                       out border_width_out, out depth_out);
6115
6116                         IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
6117
6118                         offscreen_drawable = pixmap;
6119
6120                 }
6121
6122                 internal override void DestroyOffscreenDrawable (object offscreen_drawable)
6123                 {
6124                         XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
6125                 }
6126
6127                 internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
6128                 {
6129                         return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
6130                 }
6131                 
6132                 internal override void BlitFromOffscreen (IntPtr dest_handle,
6133                                                           Graphics dest_dc,
6134                                                           object offscreen_drawable,
6135                                                           Graphics offscreen_dc,
6136                                                           Rectangle r)
6137                 {
6138                         XGCValues gc_values;
6139                         IntPtr gc;
6140
6141                         gc_values = new XGCValues();
6142
6143                         gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
6144
6145                         XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
6146                                    gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
6147
6148                         XFreeGC (DisplayHandle, gc);
6149                 }
6150
6151                 #endregion      // Public Static Methods
6152
6153                 #region Events
6154                 internal override event EventHandler Idle;
6155                 #endregion      // Events
6156
6157                 
6158 #if TRACE
6159                 
6160 #region Xcursor imports
6161                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
6162                 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
6163
6164                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
6165                 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
6166                 
6167                 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
6168                 internal extern static void XcursorImagesDestroy (IntPtr images);
6169                 
6170                 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
6171                 internal extern static int XcursorGetDefaultSize (IntPtr display);
6172
6173                 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
6174                 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
6175
6176                 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
6177                 internal extern static IntPtr XcursorGetTheme (IntPtr display);
6178 #endregion
6179 #region X11 Imports
6180                 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
6181                 internal extern static IntPtr XOpenDisplay(IntPtr display);
6182                 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
6183                 internal extern static int XCloseDisplay(IntPtr display);                                                   
6184                 [DllImport ("libX11", EntryPoint="XSynchronize")]
6185                 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
6186
6187                 [DllImport ("libX11", EntryPoint="XCreateWindow")]
6188                 internal extern static IntPtr _XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
6189                 internal static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes) {
6190                         DebugHelper.TraceWriteLine ("XCreateWindow");
6191                         return _XCreateWindow(display, parent, x, y, width, height, 
6192                                        border_width, depth, xclass, visual, valuemask, ref attributes);
6193                 }
6194                 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
6195                 internal extern static IntPtr _XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
6196                 internal static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background) {
6197                         DebugHelper.TraceWriteLine ("XCreateSimpleWindow");
6198                         return _XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background);
6199                 }
6200                 [DllImport ("libX11", EntryPoint="XMapWindow")]
6201                 internal extern static int _XMapWindow(IntPtr display, IntPtr window);
6202                 internal static int XMapWindow(IntPtr display, IntPtr window) {
6203                         DebugHelper.TraceWriteLine ("XMapWindow");
6204                         return _XMapWindow(display, window);
6205                 }
6206                 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
6207                 internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
6208                 internal static int XUnmapWindow(IntPtr display, IntPtr window) {
6209                         DebugHelper.TraceWriteLine ("XUnmapWindow");
6210                         return _XUnmapWindow(display, window);
6211                 }
6212                 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
6213                 internal extern static int _XMapSubindows(IntPtr display, IntPtr window);
6214                 internal static int XMapSubindows(IntPtr display, IntPtr window) {
6215                         DebugHelper.TraceWriteLine ("XMapSubindows");
6216                         return _XMapSubindows(display, window);
6217                 }
6218                 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
6219                 internal extern static int _XUnmapSubwindows(IntPtr display, IntPtr window);
6220                 internal static int XUnmapSubwindows(IntPtr display, IntPtr window) {
6221                         DebugHelper.TraceWriteLine ("XUnmapSubwindows");
6222                         return _XUnmapSubwindows(display, window);
6223                 }
6224                 [DllImport ("libX11", EntryPoint="XRootWindow")]
6225                 internal extern static IntPtr _XRootWindow(IntPtr display, int screen_number);
6226                 internal static IntPtr XRootWindow(IntPtr display, int screen_number) {
6227                         DebugHelper.TraceWriteLine ("XRootWindow");
6228                         return _XRootWindow(display, screen_number);
6229                 }
6230                 [DllImport ("libX11", EntryPoint="XNextEvent")]
6231                 internal extern static IntPtr _XNextEvent(IntPtr display, ref XEvent xevent);
6232                 internal static IntPtr XNextEvent(IntPtr display, ref XEvent xevent) {
6233                         DebugHelper.TraceWriteLine ("XNextEvent");
6234                         return _XNextEvent(display, ref xevent);
6235                 }
6236                 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
6237                 internal extern static int _XConnectionNumber (IntPtr display);
6238                 internal static int XConnectionNumber (IntPtr display) {
6239                         DebugHelper.TraceWriteLine ("XConnectionNumber");
6240                         return _XConnectionNumber (display);
6241                 }
6242                 [DllImport ("libX11", EntryPoint="XPending")]
6243                 internal extern static int _XPending (IntPtr display);
6244                 internal static int XPending (IntPtr display) {
6245                         DebugHelper.TraceWriteLine ("XPending");
6246                         DebugHelper.DumpCallers (3);
6247                         return _XPending (display);
6248                 }
6249                 [DllImport ("libX11", EntryPoint="XSelectInput")]
6250                 internal extern static IntPtr _XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
6251                 internal static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask) {
6252                         DebugHelper.TraceWriteLine ("XSelectInput");
6253                         return _XSelectInput(display, window, mask);
6254                 }
6255
6256                 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
6257                 internal extern static int _XDestroyWindow(IntPtr display, IntPtr window);
6258                 internal static int XDestroyWindow(IntPtr display, IntPtr window) {
6259                         DebugHelper.TraceWriteLine ("XDestroyWindow 0x{0:x}", window.ToInt32());
6260                         return _XDestroyWindow(display, window);
6261                 }
6262
6263                 [DllImport ("libX11", EntryPoint="XReparentWindow")]
6264                 internal extern static int _XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
6265                 internal static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y) {
6266                         DebugHelper.TraceWriteLine ("XReparentWindow");
6267                         return _XReparentWindow(display, window, parent, x, y);
6268                 }
6269                 
6270                 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
6271                 private extern static int _XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
6272                 private static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height) {
6273                         DebugHelper.TraceWriteLine ("XMoveResizeWindow");
6274                         return _XMoveResizeWindow(display, window, x, y, width, height);
6275                 }
6276
6277                 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
6278                 {
6279                         int ret = XMoveResizeWindow (display, window, x, y, width, height);
6280                         Keyboard.MoveCurrentCaretPos ();
6281                         return ret;
6282                 }
6283
6284                 [DllImport ("libX11", EntryPoint="XResizeWindow")]
6285                 internal extern static int _XResizeWindow(IntPtr display, IntPtr window, int width, int height);
6286                 internal static int XResizeWindow(IntPtr display, IntPtr window, int width, int height) {
6287                         DebugHelper.TraceWriteLine ("XResizeWindow");
6288                         return _XResizeWindow(display, window, width, height);
6289                 }
6290
6291                 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
6292                 internal extern static int _XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
6293                 internal static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes) {
6294                         DebugHelper.TraceWriteLine ("XGetWindowAttributes");
6295                         return _XGetWindowAttributes(display, window, ref attributes);
6296                 }
6297
6298                 [DllImport ("libX11", EntryPoint="XFlush")]
6299                 internal extern static int _XFlush(IntPtr display);
6300                 internal static int XFlush(IntPtr display) {
6301                         DebugHelper.TraceWriteLine ("XFlush");
6302                         return _XFlush(display);
6303                 }
6304
6305                 [DllImport ("libX11", EntryPoint="XSetWMName")]
6306                 internal extern static int _XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
6307                 internal static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop) {
6308                         DebugHelper.TraceWriteLine ("XSetWMName");
6309                         return _XSetWMName(display, window, ref text_prop);
6310                 }
6311
6312                 [DllImport ("libX11", EntryPoint="XStoreName")]
6313                 internal extern static int _XStoreName(IntPtr display, IntPtr window, string window_name);
6314                 internal static int XStoreName(IntPtr display, IntPtr window, string window_name) {
6315                         DebugHelper.TraceWriteLine ("XStoreName");
6316                         return _XStoreName(display, window, window_name);
6317                 }
6318
6319                 [DllImport ("libX11", EntryPoint="XFetchName")]
6320                 internal extern static int _XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
6321                 internal static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name) {
6322                         DebugHelper.TraceWriteLine ("XFetchName");
6323                         return _XFetchName(display, window, ref window_name);
6324                 }
6325
6326                 [DllImport ("libX11", EntryPoint="XSendEvent")]
6327                 internal extern static int _XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
6328                 internal static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event) {
6329                         DebugHelper.TraceWriteLine ("XSendEvent");
6330                         return _XSendEvent(display, window, propagate, event_mask, ref send_event);
6331                 }
6332
6333                 [DllImport ("libX11", EntryPoint="XQueryTree")]
6334                 internal extern static int _XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return);
6335                 internal static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return) {
6336                         DebugHelper.TraceWriteLine ("XQueryTree");
6337                         return _XQueryTree(display, window, out root_return, out parent_return, out children_return, out nchildren_return);
6338                 }
6339
6340                 [DllImport ("libX11", EntryPoint="XFree")]
6341                 internal extern static int _XFree(IntPtr data);
6342                 internal static int XFree(IntPtr data) {
6343                         DebugHelper.TraceWriteLine ("XFree");
6344                         return _XFree(data);
6345                 }
6346
6347                 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
6348                 internal extern static int _XRaiseWindow(IntPtr display, IntPtr window);
6349                 internal static int XRaiseWindow(IntPtr display, IntPtr window) {
6350                         DebugHelper.TraceWriteLine ("XRaiseWindow");
6351                         return _XRaiseWindow(display, window);
6352                 }
6353
6354                 [DllImport ("libX11", EntryPoint="XLowerWindow")]
6355                 internal extern static uint _XLowerWindow(IntPtr display, IntPtr window);
6356                 internal static uint XLowerWindow(IntPtr display, IntPtr window) {
6357                         DebugHelper.TraceWriteLine ("XLowerWindow");
6358                         return _XLowerWindow(display, window);
6359                 }
6360
6361                 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
6362                 internal extern static uint _XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
6363                 internal static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values) {
6364                         DebugHelper.TraceWriteLine ("XConfigureWindow");
6365                         return _XConfigureWindow(display, window, value_mask, ref values);
6366                 }
6367
6368                 [DllImport ("libX11", EntryPoint="XInternAtom")]
6369                 internal extern static IntPtr _XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
6370                 internal static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists) {
6371                         DebugHelper.TraceWriteLine ("XInternAtom");
6372                         return _XInternAtom(display, atom_name, only_if_exists);
6373                 }
6374
6375                 [DllImport ("libX11", EntryPoint="XInternAtoms")]
6376                 internal extern static int _XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
6377                 internal static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms) {
6378                         DebugHelper.TraceWriteLine ("XInternAtoms");
6379                         return _XInternAtoms(display, atom_names, atom_count, only_if_exists, atoms);
6380                 }
6381
6382                 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
6383                 internal extern static int _XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
6384                 internal static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count) {
6385                         DebugHelper.TraceWriteLine ("XSetWMProtocols");
6386                         return _XSetWMProtocols(display, window, protocols, count);
6387                 }
6388
6389                 [DllImport ("libX11", EntryPoint="XGrabPointer")]
6390                 internal extern static int _XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
6391                 internal static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp) {
6392                         DebugHelper.TraceWriteLine ("XGrabPointer");
6393                         return _XGrabPointer(display, window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, timestamp);
6394                 }
6395
6396                 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
6397                 internal extern static int _XUngrabPointer(IntPtr display, IntPtr timestamp);
6398                 internal static int XUngrabPointer(IntPtr display, IntPtr timestamp) {
6399                         DebugHelper.TraceWriteLine ("XUngrabPointer");
6400                         return _XUngrabPointer(display, timestamp);
6401                 }
6402
6403                 [DllImport ("libX11", EntryPoint="XQueryPointer")]
6404                 internal extern static bool _XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons);
6405                 internal static bool XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons) {
6406                         DebugHelper.TraceWriteLine ("XQueryPointer");
6407                         return _XQueryPointer(display, window, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
6408                 }
6409
6410                 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
6411                 internal extern static bool _XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return, out int dest_y_return, out IntPtr child_return);
6412                 internal static bool XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return,         out int dest_y_return, out IntPtr child_return) {
6413                         DebugHelper.TraceWriteLine ("XTranslateCoordinates");
6414                         return _XTranslateCoordinates (display, src_w, dest_w, src_x, src_y, out intdest_x_return, out dest_y_return, out child_return);
6415                 }
6416
6417                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6418                 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
6419                 internal static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth) {
6420                         DebugHelper.TraceWriteLine ("XGetGeometry");
6421                         return _XGetGeometry(display, window, out root, out x, out y, out width, out height, out border_width, out depth);
6422                 }
6423
6424                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6425                 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth);
6426                 internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth) {
6427                         DebugHelper.TraceWriteLine ("XGetGeometry");
6428                         return _XGetGeometry(display, window, root, out x, out y, out width, out height, border_width, depth);
6429                 }
6430
6431                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6432                 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
6433                 internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth) {
6434                         DebugHelper.TraceWriteLine ("XGetGeometry");
6435                         return _XGetGeometry(display, window, root, out x, out y, width, height, border_width, depth);
6436                 }
6437
6438                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6439                 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth);
6440                 internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth) {
6441                         DebugHelper.TraceWriteLine ("XGetGeometry");
6442                         return _XGetGeometry(display, window, root, x, y, out width, out height, border_width, depth);
6443                 }
6444
6445                 [DllImport ("libX11", EntryPoint="XWarpPointer")]
6446                 internal extern static uint _XWarpPointer(IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y);
6447                 internal static uint XWarpPointer(IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y) {
6448                         DebugHelper.TraceWriteLine ("XWarpPointer");
6449                         return _XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y);
6450                 }
6451
6452                 [DllImport ("libX11", EntryPoint="XClearWindow")]
6453                 internal extern static int _XClearWindow(IntPtr display, IntPtr window);
6454                 internal static int XClearWindow(IntPtr display, IntPtr window) {
6455                         DebugHelper.TraceWriteLine ("XClearWindow");
6456                         return _XClearWindow(display, window);
6457                 }
6458
6459                 [DllImport ("libX11", EntryPoint="XClearArea")]
6460                 internal extern static int _XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
6461                 internal static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures) {
6462                         DebugHelper.TraceWriteLine ("XClearArea");
6463                         return _XClearArea(display, window, x, y, width, height, exposures);
6464                 }
6465
6466                 // Colormaps
6467                 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
6468                 internal extern static IntPtr _XDefaultScreenOfDisplay(IntPtr display);
6469                 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display) {
6470                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6471                         return _XDefaultScreenOfDisplay(display);
6472                 }
6473
6474                 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
6475                 internal extern static int _XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
6476                 internal static int XDefaultScreenOfDisplay(IntPtr display, IntPtr Screen) {
6477                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6478                         return _XScreenNumberOfScreen(display, Screen);
6479                 }
6480
6481                 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
6482                 internal extern static IntPtr _XDefaultVisual(IntPtr display, int screen_number);
6483                 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display, int screen_number) {
6484                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6485                         return _XDefaultVisual(display, screen_number);
6486                 }
6487
6488                 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
6489                 internal extern static uint _XDefaultDepth(IntPtr display, int screen_number);
6490                 internal static uint XDefaultDepth(IntPtr display, int screen_number) {
6491                         DebugHelper.TraceWriteLine ("XDefaultDepth");
6492                         return _XDefaultDepth(display, screen_number);
6493                 }
6494
6495                 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
6496                 internal extern static int _XDefaultScreen(IntPtr display);
6497                 internal static int XDefaultScreen(IntPtr display) {
6498                         DebugHelper.TraceWriteLine ("XDefaultScreen");
6499                         return _XDefaultScreen(display);
6500                 }
6501
6502                 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
6503                 internal extern static IntPtr _XDefaultColormap(IntPtr display, int screen_number);
6504                 internal static IntPtr XDefaultColormap(IntPtr display, int screen_number) {
6505                         DebugHelper.TraceWriteLine ("XDefaultColormap");
6506                         return _XDefaultColormap(display, screen_number);
6507                 }
6508
6509                 [DllImport ("libX11", EntryPoint="XLookupColor")]
6510                 internal extern static int _XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
6511                 internal static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color) {
6512                         DebugHelper.TraceWriteLine ("XLookupColor");
6513                         return _XLookupColor(display, Colormap, Coloranem, ref exact_def_color, ref screen_def_color);
6514                 }
6515
6516                 [DllImport ("libX11", EntryPoint="XAllocColor")]
6517                 internal extern static int _XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
6518                 internal static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def) {
6519                         DebugHelper.TraceWriteLine ("XAllocColor");
6520                         return _XAllocColor(display, Colormap, ref colorcell_def);
6521                 }
6522
6523                 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
6524                 internal extern static int _XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
6525                 internal static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window) {
6526                         DebugHelper.TraceWriteLine ("XSetTransientForHint");
6527                         return _XSetTransientForHint(display, window, prop_window);
6528                 }
6529
6530                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6531                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
6532                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements) {
6533                         DebugHelper.TraceWriteLine ("XChangeProperty");
6534                         return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
6535                 }
6536
6537                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6538                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
6539                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements) {
6540                         DebugHelper.TraceWriteLine ("XChangeProperty");
6541                         return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6542                 }
6543
6544                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6545                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
6546                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements) {
6547                         DebugHelper.TraceWriteLine ("XChangeProperty");
6548                         return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6549                 }
6550
6551                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6552                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
6553                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements) {
6554                         DebugHelper.TraceWriteLine ("XChangeProperty");
6555                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6556                 }
6557
6558                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6559                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
6560                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements) {
6561                         DebugHelper.TraceWriteLine ("XChangeProperty");
6562                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6563                 }
6564
6565                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6566                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
6567                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements) {
6568                         DebugHelper.TraceWriteLine ("XChangeProperty");
6569                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6570                 }
6571
6572                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6573                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
6574                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements) {
6575                         DebugHelper.TraceWriteLine ("XChangeProperty");
6576                         return _XChangeProperty(display, window, property, type, format, mode, atoms, nelements);
6577                 }
6578
6579                 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
6580                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
6581                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length) {
6582                         DebugHelper.TraceWriteLine ("XChangeProperty");
6583                         return _XChangeProperty(display, window, property, type, format, mode, text, text_length);
6584                 }
6585
6586                 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
6587                 internal extern static int _XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
6588                 internal static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property) {
6589                         DebugHelper.TraceWriteLine ("XDeleteProperty");
6590                         return _XDeleteProperty(display, window, property);
6591                 }
6592
6593                 // Drawing
6594                 [DllImport ("libX11", EntryPoint="XCreateGC")]
6595                 internal extern static IntPtr _XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
6596                 internal static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values) {
6597                         DebugHelper.TraceWriteLine ("XCreateGC");
6598                         return _XCreateGC(display, window, valuemask, ref values);
6599                 }
6600
6601                 [DllImport ("libX11", EntryPoint="XFreeGC")]
6602                 internal extern static int _XFreeGC(IntPtr display, IntPtr gc);
6603                 internal static int XFreeGC(IntPtr display, IntPtr gc) {
6604                         DebugHelper.TraceWriteLine ("XFreeGC");
6605                         return _XFreeGC(display, gc);
6606                 }
6607
6608                 [DllImport ("libX11", EntryPoint="XSetFunction")]
6609                 internal extern static int _XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
6610                 internal static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function) {
6611                         DebugHelper.TraceWriteLine ("XSetFunction");
6612                         return _XSetFunction(display, gc, function);
6613                 }
6614
6615                 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
6616                 internal extern static int _XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
6617                 internal static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style) {
6618                         DebugHelper.TraceWriteLine ("XSetLineAttributes");
6619                         return _XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
6620                 }
6621
6622                 [DllImport ("libX11", EntryPoint="XDrawLine")]
6623                 internal extern static int _XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
6624                 internal static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2) {
6625                         DebugHelper.TraceWriteLine ("XDrawLine");
6626                         return _XDrawLine(display, drawable, gc, x1, y1, x2, y2);
6627                 }
6628
6629                 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
6630                 internal extern static int _XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6631                 internal static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height) {
6632                         DebugHelper.TraceWriteLine ("XDrawRectangle");
6633                         return _XDrawRectangle(display, drawable, gc, x1, y1, width, height);
6634                 }
6635
6636                 [DllImport ("libX11", EntryPoint="XFillRectangle")]
6637                 internal extern static int _XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6638                 internal static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height) {
6639                         DebugHelper.TraceWriteLine ("XFillRectangle");
6640                         return _XFillRectangle(display, drawable, gc, x1, y1, width, height);
6641                 }
6642
6643                 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
6644                 internal extern static int _XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
6645                 internal static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background) {
6646                         DebugHelper.TraceWriteLine ("XSetWindowBackground");
6647                         return _XSetWindowBackground(display, window, background);
6648                 }
6649
6650                 [DllImport ("libX11", EntryPoint="XCopyArea")]
6651                 internal extern static int _XCopyArea(IntPtr display, IntPtr src, IntPtr dest, IntPtr gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y);
6652                 internal static int XCopyArea(IntPtr display, IntPtr src, IntPtr dest, IntPtr gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y) {
6653                         DebugHelper.TraceWriteLine ("XCopyArea");
6654                         return _XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
6655                 }
6656
6657                 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
6658                 internal extern static int _XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
6659                 internal static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop) {
6660                         DebugHelper.TraceWriteLine ("XGetWindowProperty");
6661                         return _XGetWindowProperty(display, window, atom, long_offset, long_length, delete, req_type, out actual_type, out actual_format, out nitems, out bytes_after, ref prop);
6662                 }
6663
6664                 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
6665                 internal extern static int _XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
6666                 internal static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time) {
6667                         DebugHelper.TraceWriteLine ("XSetInputFocus");
6668                         return _XSetInputFocus(display, window, revert_to, time);
6669                 }
6670
6671                 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
6672                 internal extern static int _XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
6673                 internal static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number) {
6674                         DebugHelper.TraceWriteLine ("XIconifyWindow");
6675                         return _XIconifyWindow(display, window, screen_number);
6676                 }
6677
6678                 [DllImport ("libX11", EntryPoint="XDefineCursor")]
6679                 internal extern static int _XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
6680                 internal static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor) {
6681                         DebugHelper.TraceWriteLine ("XDefineCursor");
6682                         return _XDefineCursor(display, window, cursor);
6683                 }
6684
6685                 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
6686                 internal extern static int _XUndefineCursor(IntPtr display, IntPtr window);
6687                 internal static int XUndefineCursor(IntPtr display, IntPtr window) {
6688                         DebugHelper.TraceWriteLine ("XUndefineCursor");
6689                         return _XUndefineCursor(display, window);
6690                 }
6691
6692                 [DllImport ("libX11", EntryPoint="XFreeCursor")]
6693                 internal extern static int _XFreeCursor(IntPtr display, IntPtr cursor);
6694                 internal static int XFreeCursor(IntPtr display, IntPtr cursor) {
6695                         DebugHelper.TraceWriteLine ("XFreeCursor");
6696                         return _XFreeCursor(display, cursor);
6697                 }
6698
6699                 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
6700                 internal extern static IntPtr _XCreateFontCursor(IntPtr display, CursorFontShape shape);
6701                 internal static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape) {
6702                         DebugHelper.TraceWriteLine ("XCreateFontCursor");
6703                         return _XCreateFontCursor(display, shape);
6704                 }
6705
6706                 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
6707                 internal extern static IntPtr _XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot);
6708                 internal static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot) {
6709                         DebugHelper.TraceWriteLine ("XCreatePixmapCursor");
6710                         return _XCreatePixmapCursor(display, source, mask, ref foreground_color, ref background_color, x_hot, y_hot);
6711                 }
6712
6713                 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
6714                 internal extern static IntPtr _XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
6715                 internal static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth) {
6716                         DebugHelper.TraceWriteLine ("XCreatePixmapFromBitmapData");
6717                         return _XCreatePixmapFromBitmapData(display, drawable, data, width, height, fg, bg, depth);
6718                 }
6719
6720                 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
6721                 internal extern static IntPtr _XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
6722                 internal static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth) {
6723                         DebugHelper.TraceWriteLine ("XCreatePixmap");
6724                         return _XCreatePixmap(display, d, width, height, depth);
6725                 }
6726
6727                 [DllImport ("libX11", EntryPoint="XFreePixmap")]
6728                 internal extern static IntPtr _XFreePixmap(IntPtr display, IntPtr pixmap);
6729                 internal static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap) {
6730                         DebugHelper.TraceWriteLine ("XFreePixmap");
6731                         return _XFreePixmap(display, pixmap);
6732                 }
6733
6734                 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
6735                 internal extern static int _XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
6736                 internal static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height) {
6737                         DebugHelper.TraceWriteLine ("XQueryBestCursor");
6738                         return _XQueryBestCursor(display, drawable, width, height, out best_width, out best_height);
6739                 }
6740
6741                 [DllImport ("libX11", EntryPoint="XQueryExtension")]
6742                 internal extern static int _XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
6743                 internal static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error) {
6744                         DebugHelper.TraceWriteLine ("XQueryExtension");
6745                         return _XQueryExtension(display, extension_name, ref major, ref first_event, ref first_error);
6746                 }
6747
6748                 [DllImport ("libX11", EntryPoint="XWhitePixel")]
6749                 internal extern static IntPtr _XWhitePixel(IntPtr display, int screen_no);
6750                 internal static IntPtr XWhitePixel(IntPtr display, int screen_no) {
6751                         DebugHelper.TraceWriteLine ("XWhitePixel");
6752                         return _XWhitePixel(display, screen_no);
6753                 }
6754
6755                 [DllImport ("libX11", EntryPoint="XBlackPixel")]
6756                 internal extern static IntPtr _XBlackPixel(IntPtr display, int screen_no);
6757                 internal static IntPtr XBlackPixel(IntPtr display, int screen_no) {
6758                         DebugHelper.TraceWriteLine ("XBlackPixel");
6759                         return _XBlackPixel(display, screen_no);
6760                 }
6761
6762                 [DllImport ("libX11", EntryPoint="XGrabServer")]
6763                 internal extern static void _XGrabServer(IntPtr display);
6764                 internal static void XGrabServer(IntPtr display) {
6765                         DebugHelper.TraceWriteLine ("XGrabServer");
6766                         _XGrabServer(display);
6767                 }
6768
6769                 [DllImport ("libX11", EntryPoint="XUngrabServer")]
6770                 internal extern static void _XUngrabServer(IntPtr display);
6771                 internal static void XUngrabServer(IntPtr display) {
6772                         DebugHelper.TraceWriteLine ("XUngrabServer");
6773                         _XUngrabServer(display);
6774                 }
6775
6776                 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
6777                 internal extern static void _XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
6778                 internal static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return) {
6779                         DebugHelper.TraceWriteLine ("XGetWMNormalHints");
6780                         _XGetWMNormalHints(display, window, ref hints, out supplied_return);
6781                 }
6782
6783                 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
6784                 internal extern static void _XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
6785                 internal static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints) {
6786                         DebugHelper.TraceWriteLine ("XSetWMNormalHints");
6787                         _XSetWMNormalHints(display, window, ref hints);
6788                 }
6789
6790                 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
6791                 internal extern static void _XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
6792                 internal static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints) {
6793                         DebugHelper.TraceWriteLine ("XSetZoomHints");
6794                         _XSetZoomHints(display, window, ref hints);
6795                 }
6796
6797                 [DllImport ("libX11", EntryPoint="XSetWMHints")]
6798                 internal extern static void _XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
6799                 internal static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints) {
6800                         DebugHelper.TraceWriteLine ("XSetWMHints");
6801                         _XSetWMHints(display, window, ref wmhints);
6802                 }
6803
6804                 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
6805                 internal extern static int _XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
6806                 internal static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count) {
6807                         DebugHelper.TraceWriteLine ("XGetIconSizes");
6808                         return _XGetIconSizes(display, window, out size_list, out count);
6809                 }
6810
6811                 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
6812                 internal extern static IntPtr _XSetErrorHandler(XErrorHandler error_handler);
6813                 internal static IntPtr XSetErrorHandler(XErrorHandler error_handler) {
6814                         DebugHelper.TraceWriteLine ("XSetErrorHandler");
6815                         return _XSetErrorHandler(error_handler);
6816                 }
6817
6818                 [DllImport ("libX11", EntryPoint="XGetErrorText")]
6819                 internal extern static IntPtr _XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
6820                 internal static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length) {
6821                         DebugHelper.TraceWriteLine ("XGetErrorText");
6822                         return _XGetErrorText(display, code, buffer, length);
6823                 }
6824
6825                 [DllImport ("libX11", EntryPoint="XInitThreads")]
6826                 internal extern static int _XInitThreads();
6827                 internal static int XInitThreads() {
6828                         DebugHelper.TraceWriteLine ("XInitThreads");
6829                         return _XInitThreads();
6830                 }
6831
6832                 [DllImport ("libX11", EntryPoint="XConvertSelection")]
6833                 internal extern static int _XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
6834                 internal static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time) {
6835                         DebugHelper.TraceWriteLine ("XConvertSelection");
6836                         return _XConvertSelection(display, selection, target, property, requestor, time);
6837                 }
6838
6839                 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
6840                 internal extern static IntPtr _XGetSelectionOwner(IntPtr display, IntPtr selection);
6841                 internal static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection) {
6842                         DebugHelper.TraceWriteLine ("XGetSelectionOwner");
6843                         return _XGetSelectionOwner(display, selection);
6844                 }
6845
6846                 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
6847                 internal extern static int _XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
6848                 internal static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time) {
6849                         DebugHelper.TraceWriteLine ("XSetSelectionOwner");
6850                         return _XSetSelectionOwner(display, selection, owner, time);
6851                 }
6852
6853                 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
6854                 internal extern static int _XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
6855                 internal static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask) {
6856                         DebugHelper.TraceWriteLine ("XSetPlaneMask");
6857                         return _XSetPlaneMask(display, gc, mask);
6858                 }
6859
6860                 [DllImport ("libX11", EntryPoint="XSetForeground")]
6861                 internal extern static int _XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
6862                 internal static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground) {
6863                         DebugHelper.TraceWriteLine ("XSetForeground");
6864                         return _XSetForeground(display, gc, foreground);
6865                 }
6866
6867                 [DllImport ("libX11", EntryPoint="XSetBackground")]
6868                 internal extern static int _XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
6869                 internal static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background) {
6870                         DebugHelper.TraceWriteLine ("XSetBackground");
6871                         return _XSetBackground(display, gc, background);
6872                 }
6873
6874                 [DllImport ("libX11", EntryPoint="XBell")]
6875                 internal extern static int _XBell(IntPtr display, int percent);
6876                 internal static int XBell(IntPtr display, int percent) {
6877                         DebugHelper.TraceWriteLine ("XBell");
6878                         return _XBell(display, percent);
6879                 }
6880
6881                 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
6882                 internal extern static int _XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
6883                 internal static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time) {
6884                         DebugHelper.TraceWriteLine ("XChangeActivePointerGrab");
6885                         return _XChangeActivePointerGrab (display, event_mask, cursor, time);
6886                 }
6887
6888                 [DllImport ("libX11", EntryPoint="XFilterEvent")]
6889                 internal extern static bool _XFilterEvent(ref XEvent xevent, IntPtr window);
6890                 internal static bool XFilterEvent(ref XEvent xevent, IntPtr window) {
6891                         DebugHelper.TraceWriteLine ("XFilterEvent");
6892                         return _XFilterEvent(ref xevent, window);
6893                 }
6894
6895                 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
6896                 internal extern static void _XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
6897                 internal static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported) {
6898                         DebugHelper.TraceWriteLine ("XkbSetDetectableAutoRepeat");
6899                         _XkbSetDetectableAutoRepeat (display, detectable, supported);
6900                 }
6901
6902                 [DllImport ("libX11", EntryPoint="XPeekEvent")]
6903                 internal extern static void _XPeekEvent (IntPtr display, ref XEvent xevent);
6904                 internal static void XPeekEvent (IntPtr display, ref XEvent xevent) {
6905                         DebugHelper.TraceWriteLine ("XPeekEvent");
6906                         _XPeekEvent (display, ref xevent);
6907                 }
6908
6909                 [DllImport ("libX11", EntryPoint="XIfEvent")]
6910                 internal extern static void _XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
6911                 internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg) {
6912                         DebugHelper.TraceWriteLine ("XIfEvent");
6913                         _XIfEvent (display, ref xevent, event_predicate, arg);
6914                 }
6915 #endregion
6916
6917
6918 #else //no TRACE defined
6919
6920 #region Xcursor imports
6921                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
6922                 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
6923
6924                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
6925                 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
6926                 
6927                 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
6928                 internal extern static void XcursorImagesDestroy (IntPtr images);
6929                 
6930                 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
6931                 internal extern static int XcursorGetDefaultSize (IntPtr display);
6932
6933                 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
6934                 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
6935
6936                 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
6937                 internal extern static IntPtr XcursorGetTheme (IntPtr display);
6938 #endregion
6939                 #region X11 Imports
6940                 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
6941                 internal extern static IntPtr XOpenDisplay(IntPtr display);
6942                 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
6943                 internal extern static int XCloseDisplay(IntPtr display);                                                   
6944                 [DllImport ("libX11", EntryPoint="XSynchronize")]
6945                 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
6946
6947                 [DllImport ("libX11", EntryPoint="XCreateWindow")]
6948                 internal extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
6949                 
6950                 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
6951                 internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
6952                 
6953                 [DllImport ("libX11", EntryPoint="XMapWindow")]
6954                 internal extern static int XMapWindow(IntPtr display, IntPtr window);
6955                 
6956                 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
6957                 internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
6958                 
6959                 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
6960                 internal extern static int XMapSubindows(IntPtr display, IntPtr window);
6961                 
6962                 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
6963                 internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
6964                 
6965                 [DllImport ("libX11", EntryPoint="XRootWindow")]
6966                 internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
6967                 
6968                 [DllImport ("libX11", EntryPoint="XNextEvent")]
6969                 internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
6970
6971                 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
6972                 internal extern static int XConnectionNumber (IntPtr display);
6973                 
6974                 [DllImport ("libX11", EntryPoint="XPending")]
6975                 internal extern static int XPending (IntPtr display);
6976                 
6977                 [DllImport ("libX11", EntryPoint="XSelectInput")]
6978                 internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
6979                 
6980                 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
6981                 internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
6982                 
6983                 [DllImport ("libX11", EntryPoint="XReparentWindow")]
6984                 internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
6985                 
6986                 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
6987                 private extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
6988                 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
6989                 {
6990                         int ret = XMoveResizeWindow (display, window, x, y, width, height);
6991                         Keyboard.MoveCurrentCaretPos ();
6992                         return ret;
6993                 }
6994
6995                 [DllImport ("libX11", EntryPoint="XResizeWindow")]
6996                 internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
6997
6998                 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
6999                 internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
7000
7001                 [DllImport ("libX11", EntryPoint="XFlush")]
7002                 internal extern static int XFlush(IntPtr display);
7003
7004                 [DllImport ("libX11", EntryPoint="XSetWMName")]
7005                 internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
7006
7007                 [DllImport ("libX11", EntryPoint="XStoreName")]
7008                 internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
7009
7010                 [DllImport ("libX11", EntryPoint="XFetchName")]
7011                 internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
7012
7013                 [DllImport ("libX11", EntryPoint="XSendEvent")]
7014                 internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
7015
7016                 [DllImport ("libX11", EntryPoint="XQueryTree")]
7017                 internal extern static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return);
7018
7019                 [DllImport ("libX11", EntryPoint="XFree")]
7020                 internal extern static int XFree(IntPtr data);
7021
7022                 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
7023                 internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
7024
7025                 [DllImport ("libX11", EntryPoint="XLowerWindow")]
7026                 internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
7027
7028                 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
7029                 internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
7030
7031                 [DllImport ("libX11", EntryPoint="XInternAtom")]
7032                 internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
7033
7034                 [DllImport ("libX11", EntryPoint="XInternAtoms")]
7035                 internal extern static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
7036
7037                 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
7038                 internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
7039
7040                 [DllImport ("libX11", EntryPoint="XGrabPointer")]
7041                 internal extern static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
7042
7043                 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
7044                 internal extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
7045
7046                 [DllImport ("libX11", EntryPoint="XQueryPointer")]
7047                 internal extern static bool XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons);
7048
7049                 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
7050                 internal extern static bool XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return, out int dest_y_return, out IntPtr child_return);
7051
7052                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7053                 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
7054
7055                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7056                 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth);
7057
7058                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7059                 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
7060
7061                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7062                 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth);
7063
7064                 [DllImport ("libX11", EntryPoint="XWarpPointer")]
7065                 internal extern static uint XWarpPointer(IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y);
7066
7067                 [DllImport ("libX11", EntryPoint="XClearWindow")]
7068                 internal extern static int XClearWindow(IntPtr display, IntPtr window);
7069
7070                 [DllImport ("libX11", EntryPoint="XClearArea")]
7071                 internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
7072
7073                 // Colormaps
7074                 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
7075                 internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
7076
7077                 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
7078                 internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
7079
7080                 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
7081                 internal extern static IntPtr XDefaultVisual(IntPtr display, int screen_number);
7082
7083                 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
7084                 internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
7085
7086                 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
7087                 internal extern static int XDefaultScreen(IntPtr display);
7088
7089                 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
7090                 internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
7091
7092                 [DllImport ("libX11", EntryPoint="XLookupColor")]
7093                 internal extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
7094
7095                 [DllImport ("libX11", EntryPoint="XAllocColor")]
7096                 internal extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
7097
7098                 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
7099                 internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
7100
7101                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7102                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
7103
7104                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7105                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
7106
7107                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7108                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
7109
7110                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7111                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
7112
7113                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7114                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
7115
7116                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7117                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
7118
7119                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7120                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
7121
7122                 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
7123                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
7124
7125                 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
7126                 internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
7127
7128                 // Drawing
7129                 [DllImport ("libX11", EntryPoint="XCreateGC")]
7130                 internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
7131
7132                 [DllImport ("libX11", EntryPoint="XFreeGC")]
7133                 internal extern static int XFreeGC(IntPtr display, IntPtr gc);
7134
7135                 [DllImport ("libX11", EntryPoint="XSetFunction")]
7136                 internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
7137
7138                 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
7139                 internal extern static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
7140
7141                 [DllImport ("libX11", EntryPoint="XDrawLine")]
7142                 internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
7143
7144                 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
7145                 internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7146
7147                 [DllImport ("libX11", EntryPoint="XFillRectangle")]
7148                 internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7149
7150                 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
7151                 internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
7152
7153                 [DllImport ("libX11", EntryPoint="XCopyArea")]
7154                 internal extern static int XCopyArea(IntPtr display, IntPtr src, IntPtr dest, IntPtr gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y);
7155
7156                 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
7157                 internal extern static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
7158
7159                 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
7160                 internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
7161
7162                 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
7163                 internal extern static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
7164
7165                 [DllImport ("libX11", EntryPoint="XDefineCursor")]
7166                 internal extern static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
7167
7168                 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
7169                 internal extern static int XUndefineCursor(IntPtr display, IntPtr window);
7170
7171                 [DllImport ("libX11", EntryPoint="XFreeCursor")]
7172                 internal extern static int XFreeCursor(IntPtr display, IntPtr cursor);
7173
7174                 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
7175                 internal extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
7176
7177                 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
7178                 internal extern static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot);
7179
7180                 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
7181                 internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
7182
7183                 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7184                 internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7185
7186                 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7187                 internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
7188
7189                 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7190                 internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7191
7192                 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7193                 internal extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7194
7195                 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7196                 internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
7197
7198                 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7199                 internal extern static IntPtr XBlackPixel(IntPtr display, int screen_no);
7200
7201                 [DllImport ("libX11", EntryPoint="XGrabServer")]
7202                 internal extern static void XGrabServer(IntPtr display);
7203
7204                 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7205                 internal extern static void XUngrabServer(IntPtr display);
7206
7207                 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7208                 internal extern static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7209
7210                 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7211                 internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7212
7213                 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7214                 internal extern static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7215
7216                 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7217                 internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7218
7219                 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7220                 internal extern static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7221
7222                 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7223                 internal extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
7224
7225                 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7226                 internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7227
7228                 [DllImport ("libX11", EntryPoint="XInitThreads")]
7229                 internal extern static int XInitThreads();
7230
7231                 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7232                 internal extern static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7233
7234                 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7235                 internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
7236
7237                 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7238                 internal extern static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7239
7240                 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7241                 internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7242
7243                 [DllImport ("libX11", EntryPoint="XSetForeground")]
7244                 internal extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7245
7246                 [DllImport ("libX11", EntryPoint="XSetBackground")]
7247                 internal extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7248
7249                 [DllImport ("libX11", EntryPoint="XBell")]
7250                 internal extern static int XBell(IntPtr display, int percent);
7251
7252                 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7253                 internal extern static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7254
7255                 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7256                 internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
7257
7258                 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7259                 internal extern static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7260
7261                 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7262                 internal extern static void XPeekEvent (IntPtr display, ref XEvent xevent);
7263
7264                 [DllImport ("libX11", EntryPoint="XIfEvent")]
7265                 internal extern static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7266                 #endregion
7267 #endif
7268         }
7269 }