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