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