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