2009-02-02 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                                 // We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
4371                                 // in case we break a scenario not taken into account in the tests
4372                                 case XEventName.MapNotify: {
4373                                         /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
4374                                                 hwnd.mapped = true;
4375                                                 msg.message = Msg.WM_SHOWWINDOW;
4376                                                 msg.wParam = (IntPtr) 1;
4377                                                 // XXX we're missing the lParam..
4378                                                 break;
4379                                         }*/
4380                                         goto ProcessNextMessage;
4381                                 }
4382
4383                                 case XEventName.UnmapNotify: {
4384                                         /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
4385                                                 hwnd.mapped = false;
4386                                                 msg.message = Msg.WM_SHOWWINDOW;
4387                                                 msg.wParam = (IntPtr) 0;
4388                                                 // XXX we're missing the lParam..
4389                                                 break;
4390                                         }*/
4391                                         goto ProcessNextMessage;
4392                                 }
4393
4394                                 case XEventName.Expose: {
4395                                         if (!hwnd.Mapped) {
4396                                                 if (client) {
4397                                                         hwnd.expose_pending = false;
4398                                                 } else {
4399                                                         hwnd.nc_expose_pending = false;
4400                                                 }
4401                                                 goto ProcessNextMessage;
4402                                         }
4403
4404                                         if (client) {
4405                                                 if (!hwnd.expose_pending) {
4406                                                         goto ProcessNextMessage;
4407                                                 }
4408                                         } else {
4409                                                 if (!hwnd.nc_expose_pending) {
4410                                                         goto ProcessNextMessage;
4411                                                 }
4412
4413                                                 switch (hwnd.border_style) {
4414                                                         case FormBorderStyle.Fixed3D: {
4415                                                                 Graphics g;
4416
4417                                                                 g = Graphics.FromHwnd(hwnd.whole_window);
4418                                                                 if (hwnd.border_static)
4419                                                                         ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.SunkenOuter);
4420                                                                 else
4421                                                                         ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
4422                                                                 g.Dispose();
4423                                                                 break;
4424                                                         }
4425
4426                                                         case FormBorderStyle.FixedSingle: {
4427                                                                 Graphics g;
4428
4429                                                                 g = Graphics.FromHwnd(hwnd.whole_window);
4430                                                                 ControlPaint.DrawBorder(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
4431                                                                 g.Dispose();
4432                                                                 break;
4433                                                         }
4434                                                 }
4435                                                 #if DriverDebugExtra
4436                                                         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);
4437                                                 #endif
4438
4439                                                 Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4440                                                 Region region = new Region (rect);
4441                                                 IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
4442                                                 msg.message = Msg.WM_NCPAINT;
4443                                                 msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
4444                                                 msg.refobject = region;
4445                                                 break;
4446                                         }
4447                                         #if DriverDebugExtra
4448                                                 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);
4449                                         #endif
4450                                         if (Caret.Visible == true) {
4451                                                 Caret.Paused = true;
4452                                                 HideCaret();
4453                                         }
4454
4455                                         if (Caret.Visible == true) {
4456                                                 ShowCaret();
4457                                                 Caret.Paused = false;
4458                                         }
4459                                         msg.message = Msg.WM_PAINT;
4460                                         break;
4461                                 }
4462
4463                                 case XEventName.DestroyNotify: {
4464
4465                                         // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
4466                                         hwnd = Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
4467
4468                                         // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
4469                                         if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
4470                                                 CleanupCachedWindows (hwnd);
4471
4472                                                 #if DriverDebugDestroy
4473                                                         Console.WriteLine("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
4474                                                 #endif
4475
4476                                                 msg.hwnd = hwnd.client_window;
4477                                                 msg.message=Msg.WM_DESTROY;
4478                                                 hwnd.Dispose();
4479                                         } else {
4480                                                 goto ProcessNextMessage;
4481                                         }
4482
4483                                         break;
4484                                 }
4485
4486                                 case XEventName.ClientMessage: {
4487                                         if (Dnd.HandleClientMessage (ref xevent)) {
4488                                                 goto ProcessNextMessage;
4489                                         }
4490
4491                                         if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
4492                                                 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
4493                                                 goto ProcessNextMessage;
4494                                         }
4495
4496                                         if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
4497                                                 msg.message = Msg.WM_MOUSEHOVER;
4498                                                 msg.wParam = GetMousewParam(0);
4499                                                 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
4500                                                 return true;
4501                                         }
4502
4503                                         if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {                                               
4504                                                 DebugHelper.Indent ();
4505                                                 DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
4506                                                 DebugHelper.Unindent ();
4507                                                 msg.hwnd = xevent.ClientMessageEvent.ptr1;
4508                                                 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
4509                                                 msg.wParam = xevent.ClientMessageEvent.ptr3;
4510                                                 msg.lParam = xevent.ClientMessageEvent.ptr4;
4511                                                 if (msg.message == (Msg)Msg.WM_QUIT)
4512                                                         return false;
4513                                                 else
4514                                                         return true;
4515                                         }
4516
4517                                         if  (xevent.ClientMessageEvent.message_type == _XEMBED) {
4518 #if DriverDebugXEmbed
4519                                                 Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
4520 #endif
4521
4522                                                 if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
4523                                                         XSizeHints hints = new XSizeHints();
4524                                                         IntPtr dummy;
4525
4526                                                         XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
4527
4528                                                         hwnd.width = hints.max_width;
4529                                                         hwnd.height = hints.max_height;
4530                                                         hwnd.ClientRect = Rectangle.Empty;
4531                                                         SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4532                                                 }
4533                                         }
4534
4535                                         if  (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
4536                                                 if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
4537                                                         SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
4538                                                         msg.message = Msg.WM_CLOSE;
4539                                                         return true;
4540                                                 }
4541
4542                                                 // We should not get this, but I'll leave the code in case we need it in the future
4543                                                 if (xevent.ClientMessageEvent.ptr1 == WM_TAKE_FOCUS) {
4544                                                         goto ProcessNextMessage;
4545                                                 }
4546                                         }
4547                                         goto ProcessNextMessage;
4548                                 }
4549
4550                                 default: {
4551                                         goto ProcessNextMessage;
4552                                 }
4553                         }
4554
4555                         return true;
4556                 }
4557
4558                 private HitTest NCHitTest (Hwnd hwnd, int x, int y)
4559                 {
4560                         // The hit test is sent in screen coordinates
4561                         IntPtr dummy;
4562                         int screen_x, screen_y;
4563                         XTranslateCoordinates (DisplayHandle, hwnd.WholeWindow, RootWindow, x, y, out screen_x, out screen_y, out dummy);
4564                         return (HitTest) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, 
4565                                                                (IntPtr) (screen_y << 16 | screen_x & 0xFFFF));
4566                 }
4567
4568                 internal override bool GetText(IntPtr handle, out string text) {
4569
4570                         lock (XlibLock) {
4571                                 IntPtr actual_atom;
4572                                 int actual_format;
4573                                 IntPtr nitems;
4574                                 IntPtr bytes_after;
4575                                 IntPtr prop = IntPtr.Zero;
4576
4577                                 XGetWindowProperty(DisplayHandle, handle,
4578                                                    _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
4579                                                    UTF8_STRING, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
4580
4581                                 if ((long)nitems > 0 && prop != IntPtr.Zero) {
4582                                         text = Marshal.PtrToStringUni (prop, (int)nitems);
4583                                         XFree (prop);
4584                                         return true;
4585                                 }
4586                                 else {
4587                                         // fallback on the non-_NET property
4588                                         IntPtr  textptr;
4589
4590                                         textptr = IntPtr.Zero;
4591
4592                                         XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
4593                                         if (textptr != IntPtr.Zero) {
4594                                                 text = Marshal.PtrToStringAnsi(textptr);
4595                                                 XFree(textptr);
4596                                                 return true;
4597                                         } else {
4598                                                 text = "";
4599                                                 return false;
4600                                         }
4601                                 }
4602                         }
4603                 }
4604
4605                 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) {
4606                         Hwnd            hwnd;
4607
4608                         hwnd = Hwnd.ObjectFromHandle(handle);
4609
4610                         if (hwnd != null) {
4611                                 x = hwnd.x;
4612                                 y = hwnd.y;
4613                                 width = hwnd.width;
4614                                 height = hwnd.height;
4615
4616                                 PerformNCCalc(hwnd);
4617
4618                                 client_width = hwnd.ClientRect.Width;
4619                                 client_height = hwnd.ClientRect.Height;
4620
4621                                 return;
4622                         }
4623
4624                         // Should we throw an exception or fail silently?
4625                         // throw new ArgumentException("Called with an invalid window handle", "handle");
4626
4627                         x = 0;
4628                         y = 0;
4629                         width = 0;
4630                         height = 0;
4631                         client_width = 0;
4632                         client_height = 0;
4633                 }
4634
4635                 internal override FormWindowState GetWindowState(IntPtr handle) {
4636                         Hwnd                    hwnd;
4637
4638                         hwnd = Hwnd.ObjectFromHandle(handle);
4639
4640                         if (hwnd.cached_window_state == (FormWindowState)(-1))
4641                                 hwnd.cached_window_state = UpdateWindowState (handle);
4642
4643                         return hwnd.cached_window_state;
4644                 }
4645
4646                 private FormWindowState UpdateWindowState (IntPtr handle) {
4647                         IntPtr                  actual_atom;
4648                         int                     actual_format;
4649                         IntPtr                  nitems;
4650                         IntPtr                  bytes_after;
4651                         IntPtr                  prop = IntPtr.Zero;
4652                         IntPtr                  atom;
4653                         int                     maximized;
4654                         bool                    minimized;
4655                         XWindowAttributes       attributes;
4656                         Hwnd                    hwnd;
4657
4658                         hwnd = Hwnd.ObjectFromHandle(handle);
4659
4660                         maximized = 0;
4661                         minimized = false;
4662                         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);
4663                         if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
4664                                 for (int i = 0; i < (long)nitems; i++) {
4665                                         atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
4666                                         if ((atom == _NET_WM_STATE_MAXIMIZED_HORZ) || (atom == _NET_WM_STATE_MAXIMIZED_VERT)) {
4667                                                 maximized++;
4668                                         } else if (atom == _NET_WM_STATE_HIDDEN) {
4669                                                 minimized = true;
4670                                         }
4671                                 }
4672                                 XFree(prop);
4673                         }
4674
4675                         if (minimized) {
4676                                 return FormWindowState.Minimized;
4677                         } else if (maximized == 2) {
4678                                 return FormWindowState.Maximized;
4679                         }
4680
4681                         attributes = new XWindowAttributes();
4682                         XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4683                         if (attributes.map_state == MapState.IsUnmapped) {
4684                                 return (FormWindowState)(-1);
4685                         }
4686
4687
4688                         return FormWindowState.Normal;
4689                 }
4690
4691                 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea) {
4692                         handle = Grab.Hwnd;
4693                         GrabConfined = Grab.Confined;
4694                         GrabArea = Grab.Area;
4695                 }
4696
4697                 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
4698                         Hwnd    hwnd;
4699                         IntPtr  confine_to_window;
4700
4701                         confine_to_window = IntPtr.Zero;
4702
4703                         if (confine_to_handle != IntPtr.Zero) {
4704                                 XWindowAttributes       attributes = new XWindowAttributes();
4705
4706                                 hwnd = Hwnd.ObjectFromHandle(confine_to_handle);
4707
4708                                 lock (XlibLock) {
4709                                         XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4710                                 }
4711                                 Grab.Area.X = attributes.x;
4712                                 Grab.Area.Y = attributes.y;
4713                                 Grab.Area.Width = attributes.width;
4714                                 Grab.Area.Height = attributes.height;
4715                                 Grab.Confined = true;
4716                                 confine_to_window = hwnd.client_window;
4717                         }
4718
4719                         Grab.Hwnd = handle;
4720
4721                         hwnd = Hwnd.ObjectFromHandle(handle);
4722
4723                         lock (XlibLock) {
4724                                 XGrabPointer(DisplayHandle, hwnd.client_window, false, 
4725                                         EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
4726                                         EventMask.ButtonReleaseMask | EventMask.PointerMotionMask | 
4727                                         EventMask.PointerMotionHintMask | EventMask.LeaveWindowMask,
4728                                         GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
4729                         }
4730                 }
4731
4732                 internal override void UngrabWindow(IntPtr hwnd) {
4733                         lock (XlibLock) {
4734                                 XUngrabPointer(DisplayHandle, IntPtr.Zero);
4735                                 XFlush(DisplayHandle);
4736                         }
4737                         WindowUngrabbed (hwnd);                 
4738                 }
4739                 
4740                 private void WindowUngrabbed (IntPtr hwnd) {
4741                         bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
4742                         
4743                         Grab.Hwnd = IntPtr.Zero;
4744                         Grab.Confined = false;
4745                         
4746                         if (was_grabbed) {
4747                                 // lparam should be the handle to the window gaining the mouse capture,
4748                                 // but X doesn't seem to give us that information.
4749                                 // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
4750                                 // X will send a NotifyUngrab, but since it comes late sometimes we're
4751                                 // calling WindowUngrabbed directly from UngrabWindow in order to send
4752                                 // this WM right away.
4753                                 SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
4754                         }
4755                 }
4756
4757                 internal override void HandleException(Exception e) {
4758                         StackTrace st = new StackTrace(e, true);
4759                         Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
4760                         Console.WriteLine("{0}{1}", e.Message, st.ToString());
4761                 }
4762
4763                 internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
4764                         Hwnd    hwnd;
4765
4766                         hwnd = Hwnd.ObjectFromHandle(handle);
4767
4768                         if (clear) {
4769                                 AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
4770                         } else {
4771                                 AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
4772                         }
4773                 }
4774
4775                 internal override void InvalidateNC (IntPtr handle) {
4776                         Hwnd    hwnd;
4777
4778                         hwnd = Hwnd.ObjectFromHandle(handle);
4779
4780                         AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
4781                 }
4782
4783                 internal override bool IsEnabled(IntPtr handle) {
4784                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4785                         return (hwnd != null && hwnd.Enabled);
4786                 }
4787                 
4788                 internal override bool IsVisible(IntPtr handle) {
4789                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4790                         return (hwnd != null && hwnd.visible);
4791                 }
4792
4793                 internal override void KillTimer(Timer timer) {
4794                         XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
4795
4796                         if (queue == null) {
4797                                 // This isn't really an error, MS doesn't start the timer if
4798                                 // it has no assosciated queue. In this case, remove the timer
4799                                 // from the list of unattached timers (if it was enabled).
4800                                 lock (unattached_timer_list) {
4801                                         if (unattached_timer_list.Contains (timer))
4802                                                 unattached_timer_list.Remove (timer);
4803                                 }
4804                                 return;
4805                         }
4806                         queue.timer_list.Remove (timer);
4807                 }
4808
4809                 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
4810                         int     dest_x_return;
4811                         int     dest_y_return;
4812                         IntPtr  child;
4813                         Hwnd    hwnd;
4814
4815                         hwnd = Hwnd.ObjectFromHandle(handle);
4816
4817                         lock (XlibLock) {
4818                                 XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
4819                         }
4820
4821                         x = dest_x_return;
4822                         y = dest_y_return;
4823                 }
4824
4825                 internal override void OverrideCursor(IntPtr cursor)
4826                 {
4827                         if (Grab.Hwnd != IntPtr.Zero) {
4828                                 XChangeActivePointerGrab (DisplayHandle,
4829                                                 EventMask.ButtonMotionMask |
4830                                                 EventMask.PointerMotionMask |
4831                                                 EventMask.PointerMotionHintMask |
4832                                                 EventMask.ButtonPressMask |
4833                                                 EventMask.ButtonReleaseMask,
4834                                                 cursor, IntPtr.Zero);
4835                                 return;
4836                         }
4837
4838                         OverrideCursorHandle = cursor;
4839                 }
4840
4841                 internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client) {
4842                         PaintEventArgs  paint_event;
4843                         Hwnd            hwnd;
4844                         Hwnd            paint_hwnd;
4845                         
4846                         // 
4847                         // handle  (and paint_hwnd) refers to the window that is should be painted.
4848                         // msg.HWnd (and hwnd) refers to the window that got the paint message.
4849                         // 
4850                         
4851                         hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
4852                         if (msg.HWnd == handle) {
4853                                 paint_hwnd = hwnd;
4854                         } else {
4855                                 paint_hwnd = Hwnd.ObjectFromHandle (handle);
4856                         }
4857         
4858                         if (Caret.Visible == true) {
4859                                 Caret.Paused = true;
4860                                 HideCaret();
4861                         }
4862
4863                         Graphics dc;
4864
4865                         if (client) {
4866                                 dc = Graphics.FromHwnd (paint_hwnd.client_window);
4867
4868                                 Region clip_region = new Region ();
4869                                 clip_region.MakeEmpty();
4870
4871                                 foreach (Rectangle r in hwnd.ClipRectangles) {
4872                                         clip_region.Union (r);
4873                                 }
4874
4875                                 if (hwnd.UserClip != null) {
4876                                         clip_region.Intersect(hwnd.UserClip);
4877                                 }
4878
4879                                 dc.Clip = clip_region;
4880                                 paint_event = new PaintEventArgs(dc, hwnd.Invalid);
4881                                 hwnd.expose_pending = false;
4882
4883                                 hwnd.ClearInvalidArea();
4884
4885                                 hwnd.drawing_stack.Push (paint_event);
4886                                 hwnd.drawing_stack.Push (dc);
4887
4888                                 return paint_event;
4889                         } else {
4890                                 dc = Graphics.FromHwnd (paint_hwnd.whole_window);
4891
4892                                 if (!hwnd.nc_invalid.IsEmpty) {
4893                                         dc.SetClip (hwnd.nc_invalid);
4894                                         paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
4895                                 } else {
4896                                         paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
4897                                 }
4898                                 hwnd.nc_expose_pending = false;
4899
4900                                 hwnd.ClearNcInvalidArea ();
4901
4902                                 hwnd.drawing_stack.Push (paint_event);
4903                                 hwnd.drawing_stack.Push (dc);
4904
4905                                 return paint_event;
4906                         }
4907                 }
4908
4909                 internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client) {
4910                         Hwnd    hwnd;
4911
4912                         hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
4913
4914                         Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
4915                         dc.Flush();
4916                         dc.Dispose();
4917                         
4918                         PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
4919                         pe.SetGraphics (null);
4920                         pe.Dispose ();
4921
4922                         if (Caret.Visible == true) {
4923                                 ShowCaret();
4924                                 Caret.Paused = false;
4925                         }
4926                 }
4927
4928                 [MonoTODO("Implement filtering and PM_NOREMOVE")]
4929                 internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
4930                         XEventQueue queue = (XEventQueue) queue_id;
4931                         bool    pending;
4932
4933                         if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
4934                                 throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet");    // FIXME - Implement PM_NOREMOVE flag
4935                         }
4936
4937                         pending = false;
4938                         if (queue.Count > 0) {
4939                                 pending = true;
4940                         } else {
4941                                 // Only call UpdateMessageQueue if real events are pending 
4942                                 // otherwise we go to sleep on the socket
4943                                 if (XPending(DisplayHandle) != 0) {
4944                                         UpdateMessageQueue((XEventQueue)queue_id);
4945                                         pending = true;
4946                                 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
4947                                         pending = true;
4948                                 }
4949                         }
4950
4951                         CheckTimers(queue.timer_list, DateTime.UtcNow);
4952
4953                         if (!pending) {
4954                                 return false;
4955                         }
4956                         return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
4957                 }
4958
4959                 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam) {
4960                         XEvent xevent = new XEvent ();
4961                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
4962
4963                         xevent.type = XEventName.ClientMessage;
4964                         xevent.ClientMessageEvent.display = DisplayHandle;
4965
4966                         if (hwnd != null) {
4967                                 xevent.ClientMessageEvent.window = hwnd.whole_window;
4968                         } else {
4969                                 xevent.ClientMessageEvent.window = IntPtr.Zero;
4970                         }
4971
4972                         xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
4973                         xevent.ClientMessageEvent.format = 32;
4974                         xevent.ClientMessageEvent.ptr1 = handle;
4975                         xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
4976                         xevent.ClientMessageEvent.ptr3 = wparam;
4977                         xevent.ClientMessageEvent.ptr4 = lparam;
4978
4979                         if (hwnd != null)
4980                                 hwnd.Queue.EnqueueLocked (xevent);
4981                         else
4982                                 ThreadQueue(Thread.CurrentThread).EnqueueLocked (xevent);
4983
4984                         return true;
4985                 }
4986
4987                 internal override void PostQuitMessage(int exitCode) {
4988                         ApplicationContext ctx = Application.MWFThread.Current.Context;
4989                         Form f = ctx != null ? ctx.MainForm : null;
4990                         if (f != null)
4991                                 PostMessage (Application.MWFThread.Current.Context.MainForm.window.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
4992                         else
4993                                 PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
4994                         XFlush(DisplayHandle);
4995                 }
4996
4997                 internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
4998                 {
4999                         // TODO
5000                 }
5001
5002                 internal override void RequestNCRecalc(IntPtr handle) {
5003                         Hwnd                            hwnd;
5004
5005                         hwnd = Hwnd.ObjectFromHandle(handle);
5006
5007                         if (hwnd == null) {
5008                                 return;
5009                         }
5010
5011                         PerformNCCalc(hwnd);
5012                         SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5013                         InvalidateNC(handle);
5014                 }
5015
5016                 internal override void ResetMouseHover(IntPtr handle) {
5017                         Hwnd    hwnd;
5018
5019                         hwnd = Hwnd.ObjectFromHandle(handle);
5020                         if (hwnd == null) {
5021                                 return;
5022                         }
5023
5024                         HoverState.Timer.Enabled = true;
5025                         HoverState.X = mouse_position.X;
5026                         HoverState.Y = mouse_position.Y;
5027                         HoverState.Window = handle;
5028                 }
5029
5030
5031                 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
5032                         int     dest_x_return;
5033                         int     dest_y_return;
5034                         IntPtr  child;
5035                         Hwnd    hwnd;
5036
5037                         hwnd = Hwnd.ObjectFromHandle(handle);
5038
5039                         lock (XlibLock) {
5040                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
5041                         }
5042
5043                         x = dest_x_return;
5044                         y = dest_y_return;
5045                 }
5046
5047                 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
5048                         int     dest_x_return;
5049                         int     dest_y_return;
5050                         IntPtr  child;
5051                         Hwnd    hwnd;
5052
5053                         hwnd = Hwnd.ObjectFromHandle(handle);
5054
5055                         lock (XlibLock) {
5056                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
5057                         }
5058
5059                         Form form = Control.FromHandle (handle) as Form;
5060                         if (form != null && form.window_manager != null) {
5061                                 dest_y_return -= form.window_manager.TitleBarHeight;
5062                         }
5063
5064                         x = dest_x_return;
5065                         y = dest_y_return;
5066                 }
5067
5068                 bool GraphicsExposePredicate (IntPtr display, ref XEvent xevent, IntPtr arg)
5069                 {
5070                         return (xevent.type == XEventName.GraphicsExpose || xevent.type == XEventName.NoExpose) &&
5071                                 arg == xevent.GraphicsExposeEvent.drawable;
5072                 }
5073
5074                 delegate bool EventPredicate (IntPtr display, ref XEvent xevent, IntPtr arg);
5075
5076                 void ProcessGraphicsExpose (Hwnd hwnd)
5077                 {
5078                         XEvent xevent = new XEvent ();
5079                         IntPtr handle = Hwnd.HandleFromObject (hwnd);
5080                         EventPredicate predicate = GraphicsExposePredicate;
5081
5082                         for (;;) {
5083                                 XIfEvent (Display, ref xevent, predicate, handle);
5084                                 if (xevent.type != XEventName.GraphicsExpose)
5085                                         break;
5086
5087                                 AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.GraphicsExposeEvent.x, xevent.GraphicsExposeEvent.y,
5088                                                 xevent.GraphicsExposeEvent.width, xevent.GraphicsExposeEvent.height);
5089
5090                                 if (xevent.GraphicsExposeEvent.count == 0)
5091                                         break;
5092                         }
5093                 }
5094
5095                 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children) {
5096                         Hwnd            hwnd;
5097                         IntPtr          gc;
5098                         XGCValues       gc_values;
5099
5100                         hwnd = Hwnd.ObjectFromHandle(handle);
5101
5102                         Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
5103                         if (!r.IsEmpty) {
5104                                 /* We have an invalid area in the window we're scrolling. 
5105                                    Adjust our stored invalid rectangle to to match the scrolled amount */
5106
5107                                 r.X += XAmount;
5108                                 r.Y += YAmount;
5109
5110                                 if (r.X < 0) {
5111                                         r.Width += r.X;
5112                                         r.X =0;
5113                                 }
5114
5115                                 if (r.Y < 0) {
5116                                         r.Height += r.Y;
5117                                         r.Y =0;
5118                                 }
5119
5120                                 if (area.Contains (hwnd.Invalid))
5121                                         hwnd.ClearInvalidArea ();
5122                                 hwnd.AddInvalidArea(r);
5123                         }
5124
5125                         gc_values = new XGCValues();
5126
5127                         if (with_children) {
5128                                 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
5129                         }
5130
5131                         gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
5132
5133                         Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
5134                         visible_rect.Intersect (area);
5135
5136                         Rectangle dest_rect = visible_rect;
5137                         dest_rect.Y += YAmount;
5138                         dest_rect.X += XAmount;
5139                         dest_rect.Intersect (area);
5140
5141                         Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
5142                         XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y, 
5143                                         dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
5144
5145                         Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
5146                         AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
5147
5148                         ProcessGraphicsExpose (hwnd);
5149
5150                         XFreeGC(DisplayHandle, gc);
5151                 }
5152
5153                 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children) {
5154                         Hwnd            hwnd;
5155                         Rectangle       rect;
5156
5157                         hwnd = Hwnd.GetObjectFromWindow(handle);
5158
5159                         rect = hwnd.ClientRect;
5160                         rect.X = 0;
5161                         rect.Y = 0;
5162                         ScrollWindow(handle, rect, XAmount, YAmount, with_children);
5163                 }
5164
5165                 Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
5166                 {
5167                         Rectangle dirty_area = total_area;
5168
5169                         if (YAmount > 0)
5170                                 dirty_area.Height -= valid_area.Height;
5171                         else if (YAmount < 0) {
5172                                 dirty_area.Height -= valid_area.Height;
5173                                 dirty_area.Y += valid_area.Height;
5174                         }
5175
5176                         if (XAmount > 0)
5177                                 dirty_area.Width -= valid_area.Width;
5178                         else if (XAmount < 0) {
5179                                 dirty_area.Width -= valid_area.Width;
5180                                 dirty_area.X += valid_area.Width;
5181                         }
5182
5183                         return dirty_area;
5184                 }
5185
5186                 Rectangle GetTotalVisibleArea (IntPtr handle)
5187                 {
5188                         Control c = Control.FromHandle (handle);
5189
5190                         Rectangle visible_area = c.ClientRectangle;
5191                         visible_area.Location = c.PointToScreen (Point.Empty);
5192
5193                         for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
5194                                 if (!parent.IsHandleCreated || !parent.Visible)
5195                                         return visible_area; // Non visible, not need to finish computations
5196
5197                                 Rectangle r = parent.ClientRectangle;
5198                                 r.Location = parent.PointToScreen (Point.Empty);
5199
5200                                 visible_area.Intersect (r);
5201                         }
5202
5203                         visible_area.Location = c.PointToClient (visible_area.Location);
5204                         return visible_area;
5205                 }
5206
5207                 internal override void SendAsyncMethod (AsyncMethodData method) {
5208                         Hwnd    hwnd;
5209                         XEvent  xevent = new XEvent ();
5210
5211                         hwnd = Hwnd.ObjectFromHandle(method.Handle);
5212
5213                         xevent.type = XEventName.ClientMessage;
5214                         xevent.ClientMessageEvent.display = DisplayHandle;
5215                         xevent.ClientMessageEvent.window = method.Handle;
5216                         xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
5217                         xevent.ClientMessageEvent.format = 32;
5218                         xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
5219
5220                         hwnd.Queue.EnqueueLocked (xevent);
5221
5222                         WakeupMain ();
5223                 }
5224
5225                 delegate IntPtr WndProcDelegate (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam);
5226
5227                 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
5228                 {
5229                         Hwnd    h;
5230                         h = Hwnd.ObjectFromHandle(hwnd);
5231
5232                         if (h != null && h.queue != ThreadQueue (Thread.CurrentThread)) {
5233                                 AsyncMethodResult       result;
5234                                 AsyncMethodData         data;
5235
5236                                 result = new AsyncMethodResult ();
5237                                 data = new AsyncMethodData ();
5238
5239                                 data.Handle = hwnd;
5240                                 data.Method = new WndProcDelegate (NativeWindow.WndProc);
5241                                 data.Args = new object[] { hwnd, message, wParam, lParam };
5242                                 data.Result = result;
5243                                 
5244                                 SendAsyncMethod (data);
5245                                 #if DriverDebug || DriverDebugThreads
5246                                 Console.WriteLine ("Sending {0} message across.", message);
5247                                 #endif
5248
5249                                 return IntPtr.Zero;
5250                         }
5251                         string key = hwnd + ":" + message;
5252                         if (messageHold[key] != null)
5253                                 messageHold[key] = ((int)messageHold[key]) - 1;
5254                         return NativeWindow.WndProc(hwnd, message, wParam, lParam);
5255                 }
5256
5257                 internal override int SendInput(IntPtr handle, Queue keys) { 
5258                         if (handle == IntPtr.Zero)
5259                                 return 0;
5260
5261                         int count = keys.Count;
5262                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5263
5264                         while (keys.Count > 0) {
5265                         
5266                                 MSG msg = (MSG)keys.Dequeue();
5267
5268                                 XEvent xevent = new XEvent ();
5269
5270                                 xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
5271                                 xevent.KeyEvent.display = DisplayHandle;
5272
5273                                 if (hwnd != null) {
5274                                         xevent.KeyEvent.window = hwnd.whole_window;
5275                                 } else {
5276                                         xevent.KeyEvent.window = IntPtr.Zero;
5277                                 }
5278
5279                                 xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
5280
5281                                 hwnd.Queue.EnqueueLocked (xevent);
5282                         }
5283                         return count;
5284                 }
5285
5286                 internal override void SetAllowDrop (IntPtr handle, bool value)
5287                 {
5288                         // We allow drop on all windows
5289                 }
5290
5291                 internal override DragDropEffects StartDrag (IntPtr handle, object data,
5292                                 DragDropEffects allowed_effects)
5293                 {
5294                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5295
5296                         if (hwnd == null)
5297                                 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
5298
5299                         return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
5300                 }
5301
5302                 internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style) {
5303                         Form form = Control.FromHandle (handle) as Form;
5304                         if (form != null && form.window_manager == null) {
5305                                 CreateParams cp = form.GetCreateParams ();
5306                                 if (border_style == FormBorderStyle.FixedToolWindow ||
5307                                      border_style == FormBorderStyle.SizableToolWindow || 
5308                                      cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
5309                                         form.window_manager = new ToolWindowManager (form);
5310                                 }
5311                         }
5312                         
5313                         RequestNCRecalc(handle);
5314                 }
5315
5316                 internal override void SetCaretPos(IntPtr handle, int x, int y) {
5317                         if (Caret.Hwnd == handle) {
5318                                 Caret.Timer.Stop();
5319                                 HideCaret();
5320
5321                                 Caret.X = x;
5322                                 Caret.Y = y;
5323
5324                                 Keyboard.SetCaretPos (Caret, handle, x, y);
5325
5326                                 if (Caret.Visible == true) {
5327                                         ShowCaret();
5328                                         Caret.Timer.Start();
5329                                 }
5330                         }
5331                 }
5332
5333                 internal override void SetClipRegion(IntPtr handle, Region region) {
5334                         Hwnd    hwnd;
5335
5336                         hwnd = Hwnd.ObjectFromHandle(handle);
5337                         if (hwnd == null) {
5338                                 return;
5339                         }
5340
5341                         hwnd.UserClip = region;
5342                 }
5343
5344                 internal override void SetCursor(IntPtr handle, IntPtr cursor) {
5345                         Hwnd    hwnd;
5346
5347                         if (OverrideCursorHandle == IntPtr.Zero) {
5348                                 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
5349                                         return;
5350                                 }
5351
5352                                 LastCursorHandle = cursor;
5353                                 LastCursorWindow = handle;
5354
5355                                 hwnd = Hwnd.ObjectFromHandle(handle);
5356                                 lock (XlibLock) {
5357                                         if (cursor != IntPtr.Zero) {
5358                                                 XDefineCursor(DisplayHandle, hwnd.whole_window, cursor);
5359                                         } else {
5360                                                 XUndefineCursor(DisplayHandle, hwnd.whole_window);
5361                                         }
5362                                         XFlush(DisplayHandle);
5363                                 }
5364                                 return;
5365                         }
5366
5367                         hwnd = Hwnd.ObjectFromHandle(handle);
5368                         lock (XlibLock) {
5369                                 XDefineCursor(DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
5370                         }
5371                 }
5372
5373                 private void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
5374                                            out int root_x, out int root_y, out int child_x, out int child_y,
5375                                            out int mask)
5376                 {
5377                         /* this code was written with the help of
5378                         glance at gdk.  I never would have realized we
5379                         needed a loop in order to traverse down in the
5380                         hierarchy.  I would have assumed you'd get the
5381                         most deeply nested child and have to do
5382                         XQueryTree to move back up the hierarchy..
5383                         stupid me, of course. */
5384                         IntPtr c;
5385
5386                         XGrabServer (display);
5387
5388                         XQueryPointer(display, w, out root, out c,
5389                                       out root_x, out root_y, out child_x, out child_y,
5390                                       out mask);
5391
5392                         if (root != w)
5393                                 c = root;
5394
5395                         IntPtr child_last = IntPtr.Zero;
5396                         while (c != IntPtr.Zero) {
5397                                 child_last = c;
5398                                 XQueryPointer(display, c, out root, out c,
5399                                               out root_x, out root_y, out child_x, out child_y,
5400                                               out mask);
5401                         }
5402                         XUngrabServer (display);
5403                         XFlush (display);
5404
5405                         child = child_last;
5406                 }
5407
5408                 internal override void SetCursorPos(IntPtr handle, int x, int y) {
5409                         if (handle == IntPtr.Zero) {
5410                                 lock (XlibLock) {
5411                                         IntPtr root, child;
5412                                         int root_x, root_y, child_x, child_y, mask;
5413
5414                                         /* we need to do a
5415                                          * QueryPointer before warping
5416                                          * because if the warp is on
5417                                          * the RootWindow, the x/y are
5418                                          * relative to the current
5419                                          * mouse position
5420                                          */
5421                                         QueryPointer (DisplayHandle, RootWindow,
5422                                                       out root,
5423                                                       out child,
5424                                                       out root_x, out root_y,
5425                                                       out child_x, out child_y,
5426                                                       out mask);
5427
5428                                         XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x - root_x, y - root_y);
5429
5430                                         XFlush (DisplayHandle);
5431
5432                                         /* then we need to a
5433                                          * QueryPointer after warping
5434                                          * to manually generate a
5435                                          * motion event for the window
5436                                          * we move into.
5437                                          */
5438                                         QueryPointer (DisplayHandle, RootWindow,
5439                                                       out root,
5440                                                       out child,
5441                                                       out root_x, out root_y,
5442                                                       out child_x, out child_y,
5443                                                       out mask);
5444
5445                                         Hwnd child_hwnd = Hwnd.ObjectFromHandle(child);
5446                                         if (child_hwnd == null) {
5447                                                 return;
5448                                         }
5449
5450                                         XEvent xevent = new XEvent ();
5451
5452                                         xevent.type = XEventName.MotionNotify;
5453                                         xevent.MotionEvent.display = DisplayHandle;
5454                                         xevent.MotionEvent.window = child_hwnd.client_window;
5455                                         xevent.MotionEvent.root = RootWindow;
5456                                         xevent.MotionEvent.x = child_x;
5457                                         xevent.MotionEvent.y = child_y;
5458                                         xevent.MotionEvent.x_root = root_x;
5459                                         xevent.MotionEvent.y_root = root_y;
5460                                         xevent.MotionEvent.state = mask;
5461
5462                                         child_hwnd.Queue.EnqueueLocked (xevent);
5463                                 }
5464                         } else {
5465                                 Hwnd    hwnd;
5466
5467                                 hwnd = Hwnd.ObjectFromHandle(handle);
5468                                 lock (XlibLock) {
5469                                         XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
5470                                 }
5471                         }
5472                 }
5473
5474                 internal override void SetFocus(IntPtr handle) {
5475                         Hwnd    hwnd;
5476                         IntPtr  prev_focus_window;
5477
5478                         hwnd = Hwnd.ObjectFromHandle(handle);
5479
5480                         if (hwnd.client_window == FocusWindow) {
5481                                 return;
5482                         }
5483
5484                         // Win32 doesn't do anything if disabled
5485                         if (!hwnd.enabled)
5486                                 return;
5487
5488                         prev_focus_window = FocusWindow;
5489                         FocusWindow = hwnd.client_window;
5490
5491                         if (prev_focus_window != IntPtr.Zero) {
5492                                 SendMessage(prev_focus_window, Msg.WM_KILLFOCUS, FocusWindow, IntPtr.Zero);
5493                         }
5494                         SendMessage(FocusWindow, Msg.WM_SETFOCUS, prev_focus_window, IntPtr.Zero);
5495                         Keyboard.FocusIn (FocusWindow);
5496
5497                         //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
5498                 }
5499
5500                 internal override void SetIcon(IntPtr handle, Icon icon) {
5501                         Hwnd    hwnd;
5502
5503                         hwnd = Hwnd.ObjectFromHandle(handle);
5504                         if (hwnd != null) {
5505                                 SetIcon(hwnd, icon);
5506                         }
5507                 }
5508
5509                 internal override void SetMenu(IntPtr handle, Menu menu) {
5510                         Hwnd    hwnd;
5511
5512                         hwnd = Hwnd.ObjectFromHandle(handle);
5513                         hwnd.menu = menu;
5514
5515                         RequestNCRecalc(handle);
5516                 }
5517
5518                 internal override void SetModal(IntPtr handle, bool Modal) {
5519                         if (Modal) {
5520                                 ModalWindows.Push(handle);
5521                         } else {
5522                                 if (ModalWindows.Contains(handle)) {
5523                                         ModalWindows.Pop();
5524                                 }
5525                                 if (ModalWindows.Count > 0) {
5526                                         Activate((IntPtr)ModalWindows.Peek());
5527                                 }
5528                         }
5529
5530                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5531                         Control ctrl = Control.FromHandle (handle);
5532                         SetWMStyles (hwnd, ctrl.GetCreateParams ());
5533                 }
5534
5535                 internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
5536                         Hwnd    hwnd;
5537
5538                         hwnd = Hwnd.ObjectFromHandle(handle);
5539                         hwnd.parent = Hwnd.ObjectFromHandle(parent);
5540
5541                         lock (XlibLock) {
5542                                 #if DriverDebug || DriverDebugParent
5543                                         Console.WriteLine("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
5544                                 #endif
5545                                 XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent == null ? FosterParent : hwnd.parent.client_window, hwnd.x, hwnd.y);
5546                         }
5547
5548                         return IntPtr.Zero;
5549                 }
5550
5551                 internal override void SetTimer (Timer timer) {
5552                         XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5553
5554                         if (queue == null) {
5555                                 // This isn't really an error, MS doesn't start the timer if
5556                                 // it has no assosciated queue at this stage (it will be
5557                                 // enabled when a window is activated).
5558                                 unattached_timer_list.Add (timer);
5559                                 return;
5560                         }
5561                         queue.timer_list.Add (timer);
5562                         WakeupMain ();
5563                 }
5564
5565                 internal override bool SetTopmost(IntPtr handle, bool enabled) {
5566
5567                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5568
5569                         if (enabled) {
5570                                 lock (XlibLock) {
5571                                         if (hwnd.Mapped) {
5572                                                 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_ADD, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5573                                         } else {
5574                                                 int[] atoms = new int[8];
5575                                                 atoms[0] = _NET_WM_STATE_ABOVE.ToInt32();
5576                                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5577                                         }
5578                                 }
5579                         } else {
5580                                 lock (XlibLock) {
5581                                         if (hwnd.Mapped)
5582                                                 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_REMOVE, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5583                                         else
5584                                                 XDeleteProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE);
5585                                 }
5586                         }
5587                         return true;
5588                 }
5589
5590                 internal override bool SetOwner(IntPtr handle, IntPtr handle_owner) {
5591                         Hwnd hwnd;
5592                         Hwnd hwnd_owner;
5593
5594                         hwnd = Hwnd.ObjectFromHandle(handle);
5595
5596                         if (handle_owner != IntPtr.Zero) {
5597                                 hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
5598                                 lock (XlibLock) {
5599                                         int[]   atoms;
5600
5601                                         atoms = new int[8];
5602
5603                                         atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
5604                                         XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5605
5606                                         if (hwnd_owner != null) {
5607                                                 XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
5608                                         } else {
5609                                                 XSetTransientForHint(DisplayHandle, hwnd.whole_window, RootWindow);
5610                                         }
5611                                 }
5612                         } else {
5613                                 lock (XlibLock) {
5614                                         XDeleteProperty(DisplayHandle, hwnd.whole_window, (IntPtr)Atom.XA_WM_TRANSIENT_FOR);
5615                                 }
5616                         }
5617                         return true;
5618                 }
5619
5620                 internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
5621                 {
5622                         Hwnd    hwnd;
5623
5624                         hwnd = Hwnd.ObjectFromHandle(handle);
5625                         hwnd.visible = visible;
5626
5627                         lock (XlibLock) {
5628                                 if (visible) {
5629                                         MapWindow(hwnd, WindowType.Both);
5630
5631                                         if (Control.FromHandle(handle) is Form) {
5632                                                 FormWindowState s;
5633
5634                                                 s = ((Form)Control.FromHandle(handle)).WindowState;
5635
5636                                                 switch(s) {
5637                                                         case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
5638                                                         case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
5639                                                 }
5640                                         }
5641
5642                                         SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5643                                 }
5644                                 else {
5645                                         UnmapWindow(hwnd, WindowType.Both);
5646                                 }
5647                         }
5648                         return true;
5649                 }
5650
5651                 internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
5652                         Control ctrl = Control.FromHandle (handle);
5653                         SetWindowMinMax (handle, maximized, min, max, ctrl != null ? ctrl.GetCreateParams () : null);
5654                 }
5655
5656                 internal void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max, CreateParams cp)
5657                 {
5658                         Hwnd            hwnd;
5659                         XSizeHints      hints;
5660                         IntPtr          dummy;
5661
5662                         hwnd = Hwnd.ObjectFromHandle(handle);
5663                         if (hwnd == null) {
5664                                 return;
5665                         }
5666
5667                         min.Width = Math.Max (min.Width, SystemInformation.MinimumWindowSize.Width);
5668                         min.Height = Math.Max (min.Height, SystemInformation.MinimumWindowSize.Height);
5669                         
5670                         hints = new XSizeHints();
5671
5672                         XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
5673                         if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
5674                                 if (cp != null)
5675                                         min = TranslateWindowSizeToXWindowSize (cp, min);
5676                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
5677                                 hints.min_width = min.Width;
5678                                 hints.min_height = min.Height;
5679                         }
5680
5681                         if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
5682                                 if (cp != null)
5683                                         max = TranslateWindowSizeToXWindowSize (cp, max);
5684                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
5685                                 hints.max_width = max.Width;
5686                                 hints.max_height = max.Height;
5687                         }
5688
5689                         if (hints.flags != IntPtr.Zero) {
5690                                 // The Metacity team has decided that they won't care about this when clicking the maximize icon, 
5691                                 // they will maximize the window to fill the screen/parent no matter what.
5692                                 // http://bugzilla.ximian.com/show_bug.cgi?id=80021
5693                                 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
5694                         }
5695
5696                         if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
5697                                 if (cp != null)
5698                                         maximized.Size = TranslateWindowSizeToXWindowSize (cp);
5699                                 hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
5700                                 hints.x = maximized.X;
5701                                 hints.y = maximized.Y;
5702                                 hints.width = maximized.Width;
5703                                 hints.height = maximized.Height;
5704
5705                                 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
5706                                 XSetZoomHints(DisplayHandle, hwnd.whole_window, ref hints);
5707                         }
5708                 }
5709
5710
5711                 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
5712                         Hwnd            hwnd;
5713
5714                         hwnd = Hwnd.ObjectFromHandle(handle);
5715
5716                         if (hwnd == null) {
5717                                 return;
5718                         }
5719
5720                         // Win32 automatically changes negative width/height to 0.
5721                         if (width < 0)
5722                                 width = 0;
5723                         if (height < 0)
5724                                 height = 0;
5725                                 
5726                         // X requires a sanity check for width & height; otherwise it dies
5727                         if (hwnd.zero_sized && width > 0 && height > 0) {
5728                                 if (hwnd.visible) {
5729                                         MapWindow(hwnd, WindowType.Whole);
5730                                 }
5731                                 hwnd.zero_sized = false;
5732                         }
5733
5734                         if ((width < 1) || (height < 1)) {
5735                                 hwnd.zero_sized = true;
5736                                 UnmapWindow(hwnd, WindowType.Whole);
5737                         }
5738
5739                         // Save a server roundtrip (and prevent a feedback loop)
5740                         if ((hwnd.x == x) && (hwnd.y == y) && 
5741                                 (hwnd.width == width) && (hwnd.height == height)) {
5742                                 return;
5743                         }
5744
5745                         if (!hwnd.zero_sized) {
5746                                 //Hack?
5747                                 hwnd.x = x;
5748                                 hwnd.y = y;
5749                                 hwnd.width = width;
5750                                 hwnd.height = height;
5751                                 SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5752
5753                                 if (hwnd.fixed_size) {
5754                                         SetWindowMinMax(handle, Rectangle.Empty, new Size(width, height), new Size(width, height));
5755                                 }
5756
5757                                 lock (XlibLock) {
5758                                         Control ctrl = Control.FromHandle (handle);
5759                                         Size TranslatedSize = TranslateWindowSizeToXWindowSize (ctrl.GetCreateParams (), new Size (width, height));
5760                                         MoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, TranslatedSize.Width, TranslatedSize.Height);
5761                                         PerformNCCalc(hwnd);
5762                                 }
5763                         }
5764
5765                         // Update our position/size immediately, so
5766                         // that future calls to SetWindowPos aren't
5767                         // kept from calling XMoveResizeWindow (by the
5768                         // "Save a server roundtrip" block above).
5769                         hwnd.x = x;
5770                         hwnd.y = y;
5771                         hwnd.width = width;
5772                         hwnd.height = height;
5773                         hwnd.ClientRect = Rectangle.Empty;
5774                 }
5775
5776                 internal override void SetWindowState(IntPtr handle, FormWindowState state) {
5777                         FormWindowState current_state;
5778                         Hwnd            hwnd;
5779
5780                         hwnd = Hwnd.ObjectFromHandle(handle);
5781
5782                         current_state = GetWindowState(handle);
5783
5784                         if (current_state == state) {
5785                                 return;
5786                         }
5787
5788                         switch(state) {
5789                                 case FormWindowState.Normal: {
5790                                         lock (XlibLock) {
5791                                                 if (current_state == FormWindowState.Minimized) {
5792                                                         MapWindow(hwnd, WindowType.Both);
5793                                                 } else if (current_state == FormWindowState.Maximized) {
5794                                                         SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
5795                                                 }
5796                                         }
5797                                         Activate(handle);
5798                                         return;
5799                                 }
5800
5801                                 case FormWindowState.Minimized: {
5802                                         lock (XlibLock) {
5803                                                 if (current_state == FormWindowState.Maximized) {
5804                                                         SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
5805                                                 }
5806                                                 XIconifyWindow(DisplayHandle, hwnd.whole_window, ScreenNo);
5807                                         }
5808                                         return;
5809                                 }
5810
5811                                 case FormWindowState.Maximized: {
5812                                         lock (XlibLock) {
5813                                                 if (current_state == FormWindowState.Minimized) {
5814                                                         MapWindow(hwnd, WindowType.Both);
5815                                                 }
5816
5817                                                 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)1 /* Add */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
5818                                         }
5819                                         Activate(handle);
5820                                         return;
5821                                 }
5822                         }
5823                 }
5824
5825                 internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
5826                         Hwnd    hwnd;
5827
5828                         hwnd = Hwnd.ObjectFromHandle(handle);
5829                         SetHwndStyles(hwnd, cp);
5830                         SetWMStyles(hwnd, cp);
5831                 }
5832
5833                 internal override double GetWindowTransparency(IntPtr handle)
5834                 {
5835                         return 1.0;
5836                 }
5837
5838                 internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
5839                         Hwnd    hwnd;
5840                         IntPtr  opacity;
5841
5842                         hwnd = Hwnd.ObjectFromHandle(handle);
5843
5844                         if (hwnd == null) {
5845                                 return;
5846                         }
5847
5848                         hwnd.opacity = (uint)(0xffffffff * transparency);
5849                         opacity = (IntPtr)((int)hwnd.opacity);
5850
5851                         IntPtr w = hwnd.whole_window;
5852                         if (hwnd.reparented)
5853                                 w = XGetParent (hwnd.whole_window);
5854                         XChangeProperty(DisplayHandle, w, _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
5855                 }
5856
5857                 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom) {
5858                         Hwnd    hwnd = Hwnd.ObjectFromHandle(handle);
5859
5860                         if (!hwnd.mapped) {
5861                                 return false;
5862                         }
5863
5864                         if (top) {
5865                                 lock (XlibLock) {
5866                                         XRaiseWindow(DisplayHandle, hwnd.whole_window);
5867                                 }
5868                                 return true;
5869                         } else if (!bottom) {
5870                                 Hwnd    after_hwnd = null;
5871
5872                                 if (after_handle != IntPtr.Zero) {
5873                                         after_hwnd = Hwnd.ObjectFromHandle(after_handle);
5874                                 }
5875
5876                                 XWindowChanges  values = new XWindowChanges();
5877
5878                                 if (after_hwnd == null) {
5879                                         // Work around metacity 'issues'
5880                                         int[]   atoms;
5881
5882                                         atoms = new int[2];
5883                                         atoms[0] = unixtime();
5884                                         XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_USER_TIME, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, atoms, 1);
5885
5886                                         XRaiseWindow(DisplayHandle, hwnd.whole_window);
5887                                         SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
5888                                         return true;
5889                                         //throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
5890                                 }
5891
5892                                 values.sibling = after_hwnd.whole_window;
5893                                 values.stack_mode = StackMode.Below;
5894
5895                                 lock (XlibLock) {
5896                                         XConfigureWindow(DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
5897                                 }
5898                         } else {
5899                                 // Bottom
5900                                 lock (XlibLock) {
5901                                         XLowerWindow(DisplayHandle, hwnd.whole_window);
5902                                 }
5903                                 return true;
5904                         }
5905                         return false;
5906                 }
5907
5908                 internal override void ShowCursor(bool show) {
5909                         ;       // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
5910                 }
5911
5912                 internal override object StartLoop(Thread thread) {
5913                         XEventQueue q = ThreadQueue(thread);
5914                         return q;
5915                 }
5916
5917                 internal override TransparencySupport SupportsTransparency() {
5918                         // We need to check if the x compositing manager is running
5919                         return TransparencySupport.Set;
5920                 }
5921
5922                 internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {
5923                         GetSystrayManagerWindow();
5924
5925                         if (SystrayMgrWindow != IntPtr.Zero) {
5926                                 XSizeHints      size_hints;
5927                                 Hwnd            hwnd;
5928
5929                                 hwnd = Hwnd.ObjectFromHandle(handle);
5930                                 #if DriverDebug
5931                                         Console.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
5932                                 #endif
5933
5934                                 // Oh boy.
5935                                 if (hwnd.client_window != hwnd.whole_window) {
5936                                         Keyboard.DestroyICForWindow (hwnd.client_window);
5937                                         XDestroyWindow(DisplayHandle, hwnd.client_window);
5938                                         hwnd.client_window = hwnd.whole_window;
5939                                 }       
5940
5941                                 /* by virtue of the way the tests are ordered when determining if it's PAINT
5942                                    or NCPAINT, client_window == whole_window will always be PAINT.  So, if we're
5943                                    waiting on an nc_expose, drop it and remove the hwnd from the list (unless
5944                                    there's a pending expose). */
5945                                 if (hwnd.nc_expose_pending) {
5946                                         hwnd.nc_expose_pending = false;
5947                                         if (!hwnd.expose_pending)
5948                                                 hwnd.Queue.Paint.Remove (hwnd);
5949                                 }
5950
5951                                 size_hints = new XSizeHints();
5952
5953                                 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
5954
5955                                 size_hints.min_width = 24;
5956                                 size_hints.min_height = 24;
5957                                 size_hints.max_width = 24;
5958                                 size_hints.max_height = 24;
5959                                 size_hints.base_width = 24;
5960                                 size_hints.base_height = 24;
5961
5962                                 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
5963
5964                                 int[] atoms = new int[2];
5965                                 atoms [0] = 1;                  // Version 1
5966                                 atoms [1] = 1;                  // we want to be mapped
5967
5968                                 // This line cost me 3 days...
5969                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _XEMBED_INFO, _XEMBED_INFO, 32, PropertyMode.Replace, atoms, 2);
5970
5971                                 // Need to pick some reasonable defaults
5972                                 tt = new ToolTip();
5973                                 tt.AutomaticDelay = 350;
5974                                 tt.InitialDelay = 250;
5975                                 tt.ReshowDelay = 250;
5976                                 tt.ShowAlways = true;
5977
5978                                 if ((tip != null) && (tip != string.Empty)) {
5979                                         tt.SetToolTip(Control.FromHandle(handle), tip);
5980                                         tt.Active = true;
5981                                 } else {
5982                                         tt.Active = false;
5983                                 }
5984
5985                                 SendNetClientMessage(SystrayMgrWindow, _NET_SYSTEM_TRAY_OPCODE, IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
5986
5987                                 return true;
5988                         }
5989                         tt = null;
5990                         return false;
5991                 }
5992
5993                 internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt) {
5994                         Control control;
5995
5996                         control = Control.FromHandle(handle);
5997                         if (control != null && tt != null) {
5998                                 tt.SetToolTip(control, tip);
5999                                 tt.Active = true;
6000                                 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6001                                 return true;
6002                         } else {
6003                                 return false;
6004                         }
6005                 }
6006
6007                 internal override void SystrayRemove(IntPtr handle, ref ToolTip tt) {
6008
6009                         SetVisible (handle, false, false);
6010
6011                         // The caller can now re-dock it later...
6012                         if (tt != null) {
6013                                 tt.Dispose();
6014                                 tt = null;
6015                         }
6016                 }
6017
6018 #if NET_2_0
6019                 internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
6020                 {
6021                         ThemeEngine.Current.ShowBalloonWindow (handle, timeout, title, text, icon);
6022                         SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);    
6023                 }
6024 #endif
6025
6026                 internal override bool Text(IntPtr handle, string text) {
6027                         Hwnd    hwnd;
6028
6029                         hwnd = Hwnd.ObjectFromHandle(handle);
6030
6031                         lock (XlibLock) {
6032                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UTF8_STRING, 8,
6033                                                 PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
6034
6035                                 // XXX this has problems with UTF8.
6036                                 // we need to either use the actual
6037                                 // text if it's latin-1, or convert it
6038                                 // to compound text if it's in a
6039                                 // different charset.
6040                                 XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
6041                         }
6042                         return true;
6043                 }
6044
6045                 internal override bool TranslateMessage(ref MSG msg) {
6046                         return Keyboard.TranslateMessage (ref msg);
6047                 }
6048
6049                 internal override void UpdateWindow(IntPtr handle) {
6050                         Hwnd    hwnd;
6051
6052                         hwnd = Hwnd.ObjectFromHandle(handle);
6053
6054                         if (!hwnd.visible || !hwnd.expose_pending || !hwnd.Mapped) {
6055                                 return;
6056                         }
6057
6058                         SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6059                         hwnd.Queue.Paint.Remove(hwnd);
6060                 }
6061
6062                 internal override void CreateOffscreenDrawable (IntPtr handle,
6063                                                                 int width, int height,
6064                                                                 out object offscreen_drawable)
6065                 {
6066                         IntPtr root_out;
6067                         int x_out, y_out, width_out, height_out, border_width_out, depth_out;
6068
6069                         XGetGeometry (DisplayHandle, handle,
6070                                       out root_out,
6071                                       out x_out, out y_out,
6072                                       out width_out, out height_out,
6073                                       out border_width_out, out depth_out);
6074
6075                         IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
6076
6077                         offscreen_drawable = pixmap;
6078
6079                 }
6080
6081                 internal override void DestroyOffscreenDrawable (object offscreen_drawable)
6082                 {
6083                         XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
6084                 }
6085
6086                 internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
6087                 {
6088                         return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
6089                 }
6090                 
6091                 internal override void BlitFromOffscreen (IntPtr dest_handle,
6092                                                           Graphics dest_dc,
6093                                                           object offscreen_drawable,
6094                                                           Graphics offscreen_dc,
6095                                                           Rectangle r)
6096                 {
6097                         XGCValues gc_values;
6098                         IntPtr gc;
6099
6100                         gc_values = new XGCValues();
6101
6102                         gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
6103
6104                         XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
6105                                    gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
6106
6107                         XFreeGC (DisplayHandle, gc);
6108                 }
6109
6110                 #endregion      // Public Static Methods
6111
6112                 #region Events
6113                 internal override event EventHandler Idle;
6114                 #endregion      // Events
6115
6116                 
6117 #if TRACE
6118                 
6119 #region Xcursor imports
6120                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
6121                 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
6122
6123                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
6124                 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
6125                 
6126                 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
6127                 internal extern static void XcursorImagesDestroy (IntPtr images);
6128                 
6129                 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
6130                 internal extern static int XcursorGetDefaultSize (IntPtr display);
6131
6132                 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
6133                 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
6134
6135                 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
6136                 internal extern static IntPtr XcursorGetTheme (IntPtr display);
6137 #endregion
6138 #region X11 Imports
6139                 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
6140                 internal extern static IntPtr XOpenDisplay(IntPtr display);
6141                 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
6142                 internal extern static int XCloseDisplay(IntPtr display);                                                   
6143                 [DllImport ("libX11", EntryPoint="XSynchronize")]
6144                 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
6145
6146                 [DllImport ("libX11", EntryPoint="XCreateWindow")]
6147                 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);
6148                 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) {
6149                         DebugHelper.TraceWriteLine ("XCreateWindow");
6150                         return _XCreateWindow(display, parent, x, y, width, height, 
6151                                        border_width, depth, xclass, visual, valuemask, ref attributes);
6152                 }
6153                 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
6154                 internal extern static IntPtr _XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
6155                 internal static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background) {
6156                         DebugHelper.TraceWriteLine ("XCreateSimpleWindow");
6157                         return _XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background);
6158                 }
6159                 [DllImport ("libX11", EntryPoint="XMapWindow")]
6160                 internal extern static int _XMapWindow(IntPtr display, IntPtr window);
6161                 internal static int XMapWindow(IntPtr display, IntPtr window) {
6162                         DebugHelper.TraceWriteLine ("XMapWindow");
6163                         return _XMapWindow(display, window);
6164                 }
6165                 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
6166                 internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
6167                 internal static int XUnmapWindow(IntPtr display, IntPtr window) {
6168                         DebugHelper.TraceWriteLine ("XUnmapWindow");
6169                         return _XUnmapWindow(display, window);
6170                 }
6171                 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
6172                 internal extern static int _XMapSubindows(IntPtr display, IntPtr window);
6173                 internal static int XMapSubindows(IntPtr display, IntPtr window) {
6174                         DebugHelper.TraceWriteLine ("XMapSubindows");
6175                         return _XMapSubindows(display, window);
6176                 }
6177                 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
6178                 internal extern static int _XUnmapSubwindows(IntPtr display, IntPtr window);
6179                 internal static int XUnmapSubwindows(IntPtr display, IntPtr window) {
6180                         DebugHelper.TraceWriteLine ("XUnmapSubwindows");
6181                         return _XUnmapSubwindows(display, window);
6182                 }
6183                 [DllImport ("libX11", EntryPoint="XRootWindow")]
6184                 internal extern static IntPtr _XRootWindow(IntPtr display, int screen_number);
6185                 internal static IntPtr XRootWindow(IntPtr display, int screen_number) {
6186                         DebugHelper.TraceWriteLine ("XRootWindow");
6187                         return _XRootWindow(display, screen_number);
6188                 }
6189                 [DllImport ("libX11", EntryPoint="XNextEvent")]
6190                 internal extern static IntPtr _XNextEvent(IntPtr display, ref XEvent xevent);
6191                 internal static IntPtr XNextEvent(IntPtr display, ref XEvent xevent) {
6192                         DebugHelper.TraceWriteLine ("XNextEvent");
6193                         return _XNextEvent(display, ref xevent);
6194                 }
6195                 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
6196                 internal extern static int _XConnectionNumber (IntPtr display);
6197                 internal static int XConnectionNumber (IntPtr display) {
6198                         DebugHelper.TraceWriteLine ("XConnectionNumber");
6199                         return _XConnectionNumber (display);
6200                 }
6201                 [DllImport ("libX11", EntryPoint="XPending")]
6202                 internal extern static int _XPending (IntPtr display);
6203                 internal static int XPending (IntPtr display) {
6204                         DebugHelper.TraceWriteLine ("XPending");
6205                         DebugHelper.DumpCallers (3);
6206                         return _XPending (display);
6207                 }
6208                 [DllImport ("libX11", EntryPoint="XSelectInput")]
6209                 internal extern static IntPtr _XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
6210                 internal static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask) {
6211                         DebugHelper.TraceWriteLine ("XSelectInput");
6212                         return _XSelectInput(display, window, mask);
6213                 }
6214
6215                 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
6216                 internal extern static int _XDestroyWindow(IntPtr display, IntPtr window);
6217                 internal static int XDestroyWindow(IntPtr display, IntPtr window) {
6218                         DebugHelper.TraceWriteLine ("XDestroyWindow 0x{0:x}", window.ToInt32());
6219                         return _XDestroyWindow(display, window);
6220                 }
6221
6222                 [DllImport ("libX11", EntryPoint="XReparentWindow")]
6223                 internal extern static int _XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
6224                 internal static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y) {
6225                         DebugHelper.TraceWriteLine ("XReparentWindow");
6226                         return _XReparentWindow(display, window, parent, x, y);
6227                 }
6228                 
6229                 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
6230                 private extern static int _XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
6231                 private static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height) {
6232                         DebugHelper.TraceWriteLine ("XMoveResizeWindow");
6233                         return _XMoveResizeWindow(display, window, x, y, width, height);
6234                 }
6235
6236                 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
6237                 {
6238                         int ret = XMoveResizeWindow (display, window, x, y, width, height);
6239                         Keyboard.MoveCurrentCaretPos ();
6240                         return ret;
6241                 }
6242
6243                 [DllImport ("libX11", EntryPoint="XResizeWindow")]
6244                 internal extern static int _XResizeWindow(IntPtr display, IntPtr window, int width, int height);
6245                 internal static int XResizeWindow(IntPtr display, IntPtr window, int width, int height) {
6246                         DebugHelper.TraceWriteLine ("XResizeWindow");
6247                         return _XResizeWindow(display, window, width, height);
6248                 }
6249
6250                 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
6251                 internal extern static int _XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
6252                 internal static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes) {
6253                         DebugHelper.TraceWriteLine ("XGetWindowAttributes");
6254                         return _XGetWindowAttributes(display, window, ref attributes);
6255                 }
6256
6257                 [DllImport ("libX11", EntryPoint="XFlush")]
6258                 internal extern static int _XFlush(IntPtr display);
6259                 internal static int XFlush(IntPtr display) {
6260                         DebugHelper.TraceWriteLine ("XFlush");
6261                         return _XFlush(display);
6262                 }
6263
6264                 [DllImport ("libX11", EntryPoint="XSetWMName")]
6265                 internal extern static int _XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
6266                 internal static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop) {
6267                         DebugHelper.TraceWriteLine ("XSetWMName");
6268                         return _XSetWMName(display, window, ref text_prop);
6269                 }
6270
6271                 [DllImport ("libX11", EntryPoint="XStoreName")]
6272                 internal extern static int _XStoreName(IntPtr display, IntPtr window, string window_name);
6273                 internal static int XStoreName(IntPtr display, IntPtr window, string window_name) {
6274                         DebugHelper.TraceWriteLine ("XStoreName");
6275                         return _XStoreName(display, window, window_name);
6276                 }
6277
6278                 [DllImport ("libX11", EntryPoint="XFetchName")]
6279                 internal extern static int _XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
6280                 internal static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name) {
6281                         DebugHelper.TraceWriteLine ("XFetchName");
6282                         return _XFetchName(display, window, ref window_name);
6283                 }
6284
6285                 [DllImport ("libX11", EntryPoint="XSendEvent")]
6286                 internal extern static int _XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
6287                 internal static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event) {
6288                         DebugHelper.TraceWriteLine ("XSendEvent");
6289                         return _XSendEvent(display, window, propagate, event_mask, ref send_event);
6290                 }
6291
6292                 [DllImport ("libX11", EntryPoint="XQueryTree")]
6293                 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);
6294                 internal static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return) {
6295                         DebugHelper.TraceWriteLine ("XQueryTree");
6296                         return _XQueryTree(display, window, out root_return, out parent_return, out children_return, out nchildren_return);
6297                 }
6298
6299                 [DllImport ("libX11", EntryPoint="XFree")]
6300                 internal extern static int _XFree(IntPtr data);
6301                 internal static int XFree(IntPtr data) {
6302                         DebugHelper.TraceWriteLine ("XFree");
6303                         return _XFree(data);
6304                 }
6305
6306                 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
6307                 internal extern static int _XRaiseWindow(IntPtr display, IntPtr window);
6308                 internal static int XRaiseWindow(IntPtr display, IntPtr window) {
6309                         DebugHelper.TraceWriteLine ("XRaiseWindow");
6310                         return _XRaiseWindow(display, window);
6311                 }
6312
6313                 [DllImport ("libX11", EntryPoint="XLowerWindow")]
6314                 internal extern static uint _XLowerWindow(IntPtr display, IntPtr window);
6315                 internal static uint XLowerWindow(IntPtr display, IntPtr window) {
6316                         DebugHelper.TraceWriteLine ("XLowerWindow");
6317                         return _XLowerWindow(display, window);
6318                 }
6319
6320                 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
6321                 internal extern static uint _XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
6322                 internal static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values) {
6323                         DebugHelper.TraceWriteLine ("XConfigureWindow");
6324                         return _XConfigureWindow(display, window, value_mask, ref values);
6325                 }
6326
6327                 [DllImport ("libX11", EntryPoint="XInternAtom")]
6328                 internal extern static IntPtr _XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
6329                 internal static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists) {
6330                         DebugHelper.TraceWriteLine ("XInternAtom");
6331                         return _XInternAtom(display, atom_name, only_if_exists);
6332                 }
6333
6334                 [DllImport ("libX11", EntryPoint="XInternAtoms")]
6335                 internal extern static int _XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
6336                 internal static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms) {
6337                         DebugHelper.TraceWriteLine ("XInternAtoms");
6338                         return _XInternAtoms(display, atom_names, atom_count, only_if_exists, atoms);
6339                 }
6340
6341                 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
6342                 internal extern static int _XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
6343                 internal static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count) {
6344                         DebugHelper.TraceWriteLine ("XSetWMProtocols");
6345                         return _XSetWMProtocols(display, window, protocols, count);
6346                 }
6347
6348                 [DllImport ("libX11", EntryPoint="XGrabPointer")]
6349                 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);
6350                 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) {
6351                         DebugHelper.TraceWriteLine ("XGrabPointer");
6352                         return _XGrabPointer(display, window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, timestamp);
6353                 }
6354
6355                 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
6356                 internal extern static int _XUngrabPointer(IntPtr display, IntPtr timestamp);
6357                 internal static int XUngrabPointer(IntPtr display, IntPtr timestamp) {
6358                         DebugHelper.TraceWriteLine ("XUngrabPointer");
6359                         return _XUngrabPointer(display, timestamp);
6360                 }
6361
6362                 [DllImport ("libX11", EntryPoint="XQueryPointer")]
6363                 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);
6364                 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) {
6365                         DebugHelper.TraceWriteLine ("XQueryPointer");
6366                         return _XQueryPointer(display, window, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
6367                 }
6368
6369                 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
6370                 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);
6371                 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) {
6372                         DebugHelper.TraceWriteLine ("XTranslateCoordinates");
6373                         return _XTranslateCoordinates (display, src_w, dest_w, src_x, src_y, out intdest_x_return, out dest_y_return, out child_return);
6374                 }
6375
6376                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6377                 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);
6378                 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) {
6379                         DebugHelper.TraceWriteLine ("XGetGeometry");
6380                         return _XGetGeometry(display, window, out root, out x, out y, out width, out height, out border_width, out depth);
6381                 }
6382
6383                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6384                 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);
6385                 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) {
6386                         DebugHelper.TraceWriteLine ("XGetGeometry");
6387                         return _XGetGeometry(display, window, root, out x, out y, out width, out height, border_width, depth);
6388                 }
6389
6390                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6391                 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);
6392                 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) {
6393                         DebugHelper.TraceWriteLine ("XGetGeometry");
6394                         return _XGetGeometry(display, window, root, out x, out y, width, height, border_width, depth);
6395                 }
6396
6397                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6398                 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);
6399                 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) {
6400                         DebugHelper.TraceWriteLine ("XGetGeometry");
6401                         return _XGetGeometry(display, window, root, x, y, out width, out height, border_width, depth);
6402                 }
6403
6404                 [DllImport ("libX11", EntryPoint="XWarpPointer")]
6405                 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);
6406                 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) {
6407                         DebugHelper.TraceWriteLine ("XWarpPointer");
6408                         return _XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y);
6409                 }
6410
6411                 [DllImport ("libX11", EntryPoint="XClearWindow")]
6412                 internal extern static int _XClearWindow(IntPtr display, IntPtr window);
6413                 internal static int XClearWindow(IntPtr display, IntPtr window) {
6414                         DebugHelper.TraceWriteLine ("XClearWindow");
6415                         return _XClearWindow(display, window);
6416                 }
6417
6418                 [DllImport ("libX11", EntryPoint="XClearArea")]
6419                 internal extern static int _XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
6420                 internal static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures) {
6421                         DebugHelper.TraceWriteLine ("XClearArea");
6422                         return _XClearArea(display, window, x, y, width, height, exposures);
6423                 }
6424
6425                 // Colormaps
6426                 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
6427                 internal extern static IntPtr _XDefaultScreenOfDisplay(IntPtr display);
6428                 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display) {
6429                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6430                         return _XDefaultScreenOfDisplay(display);
6431                 }
6432
6433                 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
6434                 internal extern static int _XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
6435                 internal static int XDefaultScreenOfDisplay(IntPtr display, IntPtr Screen) {
6436                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6437                         return _XScreenNumberOfScreen(display, Screen);
6438                 }
6439
6440                 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
6441                 internal extern static IntPtr _XDefaultVisual(IntPtr display, int screen_number);
6442                 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display, int screen_number) {
6443                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6444                         return _XDefaultVisual(display, screen_number);
6445                 }
6446
6447                 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
6448                 internal extern static uint _XDefaultDepth(IntPtr display, int screen_number);
6449                 internal static uint XDefaultDepth(IntPtr display, int screen_number) {
6450                         DebugHelper.TraceWriteLine ("XDefaultDepth");
6451                         return _XDefaultDepth(display, screen_number);
6452                 }
6453
6454                 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
6455                 internal extern static int _XDefaultScreen(IntPtr display);
6456                 internal static int XDefaultScreen(IntPtr display) {
6457                         DebugHelper.TraceWriteLine ("XDefaultScreen");
6458                         return _XDefaultScreen(display);
6459                 }
6460
6461                 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
6462                 internal extern static IntPtr _XDefaultColormap(IntPtr display, int screen_number);
6463                 internal static IntPtr XDefaultColormap(IntPtr display, int screen_number) {
6464                         DebugHelper.TraceWriteLine ("XDefaultColormap");
6465                         return _XDefaultColormap(display, screen_number);
6466                 }
6467
6468                 [DllImport ("libX11", EntryPoint="XLookupColor")]
6469                 internal extern static int _XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
6470                 internal static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color) {
6471                         DebugHelper.TraceWriteLine ("XLookupColor");
6472                         return _XLookupColor(display, Colormap, Coloranem, ref exact_def_color, ref screen_def_color);
6473                 }
6474
6475                 [DllImport ("libX11", EntryPoint="XAllocColor")]
6476                 internal extern static int _XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
6477                 internal static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def) {
6478                         DebugHelper.TraceWriteLine ("XAllocColor");
6479                         return _XAllocColor(display, Colormap, ref colorcell_def);
6480                 }
6481
6482                 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
6483                 internal extern static int _XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
6484                 internal static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window) {
6485                         DebugHelper.TraceWriteLine ("XSetTransientForHint");
6486                         return _XSetTransientForHint(display, window, prop_window);
6487                 }
6488
6489                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6490                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
6491                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements) {
6492                         DebugHelper.TraceWriteLine ("XChangeProperty");
6493                         return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
6494                 }
6495
6496                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6497                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
6498                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements) {
6499                         DebugHelper.TraceWriteLine ("XChangeProperty");
6500                         return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6501                 }
6502
6503                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6504                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
6505                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements) {
6506                         DebugHelper.TraceWriteLine ("XChangeProperty");
6507                         return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6508                 }
6509
6510                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6511                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
6512                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements) {
6513                         DebugHelper.TraceWriteLine ("XChangeProperty");
6514                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6515                 }
6516
6517                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6518                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
6519                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements) {
6520                         DebugHelper.TraceWriteLine ("XChangeProperty");
6521                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6522                 }
6523
6524                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6525                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
6526                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements) {
6527                         DebugHelper.TraceWriteLine ("XChangeProperty");
6528                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6529                 }
6530
6531                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6532                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
6533                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements) {
6534                         DebugHelper.TraceWriteLine ("XChangeProperty");
6535                         return _XChangeProperty(display, window, property, type, format, mode, atoms, nelements);
6536                 }
6537
6538                 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
6539                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
6540                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length) {
6541                         DebugHelper.TraceWriteLine ("XChangeProperty");
6542                         return _XChangeProperty(display, window, property, type, format, mode, text, text_length);
6543                 }
6544
6545                 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
6546                 internal extern static int _XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
6547                 internal static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property) {
6548                         DebugHelper.TraceWriteLine ("XDeleteProperty");
6549                         return _XDeleteProperty(display, window, property);
6550                 }
6551
6552                 // Drawing
6553                 [DllImport ("libX11", EntryPoint="XCreateGC")]
6554                 internal extern static IntPtr _XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
6555                 internal static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values) {
6556                         DebugHelper.TraceWriteLine ("XCreateGC");
6557                         return _XCreateGC(display, window, valuemask, ref values);
6558                 }
6559
6560                 [DllImport ("libX11", EntryPoint="XFreeGC")]
6561                 internal extern static int _XFreeGC(IntPtr display, IntPtr gc);
6562                 internal static int XFreeGC(IntPtr display, IntPtr gc) {
6563                         DebugHelper.TraceWriteLine ("XFreeGC");
6564                         return _XFreeGC(display, gc);
6565                 }
6566
6567                 [DllImport ("libX11", EntryPoint="XSetFunction")]
6568                 internal extern static int _XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
6569                 internal static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function) {
6570                         DebugHelper.TraceWriteLine ("XSetFunction");
6571                         return _XSetFunction(display, gc, function);
6572                 }
6573
6574                 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
6575                 internal extern static int _XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
6576                 internal static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style) {
6577                         DebugHelper.TraceWriteLine ("XSetLineAttributes");
6578                         return _XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
6579                 }
6580
6581                 [DllImport ("libX11", EntryPoint="XDrawLine")]
6582                 internal extern static int _XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
6583                 internal static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2) {
6584                         DebugHelper.TraceWriteLine ("XDrawLine");
6585                         return _XDrawLine(display, drawable, gc, x1, y1, x2, y2);
6586                 }
6587
6588                 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
6589                 internal extern static int _XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6590                 internal static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height) {
6591                         DebugHelper.TraceWriteLine ("XDrawRectangle");
6592                         return _XDrawRectangle(display, drawable, gc, x1, y1, width, height);
6593                 }
6594
6595                 [DllImport ("libX11", EntryPoint="XFillRectangle")]
6596                 internal extern static int _XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6597                 internal static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height) {
6598                         DebugHelper.TraceWriteLine ("XFillRectangle");
6599                         return _XFillRectangle(display, drawable, gc, x1, y1, width, height);
6600                 }
6601
6602                 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
6603                 internal extern static int _XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
6604                 internal static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background) {
6605                         DebugHelper.TraceWriteLine ("XSetWindowBackground");
6606                         return _XSetWindowBackground(display, window, background);
6607                 }
6608
6609                 [DllImport ("libX11", EntryPoint="XCopyArea")]
6610                 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);
6611                 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) {
6612                         DebugHelper.TraceWriteLine ("XCopyArea");
6613                         return _XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
6614                 }
6615
6616                 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
6617                 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);
6618                 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) {
6619                         DebugHelper.TraceWriteLine ("XGetWindowProperty");
6620                         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);
6621                 }
6622
6623                 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
6624                 internal extern static int _XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
6625                 internal static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time) {
6626                         DebugHelper.TraceWriteLine ("XSetInputFocus");
6627                         return _XSetInputFocus(display, window, revert_to, time);
6628                 }
6629
6630                 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
6631                 internal extern static int _XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
6632                 internal static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number) {
6633                         DebugHelper.TraceWriteLine ("XIconifyWindow");
6634                         return _XIconifyWindow(display, window, screen_number);
6635                 }
6636
6637                 [DllImport ("libX11", EntryPoint="XDefineCursor")]
6638                 internal extern static int _XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
6639                 internal static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor) {
6640                         DebugHelper.TraceWriteLine ("XDefineCursor");
6641                         return _XDefineCursor(display, window, cursor);
6642                 }
6643
6644                 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
6645                 internal extern static int _XUndefineCursor(IntPtr display, IntPtr window);
6646                 internal static int XUndefineCursor(IntPtr display, IntPtr window) {
6647                         DebugHelper.TraceWriteLine ("XUndefineCursor");
6648                         return _XUndefineCursor(display, window);
6649                 }
6650
6651                 [DllImport ("libX11", EntryPoint="XFreeCursor")]
6652                 internal extern static int _XFreeCursor(IntPtr display, IntPtr cursor);
6653                 internal static int XFreeCursor(IntPtr display, IntPtr cursor) {
6654                         DebugHelper.TraceWriteLine ("XFreeCursor");
6655                         return _XFreeCursor(display, cursor);
6656                 }
6657
6658                 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
6659                 internal extern static IntPtr _XCreateFontCursor(IntPtr display, CursorFontShape shape);
6660                 internal static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape) {
6661                         DebugHelper.TraceWriteLine ("XCreateFontCursor");
6662                         return _XCreateFontCursor(display, shape);
6663                 }
6664
6665                 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
6666                 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);
6667                 internal static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot) {
6668                         DebugHelper.TraceWriteLine ("XCreatePixmapCursor");
6669                         return _XCreatePixmapCursor(display, source, mask, ref foreground_color, ref background_color, x_hot, y_hot);
6670                 }
6671
6672                 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
6673                 internal extern static IntPtr _XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
6674                 internal static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth) {
6675                         DebugHelper.TraceWriteLine ("XCreatePixmapFromBitmapData");
6676                         return _XCreatePixmapFromBitmapData(display, drawable, data, width, height, fg, bg, depth);
6677                 }
6678
6679                 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
6680                 internal extern static IntPtr _XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
6681                 internal static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth) {
6682                         DebugHelper.TraceWriteLine ("XCreatePixmap");
6683                         return _XCreatePixmap(display, d, width, height, depth);
6684                 }
6685
6686                 [DllImport ("libX11", EntryPoint="XFreePixmap")]
6687                 internal extern static IntPtr _XFreePixmap(IntPtr display, IntPtr pixmap);
6688                 internal static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap) {
6689                         DebugHelper.TraceWriteLine ("XFreePixmap");
6690                         return _XFreePixmap(display, pixmap);
6691                 }
6692
6693                 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
6694                 internal extern static int _XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
6695                 internal static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height) {
6696                         DebugHelper.TraceWriteLine ("XQueryBestCursor");
6697                         return _XQueryBestCursor(display, drawable, width, height, out best_width, out best_height);
6698                 }
6699
6700                 [DllImport ("libX11", EntryPoint="XQueryExtension")]
6701                 internal extern static int _XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
6702                 internal static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error) {
6703                         DebugHelper.TraceWriteLine ("XQueryExtension");
6704                         return _XQueryExtension(display, extension_name, ref major, ref first_event, ref first_error);
6705                 }
6706
6707                 [DllImport ("libX11", EntryPoint="XWhitePixel")]
6708                 internal extern static IntPtr _XWhitePixel(IntPtr display, int screen_no);
6709                 internal static IntPtr XWhitePixel(IntPtr display, int screen_no) {
6710                         DebugHelper.TraceWriteLine ("XWhitePixel");
6711                         return _XWhitePixel(display, screen_no);
6712                 }
6713
6714                 [DllImport ("libX11", EntryPoint="XBlackPixel")]
6715                 internal extern static IntPtr _XBlackPixel(IntPtr display, int screen_no);
6716                 internal static IntPtr XBlackPixel(IntPtr display, int screen_no) {
6717                         DebugHelper.TraceWriteLine ("XBlackPixel");
6718                         return _XBlackPixel(display, screen_no);
6719                 }
6720
6721                 [DllImport ("libX11", EntryPoint="XGrabServer")]
6722                 internal extern static void _XGrabServer(IntPtr display);
6723                 internal static void XGrabServer(IntPtr display) {
6724                         DebugHelper.TraceWriteLine ("XGrabServer");
6725                         _XGrabServer(display);
6726                 }
6727
6728                 [DllImport ("libX11", EntryPoint="XUngrabServer")]
6729                 internal extern static void _XUngrabServer(IntPtr display);
6730                 internal static void XUngrabServer(IntPtr display) {
6731                         DebugHelper.TraceWriteLine ("XUngrabServer");
6732                         _XUngrabServer(display);
6733                 }
6734
6735                 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
6736                 internal extern static void _XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
6737                 internal static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return) {
6738                         DebugHelper.TraceWriteLine ("XGetWMNormalHints");
6739                         _XGetWMNormalHints(display, window, ref hints, out supplied_return);
6740                 }
6741
6742                 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
6743                 internal extern static void _XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
6744                 internal static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints) {
6745                         DebugHelper.TraceWriteLine ("XSetWMNormalHints");
6746                         _XSetWMNormalHints(display, window, ref hints);
6747                 }
6748
6749                 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
6750                 internal extern static void _XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
6751                 internal static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints) {
6752                         DebugHelper.TraceWriteLine ("XSetZoomHints");
6753                         _XSetZoomHints(display, window, ref hints);
6754                 }
6755
6756                 [DllImport ("libX11", EntryPoint="XSetWMHints")]
6757                 internal extern static void _XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
6758                 internal static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints) {
6759                         DebugHelper.TraceWriteLine ("XSetWMHints");
6760                         _XSetWMHints(display, window, ref wmhints);
6761                 }
6762
6763                 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
6764                 internal extern static int _XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
6765                 internal static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count) {
6766                         DebugHelper.TraceWriteLine ("XGetIconSizes");
6767                         return _XGetIconSizes(display, window, out size_list, out count);
6768                 }
6769
6770                 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
6771                 internal extern static IntPtr _XSetErrorHandler(XErrorHandler error_handler);
6772                 internal static IntPtr XSetErrorHandler(XErrorHandler error_handler) {
6773                         DebugHelper.TraceWriteLine ("XSetErrorHandler");
6774                         return _XSetErrorHandler(error_handler);
6775                 }
6776
6777                 [DllImport ("libX11", EntryPoint="XGetErrorText")]
6778                 internal extern static IntPtr _XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
6779                 internal static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length) {
6780                         DebugHelper.TraceWriteLine ("XGetErrorText");
6781                         return _XGetErrorText(display, code, buffer, length);
6782                 }
6783
6784                 [DllImport ("libX11", EntryPoint="XInitThreads")]
6785                 internal extern static int _XInitThreads();
6786                 internal static int XInitThreads() {
6787                         DebugHelper.TraceWriteLine ("XInitThreads");
6788                         return _XInitThreads();
6789                 }
6790
6791                 [DllImport ("libX11", EntryPoint="XConvertSelection")]
6792                 internal extern static int _XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
6793                 internal static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time) {
6794                         DebugHelper.TraceWriteLine ("XConvertSelection");
6795                         return _XConvertSelection(display, selection, target, property, requestor, time);
6796                 }
6797
6798                 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
6799                 internal extern static IntPtr _XGetSelectionOwner(IntPtr display, IntPtr selection);
6800                 internal static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection) {
6801                         DebugHelper.TraceWriteLine ("XGetSelectionOwner");
6802                         return _XGetSelectionOwner(display, selection);
6803                 }
6804
6805                 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
6806                 internal extern static int _XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
6807                 internal static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time) {
6808                         DebugHelper.TraceWriteLine ("XSetSelectionOwner");
6809                         return _XSetSelectionOwner(display, selection, owner, time);
6810                 }
6811
6812                 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
6813                 internal extern static int _XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
6814                 internal static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask) {
6815                         DebugHelper.TraceWriteLine ("XSetPlaneMask");
6816                         return _XSetPlaneMask(display, gc, mask);
6817                 }
6818
6819                 [DllImport ("libX11", EntryPoint="XSetForeground")]
6820                 internal extern static int _XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
6821                 internal static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground) {
6822                         DebugHelper.TraceWriteLine ("XSetForeground");
6823                         return _XSetForeground(display, gc, foreground);
6824                 }
6825
6826                 [DllImport ("libX11", EntryPoint="XSetBackground")]
6827                 internal extern static int _XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
6828                 internal static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background) {
6829                         DebugHelper.TraceWriteLine ("XSetBackground");
6830                         return _XSetBackground(display, gc, background);
6831                 }
6832
6833                 [DllImport ("libX11", EntryPoint="XBell")]
6834                 internal extern static int _XBell(IntPtr display, int percent);
6835                 internal static int XBell(IntPtr display, int percent) {
6836                         DebugHelper.TraceWriteLine ("XBell");
6837                         return _XBell(display, percent);
6838                 }
6839
6840                 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
6841                 internal extern static int _XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
6842                 internal static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time) {
6843                         DebugHelper.TraceWriteLine ("XChangeActivePointerGrab");
6844                         return _XChangeActivePointerGrab (display, event_mask, cursor, time);
6845                 }
6846
6847                 [DllImport ("libX11", EntryPoint="XFilterEvent")]
6848                 internal extern static bool _XFilterEvent(ref XEvent xevent, IntPtr window);
6849                 internal static bool XFilterEvent(ref XEvent xevent, IntPtr window) {
6850                         DebugHelper.TraceWriteLine ("XFilterEvent");
6851                         return _XFilterEvent(ref xevent, window);
6852                 }
6853
6854                 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
6855                 internal extern static void _XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
6856                 internal static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported) {
6857                         DebugHelper.TraceWriteLine ("XkbSetDetectableAutoRepeat");
6858                         _XkbSetDetectableAutoRepeat (display, detectable, supported);
6859                 }
6860
6861                 [DllImport ("libX11", EntryPoint="XPeekEvent")]
6862                 internal extern static void _XPeekEvent (IntPtr display, ref XEvent xevent);
6863                 internal static void XPeekEvent (IntPtr display, ref XEvent xevent) {
6864                         DebugHelper.TraceWriteLine ("XPeekEvent");
6865                         _XPeekEvent (display, ref xevent);
6866                 }
6867
6868                 [DllImport ("libX11", EntryPoint="XIfEvent")]
6869                 internal extern static void _XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
6870                 internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg) {
6871                         DebugHelper.TraceWriteLine ("XIfEvent");
6872                         _XIfEvent (display, ref xevent, event_predicate, arg);
6873                 }
6874 #endregion
6875
6876
6877 #else //no TRACE defined
6878
6879 #region Xcursor imports
6880                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
6881                 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
6882
6883                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
6884                 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
6885                 
6886                 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
6887                 internal extern static void XcursorImagesDestroy (IntPtr images);
6888                 
6889                 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
6890                 internal extern static int XcursorGetDefaultSize (IntPtr display);
6891
6892                 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
6893                 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
6894
6895                 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
6896                 internal extern static IntPtr XcursorGetTheme (IntPtr display);
6897 #endregion
6898                 #region X11 Imports
6899                 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
6900                 internal extern static IntPtr XOpenDisplay(IntPtr display);
6901                 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
6902                 internal extern static int XCloseDisplay(IntPtr display);                                                   
6903                 [DllImport ("libX11", EntryPoint="XSynchronize")]
6904                 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
6905
6906                 [DllImport ("libX11", EntryPoint="XCreateWindow")]
6907                 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);
6908                 
6909                 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
6910                 internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
6911                 
6912                 [DllImport ("libX11", EntryPoint="XMapWindow")]
6913                 internal extern static int XMapWindow(IntPtr display, IntPtr window);
6914                 
6915                 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
6916                 internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
6917                 
6918                 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
6919                 internal extern static int XMapSubindows(IntPtr display, IntPtr window);
6920                 
6921                 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
6922                 internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
6923                 
6924                 [DllImport ("libX11", EntryPoint="XRootWindow")]
6925                 internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
6926                 
6927                 [DllImport ("libX11", EntryPoint="XNextEvent")]
6928                 internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
6929
6930                 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
6931                 internal extern static int XConnectionNumber (IntPtr display);
6932                 
6933                 [DllImport ("libX11", EntryPoint="XPending")]
6934                 internal extern static int XPending (IntPtr display);
6935                 
6936                 [DllImport ("libX11", EntryPoint="XSelectInput")]
6937                 internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
6938                 
6939                 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
6940                 internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
6941                 
6942                 [DllImport ("libX11", EntryPoint="XReparentWindow")]
6943                 internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
6944                 
6945                 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
6946                 private extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
6947                 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
6948                 {
6949                         int ret = XMoveResizeWindow (display, window, x, y, width, height);
6950                         Keyboard.MoveCurrentCaretPos ();
6951                         return ret;
6952                 }
6953
6954                 [DllImport ("libX11", EntryPoint="XResizeWindow")]
6955                 internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
6956
6957                 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
6958                 internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
6959
6960                 [DllImport ("libX11", EntryPoint="XFlush")]
6961                 internal extern static int XFlush(IntPtr display);
6962
6963                 [DllImport ("libX11", EntryPoint="XSetWMName")]
6964                 internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
6965
6966                 [DllImport ("libX11", EntryPoint="XStoreName")]
6967                 internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
6968
6969                 [DllImport ("libX11", EntryPoint="XFetchName")]
6970                 internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
6971
6972                 [DllImport ("libX11", EntryPoint="XSendEvent")]
6973                 internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
6974
6975                 [DllImport ("libX11", EntryPoint="XQueryTree")]
6976                 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);
6977
6978                 [DllImport ("libX11", EntryPoint="XFree")]
6979                 internal extern static int XFree(IntPtr data);
6980
6981                 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
6982                 internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
6983
6984                 [DllImport ("libX11", EntryPoint="XLowerWindow")]
6985                 internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
6986
6987                 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
6988                 internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
6989
6990                 [DllImport ("libX11", EntryPoint="XInternAtom")]
6991                 internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
6992
6993                 [DllImport ("libX11", EntryPoint="XInternAtoms")]
6994                 internal extern static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
6995
6996                 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
6997                 internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
6998
6999                 [DllImport ("libX11", EntryPoint="XGrabPointer")]
7000                 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);
7001
7002                 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
7003                 internal extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
7004
7005                 [DllImport ("libX11", EntryPoint="XQueryPointer")]
7006                 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);
7007
7008                 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
7009                 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);
7010
7011                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7012                 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);
7013
7014                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7015                 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);
7016
7017                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7018                 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);
7019
7020                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7021                 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);
7022
7023                 [DllImport ("libX11", EntryPoint="XWarpPointer")]
7024                 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);
7025
7026                 [DllImport ("libX11", EntryPoint="XClearWindow")]
7027                 internal extern static int XClearWindow(IntPtr display, IntPtr window);
7028
7029                 [DllImport ("libX11", EntryPoint="XClearArea")]
7030                 internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
7031
7032                 // Colormaps
7033                 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
7034                 internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
7035
7036                 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
7037                 internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
7038
7039                 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
7040                 internal extern static IntPtr XDefaultVisual(IntPtr display, int screen_number);
7041
7042                 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
7043                 internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
7044
7045                 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
7046                 internal extern static int XDefaultScreen(IntPtr display);
7047
7048                 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
7049                 internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
7050
7051                 [DllImport ("libX11", EntryPoint="XLookupColor")]
7052                 internal extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
7053
7054                 [DllImport ("libX11", EntryPoint="XAllocColor")]
7055                 internal extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
7056
7057                 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
7058                 internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
7059
7060                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7061                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
7062
7063                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7064                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
7065
7066                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7067                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
7068
7069                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7070                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
7071
7072                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7073                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
7074
7075                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7076                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
7077
7078                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7079                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
7080
7081                 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
7082                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
7083
7084                 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
7085                 internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
7086
7087                 // Drawing
7088                 [DllImport ("libX11", EntryPoint="XCreateGC")]
7089                 internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
7090
7091                 [DllImport ("libX11", EntryPoint="XFreeGC")]
7092                 internal extern static int XFreeGC(IntPtr display, IntPtr gc);
7093
7094                 [DllImport ("libX11", EntryPoint="XSetFunction")]
7095                 internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
7096
7097                 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
7098                 internal extern static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
7099
7100                 [DllImport ("libX11", EntryPoint="XDrawLine")]
7101                 internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
7102
7103                 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
7104                 internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7105
7106                 [DllImport ("libX11", EntryPoint="XFillRectangle")]
7107                 internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7108
7109                 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
7110                 internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
7111
7112                 [DllImport ("libX11", EntryPoint="XCopyArea")]
7113                 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);
7114
7115                 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
7116                 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);
7117
7118                 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
7119                 internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
7120
7121                 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
7122                 internal extern static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
7123
7124                 [DllImport ("libX11", EntryPoint="XDefineCursor")]
7125                 internal extern static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
7126
7127                 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
7128                 internal extern static int XUndefineCursor(IntPtr display, IntPtr window);
7129
7130                 [DllImport ("libX11", EntryPoint="XFreeCursor")]
7131                 internal extern static int XFreeCursor(IntPtr display, IntPtr cursor);
7132
7133                 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
7134                 internal extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
7135
7136                 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
7137                 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);
7138
7139                 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
7140                 internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
7141
7142                 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7143                 internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7144
7145                 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7146                 internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
7147
7148                 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7149                 internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7150
7151                 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7152                 internal extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7153
7154                 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7155                 internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
7156
7157                 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7158                 internal extern static IntPtr XBlackPixel(IntPtr display, int screen_no);
7159
7160                 [DllImport ("libX11", EntryPoint="XGrabServer")]
7161                 internal extern static void XGrabServer(IntPtr display);
7162
7163                 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7164                 internal extern static void XUngrabServer(IntPtr display);
7165
7166                 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7167                 internal extern static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7168
7169                 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7170                 internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7171
7172                 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7173                 internal extern static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7174
7175                 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7176                 internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7177
7178                 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7179                 internal extern static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7180
7181                 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7182                 internal extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
7183
7184                 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7185                 internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7186
7187                 [DllImport ("libX11", EntryPoint="XInitThreads")]
7188                 internal extern static int XInitThreads();
7189
7190                 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7191                 internal extern static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7192
7193                 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7194                 internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
7195
7196                 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7197                 internal extern static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7198
7199                 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7200                 internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7201
7202                 [DllImport ("libX11", EntryPoint="XSetForeground")]
7203                 internal extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7204
7205                 [DllImport ("libX11", EntryPoint="XSetBackground")]
7206                 internal extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7207
7208                 [DllImport ("libX11", EntryPoint="XBell")]
7209                 internal extern static int XBell(IntPtr display, int percent);
7210
7211                 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7212                 internal extern static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7213
7214                 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7215                 internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
7216
7217                 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7218                 internal extern static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7219
7220                 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7221                 internal extern static void XPeekEvent (IntPtr display, ref XEvent xevent);
7222
7223                 [DllImport ("libX11", EntryPoint="XIfEvent")]
7224                 internal extern static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7225                 #endregion
7226 #endif
7227         }
7228 }