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