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