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