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