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