Fix:Idle event handler was called on every thread rather than thread assigned on
[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 ((windows & WindowType.Whole) != 0) {
1623                                         XMapWindow(DisplayHandle, hwnd.whole_window);
1624                                 }
1625                                 if ((windows & WindowType.Client) != 0) {
1626                                         XMapWindow(DisplayHandle, hwnd.client_window);
1627                                 }
1628
1629                                 hwnd.mapped = true;
1630
1631                                 if (f != null) {
1632                                         if (f.waiting_showwindow) {
1633                                                 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1634                                                 CreateParams cp = f.GetCreateParams();
1635                                                 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1636                                                     !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1637                                                         WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1638                                                 }
1639                                         }
1640                                 }
1641                         }
1642                 }
1643
1644                 void UnmapWindow(Hwnd hwnd, WindowType windows) {
1645                         if (hwnd.mapped) {
1646                                 Form f = null;
1647                                 if (Control.FromHandle(hwnd.Handle) is Form) {
1648                                         f = Control.FromHandle(hwnd.Handle) as Form;
1649                                         if (f.WindowState == FormWindowState.Normal) {
1650                                                 f.waiting_showwindow = true;
1651                                                 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, IntPtr.Zero, IntPtr.Zero);
1652                                         }
1653                                 }
1654
1655                                 // it's possible that our Hwnd is no
1656                                 // longer valid after making that
1657                                 // SendMessage call, so check here.
1658                                 // FIXME: it is likely wrong, as it has already sent WM_SHOWWINDOW
1659                                 if (hwnd.zombie)
1660                                         return;
1661
1662                                 if ((windows & WindowType.Client) != 0) {
1663                                         XUnmapWindow(DisplayHandle, hwnd.client_window);
1664                                 }
1665                                 if ((windows & WindowType.Whole) != 0) {
1666                                         XUnmapWindow(DisplayHandle, hwnd.whole_window);
1667                                 }
1668
1669                                 hwnd.mapped = false;
1670
1671                                 if (f != null) {
1672                                         if (f.waiting_showwindow) {
1673                                                 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1674                                                 CreateParams cp = f.GetCreateParams();
1675                                                 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1676                                                     !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1677                                                         WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1678                                                 }
1679                                         }
1680                                 }
1681                         }
1682                 }
1683
1684                 void UpdateMessageQueue (XEventQueue queue) {
1685                         UpdateMessageQueue(queue, true);
1686                 }
1687
1688                 void UpdateMessageQueue (XEventQueue queue, bool allowIdle) {
1689                         DateTime        now;
1690                         int             pending;
1691                         Hwnd            hwnd;
1692
1693                         now = DateTime.UtcNow;
1694
1695                         lock (XlibLock) {
1696                                 pending = XPending (DisplayHandle);
1697                         }
1698
1699                         if (pending == 0 && allowIdle) {
1700                                 int id = Thread.CurrentThread.ManagedThreadId;
1701                                 if ((queue == null || queue.DispatchIdle) && 
1702                                         Idle_Threads != null &&         
1703                                         Idle_Threads.ContainsKey (id) && 
1704                                         Idle_Threads [id] != null) 
1705                                 {
1706                                         Idle_Threads [id] (this, EventArgs.Empty);
1707                                 }
1708
1709                                 lock (XlibLock) {
1710                                         pending = XPending (DisplayHandle);
1711                                 }
1712                         }
1713
1714                         if (pending == 0) {
1715                                 int     timeout = 0;
1716
1717                                 if (queue != null) {
1718                                         if (queue.Paint.Count > 0)
1719                                                 return;
1720
1721                                         timeout = NextTimeout (queue.timer_list, now);
1722                                 }
1723
1724                                 if (timeout > 0) {
1725                                         #if __MonoCS__
1726                                         int length = pollfds.Length - 1;
1727                                         lock (wake_waiting_lock) {
1728                                                 if (wake_waiting == false) {
1729                                                         length ++;
1730                                                         wake_waiting = true;
1731                                                 }
1732                                         }
1733
1734                                         Syscall.poll (pollfds, (uint)length, timeout);
1735                                         // Clean out buffer, so we're not busy-looping on the same data
1736                                         if (length == pollfds.Length) {
1737                                                 if (pollfds[1].revents != 0)
1738                                                         wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
1739                                                 lock (wake_waiting_lock) {
1740                                                         wake_waiting = false;
1741                                                 }
1742                                         }
1743                                         #endif
1744                                         lock (XlibLock) {
1745                                                 pending = XPending (DisplayHandle);
1746                                         }
1747                                 }
1748                         }
1749
1750                         if (queue != null)
1751                                 CheckTimers (queue.timer_list, now);
1752
1753                         while (true) {
1754                                 XEvent xevent = new XEvent ();
1755
1756                                 lock (XlibLock) {
1757                                         if (XPending (DisplayHandle) == 0)
1758                                                 break;
1759
1760                                         XNextEvent (DisplayHandle, ref xevent);
1761
1762                                         if (xevent.AnyEvent.type == XEventName.KeyPress ||
1763                                             xevent.AnyEvent.type == XEventName.KeyRelease) {
1764                                                 // PreFilter() handles "shift key state updates.
1765                                                 Keyboard.PreFilter (xevent);
1766                                                 if (XFilterEvent (ref xevent, Keyboard.ClientWindow)) {
1767                                                         // probably here we could raise WM_IME_KEYDOWN and
1768                                                         // WM_IME_KEYUP, but I'm not sure it is worthy.
1769                                                         continue;
1770                                                 }
1771                                         }
1772                                         else if (XFilterEvent (ref xevent, IntPtr.Zero))
1773                                                 continue;
1774                                 }
1775
1776                                 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
1777                                 if (hwnd == null)
1778                                         continue;
1779
1780                                 DebugHelper.WriteLine  ("UpdateMessageQueue got Event: " + xevent.ToString ());
1781
1782                                 switch (xevent.type) {
1783                                 case XEventName.Expose:
1784                                         AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
1785                                         break;
1786
1787                                 case XEventName.SelectionClear: {
1788                                         // Should we do something?
1789                                         break;
1790                                 }
1791
1792                                 case XEventName.SelectionRequest: {
1793                                         if (Dnd.HandleSelectionRequestEvent (ref xevent))
1794                                                 break;
1795                                         XEvent sel_event;
1796
1797                                         sel_event = new XEvent();
1798                                         sel_event.SelectionEvent.type = XEventName.SelectionNotify;
1799                                         sel_event.SelectionEvent.send_event = true;
1800                                         sel_event.SelectionEvent.display = DisplayHandle;
1801                                         sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
1802                                         sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
1803                                         sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
1804                                         sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
1805                                         sel_event.SelectionEvent.property = IntPtr.Zero;
1806
1807                                         IntPtr format_atom = xevent.SelectionRequestEvent.target;
1808
1809                                         // Seems that some apps support asking for supported types
1810                                         if (format_atom == TARGETS) {
1811                                                 int[]   atoms;
1812                                                 int     atom_count;
1813
1814                                                 atoms = new int[5];
1815                                                 atom_count = 0;
1816
1817                                                 if (Clipboard.IsSourceText) {
1818                                                         atoms[atom_count++] = (int)Atom.XA_STRING;
1819                                                         atoms[atom_count++] = (int)OEMTEXT;
1820                                                         atoms[atom_count++] = (int)UTF8_STRING;
1821                                                         atoms[atom_count++] = (int)UTF16_STRING;
1822                                                         atoms[atom_count++] = (int)RICHTEXTFORMAT;
1823                                                 } else if (Clipboard.IsSourceImage) {
1824                                                         atoms[atom_count++] = (int)Atom.XA_PIXMAP;
1825                                                         atoms[atom_count++] = (int)Atom.XA_BITMAP;
1826                                                 } else {
1827                                                         // FIXME - handle other types
1828                                                 }
1829
1830                                                 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, 
1831                                                                 (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
1832                                                 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1833                                         } else if (format_atom == (IntPtr)RICHTEXTFORMAT) {
1834                                                 string rtf_text = Clipboard.GetRtfText ();
1835                                                 if (rtf_text != null) {
1836                                                         // The RTF spec mentions that ascii is enough to contain it
1837                                                         Byte [] bytes = Encoding.ASCII.GetBytes (rtf_text);
1838                                                         int buflen = bytes.Length;
1839                                                         IntPtr buffer = Marshal.AllocHGlobal (buflen);
1840
1841                                                         for (int i = 0; i < buflen; i++)
1842                                                                 Marshal.WriteByte (buffer, i, bytes[i]);
1843
1844                                                         XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
1845                                                                         (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1846                                                         sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1847                                                         Marshal.FreeHGlobal(buffer);
1848                                                 }
1849                                         } else if (Clipboard.IsSourceText && 
1850                                                    (format_atom == (IntPtr)Atom.XA_STRING 
1851                                                     || format_atom == OEMTEXT
1852                                                     || format_atom == UTF16_STRING
1853                                                     || format_atom == UTF8_STRING)) {
1854                                                 IntPtr  buffer = IntPtr.Zero;
1855                                                 int     buflen;
1856                                                 Encoding encoding = null;
1857
1858                                                 buflen = 0;
1859
1860                                                 // Select an encoding depending on the target
1861                                                 IntPtr target_atom = xevent.SelectionRequestEvent.target;
1862                                                 if (target_atom == (IntPtr)Atom.XA_STRING || target_atom == OEMTEXT)
1863                                                         // FIXME - EOMTEXT should encode into ISO2022
1864                                                         encoding = Encoding.ASCII;
1865                                                 else if (target_atom == UTF16_STRING)
1866                                                         encoding = Encoding.Unicode;
1867                                                 else if (target_atom == UTF8_STRING)
1868                                                         encoding = Encoding.UTF8;
1869
1870                                                 Byte [] bytes;
1871
1872                                                 bytes = encoding.GetBytes (Clipboard.GetPlainText ());
1873                                                 buffer = Marshal.AllocHGlobal (bytes.Length);
1874                                                 buflen = bytes.Length;
1875
1876                                                 for (int i = 0; i < buflen; i++)
1877                                                         Marshal.WriteByte (buffer, i, bytes [i]);
1878
1879                                                 if (buffer != IntPtr.Zero) {
1880                                                         XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1881                                                         sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1882                                                         Marshal.FreeHGlobal(buffer);
1883                                                 }
1884                                         } else if (Clipboard.GetSource (format_atom.ToInt32 ()) != null) { // check if we have an available value of this format
1885                                                 if (DataFormats.GetFormat (format_atom.ToInt32 ()).is_serializable) {
1886                                                         object serializable = Clipboard.GetSource (format_atom.ToInt32 ());
1887
1888                                                         BinaryFormatter formatter = new BinaryFormatter ();
1889                                                         MemoryStream memory_stream = new MemoryStream ();
1890                                                         formatter.Serialize (memory_stream, serializable);
1891
1892                                                         int buflen = (int)memory_stream.Length;
1893                                                         IntPtr buffer = Marshal.AllocHGlobal (buflen);
1894                                                         memory_stream.Position = 0;
1895                                                         for (int i = 0; i < buflen; i++)
1896                                                                 Marshal.WriteByte (buffer, i, (byte)memory_stream.ReadByte ());
1897                                                         memory_stream.Close ();
1898
1899                                                         XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target,
1900                                                                         8, PropertyMode.Replace, buffer, buflen);
1901                                                         sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1902                                                         Marshal.FreeHGlobal (buffer);
1903                                                 }
1904
1905                                         } else if (Clipboard.IsSourceImage) {
1906                                                 if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1907                                                         // FIXME - convert image and store as property
1908                                                 } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1909                                                         // FIXME - convert image and store as property
1910                                                 }
1911                                         }
1912
1913                                         XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
1914                                         break;
1915                                 }
1916
1917                                 case XEventName.SelectionNotify: {
1918                                         if (Clipboard.Enumerating) {
1919                                                 Clipboard.Enumerating = false;
1920                                                 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1921                                                         XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
1922                                                         if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
1923                                                                 Clipboard.Formats.Add(xevent.SelectionEvent.property);
1924                                                                 DriverDebug("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
1925                                                         }
1926                                                 }
1927                                         } else if (Clipboard.Retrieving) {
1928                                                 Clipboard.Retrieving = false;
1929                                                 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1930                                                         TranslatePropertyToClipboard(xevent.SelectionEvent.property);
1931                                                 } else {
1932                                                         Clipboard.ClearSources ();
1933                                                         Clipboard.Item = null;
1934                                                 }
1935                                         } else {
1936                                                 Dnd.HandleSelectionNotifyEvent (ref xevent);
1937                                         }
1938                                         break;
1939                                 }
1940
1941                                 case XEventName.KeyRelease:
1942                                         if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
1943                                                 XEvent nextevent = new XEvent ();
1944
1945                                                 XPeekEvent (DisplayHandle, ref nextevent);
1946
1947                                                 if (nextevent.type == XEventName.KeyPress &&
1948                                                     nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
1949                                                     nextevent.KeyEvent.time == xevent.KeyEvent.time) {
1950                                                         continue;
1951                                                 }
1952                                         }
1953                                         goto case XEventName.KeyPress;
1954                                         
1955                                 case XEventName.MotionNotify: {
1956                                         XEvent peek;
1957
1958                                         /* we can't do motion compression across threads, so just punt if we don't match up */
1959                                         if (Thread.CurrentThread == hwnd.Queue.Thread && hwnd.Queue.Count > 0) {
1960                                                 peek = hwnd.Queue.Peek();
1961                                                 if (peek.AnyEvent.type == XEventName.MotionNotify) {
1962                                                         continue;
1963                                                 }
1964                                         }
1965                                         goto case XEventName.KeyPress;
1966                                 }
1967
1968                                 case XEventName.KeyPress:
1969                                         hwnd.Queue.EnqueueLocked (xevent);
1970                                         /* Process KeyPresses immediately. Otherwise multiple Compose messages as a result of a
1971                                          * single physical keypress are not processed correctly */
1972                                         return;
1973                                 case XEventName.ButtonPress:
1974                                 case XEventName.ButtonRelease:
1975                                 case XEventName.EnterNotify:
1976                                 case XEventName.LeaveNotify:
1977                                 case XEventName.CreateNotify:
1978                                 case XEventName.DestroyNotify:
1979                                 case XEventName.FocusIn:
1980                                 case XEventName.FocusOut:
1981                                 case XEventName.ClientMessage:
1982                                 case XEventName.ReparentNotify:
1983                                 case XEventName.MapNotify:
1984                                 case XEventName.UnmapNotify:
1985                                         hwnd.Queue.EnqueueLocked (xevent);
1986                                         break;
1987
1988                                 case XEventName.ConfigureNotify:
1989                                         AddConfigureNotify(xevent);
1990                                         break;
1991
1992                                 case XEventName.PropertyNotify:
1993                                         DriverDebug ("UpdateMessageQueue (), got Event: {0}", xevent.ToString ());
1994                                         if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
1995                                                 IntPtr  actual_atom;
1996                                                 int     actual_format;
1997                                                 IntPtr  nitems;
1998                                                 IntPtr  bytes_after;
1999                                                 IntPtr  prop = IntPtr.Zero;
2000                                                 IntPtr  prev_active;
2001
2002                                                 prev_active = ActiveWindow;
2003                                                 XGetWindowProperty(DisplayHandle, RootWindow, _NET_ACTIVE_WINDOW, IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2004                                                 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
2005                                                         ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));                                                       
2006                                                         XFree(prop);
2007
2008                                                         DebugHelper.WriteLine ("PropertyNotify: _NET_ACTIVE_WINDOW: previous = 0x{0:x}, new = 0x{1:x}", prev_active.ToInt32 (), ActiveWindow.ToInt32 ());
2009                                                         
2010                                                         if (prev_active != ActiveWindow) {
2011                                                                 if (prev_active != IntPtr.Zero) {
2012                                                                         PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
2013                                                                 }
2014                                                                 if (ActiveWindow != IntPtr.Zero) {
2015                                                                         PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
2016                                                                 }
2017                                                         }
2018                                                         if (ModalWindows.Count == 0) {
2019                                                                 break;
2020                                                         } else {
2021                                                                 // Modality Handling
2022                                                                 // 
2023                                                                 // If there is a modal window on the stack and the new active 
2024                                                                 // window is MWF window, but not the modal one and not a non-modal 
2025                                                                 // child of the modal one, switch back to the modal window.
2026                                                                 //
2027                                                                 // To identify if a non-modal form is child of a modal form 
2028                                                                 // we match their ApplicationContexts, which will be the same.
2029                                                                 // This is because each modal form runs the loop with a 
2030                                                                 // new ApplicationContext, which is inherited by the non-modal 
2031                                                                 // forms.
2032
2033                                                                 Form activeForm = Control.FromHandle (ActiveWindow) as Form;
2034                                                                 if (activeForm != null) {
2035                                                                         Form modalForm = Control.FromHandle ((IntPtr)ModalWindows.Peek()) as Form;
2036                                                                         if (ActiveWindow != (IntPtr)ModalWindows.Peek() && 
2037                                                                             (modalForm == null || activeForm.context == modalForm.context)) {
2038                                                                                 Activate((IntPtr)ModalWindows.Peek());
2039                                                                         }
2040                                                                 }
2041                                                                 break;
2042                                                         }
2043                                                 }
2044                                         }
2045                                         else if (xevent.PropertyEvent.atom == _NET_WM_STATE) {
2046                                                 // invalidate our cache - we'll query again the next time someone does GetWindowState.
2047                                                 hwnd.cached_window_state = (FormWindowState)(-1);
2048                                                 PostMessage (hwnd.Handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
2049                                         }
2050                                         break;
2051
2052                                 }
2053                         }
2054                 }
2055
2056                 IntPtr GetMousewParam(int Delta) {
2057                         int     result = 0;
2058
2059                         if ((MouseState & MouseButtons.Left) != 0) {
2060                                 result |= (int)MsgButtons.MK_LBUTTON;
2061                         }
2062
2063                         if ((MouseState & MouseButtons.Middle) != 0) {
2064                                 result |= (int)MsgButtons.MK_MBUTTON;
2065                         }
2066
2067                         if ((MouseState & MouseButtons.Right) != 0) {
2068                                 result |= (int)MsgButtons.MK_RBUTTON;
2069                         }
2070
2071                         Keys mods = ModifierKeys;
2072                         if ((mods & Keys.Control) != 0) {
2073                                 result |= (int)MsgButtons.MK_CONTROL;
2074                         }
2075
2076                         if ((mods & Keys.Shift) != 0) {
2077                                 result |= (int)MsgButtons.MK_SHIFT;
2078                         }
2079
2080                         result |= Delta << 16;
2081
2082                         return (IntPtr)result;
2083                 }
2084                 IntPtr XGetParent(IntPtr handle) {
2085                         IntPtr  Root;
2086                         IntPtr  Parent;
2087                         IntPtr  Children;
2088                         int     ChildCount;
2089
2090                         lock (XlibLock) {
2091                                 XQueryTree(DisplayHandle, handle, out Root, out Parent, out Children, out ChildCount);
2092                         }
2093
2094                         if (Children!=IntPtr.Zero) {
2095                                 lock (XlibLock) {
2096                                         XFree(Children);
2097                                 }
2098                         }
2099                         return Parent;
2100                 }
2101
2102                 int HandleError (IntPtr display, ref XErrorEvent error_event)
2103                 {
2104                         // we need to workaround a problem with the
2105                         // ordering of destruction of Drawables and
2106                         // Pictures that exists between cairo and
2107                         // RENDER on the server.
2108                         if (error_event.request_code == (XRequest)render_major_opcode
2109                             && error_event.minor_code == 7 /* X_RenderFreePicture from render.h */
2110                             && error_event.error_code == render_first_error + 1 /* BadPicture from render.h */) {
2111                                 return 0;
2112                         }
2113
2114                         if (ErrorExceptions) {
2115                                 XUngrabPointer (display, IntPtr.Zero);
2116                                 throw new XException (error_event.display, error_event.resourceid,
2117                                                       error_event.serial, error_event.error_code,
2118                                                       error_event.request_code, error_event.minor_code);
2119                         } else {
2120                                 Console.WriteLine("X11 Error encountered: {0}{1}\n",
2121                                                   XException.GetMessage (error_event.display, error_event.resourceid,
2122                                                                          error_event.serial, error_event.error_code,
2123                                                                          error_event.request_code, error_event.minor_code),
2124                                                   Environment.StackTrace);
2125                         }
2126                         return 0;
2127                 }
2128
2129                 void AccumulateDestroyedHandles (Control c, ArrayList list)
2130                 {
2131                         DebugHelper.Enter ();
2132                         if (c != null) {
2133                                 
2134                                 Control[] controls = c.Controls.GetAllControls ();
2135                                 
2136                                 DebugHelper.WriteLine  ("Checking control:0x{0:x}", c.IsHandleCreated ? c.Handle.ToInt32() : 0);
2137
2138                                 if (c.IsHandleCreated && !c.IsDisposed) {
2139                                         Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
2140
2141                                         DriverDebug (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
2142                                         DriverDebug (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
2143
2144                                         list.Add (hwnd);
2145                                         CleanupCachedWindows (hwnd);
2146                                 }
2147
2148                                 for (int  i = 0; i < controls.Length; i ++) {
2149                                         AccumulateDestroyedHandles (controls[i], list);
2150                                 }                                
2151                         }
2152                         DebugHelper.Leave ();
2153                 }
2154
2155                 void CleanupCachedWindows (Hwnd hwnd)
2156                 {
2157                         if (ActiveWindow == hwnd.Handle) {
2158                                 SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
2159                                 ActiveWindow = IntPtr.Zero;
2160                         }
2161
2162                         if (FocusWindow == hwnd.Handle) {
2163                                 SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
2164                                 FocusWindow = IntPtr.Zero;
2165                         }
2166
2167                         if (Grab.Hwnd == hwnd.Handle) {
2168                                 Grab.Hwnd = IntPtr.Zero;
2169                                 Grab.Confined = false;
2170                         }
2171
2172                         DestroyCaret (hwnd.Handle);
2173                 }
2174
2175                 void PerformNCCalc(Hwnd hwnd) {
2176                         XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
2177                         IntPtr                          ptr;
2178                         Rectangle                       rect;
2179
2180                         rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
2181
2182                         ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
2183                         ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
2184
2185                         ncp.rgrc1.left = rect.Left;
2186                         ncp.rgrc1.top = rect.Top;
2187                         ncp.rgrc1.right = rect.Right;
2188                         ncp.rgrc1.bottom = rect.Bottom;
2189
2190                         Marshal.StructureToPtr(ncp, ptr, true);
2191                         NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
2192                         ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
2193                         Marshal.FreeHGlobal(ptr);
2194
2195
2196                         rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
2197                         hwnd.ClientRect = rect;
2198                 
2199                         rect = TranslateClientRectangleToXClientRectangle (hwnd);
2200
2201                         if (hwnd.visible) {
2202                                 MoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
2203                         }
2204
2205                         AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
2206                 }
2207                 #endregion      // Methods
2208
2209                 #region Callbacks
2210                 void MouseHover(object sender, EventArgs e) {
2211                         XEvent  xevent;
2212                         Hwnd    hwnd;
2213
2214                         HoverState.Timer.Enabled = false;
2215
2216                         if (HoverState.Window != IntPtr.Zero) {
2217                                 hwnd = Hwnd.GetObjectFromWindow(HoverState.Window);
2218                                 if (hwnd != null) {
2219                                         xevent = new XEvent ();
2220
2221                                         xevent.type = XEventName.ClientMessage;
2222                                         xevent.ClientMessageEvent.display = DisplayHandle;
2223                                         xevent.ClientMessageEvent.window = HoverState.Window;
2224                                         xevent.ClientMessageEvent.message_type = HoverState.Atom;
2225                                         xevent.ClientMessageEvent.format = 32;
2226                                         xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
2227
2228                                         hwnd.Queue.EnqueueLocked (xevent);
2229
2230                                         WakeupMain ();
2231                                 }
2232                         }
2233                 }
2234
2235                 void CaretCallback(object sender, EventArgs e) {
2236                         if (Caret.Paused) {
2237                                 return;
2238                         }
2239                         Caret.On = !Caret.On;
2240
2241                         XDrawLine(DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
2242                 }
2243                 #endregion      // Callbacks
2244
2245                 #region Public Properties
2246
2247                 internal override int CaptionHeight {
2248                         get {
2249                                 return 19;
2250                         }
2251                 }
2252
2253                 internal override  Size CursorSize {
2254                         get {
2255                                 int     x;
2256                                 int     y;
2257
2258                                 if (XQueryBestCursor(DisplayHandle, RootWindow, 32, 32, out x, out y) != 0) {
2259                                         return new Size(x, y);
2260                                 } else {
2261                                         return new Size(16, 16);
2262                                 }
2263                         }
2264                 } 
2265
2266                 internal override  bool DragFullWindows {
2267                         get {
2268                                 return true;
2269                         }
2270                 } 
2271
2272                 internal override  Size DragSize {
2273                         get {
2274                                 return new Size(4, 4);
2275                         }
2276                 }
2277
2278                 internal override  Size FrameBorderSize { 
2279                         get {
2280                                 return new Size (4, 4);
2281                         }
2282                 }
2283
2284                 internal override  Size IconSize {
2285                         get {
2286                                 IntPtr          list;
2287                                 XIconSize       size;
2288                                 int             count;
2289
2290                                 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2291                                         long            current;
2292                                         int             largest;
2293
2294                                         current = (long)list;
2295                                         largest = 0;
2296
2297                                         size = new XIconSize();
2298
2299                                         for (int i = 0; i < count; i++) {
2300                                                 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2301                                                 current += Marshal.SizeOf(size);
2302
2303                                                 // Look for our preferred size
2304                                                 if (size.min_width == 32) {
2305                                                         XFree(list);
2306                                                         return new Size(32, 32);
2307                                                 }
2308
2309                                                 if (size.max_width == 32) {
2310                                                         XFree(list);
2311                                                         return new Size(32, 32);
2312                                                 }
2313
2314                                                 if (size.min_width < 32 && size.max_width > 32) {
2315                                                         int     x;
2316
2317                                                         // check if we can fit one
2318                                                         x = size.min_width;
2319                                                         while (x < size.max_width) {
2320                                                                 x += size.width_inc;
2321                                                                 if (x == 32) {
2322                                                                         XFree(list);
2323                                                                         return new Size(32, 32);
2324                                                                 }
2325                                                         }
2326                                                 }
2327
2328                                                 if (largest < size.max_width) {
2329                                                         largest = size.max_width;
2330                                                 }
2331                                         }
2332
2333                                         // We didn't find a match or we wouldn't be here
2334                                         return new Size(largest, largest);
2335
2336                                 } else {
2337                                         return new Size(32, 32);
2338                                 }
2339                         }
2340                 } 
2341
2342                 internal override int KeyboardSpeed {
2343                         get{
2344                                 //
2345                                 // A lot harder: need to do:
2346                                 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58)       = 1
2347                                 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58)        = 0x080517a8
2348                                 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58)                   = 0
2349                                 //
2350                                 // And from that we can tell the repetition rate
2351                                 //
2352                                 // Notice, the values must map to:
2353                                 //   [0, 31] which maps to 2.5 to 30 repetitions per second.
2354                                 //
2355                                 return 0;
2356                         }
2357                 }
2358
2359                 internal override int KeyboardDelay {
2360                         get {
2361                                 //
2362                                 // Return values must range from 0 to 4, 0 meaning 250ms,
2363                                 // and 4 meaning 1000 ms.
2364                                 //
2365                                 return 1; // ie, 500 ms
2366                         }
2367                 } 
2368
2369                 internal override  Size MaxWindowTrackSize {
2370                         get {
2371                                 return new Size (WorkingArea.Width, WorkingArea.Height);
2372                         }
2373                 }
2374
2375                 internal override bool MenuAccessKeysUnderlined {
2376                         get {
2377                                 return false;
2378                         }
2379                 }
2380
2381                 internal override  Size MinimizedWindowSpacingSize {
2382                         get {
2383                                 return new Size(1, 1);
2384                         }
2385                 } 
2386
2387                 internal override  Size MinimumWindowSize {
2388                         get {
2389                                 return new Size(110, 22);
2390                         }
2391                 } 
2392
2393                 internal override Size MinimumFixedToolWindowSize {
2394                         get { return new Size (27, 22); }
2395                 }
2396
2397                 internal override Size MinimumSizeableToolWindowSize {
2398                         get { return new Size (37, 22); }
2399                 }
2400
2401                 internal override Size MinimumNoBorderWindowSize {
2402                         get { return new Size (2, 2); }
2403                 }
2404                 
2405                 internal override Keys ModifierKeys {
2406                         get {
2407                                 return Keyboard.ModifierKeys;
2408                         }
2409                 }
2410
2411                 internal override  Size SmallIconSize {
2412                         get {
2413                                 IntPtr          list;
2414                                 XIconSize       size;
2415                                 int             count;
2416
2417                                 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2418                                         long            current;
2419                                         int             smallest;
2420
2421                                         current = (long)list;
2422                                         smallest = 0;
2423
2424                                         size = new XIconSize();
2425
2426                                         for (int i = 0; i < count; i++) {
2427                                                 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2428                                                 current += Marshal.SizeOf(size);
2429
2430                                                 // Look for our preferred size
2431                                                 if (size.min_width == 16) {
2432                                                         XFree(list);
2433                                                         return new Size(16, 16);
2434                                                 }
2435
2436                                                 if (size.max_width == 16) {
2437                                                         XFree(list);
2438                                                         return new Size(16, 16);
2439                                                 }
2440
2441                                                 if (size.min_width < 16 && size.max_width > 16) {
2442                                                         int     x;
2443
2444                                                         // check if we can fit one
2445                                                         x = size.min_width;
2446                                                         while (x < size.max_width) {
2447                                                                 x += size.width_inc;
2448                                                                 if (x == 16) {
2449                                                                         XFree(list);
2450                                                                         return new Size(16, 16);
2451                                                                 }
2452                                                         }
2453                                                 }
2454
2455                                                 if (smallest == 0 || smallest > size.min_width) {
2456                                                         smallest = size.min_width;
2457                                                 }
2458                                         }
2459
2460                                         // We didn't find a match or we wouldn't be here
2461                                         return new Size(smallest, smallest);
2462
2463                                 } else {
2464                                         return new Size(16, 16);
2465                                 }
2466                         }
2467                 } 
2468
2469                 internal override  int MouseButtonCount {
2470                         get {
2471                                 return 3;
2472                         }
2473                 } 
2474
2475                 internal override  bool MouseButtonsSwapped {
2476                         get {
2477                                 return false;   // FIXME - how to detect?
2478                         }
2479                 } 
2480
2481                 internal override Point MousePosition {
2482                         get {
2483                                 return mouse_position;
2484                         }
2485                 }
2486
2487                 internal override Size MouseHoverSize {
2488                         get {
2489                                 return new Size (1, 1);
2490                         }
2491                 }
2492
2493                 internal override int MouseHoverTime {
2494                         get {
2495                                 return HoverState.Interval;
2496                         }
2497                 }
2498
2499
2500
2501                 internal override  bool MouseWheelPresent {
2502                         get {
2503                                 return true;    // FIXME - how to detect?
2504                         }
2505                 } 
2506
2507                 internal override MouseButtons MouseButtons {
2508                         get {
2509                                 return MouseState;
2510                         }
2511                 }
2512
2513                 internal override  Rectangle VirtualScreen {
2514                         get {
2515                                 IntPtr                  actual_atom;
2516                                 int                     actual_format;
2517                                 IntPtr                  nitems;
2518                                 IntPtr                  bytes_after;
2519                                 IntPtr                  prop = IntPtr.Zero;
2520                                 int                     width;
2521                                 int                     height;
2522
2523                                 XGetWindowProperty(DisplayHandle, RootWindow, _NET_DESKTOP_GEOMETRY, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2524                                 if ((long)nitems < 2)
2525                                         goto failsafe;
2526
2527                                 width = Marshal.ReadIntPtr(prop, 0).ToInt32();
2528                                 height = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
2529
2530                                 XFree(prop);
2531
2532                                 return new Rectangle(0, 0, width, height);
2533
2534                         failsafe:
2535                                 XWindowAttributes       attributes=new XWindowAttributes();
2536
2537                                 lock (XlibLock) {
2538                                         XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2539                                 }
2540
2541                                 return new Rectangle(0, 0, attributes.width, attributes.height);
2542                         }
2543                 } 
2544
2545                 internal override  Rectangle WorkingArea {
2546                         get {
2547                                 IntPtr                  actual_atom;
2548                                 int                     actual_format;
2549                                 IntPtr                  nitems;
2550                                 IntPtr                  bytes_after;
2551                                 IntPtr                  prop = IntPtr.Zero;
2552                                 int                     width;
2553                                 int                     height;
2554                                 int                     current_desktop;
2555                                 int                     x;
2556                                 int                     y;
2557
2558                                 XGetWindowProperty(DisplayHandle, RootWindow, _NET_CURRENT_DESKTOP, IntPtr.Zero, new IntPtr(1), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2559                                 if ((long)nitems < 1) {
2560                                         goto failsafe;
2561                                 }
2562
2563                                 current_desktop = Marshal.ReadIntPtr(prop, 0).ToInt32();
2564                                 XFree(prop);
2565
2566                                 XGetWindowProperty(DisplayHandle, RootWindow, _NET_WORKAREA, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2567                                 if ((long)nitems < 4 * (current_desktop + 1)) {
2568                                         goto failsafe;
2569                                 }
2570
2571                                 x = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop).ToInt32();
2572                                 y = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size).ToInt32();
2573                                 width = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 2).ToInt32();
2574                                 height = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 3).ToInt32();
2575                                 XFree(prop);
2576
2577                                 return new Rectangle(x, y, width, height);
2578
2579                         failsafe:
2580                                 XWindowAttributes       attributes=new XWindowAttributes();
2581
2582                                 lock (XlibLock) {
2583                                         XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2584                                 }
2585
2586                                 return new Rectangle(0, 0, attributes.width, attributes.height);
2587                         }
2588                 }
2589
2590                 internal override bool ThemesEnabled {
2591                         get {
2592                                 return XplatUIX11.themes_enabled;
2593                         }
2594                 }
2595  
2596
2597                 #endregion      // Public properties
2598
2599                 #region Public Static Methods
2600                 internal override void RaiseIdle (EventArgs e)
2601                 {
2602                         int id = Thread.CurrentThread.ManagedThreadId;
2603                         if (Idle_Threads != null && 
2604                             Idle_Threads.ContainsKey (id) && 
2605                             Idle_Threads [id] != null) 
2606                         {
2607                                 Idle_Threads [id] (this, e);
2608                         }
2609                 }
2610                 
2611                 internal override IntPtr InitializeDriver()
2612                 {
2613                         lock (this) {
2614                                 if (DisplayHandle==IntPtr.Zero) {
2615                                         SetDisplay(XOpenDisplay(IntPtr.Zero));
2616                                 }
2617                         }
2618                         return IntPtr.Zero;
2619                 }
2620
2621                 internal override void ShutdownDriver(IntPtr token)
2622                 {
2623                         lock (this) {
2624                                 if (DisplayHandle!=IntPtr.Zero) {
2625                                         XCloseDisplay(DisplayHandle);
2626                                         DisplayHandle=IntPtr.Zero;
2627                                 }
2628                         }
2629                 }
2630
2631                 internal override void EnableThemes()
2632                 {
2633                         themes_enabled = true;
2634                 }
2635
2636
2637                 internal override void Activate(IntPtr handle)
2638                 {
2639                         Hwnd hwnd;
2640
2641                         hwnd = Hwnd.ObjectFromHandle(handle);
2642
2643                         if (hwnd != null) {
2644                                 lock (XlibLock) {
2645                                         if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
2646                                                 SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
2647                                                 XEventQueue q = null;
2648                                                 lock (unattached_timer_list) {
2649                                                         foreach (Timer t in unattached_timer_list) {
2650                                                                 if (q == null)
2651                                                                         q= (XEventQueue) MessageQueues [Thread.CurrentThread];
2652                                                                 t.thread = q.Thread;
2653                                                                 q.timer_list.Add (t);
2654                                                         }
2655                                                         unattached_timer_list.Clear ();
2656                                                 }
2657                                         }
2658 //                                      else {
2659 //                                              XRaiseWindow(DisplayHandle, handle);
2660 //                                      }
2661                                 }
2662                         }
2663                 }
2664
2665                 internal override void AudibleAlert(AlertType alert)
2666                 {
2667                         XBell(DisplayHandle, 0);
2668                         return;
2669                 }
2670
2671
2672                 internal override void CaretVisible(IntPtr handle, bool visible)
2673                 {
2674                         if (Caret.Hwnd == handle) {
2675                                 if (visible) {
2676                                         if (!Caret.Visible) {
2677                                                 Caret.Visible = true;
2678                                                 ShowCaret();
2679                                                 Caret.Timer.Start();
2680                                         }
2681                                 } else {
2682                                         Caret.Visible = false;
2683                                         Caret.Timer.Stop();
2684                                         HideCaret();
2685                                 }
2686                         }
2687                 }
2688
2689                 internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect)
2690                 {
2691                         WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
2692                         return true;
2693                 }
2694
2695                 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y)
2696                 {
2697                         int     dest_x_return;
2698                         int     dest_y_return;
2699                         IntPtr  child;
2700                         Hwnd    hwnd;
2701
2702                         hwnd = Hwnd.ObjectFromHandle(handle);
2703
2704                         lock (XlibLock) {
2705                                 XTranslateCoordinates(DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
2706                         }
2707
2708                         x = dest_x_return;
2709                         y = dest_y_return;
2710                 }
2711
2712                 internal override int[] ClipboardAvailableFormats(IntPtr handle)
2713                 {
2714                         DataFormats.Format      f;
2715                         int[]                   result;
2716
2717                         f = DataFormats.Format.List;
2718
2719                         if (XGetSelectionOwner(DisplayHandle, CLIPBOARD) == IntPtr.Zero) {
2720                                 return null;
2721                         }
2722
2723                         Clipboard.Formats = new ArrayList();
2724
2725                         while (f != null) {
2726                                 XConvertSelection(DisplayHandle, CLIPBOARD, (IntPtr)f.Id, (IntPtr)f.Id, FosterParent, IntPtr.Zero);
2727
2728                                 Clipboard.Enumerating = true;
2729                                 while (Clipboard.Enumerating) {
2730                                         UpdateMessageQueue(null, false);
2731                                 }
2732                                 f = f.Next;
2733                         }
2734
2735                         result = new int[Clipboard.Formats.Count];
2736
2737                         for (int i = 0; i < Clipboard.Formats.Count; i++) {
2738                                 result[i] = ((IntPtr)Clipboard.Formats[i]).ToInt32 ();
2739                         }
2740
2741                         Clipboard.Formats = null;
2742                         return result;
2743                 }
2744
2745                 internal override void ClipboardClose(IntPtr handle)
2746                 {
2747                         if (handle != ClipMagic) {
2748                                 throw new ArgumentException("handle is not a valid clipboard handle");
2749                         }
2750                         return;
2751                 }
2752
2753                 internal override int ClipboardGetID(IntPtr handle, string format)
2754                 {
2755                         if (handle != ClipMagic) {
2756                                 throw new ArgumentException("handle is not a valid clipboard handle");
2757                         }
2758
2759                         if (format == "Text" ) return (int)Atom.XA_STRING;
2760                         else if (format == "Bitmap" ) return (int)Atom.XA_BITMAP;
2761                         //else if (format == "MetaFilePict" ) return 3;
2762                         //else if (format == "SymbolicLink" ) return 4;
2763                         //else if (format == "DataInterchangeFormat" ) return 5;
2764                         //else if (format == "Tiff" ) return 6;
2765                         else if (format == "OEMText" ) return OEMTEXT.ToInt32();
2766                         else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP;
2767                         else if (format == "Palette" ) return (int)Atom.XA_COLORMAP;    // Useless
2768                         //else if (format == "PenData" ) return 10;
2769                         //else if (format == "RiffAudio" ) return 11;
2770                         //else if (format == "WaveAudio" ) return 12;
2771                         else if (format == "UnicodeText" ) return UTF16_STRING.ToInt32();
2772                         //else if (format == "EnhancedMetafile" ) return 14;
2773                         //else if (format == "FileDrop" ) return 15;
2774                         //else if (format == "Locale" ) return 16;
2775                         else if (format == "Rich Text Format") return RICHTEXTFORMAT.ToInt32 ();
2776
2777                         return XInternAtom(DisplayHandle, format, false).ToInt32();
2778                 }
2779
2780                 internal override IntPtr ClipboardOpen(bool primary_selection)
2781                 {
2782                         if (!primary_selection)
2783                                 ClipMagic = CLIPBOARD;
2784                         else
2785                                 ClipMagic = PRIMARY;
2786                         return ClipMagic;
2787                 }
2788
2789                 internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter)
2790                 {
2791                         XConvertSelection(DisplayHandle, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);
2792
2793                         Clipboard.Retrieving = true;
2794                         while (Clipboard.Retrieving) {
2795                                 UpdateMessageQueue(null, false);
2796                         }
2797
2798                         return Clipboard.Item;
2799                 }
2800
2801                 internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
2802                 {
2803                         Clipboard.Converter = converter;
2804
2805                         if (obj != null) {
2806                                 Clipboard.AddSource (type, obj);
2807                                 XSetSelectionOwner (DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
2808
2809                                 if (copy) {
2810                                         try {
2811                                                 var clipboardAtom = gdk_atom_intern ("CLIPBOARD", true);
2812                                                 var clipboard = gtk_clipboard_get (clipboardAtom);
2813                                                 if (clipboard != null) {
2814                                                         // for now we only store text
2815                                                         var text = Clipboard.GetRtfText ();
2816                                                         if (string.IsNullOrEmpty (text))
2817                                                                 text = Clipboard.GetPlainText ();
2818                                                         if (!string.IsNullOrEmpty (text)) {
2819                                                                 gtk_clipboard_set_text (clipboard, text, text.Length);
2820                                                                 gtk_clipboard_store (clipboard);
2821                                                         }
2822                                                 }
2823                                         } catch {
2824                                                 // ignore any errors - most likely because gtk isn't installed?
2825                                         }
2826                                 }
2827                         } else {
2828                                 // Clearing the selection
2829                                 Clipboard.ClearSources ();
2830                                 XSetSelectionOwner (DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
2831                         }
2832                 }
2833
2834                 internal override void CreateCaret (IntPtr handle, int width, int height)
2835                 {
2836                         XGCValues       gc_values;
2837                         Hwnd            hwnd;
2838
2839                         hwnd = Hwnd.ObjectFromHandle(handle);
2840
2841                         if (Caret.Hwnd != IntPtr.Zero) {
2842                                 DestroyCaret(Caret.Hwnd);
2843                         }
2844
2845                         Caret.Hwnd = handle;
2846                         Caret.Window = hwnd.client_window;
2847                         Caret.Width = width;
2848                         Caret.Height = height;
2849                         Caret.Visible = false;
2850                         Caret.On = false;
2851
2852                         gc_values = new XGCValues();
2853                         gc_values.line_width = width;
2854
2855                         Caret.gc = XCreateGC(DisplayHandle, Caret.Window, new IntPtr ((int)GCFunction.GCLineWidth), ref gc_values);
2856                         if (Caret.gc == IntPtr.Zero) {
2857                                 Caret.Hwnd = IntPtr.Zero;
2858                                 return;
2859                         }
2860
2861                         XSetFunction(DisplayHandle, Caret.gc, GXFunction.GXinvert);
2862                 }
2863
2864                 internal override IntPtr CreateWindow (CreateParams cp)
2865                 {
2866                         XSetWindowAttributes    Attributes;
2867                         Hwnd                    hwnd;
2868                         Hwnd                    parent_hwnd = null;
2869                         int                     X;
2870                         int                     Y;
2871                         int                     Width;
2872                         int                     Height;
2873                         IntPtr                  ParentHandle;
2874                         IntPtr                  WholeWindow;
2875                         IntPtr                  ClientWindow;
2876                         SetWindowValuemask      ValueMask;
2877                         int[]                   atoms;
2878
2879                         hwnd = new Hwnd();
2880
2881                         Attributes = new XSetWindowAttributes();
2882                         X = cp.X;
2883                         Y = cp.Y;
2884                         Width = cp.Width;
2885                         Height = cp.Height;
2886
2887                         if (Width<1) Width=1;
2888                         if (Height<1) Height=1;
2889
2890                         if (cp.Parent != IntPtr.Zero) {
2891                                 parent_hwnd = Hwnd.ObjectFromHandle(cp.Parent);
2892                                 ParentHandle = parent_hwnd.client_window;
2893                         } else {
2894                                 if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
2895                                         // We need to use our foster parent window until this poor child gets it's parent assigned
2896                                         ParentHandle=FosterParent;
2897                                 } else {
2898                                         ParentHandle=RootWindow;
2899                                 }
2900                         }
2901
2902                         // Set the default location location for forms.
2903                         Point next;
2904                         if (cp.control is Form) {
2905                                 next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
2906                                 X = next.X;
2907                                 Y = next.Y;
2908                         }
2909                         ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
2910
2911                         Attributes.bit_gravity = Gravity.NorthWestGravity;
2912                         Attributes.win_gravity = Gravity.NorthWestGravity;
2913
2914                         // Save what's under the toolwindow
2915                         if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
2916                                 Attributes.save_under = true;
2917                                 ValueMask |= SetWindowValuemask.SaveUnder;
2918                         }
2919
2920
2921                         // If we're a popup without caption we override the WM
2922                         if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && !StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
2923                                 Attributes.override_redirect = true;
2924                                 ValueMask |= SetWindowValuemask.OverrideRedirect;
2925                         }
2926
2927                         hwnd.x = X;
2928                         hwnd.y = Y;
2929                         hwnd.width = Width;
2930                         hwnd.height = Height;
2931                         hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
2932                         hwnd.initial_style = cp.WindowStyle;
2933                         hwnd.initial_ex_style = cp.WindowExStyle;
2934
2935                         if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
2936                                 hwnd.enabled = false;
2937                         }
2938
2939                         ClientWindow = IntPtr.Zero;
2940
2941                         Size XWindowSize = TranslateWindowSizeToXWindowSize (cp);
2942                         Rectangle XClientRect = TranslateClientRectangleToXClientRectangle (hwnd, cp.control);
2943                                 
2944                         lock (XlibLock) {
2945                                 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);
2946                                 if (WholeWindow != IntPtr.Zero) {
2947                                         ValueMask &= ~(SetWindowValuemask.OverrideRedirect | SetWindowValuemask.SaveUnder);
2948
2949                                         if (CustomVisual != IntPtr.Zero && CustomColormap != IntPtr.Zero) {
2950                                                 ValueMask = SetWindowValuemask.ColorMap;
2951                                                 Attributes.colormap = CustomColormap;
2952                                         }
2953                                         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);
2954                                 }
2955                         }
2956
2957                         if ((WholeWindow == IntPtr.Zero) || (ClientWindow == IntPtr.Zero)) {
2958                                 throw new Exception("Could not create X11 windows");
2959                         }
2960
2961                         hwnd.Queue = ThreadQueue(Thread.CurrentThread);
2962                         hwnd.WholeWindow = WholeWindow;
2963                         hwnd.ClientWindow = ClientWindow;
2964
2965                         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);
2966                         
2967                         if (!StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
2968                                 if ((X != unchecked((int)0x80000000)) && (Y != unchecked((int)0x80000000))) {
2969                                         XSizeHints      hints;
2970
2971                                         hints = new XSizeHints();
2972                                         hints.x = X;
2973                                         hints.y = Y;
2974                                         hints.flags = (IntPtr)(XSizeHintsFlags.USPosition | XSizeHintsFlags.PPosition);
2975                                         XSetWMNormalHints(DisplayHandle, WholeWindow, ref hints);
2976                                 }
2977                         }
2978
2979                         lock (XlibLock) {
2980                                 XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
2981                                 if (hwnd.whole_window != hwnd.client_window)
2982                                         XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
2983                         }
2984
2985                         if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST)) {
2986                                 atoms = new int[2];
2987                                 atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
2988                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
2989
2990                                 XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
2991                         }
2992
2993                         SetWMStyles(hwnd, cp);
2994                         
2995                         // set the group leader
2996                         XWMHints wm_hints = new XWMHints ();
2997                         
2998                         wm_hints.flags = (IntPtr)(XWMHintsFlags.InputHint | XWMHintsFlags.StateHint | XWMHintsFlags.WindowGroupHint);
2999                         wm_hints.input = !StyleSet (cp.Style, WindowStyles.WS_DISABLED);
3000                         wm_hints.initial_state = StyleSet (cp.Style, WindowStyles.WS_MINIMIZE) ? XInitialState.IconicState : XInitialState.NormalState;
3001                         
3002                         if (ParentHandle != RootWindow) {
3003                                 wm_hints.window_group = hwnd.whole_window;
3004                         } else {
3005                                 wm_hints.window_group = ParentHandle;
3006                         }
3007                         
3008                         lock (XlibLock) {
3009                                 XSetWMHints(DisplayHandle, hwnd.whole_window, ref wm_hints );
3010                         }
3011
3012                         if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
3013                                 SetWindowState(hwnd.Handle, FormWindowState.Minimized);
3014                         } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
3015                                 SetWindowState(hwnd.Handle, FormWindowState.Maximized);
3016                         }
3017
3018                         // for now make all windows dnd enabled
3019                         Dnd.SetAllowDrop (hwnd, true);
3020
3021                         // Set caption/window title
3022                         Text(hwnd.Handle, cp.Caption);
3023
3024                         SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
3025                         SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
3026
3027                         if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
3028                                 hwnd.visible = true;
3029                                 MapWindow(hwnd, WindowType.Both);
3030                                 if (!(Control.FromHandle(hwnd.Handle) is Form))
3031                                         SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
3032                         }
3033
3034                         return hwnd.Handle;
3035                 }
3036
3037                 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height)
3038                 {
3039                         CreateParams create_params = new CreateParams();
3040
3041                         create_params.Caption = "";
3042                         create_params.X = X;
3043                         create_params.Y = Y;
3044                         create_params.Width = Width;
3045                         create_params.Height = Height;
3046
3047                         create_params.ClassName=XplatUI.GetDefaultClassName (GetType ());
3048                         create_params.ClassStyle = 0;
3049                         create_params.ExStyle=0;
3050                         create_params.Parent=IntPtr.Zero;
3051                         create_params.Param=0;
3052
3053                         return CreateWindow(create_params);
3054                 }
3055
3056                 internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
3057                 {
3058                         IntPtr  cursor;
3059                         Bitmap  cursor_bitmap;
3060                         Bitmap  cursor_mask;
3061                         Byte[]  cursor_bits;
3062                         Byte[]  mask_bits;
3063                         Color   c_pixel;
3064                         Color   m_pixel;
3065                         int     width;
3066                         int     height;
3067                         IntPtr  cursor_pixmap;
3068                         IntPtr  mask_pixmap;
3069                         XColor  fg;
3070                         XColor  bg;
3071                         bool    and;
3072                         bool    xor;
3073
3074                         if (XQueryBestCursor(DisplayHandle, RootWindow, bitmap.Width, bitmap.Height, out width, out height) == 0) {
3075                                 return IntPtr.Zero;
3076                         }
3077
3078                         // Win32 only allows creation cursors of a certain size
3079                         if ((bitmap.Width != width) || (bitmap.Width != height)) {
3080                                 cursor_bitmap = new Bitmap(bitmap, new Size(width, height));
3081                                 cursor_mask = new Bitmap(mask, new Size(width, height));
3082                         } else {
3083                                 cursor_bitmap = bitmap;
3084                                 cursor_mask = mask;
3085                         }
3086
3087                         width = cursor_bitmap.Width;
3088                         height = cursor_bitmap.Height;
3089
3090                         cursor_bits = new Byte[(width / 8) * height];
3091                         mask_bits = new Byte[(width / 8) * height];
3092
3093                         for (int y = 0; y < height; y++) {
3094                                 for (int x = 0; x < width; x++) {
3095                                         c_pixel = cursor_bitmap.GetPixel(x, y);
3096                                         m_pixel = cursor_mask.GetPixel(x, y);
3097
3098                                         and = c_pixel == cursor_pixel;
3099                                         xor = m_pixel == mask_pixel;
3100
3101                                         if (!and && !xor) {
3102                                                 // Black
3103                                                 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));       // The bit already is 0
3104                                                 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3105                                         } else if (and && !xor) {
3106                                                 // White
3107                                                 cursor_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3108                                                 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3109 #if notneeded
3110                                         } else if (and && !xor) {
3111                                                 // Screen
3112                                         } else if (and && xor) {
3113                                                 // Inverse Screen
3114
3115                                                 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
3116                                                 // we want both to be 0 so nothing to be done
3117                                                 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
3118                                                 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
3119 #endif
3120                                         }
3121                                 }
3122                         }
3123
3124                         cursor_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3125                         mask_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3126                         fg = new XColor();
3127                         bg = new XColor();
3128
3129                         fg.pixel = XWhitePixel(DisplayHandle, ScreenNo);
3130                         fg.red = (ushort)65535;
3131                         fg.green = (ushort)65535;
3132                         fg.blue = (ushort)65535;
3133
3134                         bg.pixel = XBlackPixel(DisplayHandle, ScreenNo);
3135
3136                         cursor = XCreatePixmapCursor(DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
3137
3138                         XFreePixmap(DisplayHandle, cursor_pixmap);
3139                         XFreePixmap(DisplayHandle, mask_pixmap);
3140
3141                         return cursor;
3142                 }
3143
3144                 internal override Bitmap DefineStdCursorBitmap (StdCursor id)
3145                 {
3146                         CursorFontShape shape;
3147                         string name;
3148                         IntPtr theme;
3149                         int size;
3150                         Bitmap bmp = null;
3151                         
3152                         try {
3153                                 shape = StdCursorToFontShape (id);
3154                                 name = shape.ToString ().Replace ("XC_", string.Empty);
3155                                 size = XcursorGetDefaultSize (DisplayHandle);
3156                                 theme = XcursorGetTheme (DisplayHandle);
3157                                 IntPtr images_ptr = XcursorLibraryLoadImages (name, theme, size);
3158                                 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);
3159
3160                                 if (images_ptr == IntPtr.Zero) {
3161                                         return null;
3162                                 }
3163
3164                                 XcursorImages images = (XcursorImages) Marshal.PtrToStructure (images_ptr, typeof (XcursorImages));
3165                                 DriverDebug ("DefineStdCursorBitmap, cursor has {0} images", images.nimage);
3166
3167                                 if (images.nimage > 0) {                        
3168                                         // We only care about the first image.
3169                                         XcursorImage image = (XcursorImage)Marshal.PtrToStructure (Marshal.ReadIntPtr (images.images), typeof (XcursorImage));
3170                                         
3171                                         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);
3172                                         // A sanity check
3173                                         if (image.width <= short.MaxValue && image.height <= short.MaxValue) {
3174                                                 int [] pixels = new int [image.width * image.height];
3175                                                 Marshal.Copy (image.pixels, pixels, 0, pixels.Length);
3176                                                 bmp = new Bitmap (image.width, image.height);
3177                                                 for (int w = 0; w < image.width; w++) {
3178                                                         for (int h = 0; h < image.height; h++) {
3179                                                                 bmp.SetPixel (w, h, Color.FromArgb (pixels [h * image.width + w]));
3180                                                         }
3181                                                 }
3182                                         }
3183                                 }
3184                                 
3185                                 XcursorImagesDestroy (images_ptr);
3186                                 
3187                         } catch (DllNotFoundException ex) {
3188                                 Console.WriteLine ("Could not load libXcursor: " + ex.Message + " (" + ex.GetType ().Name + ")");
3189                                 return null;
3190                         }
3191                         
3192                         return bmp;
3193                 }
3194
3195                 
3196                 internal override IntPtr DefineStdCursor(StdCursor id)
3197                 {
3198                         CursorFontShape shape;
3199                         IntPtr          cursor;
3200
3201                         shape = StdCursorToFontShape (id);
3202
3203                         lock (XlibLock) {
3204                                 cursor = XCreateFontCursor(DisplayHandle, shape);
3205                         }
3206                         return cursor;
3207                 }
3208
3209                 internal static CursorFontShape StdCursorToFontShape (StdCursor id)
3210                 {
3211                         CursorFontShape shape;
3212                         // FIXME - define missing shapes
3213
3214                         switch (id) {
3215                                 case StdCursor.AppStarting: {
3216                                         shape = CursorFontShape.XC_watch;
3217                                         break;
3218                                 }
3219
3220                                 case StdCursor.Arrow: {
3221                                         shape = CursorFontShape.XC_top_left_arrow;
3222                                         break;
3223                                 }
3224
3225                                 case StdCursor.Cross: {
3226                                         shape = CursorFontShape.XC_crosshair;
3227                                         break;
3228                                 }
3229
3230                                 case StdCursor.Default: {
3231                                         shape = CursorFontShape.XC_top_left_arrow;
3232                                         break;
3233                                 }
3234
3235                                 case StdCursor.Hand: {
3236                                         shape = CursorFontShape.XC_hand1;
3237                                         break;
3238                                 }
3239
3240                                 case StdCursor.Help: {
3241                                         shape = CursorFontShape.XC_question_arrow;
3242                                         break;
3243                                 }
3244
3245                                 case StdCursor.HSplit: {
3246                                         shape = CursorFontShape.XC_sb_v_double_arrow; 
3247                                         break;
3248                                 }
3249
3250                                 case StdCursor.IBeam: {
3251                                         shape = CursorFontShape.XC_xterm; 
3252                                         break;
3253                                 }
3254
3255                                 case StdCursor.No: {
3256                                         shape = CursorFontShape.XC_circle; 
3257                                         break;
3258                                 }
3259
3260                                 case StdCursor.NoMove2D: {
3261                                         shape = CursorFontShape.XC_fleur; 
3262                                         break;
3263                                 }
3264
3265                                 case StdCursor.NoMoveHoriz: {
3266                                         shape = CursorFontShape.XC_fleur; 
3267                                         break;
3268                                 }
3269
3270                                 case StdCursor.NoMoveVert: {
3271                                         shape = CursorFontShape.XC_fleur; 
3272                                         break;
3273                                 }
3274
3275                                 case StdCursor.PanEast: {
3276                                         shape = CursorFontShape.XC_fleur; 
3277                                         break;
3278                                 }
3279
3280                                 case StdCursor.PanNE: {
3281                                         shape = CursorFontShape.XC_fleur; 
3282                                         break;
3283                                 }
3284
3285                                 case StdCursor.PanNorth: {
3286                                         shape = CursorFontShape.XC_fleur; 
3287                                         break;
3288                                 }
3289
3290                                 case StdCursor.PanNW: {
3291                                         shape = CursorFontShape.XC_fleur; 
3292                                         break;
3293                                 }
3294
3295                                 case StdCursor.PanSE: {
3296                                         shape = CursorFontShape.XC_fleur; 
3297                                         break;
3298                                 }
3299
3300                                 case StdCursor.PanSouth: {
3301                                         shape = CursorFontShape.XC_fleur; 
3302                                         break;
3303                                 }
3304
3305                                 case StdCursor.PanSW: {
3306                                         shape = CursorFontShape.XC_fleur; 
3307                                         break;
3308                                 }
3309
3310                                 case StdCursor.PanWest: {
3311                                         shape = CursorFontShape.XC_sizing; 
3312                                         break;
3313                                 }
3314
3315                                 case StdCursor.SizeAll: {
3316                                         shape = CursorFontShape.XC_fleur; 
3317                                         break;
3318                                 }
3319
3320                                 case StdCursor.SizeNESW: {
3321                                         shape = CursorFontShape.XC_top_right_corner; 
3322                                         break;
3323                                 }
3324
3325                                 case StdCursor.SizeNS: {
3326                                         shape = CursorFontShape.XC_sb_v_double_arrow;
3327                                         break;
3328                                 }
3329
3330                                 case StdCursor.SizeNWSE: {
3331                                         shape = CursorFontShape.XC_top_left_corner; 
3332                                         break;
3333                                 }
3334
3335                                 case StdCursor.SizeWE: {
3336                                         shape = CursorFontShape.XC_sb_h_double_arrow; 
3337                                         break;
3338                                 }
3339
3340                                 case StdCursor.UpArrow: {
3341                                         shape = CursorFontShape.XC_center_ptr; 
3342                                         break;
3343                                 }
3344
3345                                 case StdCursor.VSplit: {
3346                                         shape = CursorFontShape.XC_sb_h_double_arrow;
3347                                         break;
3348                                 }
3349
3350                                 case StdCursor.WaitCursor: {
3351                                         shape = CursorFontShape.XC_watch; 
3352                                         break;
3353                                 }
3354
3355                                 default: {
3356                                         shape = (CursorFontShape) 0;
3357                                         break;
3358                                 }
3359                         }
3360                         
3361                         return shape;
3362                 }
3363
3364                 internal override IntPtr DefWndProc(ref Message msg)
3365                 {
3366                         switch ((Msg)msg.Msg) {
3367                                 
3368                                 case Msg.WM_IME_COMPOSITION:
3369                                         string s = Keyboard.GetCompositionString ();
3370                                         foreach (char c in s)
3371                                                 SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
3372                                         return IntPtr.Zero;
3373
3374                                 case Msg.WM_IME_CHAR:
3375                                         // On Windows API it sends two WM_CHAR messages for each byte, but
3376                                         // I wonder if it is worthy to emulate it (also no idea how to 
3377                                         // reconstruct those bytes into chars).
3378                                         SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
3379                                         return IntPtr.Zero;
3380
3381                                 case Msg.WM_PAINT: {
3382                                         Hwnd hwnd;
3383
3384                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3385                                         if (hwnd != null) {
3386                                                 hwnd.expose_pending = false;
3387                                         }
3388
3389                                         return IntPtr.Zero;
3390                                 }
3391
3392                                 case Msg.WM_NCPAINT: {
3393                                         Hwnd hwnd;
3394
3395                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3396                                         if (hwnd != null) {
3397                                                 hwnd.nc_expose_pending = false;
3398                                         }
3399
3400                                         return IntPtr.Zero;
3401                                 }
3402
3403                                 case Msg.WM_NCCALCSIZE: {
3404                                         Hwnd hwnd;
3405
3406                                         if (msg.WParam == (IntPtr)1) {
3407                                                 hwnd = Hwnd.GetObjectFromWindow (msg.HWnd);
3408                                                 
3409                                                 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
3410                                                 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
3411
3412                                                 // Add all the stuff X is supposed to draw.
3413                                                 Control ctrl = Control.FromHandle (hwnd.Handle);
3414                                                 
3415                                                 if (ctrl != null) {
3416                                                         Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
3417                                                         
3418                                                         ncp.rgrc1.top += rect.top;
3419                                                         ncp.rgrc1.bottom -= rect.bottom;
3420                                                         ncp.rgrc1.left += rect.left;
3421                                                         ncp.rgrc1.right -= rect.right;
3422                                                         
3423                                                         Marshal.StructureToPtr (ncp, msg.LParam, true);
3424                                                 }
3425                                         }
3426
3427                                         return IntPtr.Zero;
3428                                 }
3429
3430                                 case Msg.WM_CONTEXTMENU: {
3431                                         Hwnd hwnd;
3432
3433                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3434
3435                                         if ((hwnd != null) && (hwnd.parent != null)) {
3436                                                 SendMessage(hwnd.parent.client_window, Msg.WM_CONTEXTMENU, msg.WParam, msg.LParam);
3437                                         }
3438                                         return IntPtr.Zero;
3439                                 }
3440
3441                                 case Msg.WM_MOUSEWHEEL: {
3442                                         Hwnd hwnd;
3443
3444                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3445
3446                                         if ((hwnd != null) && (hwnd.parent != null)) {
3447                                                 SendMessage(hwnd.parent.client_window, Msg.WM_MOUSEWHEEL, msg.WParam, msg.LParam);
3448                                                 if (msg.Result == IntPtr.Zero) {
3449                                                         return IntPtr.Zero;
3450                                                 }
3451                                         }
3452                                         return IntPtr.Zero;
3453                                 }
3454
3455                                 case Msg.WM_SETCURSOR: {
3456                                         Hwnd    hwnd;
3457
3458                                         hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3459                                         if (hwnd == null)
3460                                                 break; // not sure how this happens, but it does
3461
3462                                         // Pass to parent window first
3463                                         while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
3464                                                 hwnd = hwnd.parent;
3465                                                 msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
3466                                         }
3467
3468                                         if (msg.Result == IntPtr.Zero) {
3469                                                 IntPtr handle;
3470
3471                                                 switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
3472                                                         case HitTest.HTBOTTOM:          handle = Cursors.SizeNS.handle; break;
3473                                                         case HitTest.HTBORDER:          handle = Cursors.SizeNS.handle; break;
3474                                                         case HitTest.HTBOTTOMLEFT:      handle = Cursors.SizeNESW.handle; break;
3475                                                         case HitTest.HTBOTTOMRIGHT:     handle = Cursors.SizeNWSE.handle; break;
3476                                                         case HitTest.HTERROR:           if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
3477                                                                                                 AudibleAlert(AlertType.Default);
3478                                                                                         }
3479                                                                                         handle = Cursors.Default.handle;
3480                                                                                         break;
3481
3482                                                         case HitTest.HTHELP:            handle = Cursors.Help.handle; break;
3483                                                         case HitTest.HTLEFT:            handle = Cursors.SizeWE.handle; break;
3484                                                         case HitTest.HTRIGHT:           handle = Cursors.SizeWE.handle; break;
3485                                                         case HitTest.HTTOP:             handle = Cursors.SizeNS.handle; break;
3486                                                         case HitTest.HTTOPLEFT:         handle = Cursors.SizeNWSE.handle; break;
3487                                                         case HitTest.HTTOPRIGHT:        handle = Cursors.SizeNESW.handle; break;
3488
3489                                                         #if SameAsDefault
3490                                                         case HitTest.HTGROWBOX:
3491                                                         case HitTest.HTSIZE:
3492                                                         case HitTest.HTZOOM:
3493                                                         case HitTest.HTVSCROLL:
3494                                                         case HitTest.HTSYSMENU:
3495                                                         case HitTest.HTREDUCE:
3496                                                         case HitTest.HTNOWHERE:
3497                                                         case HitTest.HTMAXBUTTON:
3498                                                         case HitTest.HTMINBUTTON:
3499                                                         case HitTest.HTMENU:
3500                                                         case HitTest.HSCROLL:
3501                                                         case HitTest.HTBOTTOM:
3502                                                         case HitTest.HTCAPTION:
3503                                                         case HitTest.HTCLIENT:
3504                                                         case HitTest.HTCLOSE:
3505                                                         #endif
3506                                                         default: handle = Cursors.Default.handle; break;
3507                                                 }
3508                                                 SetCursor(msg.HWnd, handle);
3509                                         }
3510                                         return (IntPtr)1;
3511                                 }
3512                         }
3513                         return IntPtr.Zero;
3514                 }
3515
3516                 internal override void DestroyCaret(IntPtr handle)
3517                 {
3518                         if (Caret.Hwnd == handle) {
3519                                 if (Caret.Visible) {
3520                                         HideCaret ();
3521                                         Caret.Timer.Stop();
3522                                 }
3523                                 if (Caret.gc != IntPtr.Zero) {
3524                                         XFreeGC(DisplayHandle, Caret.gc);
3525                                         Caret.gc = IntPtr.Zero;
3526                                 }
3527                                 Caret.Hwnd = IntPtr.Zero;
3528                                 Caret.Visible = false;
3529                                 Caret.On = false;
3530                         }
3531                 }
3532
3533                 internal override void DestroyCursor(IntPtr cursor)
3534                 {
3535                         lock (XlibLock) {
3536                                 XFreeCursor(DisplayHandle, cursor);
3537                         }
3538                 }
3539
3540                 internal override void DestroyWindow(IntPtr handle)
3541                 {
3542                         Hwnd    hwnd;
3543                         hwnd = Hwnd.ObjectFromHandle(handle);
3544                         
3545                         // The window should never ever be a zombie here, since we should
3546                         // wait until it's completely dead before returning from 
3547                         // "destroying" calls, but just in case....
3548                         if (hwnd == null || hwnd.zombie) {
3549                                 DriverDebug ("window {0:X} already destroyed", handle.ToInt32());
3550                                 return;
3551                         }
3552
3553                         DriverDebug ("Destroying window {0}", XplatUI.Window(hwnd.client_window));
3554
3555                         SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
3556                                 
3557                         CleanupCachedWindows (hwnd);
3558
3559                         ArrayList windows = new ArrayList ();
3560
3561                         AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
3562
3563
3564                         foreach (Hwnd h in windows) {
3565                                 SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
3566                                 h.zombie = true;                                
3567                         }
3568
3569                         lock (XlibLock) {
3570                                 if (hwnd.whole_window != IntPtr.Zero) {
3571                                         DriverDebug ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
3572                                         Keyboard.DestroyICForWindow (hwnd.whole_window);
3573                                         XDestroyWindow(DisplayHandle, hwnd.whole_window);
3574                                 }
3575                                 else if (hwnd.client_window != IntPtr.Zero) {
3576                                         DriverDebug ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
3577                                         Keyboard.DestroyICForWindow (hwnd.client_window);
3578                                         XDestroyWindow(DisplayHandle, hwnd.client_window);
3579                                 }
3580
3581                         }
3582                 }
3583
3584                 internal override IntPtr DispatchMessage(ref MSG msg)
3585                 {
3586                         return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
3587                 }
3588
3589                 IntPtr GetReversibleScreenGC (Color backColor)
3590                 {
3591                         XGCValues       gc_values;
3592                         IntPtr          gc;
3593                         uint pixel;
3594
3595                         XColor xcolor = new XColor();
3596                         xcolor.red = (ushort)(backColor.R * 257);
3597                         xcolor.green = (ushort)(backColor.G * 257);
3598                         xcolor.blue = (ushort)(backColor.B * 257);
3599                         XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3600                         pixel = (uint)xcolor.pixel.ToInt32();
3601
3602
3603                         gc_values = new XGCValues();
3604
3605                         gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3606                         gc_values.foreground = (IntPtr)pixel;
3607
3608                         gc = XCreateGC(DisplayHandle, RootWindow, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCForeground)), ref gc_values);
3609                         XSetForeground(DisplayHandle, gc, (UIntPtr)pixel);
3610                         XSetFunction(DisplayHandle,   gc, GXFunction.GXxor);
3611
3612                         return gc;
3613                 }
3614
3615                 IntPtr GetReversibleControlGC (Control control, int line_width)
3616                 {
3617                         XGCValues       gc_values;
3618                         IntPtr          gc;
3619
3620                         gc_values = new XGCValues();
3621
3622                         gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3623                         gc_values.line_width = line_width;
3624                         gc_values.foreground = XBlackPixel(DisplayHandle, ScreenNo);
3625
3626                         // This logic will give us true rubber bands: (libsx, SANE_XOR)
3627                         //mask = foreground ^ background; 
3628                         //XSetForeground(DisplayHandle, gc, 0xffffffff);
3629                         //XSetBackground(DisplayHandle, gc, background);
3630                         //XSetFunction(DisplayHandle,   gc, GXxor);
3631                         //XSetPlaneMask(DisplayHandle,  gc, mask);
3632
3633
3634                         gc = XCreateGC(DisplayHandle, control.Handle, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
3635                         uint foreground;
3636                         uint background;
3637
3638                         XColor xcolor = new XColor();
3639
3640                         xcolor.red = (ushort)(control.ForeColor.R * 257);
3641                         xcolor.green = (ushort)(control.ForeColor.G * 257);
3642                         xcolor.blue = (ushort)(control.ForeColor.B * 257);
3643                         XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3644                         foreground = (uint)xcolor.pixel.ToInt32();
3645
3646                         xcolor.red = (ushort)(control.BackColor.R * 257);
3647                         xcolor.green = (ushort)(control.BackColor.G * 257);
3648                         xcolor.blue = (ushort)(control.BackColor.B * 257);
3649                         XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3650                         background = (uint)xcolor.pixel.ToInt32();
3651
3652                         uint mask = foreground ^ background; 
3653
3654                         XSetForeground(DisplayHandle, gc, (UIntPtr)0xffffffff);
3655                         XSetBackground(DisplayHandle, gc, (UIntPtr)background);
3656                         XSetFunction(DisplayHandle,   gc, GXFunction.GXxor);
3657                         XSetPlaneMask(DisplayHandle,  gc, (IntPtr)mask);
3658
3659                         return gc;
3660                 }
3661
3662                 internal override void DrawReversibleLine(Point start, Point end, Color backColor)
3663                 {
3664                         if (backColor.GetBrightness() < 0.5)
3665                                 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3666
3667                         IntPtr gc = GetReversibleScreenGC (backColor);
3668
3669                         XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
3670
3671                         XFreeGC(DisplayHandle, gc);
3672                 }
3673
3674                 internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
3675                 {
3676                         if (backColor.GetBrightness() < 0.5)
3677                                 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3678
3679                         IntPtr gc = GetReversibleScreenGC (backColor);
3680
3681                         if (rectangle.Width < 0) {
3682                                 rectangle.X += rectangle.Width;
3683                                 rectangle.Width = -rectangle.Width;
3684                         }
3685                         if (rectangle.Height < 0) {
3686                                 rectangle.Y += rectangle.Height;
3687                                 rectangle.Height = -rectangle.Height;
3688                         }
3689
3690                         int line_width = 1;
3691                         GCLineStyle line_style = GCLineStyle.LineSolid;
3692                         GCCapStyle cap_style = GCCapStyle.CapButt;
3693                         GCJoinStyle join_style = GCJoinStyle.JoinMiter;
3694
3695                         switch (style) {
3696                         case FrameStyle.Dashed:
3697                                 line_style = GCLineStyle.LineOnOffDash;
3698                                 break;
3699                         case FrameStyle.Thick:
3700                                 line_width = 2;
3701                                 break;
3702                         }
3703
3704                         XSetLineAttributes (DisplayHandle, gc, line_width, line_style, cap_style, join_style);
3705
3706                         XDrawRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3707
3708                         XFreeGC(DisplayHandle, gc);
3709                 }
3710
3711                 internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor) 
3712                 {
3713                         if (backColor.GetBrightness() < 0.5)
3714                                 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3715
3716                         IntPtr gc = GetReversibleScreenGC (backColor);
3717
3718                         if (rectangle.Width < 0) {
3719                                 rectangle.X += rectangle.Width;
3720                                 rectangle.Width = -rectangle.Width;
3721                         }
3722                         if (rectangle.Height < 0) {
3723                                 rectangle.Y += rectangle.Height;
3724                                 rectangle.Height = -rectangle.Height;
3725                         }
3726                         XFillRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3727
3728                         XFreeGC(DisplayHandle, gc);
3729                 }
3730
3731                 internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width)
3732                 {
3733                         IntPtr          gc;
3734                         Control control = Control.FromHandle(handle);
3735
3736                         gc = GetReversibleControlGC (control, line_width);
3737
3738                         if ((rect.Width > 0) && (rect.Height > 0)) {
3739                                 XDrawRectangle(DisplayHandle, control.Handle, gc, rect.Left, rect.Top, rect.Width, rect.Height);
3740                         } else {
3741                                 if (rect.Width > 0) {
3742                                         XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.Right, rect.Y);
3743                                 } else {
3744                                         XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.X, rect.Bottom);
3745                                 }
3746                         }
3747                         XFreeGC(DisplayHandle, gc);
3748                 }
3749
3750                 internal override void DoEvents()
3751                 {
3752                         DebugHelper.Enter ();
3753
3754                         MSG     msg = new MSG ();
3755                         XEventQueue queue;
3756
3757                         if (OverrideCursorHandle != IntPtr.Zero) {
3758                                 OverrideCursorHandle = IntPtr.Zero;
3759                         }
3760
3761                         queue = ThreadQueue(Thread.CurrentThread);
3762
3763                         queue.DispatchIdle = false;
3764                         in_doevents = true;
3765
3766                         while (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
3767                                 Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
3768
3769                                 if (Application.FilterMessage (ref m))
3770                                         continue;
3771
3772                                 TranslateMessage (ref msg);
3773                                 DispatchMessage (ref msg);
3774
3775                                 string key = msg.hwnd + ":" + msg.message;                              
3776                                 if (messageHold[key] != null) {
3777                                         messageHold[key] = ((int)messageHold[key]) - 1;
3778                                         DebugHelper.WriteLine  ("Got " + msg + " for " + key);
3779                                 }
3780                         }
3781
3782                         in_doevents = false;
3783                         queue.DispatchIdle = true;
3784
3785                         DebugHelper.Leave ();
3786                 }
3787
3788                 internal override void EnableWindow(IntPtr handle, bool Enable)
3789                 {
3790                         Hwnd    hwnd;
3791
3792                         hwnd = Hwnd.ObjectFromHandle(handle);
3793                         if (hwnd != null) {
3794                                 hwnd.Enabled = Enable;
3795                         }
3796                 }
3797
3798                 internal override void EndLoop(Thread thread)
3799                 {
3800                         // This is where we one day will shut down the loop for the thread
3801                 }
3802
3803                 internal override IntPtr GetActive()
3804                 {
3805                         IntPtr  actual_atom;
3806                         int     actual_format;
3807                         IntPtr  nitems;
3808                         IntPtr  bytes_after;
3809                         IntPtr  prop = IntPtr.Zero;
3810                         IntPtr  active = IntPtr.Zero;
3811
3812                         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);
3813                         if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
3814                                 active = (IntPtr)Marshal.ReadInt32(prop);
3815                                 XFree(prop);
3816                         } else {
3817                                 // The window manager does not support _NET_ACTIVE_WINDOW.  Fall back to XGetInputFocus.
3818                                 IntPtr  revert_to = IntPtr.Zero;
3819                                 XGetInputFocus(DisplayHandle, out active, out revert_to);
3820                         }
3821
3822                         if (active != IntPtr.Zero) {
3823                                 Hwnd    hwnd;
3824
3825                                 hwnd = Hwnd.GetObjectFromWindow(active);
3826                                 if (hwnd != null) {
3827                                         active = hwnd.Handle;
3828                                 } else {
3829                                         active = IntPtr.Zero;
3830                                 }
3831                         }
3832                         return active;
3833                 }
3834
3835                 internal override Region GetClipRegion(IntPtr handle)
3836                 {
3837                         Hwnd    hwnd;
3838
3839                         hwnd = Hwnd.ObjectFromHandle(handle);
3840                         if (hwnd != null) {
3841                                 return hwnd.UserClip;
3842                         }
3843
3844                         return null;
3845                 }
3846
3847                 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
3848                 {
3849                         width = 20;
3850                         height = 20;
3851                         hotspot_x = 0;
3852                         hotspot_y = 0;
3853                 }
3854
3855                 internal override void GetDisplaySize(out Size size)
3856                 {
3857                         XWindowAttributes       attributes=new XWindowAttributes();
3858
3859                         lock (XlibLock) {
3860                                 // FIXME - use _NET_WM messages instead?
3861                                 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
3862                         }
3863
3864                         size = new Size(attributes.width, attributes.height);
3865                 }
3866
3867                 internal override SizeF GetAutoScaleSize(Font font)
3868                 {
3869                         Graphics        g;
3870                         float           width;
3871                         string          magic_string = "The quick brown fox jumped over the lazy dog.";
3872                         double          magic_number = 44.549996948242189;
3873
3874                         g = Graphics.FromHwnd(FosterParent);
3875
3876                         width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
3877                         return new SizeF(width, font.Height);
3878                 }
3879
3880                 internal override IntPtr GetParent(IntPtr handle)
3881                 {
3882                         Hwnd    hwnd;
3883
3884                         hwnd = Hwnd.ObjectFromHandle(handle);
3885                         if (hwnd != null && hwnd.parent != null) {
3886                                 return hwnd.parent.Handle;
3887                         }
3888                         return IntPtr.Zero;
3889                 }
3890                 
3891                 // This is a nop on win32 and x11
3892                 internal override IntPtr GetPreviousWindow(IntPtr handle)
3893                 {
3894                         return handle;
3895                 }
3896
3897                 internal override void GetCursorPos(IntPtr handle, out int x, out int y)
3898                 {
3899                         IntPtr  use_handle;
3900                         IntPtr  root;
3901                         IntPtr  child;
3902                         int     root_x;
3903                         int     root_y;
3904                         int     win_x;
3905                         int     win_y;
3906                         int     keys_buttons;
3907
3908                         if (handle != IntPtr.Zero) {
3909                                 use_handle = Hwnd.ObjectFromHandle(handle).client_window;
3910                         } else {
3911                                 use_handle = RootWindow;
3912                         }
3913
3914                         lock (XlibLock) {
3915                                 QueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
3916                         }
3917
3918                         if (handle != IntPtr.Zero) {
3919                                 x = win_x;
3920                                 y = win_y;
3921                         } else {
3922                                 x = root_x;
3923                                 y = root_y;
3924                         }
3925                 }
3926
3927                 internal override IntPtr GetFocus()
3928                 {
3929                         return FocusWindow;
3930                 }
3931
3932
3933                 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent)
3934                 {
3935                         FontFamily ff = font.FontFamily;
3936                         ascent = ff.GetCellAscent (font.Style);
3937                         descent = ff.GetCellDescent (font.Style);
3938                         return true;
3939                 }
3940
3941                 internal override Point GetMenuOrigin(IntPtr handle)
3942                 {
3943                         Hwnd    hwnd;
3944
3945                         hwnd = Hwnd.ObjectFromHandle(handle);
3946
3947                         if (hwnd != null) {
3948                                 return hwnd.MenuOrigin;
3949                         }
3950                         return Point.Empty;
3951                 }
3952
3953                 [MonoTODO("Implement filtering")]
3954                 internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
3955                 {
3956                         XEvent  xevent;
3957                         bool    client;
3958                         Hwnd    hwnd;
3959
3960                         ProcessNextMessage:
3961
3962                         if (((XEventQueue)queue_id).Count > 0) {
3963                                 xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3964                         } else {
3965                                 UpdateMessageQueue ((XEventQueue)queue_id);
3966
3967                                 if (((XEventQueue)queue_id).Count > 0) {
3968                                         xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3969                                 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
3970                                         xevent = ((XEventQueue)queue_id).Paint.Dequeue();
3971                                 } else {
3972                                         msg.hwnd= IntPtr.Zero;
3973                                         msg.message = Msg.WM_ENTERIDLE;
3974                                         return true;
3975                                 }
3976                         }
3977
3978                         hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
3979
3980 #if DriverDebugDestroy                  
3981                         if (hwnd != null)
3982                                 if (hwnd.zombie)
3983                                         Console.WriteLine ( "GetMessage zombie, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
3984                                 else    
3985                                         Console.WriteLine ( "GetMessage, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
3986 #endif
3987                         // Handle messages for windows that are already or are about to be destroyed.
3988
3989                         // we need a special block for this because unless we remove the hwnd from the paint
3990                         // queue it will always stay there (since we don't handle the expose), and we'll
3991                         // effectively loop infinitely trying to repaint a non-existant window.
3992                         if (hwnd != null && hwnd.zombie && xevent.type == XEventName.Expose) {
3993                                 hwnd.expose_pending = hwnd.nc_expose_pending = false;
3994                                 hwnd.Queue.Paint.Remove (hwnd);
3995                                 goto ProcessNextMessage;
3996                         }
3997
3998                         // We need to make sure we only allow DestroyNotify events through for zombie
3999                         // hwnds, since much of the event handling code makes requests using the hwnd's
4000                         // client_window, and that'll result in BadWindow errors if there's some lag
4001                         // between the XDestroyWindow call and the DestroyNotify event.
4002                         if (hwnd == null || hwnd.zombie && xevent.AnyEvent.type != XEventName.ClientMessage) {
4003                                 DriverDebug("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
4004                                 goto ProcessNextMessage;
4005                         }
4006
4007
4008                         // If we get here, that means the window is no more but there are Client Messages
4009                         // to be processed, probably a Posted message (for instance, an WM_ACTIVATE message) 
4010                         // We don't want anything else to run but the ClientMessage block, so reset all hwnd
4011                         // properties that might cause other processing to occur.
4012                         if (hwnd.zombie) {
4013                                 hwnd.resizing_or_moving = false;
4014                         }
4015
4016                         if (hwnd.client_window == xevent.AnyEvent.window) {
4017                                 client = true;
4018                                 //Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
4019                         } else {
4020                                 client = false;
4021                                 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
4022                         }
4023
4024                         msg.hwnd = hwnd.Handle;
4025
4026                         // Windows sends WM_ENTERSIZEMOVE when a form resize/move operation starts and WM_EXITSIZEMOVE 
4027                         // when it is done. The problem in X11 is that there is no concept of start-end of a moving/sizing.
4028                         // Configure events ("this window has resized/moved") are sent for each step of the resize. We send a
4029                         // WM_ENTERSIZEMOVE when we get the first Configure event. The problem is the WM_EXITSIZEMOVE.
4030                         // 
4031                         //  - There is no way for us to know which is the last Configure event. We can't traverse the events 
4032                         //    queue, because the next configure event might not be pending yet.
4033                         //  - We can't get ButtonPress/Release events for the window decorations, because they are not part 
4034                         //    of the window(s) we manage.
4035                         //  - We can't rely on the mouse state to change to "up" before the last Configure event. It doesn't.
4036                         // 
4037                         // We are almost 100% guaranteed to get another event (e.g Expose or other), but we can't know for sure 
4038                         // which, so we have here to check if the mouse buttons state is "up" and send the WM_EXITSIZEMOVE
4039                         //
4040                         if (hwnd.resizing_or_moving) {
4041                                 int root_x, root_y, win_x, win_y, keys_buttons;
4042                                 IntPtr  root, child;
4043                                 XQueryPointer (DisplayHandle, hwnd.Handle, out root, out child, out root_x, out root_y, 
4044                                                out win_x, out win_y, out keys_buttons);
4045                                 if ((keys_buttons & (int)MouseKeyMasks.Button1Mask) == 0 &&
4046                                     (keys_buttons & (int)MouseKeyMasks.Button2Mask) == 0 &&
4047                                     (keys_buttons & (int)MouseKeyMasks.Button3Mask) == 0) {
4048                                         hwnd.resizing_or_moving = false;
4049                                         SendMessage (hwnd.Handle, Msg.WM_EXITSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
4050                                 }
4051                         }
4052
4053                         //
4054                         // If you add a new event to this switch make sure to add it in
4055                         // UpdateMessage also unless it is not coming through the X event system.
4056                         //
4057                         switch(xevent.type) {
4058                                 case XEventName.KeyPress: {
4059                                         Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
4060
4061                                         // F1 key special case - WM_HELP sending
4062                                         if (msg.wParam == (IntPtr)VirtualKeys.VK_F1 || msg.wParam == (IntPtr)VirtualKeys.VK_HELP) {
4063                                                 // Send wM_HELP and then return it as a keypress message in
4064                                                 // case it needs to be preproccessed.
4065                                                 HELPINFO helpInfo = new HELPINFO ();
4066                                                 GetCursorPos (IntPtr.Zero, out helpInfo.MousePos.x, out helpInfo.MousePos.y);
4067                                                 IntPtr helpInfoPtr = Marshal.AllocHGlobal (Marshal.SizeOf (helpInfo));
4068                                                 Marshal.StructureToPtr (helpInfo, helpInfoPtr, true);
4069                                                 NativeWindow.WndProc (FocusWindow, Msg.WM_HELP, IntPtr.Zero, helpInfoPtr);
4070                                                 Marshal.FreeHGlobal (helpInfoPtr);
4071                                         }
4072                                         break;
4073                                 }
4074
4075                                 case XEventName.KeyRelease: {
4076                                         Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
4077                                         break;
4078                                 }
4079
4080                                 case XEventName.ButtonPress: {
4081                                         switch(xevent.ButtonEvent.button) {
4082                                                 case 1: {
4083                                                         MouseState |= MouseButtons.Left;
4084                                                         if (client) {
4085                                                                 msg.message = Msg.WM_LBUTTONDOWN;
4086                                                                 msg.wParam = GetMousewParam (0);
4087                                                         } else {
4088                                                                 msg.message = Msg.WM_NCLBUTTONDOWN;
4089                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4090                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4091                                                         }
4092                                                         break;
4093                                                 }
4094
4095                                                 case 2: {
4096                                                         MouseState |= MouseButtons.Middle;
4097                                                         if (client) {
4098                                                                 msg.message = Msg.WM_MBUTTONDOWN;
4099                                                                 msg.wParam = GetMousewParam (0);
4100                                                         } else {
4101                                                                 msg.message = Msg.WM_NCMBUTTONDOWN;
4102                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4103                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4104                                                         }
4105                                                         break;
4106                                                 }
4107
4108                                                 case 3: {
4109                                                         MouseState |= MouseButtons.Right;
4110                                                         if (client) {
4111                                                                 msg.message = Msg.WM_RBUTTONDOWN;
4112                                                                 msg.wParam = GetMousewParam (0);
4113                                                         } else {
4114                                                                 msg.message = Msg.WM_NCRBUTTONDOWN;
4115                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4116                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4117                                                         }
4118                                                         break;
4119                                                 }
4120
4121                                                 case 4: {
4122                                                         msg.hwnd = FocusWindow;
4123                                                         msg.message=Msg.WM_MOUSEWHEEL;
4124                                                         msg.wParam=GetMousewParam(120);
4125                                                         break;
4126                                                 }
4127
4128                                                 case 5: {
4129                                                         msg.hwnd = FocusWindow;
4130                                                         msg.message=Msg.WM_MOUSEWHEEL;
4131                                                         msg.wParam=GetMousewParam(-120);
4132                                                         break;
4133                                                 }
4134
4135                                         }
4136
4137                                         msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
4138                                         mouse_position.X = xevent.ButtonEvent.x;
4139                                         mouse_position.Y = xevent.ButtonEvent.y;
4140
4141                                         if (!hwnd.Enabled) {
4142                                                 IntPtr dummy;
4143
4144                                                 msg.hwnd = hwnd.EnabledHwnd;
4145                                                 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);
4146                                                 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4147                                         }
4148
4149                                         if (Grab.Hwnd != IntPtr.Zero) {
4150                                                 msg.hwnd = Grab.Hwnd;
4151                                         }
4152
4153                                         if (ClickPending.Pending && ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message))) {
4154                                                 // Looks like a genuine double click, clicked twice on the same spot with the same keys
4155                                                 switch(xevent.ButtonEvent.button) {
4156                                                         case 1: {
4157                                                                 msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
4158                                                                 break;
4159                                                         }
4160
4161                                                         case 2: {
4162                                                                 msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
4163                                                                 break;
4164                                                         }
4165
4166                                                         case 3: {
4167                                                                 msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
4168                                                                 break;
4169                                                         }
4170                                                 }
4171                                                 ClickPending.Pending = false;
4172                                         } else {
4173                                                 ClickPending.Pending = true;
4174                                                 ClickPending.Hwnd = msg.hwnd;
4175                                                 ClickPending.Message = msg.message;
4176                                                 ClickPending.wParam = msg.wParam;
4177                                                 ClickPending.lParam = msg.lParam;
4178                                                 ClickPending.Time = (long)xevent.ButtonEvent.time;
4179                                         }
4180                                         
4181                                         if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN) {
4182                                                 SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
4183                                         }
4184                                         
4185                                         break;
4186                                 }
4187
4188                                 case XEventName.ButtonRelease: {
4189                                         switch(xevent.ButtonEvent.button) {
4190                                                 case 1: {
4191                                                         if (client) {
4192                                                                 msg.message = Msg.WM_LBUTTONUP;
4193                                                         } else {
4194                                                                 msg.message = Msg.WM_NCLBUTTONUP;
4195                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4196                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4197                                                         }
4198                                                         MouseState &= ~MouseButtons.Left;
4199                                                         msg.wParam = GetMousewParam (0);
4200                                                         break;
4201                                                 }
4202
4203                                                 case 2: {
4204                                                         if (client) {
4205                                                                 msg.message = Msg.WM_MBUTTONUP;
4206                                                         } else {
4207                                                                 msg.message = Msg.WM_NCMBUTTONUP;
4208                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4209                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4210                                                         }
4211                                                         MouseState &= ~MouseButtons.Middle;
4212                                                         msg.wParam = GetMousewParam (0);
4213                                                         break;
4214                                                 }
4215
4216                                                 case 3: {
4217                                                         if (client) {
4218                                                                 msg.message = Msg.WM_RBUTTONUP;
4219                                                         } else {
4220                                                                 msg.message = Msg.WM_NCRBUTTONUP;
4221                                                                 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4222                                                                 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4223                                                         }
4224                                                         MouseState &= ~MouseButtons.Right;
4225                                                         msg.wParam = GetMousewParam (0);
4226                                                         break;
4227                                                 }
4228
4229                                                 case 4: {
4230                                                         goto ProcessNextMessage;
4231                                                 }
4232
4233                                                 case 5: {
4234                                                         goto ProcessNextMessage;
4235                                                 }
4236                                         }
4237
4238                                         if (!hwnd.Enabled) {
4239                                                 IntPtr dummy;
4240
4241                                                 msg.hwnd = hwnd.EnabledHwnd;
4242                                                 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);
4243                                                 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4244                                         }
4245
4246                                         if (Grab.Hwnd != IntPtr.Zero) {
4247                                                 msg.hwnd = Grab.Hwnd;
4248                                         }
4249
4250                                         msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
4251                                         mouse_position.X = xevent.ButtonEvent.x;
4252                                         mouse_position.Y = xevent.ButtonEvent.y;
4253
4254                                         // Win32 splurts MouseMove events all over the place, regardless of whether the mouse is actually moving or
4255                                         // not, especially after mousedown and mouseup. To support apps relying on mousemove events between and after 
4256                                         // mouse clicks to repaint or whatever, we generate a mousemove event here. *sigh*
4257                                         if (msg.message == Msg.WM_LBUTTONUP || msg.message == Msg.WM_MBUTTONUP || msg.message == Msg.WM_RBUTTONUP) {
4258                                                 XEvent motionEvent = new XEvent ();
4259                                                 motionEvent.type = XEventName.MotionNotify;
4260                                                 motionEvent.MotionEvent.display = DisplayHandle;
4261                                                 motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4262                                                 motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4263                                                 motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4264                                                 hwnd.Queue.EnqueueLocked (motionEvent);
4265                                         }
4266                                         break;
4267                                 }
4268
4269                                 case XEventName.MotionNotify: {
4270                                         if (client) {
4271                                                 DriverDebug("GetMessage(): Window {0:X} MotionNotify x={1} y={2}",
4272                                                             client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
4273                                                             xevent.MotionEvent.x, xevent.MotionEvent.y);
4274
4275                                                 if (Grab.Hwnd != IntPtr.Zero) {
4276                                                         msg.hwnd = Grab.Hwnd;
4277                                                 } else {
4278                                                         if (hwnd.Enabled) {
4279                                                                 NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
4280                                                         }
4281                                                 }
4282
4283                                                 if (xevent.MotionEvent.is_hint != 0)
4284                                                 {
4285                                                         IntPtr root, child;
4286                                                         int mask;
4287                                                         XQueryPointer (DisplayHandle, xevent.AnyEvent.window,
4288                                                                                         out root, out child,
4289                                                                                         out xevent.MotionEvent.x_root, 
4290                                                                                         out xevent.MotionEvent.y_root,
4291                                                                                         out xevent.MotionEvent.x,      
4292                                                                                         out xevent.MotionEvent.y, out mask);
4293                                                 }
4294
4295                                                 msg.message = Msg.WM_MOUSEMOVE;
4296                                                 msg.wParam = GetMousewParam(0);
4297                                                 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
4298
4299                                                 if (!hwnd.Enabled) {
4300                                                         IntPtr dummy;
4301
4302                                                         msg.hwnd = hwnd.EnabledHwnd;
4303                                                         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);
4304                                                         msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4305                                                 }
4306
4307                                                 mouse_position.X = xevent.MotionEvent.x;
4308                                                 mouse_position.Y = xevent.MotionEvent.y;
4309
4310                                                 if ((HoverState.Timer.Enabled) &&
4311                                                     (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
4312                                                     ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
4313                                                     ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
4314                                                     ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
4315                                                         HoverState.Timer.Stop();
4316                                                         HoverState.Timer.Start();
4317                                                         HoverState.X = mouse_position.X;
4318                                                         HoverState.Y = mouse_position.Y;
4319                                                 }
4320
4321                                                 break;
4322                                         } else {
4323                                                 HitTest ht;
4324                                                 IntPtr dummy;
4325
4326                                                 DriverDebug("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}",
4327                                                             client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
4328                                                             xevent.MotionEvent.x, xevent.MotionEvent.y);
4329                                                 msg.message = Msg.WM_NCMOUSEMOVE;
4330
4331                                                 if (!hwnd.Enabled) {
4332                                                         msg.hwnd = hwnd.EnabledHwnd;
4333                                                         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);
4334                                                         msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4335                                                 }
4336
4337                                                 ht = NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4338                                                 NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
4339
4340                                                 mouse_position.X = xevent.MotionEvent.x;
4341                                                 mouse_position.Y = xevent.MotionEvent.y;
4342                                         }
4343
4344                                         break;
4345                                 }
4346
4347                                 case XEventName.EnterNotify: {
4348                                         if (!hwnd.Enabled) {
4349                                                 goto ProcessNextMessage;
4350                                         }
4351                                         if (xevent.CrossingEvent.mode == NotifyMode.NotifyGrab || xevent.AnyEvent.window != hwnd.client_window) {
4352                                                 goto ProcessNextMessage;
4353                                         }
4354                                         if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) { // Pseudo motion caused by grabbing
4355                                                 if (LastPointerWindow == xevent.AnyEvent.window)
4356                                                         goto ProcessNextMessage;
4357
4358                                                 if (LastPointerWindow != IntPtr.Zero) {
4359                                                         Point enter_loc = new Point (xevent.ButtonEvent.x, xevent.ButtonEvent.y);
4360
4361                                                         // We need this due to EnterNotify being fired on all the parent controls
4362                                                         // of the Control being grabbed, and obviously in that scenario we are not
4363                                                         // actuallty entering them
4364                                                         Control ctrl = Control.FromHandle (hwnd.client_window);
4365                                                         foreach (Control child_control in ctrl.Controls.GetAllControls ())
4366                                                                 if (child_control.Bounds.Contains (enter_loc))
4367                                                                         goto ProcessNextMessage;
4368
4369                                                         // A MouseLeave/LeaveNotify event is sent to the previous window
4370                                                         // until the mouse is ungrabbed, not when actually leaving its bounds
4371                                                         int x = xevent.CrossingEvent.x_root;
4372                                                         int y = xevent.CrossingEvent.y_root;
4373                                                         ScreenToClient (LastPointerWindow, ref x, ref y);
4374
4375                                                         XEvent leaveEvent = new XEvent ();
4376                                                         leaveEvent.type = XEventName.LeaveNotify;
4377                                                         leaveEvent.CrossingEvent.display = DisplayHandle;
4378                                                         leaveEvent.CrossingEvent.window = LastPointerWindow;
4379                                                         leaveEvent.CrossingEvent.x = x;
4380                                                         leaveEvent.CrossingEvent.y = y;
4381                                                         leaveEvent.CrossingEvent.mode = NotifyMode.NotifyNormal;
4382                                                         Hwnd last_pointer_hwnd = Hwnd.ObjectFromHandle (LastPointerWindow);
4383                                                         last_pointer_hwnd.Queue.EnqueueLocked (leaveEvent);
4384                                                 }
4385                                         }
4386
4387                                         LastPointerWindow = xevent.AnyEvent.window;
4388
4389                                         msg.message = Msg.WM_MOUSE_ENTER;
4390                                         HoverState.X = xevent.CrossingEvent.x;
4391                                         HoverState.Y = xevent.CrossingEvent.y;
4392                                         HoverState.Timer.Enabled = true;
4393                                         HoverState.Window = xevent.CrossingEvent.window;
4394
4395                                         // Win32 sends a WM_MOUSEMOVE after mouse enter
4396                                         XEvent motionEvent = new XEvent ();
4397                                         motionEvent.type = XEventName.MotionNotify;
4398                                         motionEvent.MotionEvent.display = DisplayHandle;
4399                                         motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4400                                         motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4401                                         motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4402                                         hwnd.Queue.EnqueueLocked (motionEvent);
4403                                         break;
4404                                 }
4405
4406                                 case XEventName.LeaveNotify: {
4407                                         if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) {
4408                                                 WindowUngrabbed (hwnd.Handle);
4409                                                 goto ProcessNextMessage;
4410                                         }
4411                                         if (!hwnd.Enabled) {
4412                                                 goto ProcessNextMessage;
4413                                         }
4414                                         if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
4415                                                 goto ProcessNextMessage;
4416                                         }
4417                                         // If a grab is taking place, ignore it - we handle it in EnterNotify
4418                                         if (Grab.Hwnd != IntPtr.Zero)
4419                                                 goto ProcessNextMessage;
4420
4421                                         // Reset the cursor explicitly on X11.
4422                                         // X11 remembers the last set cursor for the window and in cases where 
4423                                         // the control won't get a WM_SETCURSOR X11 will restore the last 
4424                                         // known cursor, which we don't want.
4425                                         // 
4426                                         SetCursor (hwnd.client_window, IntPtr.Zero);
4427
4428                                         msg.message=Msg.WM_MOUSELEAVE;
4429                                         HoverState.Timer.Enabled = false;
4430                                         HoverState.Window = IntPtr.Zero;
4431                                         break;
4432                                 }
4433
4434                                 #if later
4435                                 case XEventName.CreateNotify: {
4436                                         if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
4437                                                 msg.message = WM_CREATE;
4438                                                 // Set up CreateStruct
4439                                         } else {
4440                                                 goto ProcessNextMessage;
4441                                         }
4442                                         break;
4443                                 }
4444                                 #endif
4445
4446
4447                                 case XEventName.ReparentNotify: {
4448                                         if (hwnd.parent == null) {      // Toplevel
4449                                                 if ((xevent.ReparentEvent.parent != IntPtr.Zero) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
4450                                                         hwnd.Reparented = true;
4451
4452                                                         // The location given by the event is not reliable between different wm's, 
4453                                                         // so use an alternative way of getting it.
4454                                                         Point location = GetTopLevelWindowLocation (hwnd);
4455                                                         hwnd.X = location.X;
4456                                                         hwnd.Y = location.Y;
4457
4458                                                         if (hwnd.opacity != 0xffffffff) {
4459                                                                 IntPtr opacity;
4460
4461                                                                 opacity = (IntPtr)(Int32)hwnd.opacity;
4462                                                                 XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
4463                                                         }
4464                                                         SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, msg.wParam, msg.lParam);
4465                                                         goto ProcessNextMessage;
4466                                                 } else {
4467                                                         hwnd.Reparented = false;
4468                                                         goto ProcessNextMessage;
4469                                                 }
4470                                         }
4471                                         goto ProcessNextMessage;
4472                                 }
4473
4474                                 case XEventName.ConfigureNotify: {
4475                                         if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {        // Ignore events for children (SubstructureNotify) and client areas
4476                                                 DriverDebug("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}",
4477                                                             hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x,
4478                                                             xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
4479
4480                                                 lock (hwnd.configure_lock) {
4481                                                         Form form = Control.FromHandle (hwnd.client_window) as Form;
4482                                                         if (form != null && !hwnd.resizing_or_moving) {
4483                                                                 if (hwnd.x != form.Bounds.X || hwnd.y != form.Bounds.Y) {
4484                                                                         SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_MOVE, IntPtr.Zero);
4485                                                                         hwnd.resizing_or_moving = true;
4486                                                                 } else if (hwnd.width != form.Bounds.Width || hwnd.height != form.Bounds.Height) {
4487                                                                         SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_SIZE, IntPtr.Zero);
4488                                                                         hwnd.resizing_or_moving = true;
4489                                                                 }
4490                                                                 if (hwnd.resizing_or_moving)
4491                                                                         SendMessage (form.Handle, Msg.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
4492                                                         }
4493         
4494                                                         SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4495                                                         hwnd.configure_pending = false;
4496         
4497                                                         // We need to adjust our client window to track the resize of whole_window
4498                                                         if (hwnd.whole_window != hwnd.client_window)
4499                                                                 PerformNCCalc(hwnd);
4500                                                 }
4501                                         }
4502                                         goto ProcessNextMessage;
4503                                 }
4504
4505                                 case XEventName.FocusIn: {
4506                                         // We received focus. We use X11 focus only to know if the app window does or does not have focus
4507                                         // We do not track the actual focussed window via it. Instead, this is done via FocusWindow internally
4508                                         // Receiving focus means we've gotten activated and therefore we need to let the actual FocusWindow know 
4509                                         // about it having focus again
4510                                         if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4511                                                 goto ProcessNextMessage;
4512                                         }
4513
4514                                         
4515                                         if (FocusWindow == IntPtr.Zero) {
4516                                                 Control c = Control.FromHandle (hwnd.client_window);
4517
4518                                                 if (c == null)
4519                                                         goto ProcessNextMessage;                                                
4520                                                 Form form = c.FindForm ();
4521                                                 if (form == null)
4522                                                         goto ProcessNextMessage;
4523                                         
4524                                                 if (ActiveWindow != form.Handle) {
4525                                                         ActiveWindow = form.Handle;
4526                                                         SendMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr) WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
4527                                                 }
4528                                                 goto ProcessNextMessage;
4529                                         }
4530                                         Keyboard.FocusIn (FocusWindow);
4531                                         SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
4532                                         goto ProcessNextMessage;
4533                                 }
4534
4535                                 case XEventName.FocusOut: {
4536                                         // Se the comment for our FocusIn handler
4537                                         if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4538                                                 goto ProcessNextMessage;
4539                                         }
4540
4541                                         while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
4542                                                 SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
4543                                         }
4544
4545                                         Keyboard.FocusOut(hwnd.client_window);
4546                                         SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
4547                                         goto ProcessNextMessage;
4548                                 }
4549
4550                                 // We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
4551                                 // in case we break a scenario not taken into account in the tests
4552                                 case XEventName.MapNotify: {
4553                                         /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
4554                                                 hwnd.mapped = true;
4555                                                 msg.message = Msg.WM_SHOWWINDOW;
4556                                                 msg.wParam = (IntPtr) 1;
4557                                                 // XXX we're missing the lParam..
4558                                                 break;
4559                                         }*/
4560                                         goto ProcessNextMessage;
4561                                 }
4562
4563                                 case XEventName.UnmapNotify: {
4564                                         /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {       // Ignore events for children (SubstructureNotify) and client areas
4565                                                 hwnd.mapped = false;
4566                                                 msg.message = Msg.WM_SHOWWINDOW;
4567                                                 msg.wParam = (IntPtr) 0;
4568                                                 // XXX we're missing the lParam..
4569                                                 break;
4570                                         }*/
4571                                         goto ProcessNextMessage;
4572                                 }
4573
4574                                 case XEventName.Expose: {
4575                                         if (!hwnd.Mapped) {
4576                                                 if (client) {
4577                                                         hwnd.expose_pending = false;
4578                                                 } else {
4579                                                         hwnd.nc_expose_pending = false;
4580                                                 }
4581                                                 goto ProcessNextMessage;
4582                                         }
4583
4584                                         if (client) {
4585                                                 if (!hwnd.expose_pending) {
4586                                                         goto ProcessNextMessage;
4587                                                 }
4588                                         } else {
4589                                                 if (!hwnd.nc_expose_pending) {
4590                                                         goto ProcessNextMessage;
4591                                                 }
4592
4593                                                 switch (hwnd.border_style) {
4594                                                         case FormBorderStyle.Fixed3D: {
4595                                                                 Graphics g;
4596
4597                                                                 g = Graphics.FromHwnd(hwnd.whole_window);
4598                                                                 if (hwnd.border_static)
4599                                                                         ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.SunkenOuter);
4600                                                                 else
4601                                                                         ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
4602                                                                 g.Dispose();
4603                                                                 break;
4604                                                         }
4605
4606                                                         case FormBorderStyle.FixedSingle: {
4607                                                                 Graphics g;
4608
4609                                                                 g = Graphics.FromHwnd(hwnd.whole_window);
4610                                                                 ControlPaint.DrawBorder(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
4611                                                                 g.Dispose();
4612                                                                 break;
4613                                                         }
4614                                                 }
4615                                                 DriverDebug("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}",
4616                                                             hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
4617                                                             xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4618
4619                                                 Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4620                                                 Region region = new Region (rect);
4621                                                 IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
4622                                                 msg.message = Msg.WM_NCPAINT;
4623                                                 msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
4624                                                 msg.refobject = region;
4625                                                 break;
4626                                         }
4627                                         DriverDebug("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}",
4628                                                     hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
4629                                                     xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4630                                         if (Caret.Visible == true) {
4631                                                 Caret.Paused = true;
4632                                                 HideCaret();
4633                                         }
4634
4635                                         if (Caret.Visible == true) {
4636                                                 ShowCaret();
4637                                                 Caret.Paused = false;
4638                                         }
4639                                         msg.message = Msg.WM_PAINT;
4640                                         break;
4641                                 }
4642
4643                                 case XEventName.DestroyNotify: {
4644
4645                                         // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
4646                                         hwnd = Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
4647
4648                                         // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
4649                                         if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
4650                                                 CleanupCachedWindows (hwnd);
4651
4652                                                 DriverDebug("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
4653
4654                                                 msg.hwnd = hwnd.client_window;
4655                                                 msg.message=Msg.WM_DESTROY;
4656                                                 hwnd.Dispose();
4657                                         } else {
4658                                                 goto ProcessNextMessage;
4659                                         }
4660
4661                                         break;
4662                                 }
4663
4664                                 case XEventName.ClientMessage: {
4665                                         if (Dnd.HandleClientMessage (ref xevent)) {
4666                                                 goto ProcessNextMessage;
4667                                         }
4668
4669                                         if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
4670                                                 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
4671                                                 goto ProcessNextMessage;
4672                                         }
4673
4674                                         if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
4675                                                 msg.message = Msg.WM_MOUSEHOVER;
4676                                                 msg.wParam = GetMousewParam(0);
4677                                                 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
4678                                                 return true;
4679                                         }
4680
4681                                         if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {                                               
4682                                                 DebugHelper.Indent ();
4683                                                 DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
4684                                                 DebugHelper.Unindent ();
4685                                                 msg.hwnd = xevent.ClientMessageEvent.ptr1;
4686                                                 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
4687                                                 msg.wParam = xevent.ClientMessageEvent.ptr3;
4688                                                 msg.lParam = xevent.ClientMessageEvent.ptr4;
4689                                                 if (msg.message == (Msg)Msg.WM_QUIT)
4690                                                         return false;
4691                                                 else
4692                                                         return true;
4693                                         }
4694
4695                                         if  (xevent.ClientMessageEvent.message_type == _XEMBED) {
4696 #if DriverDebugXEmbed
4697                                                 Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
4698 #endif
4699
4700                                                 if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
4701                                                         XSizeHints hints = new XSizeHints();
4702                                                         IntPtr dummy;
4703
4704                                                         XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
4705
4706                                                         hwnd.width = hints.max_width;
4707                                                         hwnd.height = hints.max_height;
4708                                                         hwnd.ClientRect = Rectangle.Empty;
4709                                                         SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4710                                                 }
4711                                         }
4712
4713                                         if  (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
4714                                                 if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
4715                                                         SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
4716                                                         msg.message = Msg.WM_CLOSE;
4717                                                         return true;
4718                                                 }
4719
4720                                                 // We should not get this, but I'll leave the code in case we need it in the future
4721                                                 if (xevent.ClientMessageEvent.ptr1 == WM_TAKE_FOCUS) {
4722                                                         goto ProcessNextMessage;
4723                                                 }
4724                                         }
4725                                         goto ProcessNextMessage;
4726                                 }
4727
4728                                 default: {
4729                                         goto ProcessNextMessage;
4730                                 }
4731                         }
4732
4733                         return true;
4734                 }
4735
4736                 HitTest NCHitTest (Hwnd hwnd, int x, int y)
4737                 {
4738                         // The hit test is sent in screen coordinates
4739                         IntPtr dummy;
4740                         int screen_x, screen_y;
4741                         XTranslateCoordinates (DisplayHandle, hwnd.WholeWindow, RootWindow, x, y, out screen_x, out screen_y, out dummy);
4742                         return (HitTest) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, 
4743                                                                (IntPtr) (screen_y << 16 | screen_x & 0xFFFF));
4744                 }
4745
4746                 // Our very basic implementation of MoveResize - we can extend it later
4747                 // *if* needed
4748                 internal override void BeginMoveResize (IntPtr handle)
4749                 {
4750                         // We *need* to ungrab the pointer in the current display
4751                         XplatUI.UngrabWindow (Grab.Hwnd);
4752
4753                         int x_root, y_root;
4754                         GetCursorPos (IntPtr.Zero, out x_root, out y_root);
4755
4756                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4757                         SendNetWMMessage (hwnd.whole_window, _NET_WM_MOVERESIZE, (IntPtr) x_root, (IntPtr) y_root,
4758                                         (IntPtr) NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, 
4759                                         (IntPtr) 1); // left button
4760                 }
4761
4762                 internal override bool GetText(IntPtr handle, out string text)
4763                 {
4764
4765                         lock (XlibLock) {
4766                                 IntPtr actual_atom;
4767                                 int actual_format;
4768                                 IntPtr nitems;
4769                                 IntPtr bytes_after;
4770                                 IntPtr prop = IntPtr.Zero;
4771
4772                                 XGetWindowProperty(DisplayHandle, handle,
4773                                                    _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
4774                                                    UTF8_STRING, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
4775
4776                                 if ((long)nitems > 0 && prop != IntPtr.Zero) {
4777                                         text = Marshal.PtrToStringUni (prop, (int)nitems);
4778                                         XFree (prop);
4779                                         return true;
4780                                 }
4781                                 else {
4782                                         // fallback on the non-_NET property
4783                                         IntPtr  textptr;
4784
4785                                         textptr = IntPtr.Zero;
4786
4787                                         XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
4788                                         if (textptr != IntPtr.Zero) {
4789                                                 text = Marshal.PtrToStringAnsi(textptr);
4790                                                 XFree(textptr);
4791                                                 return true;
4792                                         } else {
4793                                                 text = "";
4794                                                 return false;
4795                                         }
4796                                 }
4797                         }
4798                 }
4799
4800                 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)
4801                 {
4802                         Hwnd            hwnd;
4803
4804                         hwnd = Hwnd.ObjectFromHandle(handle);
4805
4806                         if (hwnd != null) {
4807                                 x = hwnd.x;
4808                                 y = hwnd.y;
4809                                 width = hwnd.width;
4810                                 height = hwnd.height;
4811
4812                                 PerformNCCalc(hwnd);
4813
4814                                 client_width = hwnd.ClientRect.Width;
4815                                 client_height = hwnd.ClientRect.Height;
4816
4817                                 return;
4818                         }
4819
4820                         // Should we throw an exception or fail silently?
4821                         // throw new ArgumentException("Called with an invalid window handle", "handle");
4822
4823                         x = 0;
4824                         y = 0;
4825                         width = 0;
4826                         height = 0;
4827                         client_width = 0;
4828                         client_height = 0;
4829                 }
4830
4831                 internal override FormWindowState GetWindowState(IntPtr handle)
4832                 {
4833                         Hwnd                    hwnd;
4834
4835                         hwnd = Hwnd.ObjectFromHandle(handle);
4836
4837                         if (hwnd.cached_window_state == (FormWindowState)(-1))
4838                                 hwnd.cached_window_state = UpdateWindowState (handle);
4839
4840                         return hwnd.cached_window_state;
4841                 }
4842
4843                 FormWindowState UpdateWindowState (IntPtr handle) {
4844                         IntPtr                  actual_atom;
4845                         int                     actual_format;
4846                         IntPtr                  nitems;
4847                         IntPtr                  bytes_after;
4848                         IntPtr                  prop = IntPtr.Zero;
4849                         IntPtr                  atom;
4850                         int                     maximized;
4851                         bool                    minimized;
4852                         XWindowAttributes       attributes;
4853                         Hwnd                    hwnd;
4854
4855                         hwnd = Hwnd.ObjectFromHandle(handle);
4856
4857                         maximized = 0;
4858                         minimized = false;
4859                         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);
4860                         if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
4861                                 for (int i = 0; i < (long)nitems; i++) {
4862                                         atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
4863                                         if ((atom == _NET_WM_STATE_MAXIMIZED_HORZ) || (atom == _NET_WM_STATE_MAXIMIZED_VERT)) {
4864                                                 maximized++;
4865                                         } else if (atom == _NET_WM_STATE_HIDDEN) {
4866                                                 minimized = true;
4867                                         }
4868                                 }
4869                                 XFree(prop);
4870                         }
4871
4872                         if (minimized) {
4873                                 return FormWindowState.Minimized;
4874                         } else if (maximized == 2) {
4875                                 return FormWindowState.Maximized;
4876                         }
4877
4878                         attributes = new XWindowAttributes();
4879                         XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4880                         if (attributes.map_state == MapState.IsUnmapped) {
4881                                 return (FormWindowState)(-1);
4882                         }
4883
4884
4885                         return FormWindowState.Normal;
4886                 }
4887
4888                 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
4889                 {
4890                         handle = Grab.Hwnd;
4891                         GrabConfined = Grab.Confined;
4892                         GrabArea = Grab.Area;
4893                 }
4894
4895                 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle)
4896                 {
4897                         Hwnd    hwnd;
4898                         IntPtr  confine_to_window;
4899
4900                         confine_to_window = IntPtr.Zero;
4901
4902                         if (confine_to_handle != IntPtr.Zero) {
4903                                 XWindowAttributes       attributes = new XWindowAttributes();
4904
4905                                 hwnd = Hwnd.ObjectFromHandle(confine_to_handle);
4906
4907                                 lock (XlibLock) {
4908                                         XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4909                                 }
4910                                 Grab.Area.X = attributes.x;
4911                                 Grab.Area.Y = attributes.y;
4912                                 Grab.Area.Width = attributes.width;
4913                                 Grab.Area.Height = attributes.height;
4914                                 Grab.Confined = true;
4915                                 confine_to_window = hwnd.client_window;
4916                         }
4917
4918                         Grab.Hwnd = handle;
4919
4920                         hwnd = Hwnd.ObjectFromHandle(handle);
4921
4922                         lock (XlibLock) {
4923                                 XGrabPointer(DisplayHandle, hwnd.client_window, false, 
4924                                         EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
4925                                         EventMask.ButtonReleaseMask | EventMask.PointerMotionMask | 
4926                                         EventMask.PointerMotionHintMask | EventMask.LeaveWindowMask,
4927                                         GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
4928                         }
4929                 }
4930
4931                 internal override void UngrabWindow(IntPtr hwnd)
4932                 {
4933                         lock (XlibLock) {
4934                                 XUngrabPointer(DisplayHandle, IntPtr.Zero);
4935                                 XFlush(DisplayHandle);
4936                         }
4937                         WindowUngrabbed (hwnd);                 
4938                 }
4939                 
4940                 void WindowUngrabbed (IntPtr hwnd) {
4941                         bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
4942                         
4943                         Grab.Hwnd = IntPtr.Zero;
4944                         Grab.Confined = false;
4945                         
4946                         if (was_grabbed) {
4947                                 // lparam should be the handle to the window gaining the mouse capture,
4948                                 // but X doesn't seem to give us that information.
4949                                 // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
4950                                 // X will send a NotifyUngrab, but since it comes late sometimes we're
4951                                 // calling WindowUngrabbed directly from UngrabWindow in order to send
4952                                 // this WM right away.
4953                                 SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
4954                         }
4955                 }
4956
4957                 internal override void HandleException(Exception e)
4958                 {
4959                         StackTrace st = new StackTrace(e, true);
4960                         Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
4961                         Console.WriteLine("{0}{1}", e.Message, st.ToString());
4962                 }
4963
4964                 internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear)
4965                 {
4966                         Hwnd    hwnd;
4967
4968                         hwnd = Hwnd.ObjectFromHandle(handle);
4969
4970                         if (clear) {
4971                                 AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
4972                         } else {
4973                                 AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
4974                         }
4975                 }
4976
4977                 internal override void InvalidateNC (IntPtr handle)
4978                 {
4979                         Hwnd    hwnd;
4980
4981                         hwnd = Hwnd.ObjectFromHandle(handle);
4982
4983                         AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
4984                 }
4985
4986                 internal override bool IsEnabled(IntPtr handle)
4987                 {
4988                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4989                         return (hwnd != null && hwnd.Enabled);
4990                 }
4991                 
4992                 internal override bool IsVisible(IntPtr handle)
4993                 {
4994                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4995                         return (hwnd != null && hwnd.visible);
4996                 }
4997
4998                 internal override void KillTimer(Timer timer)
4999                 {
5000                         XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5001
5002                         if (queue == null) {
5003                                 // This isn't really an error, MS doesn't start the timer if
5004                                 // it has no assosciated queue. In this case, remove the timer
5005                                 // from the list of unattached timers (if it was enabled).
5006                                 lock (unattached_timer_list) {
5007                                         if (unattached_timer_list.Contains (timer))
5008                                                 unattached_timer_list.Remove (timer);
5009                                 }
5010                                 return;
5011                         }
5012                         queue.timer_list.Remove (timer);
5013                 }
5014
5015                 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y)
5016                 {
5017                         int     dest_x_return;
5018                         int     dest_y_return;
5019                         IntPtr  child;
5020                         Hwnd    hwnd;
5021
5022                         hwnd = Hwnd.ObjectFromHandle(handle);
5023
5024                         lock (XlibLock) {
5025                                 XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
5026                         }
5027
5028                         x = dest_x_return;
5029                         y = dest_y_return;
5030                 }
5031
5032                 internal override void OverrideCursor(IntPtr cursor)
5033                 {
5034                         if (Grab.Hwnd != IntPtr.Zero) {
5035                                 XChangeActivePointerGrab (DisplayHandle,
5036                                                 EventMask.ButtonMotionMask |
5037                                                 EventMask.PointerMotionMask |
5038                                                 EventMask.PointerMotionHintMask |
5039                                                 EventMask.ButtonPressMask |
5040                                                 EventMask.ButtonReleaseMask,
5041                                                 cursor, IntPtr.Zero);
5042                                 return;
5043                         }
5044
5045                         OverrideCursorHandle = cursor;
5046                 }
5047
5048                 internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client)
5049                 {
5050                         PaintEventArgs  paint_event;
5051                         Hwnd            hwnd;
5052                         Hwnd            paint_hwnd;
5053                         
5054                         // 
5055                         // handle  (and paint_hwnd) refers to the window that is should be painted.
5056                         // msg.HWnd (and hwnd) refers to the window that got the paint message.
5057                         // 
5058                         
5059                         hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
5060                         if (msg.HWnd == handle) {
5061                                 paint_hwnd = hwnd;
5062                         } else {
5063                                 paint_hwnd = Hwnd.ObjectFromHandle (handle);
5064                         }
5065         
5066                         if (Caret.Visible == true) {
5067                                 Caret.Paused = true;
5068                                 HideCaret();
5069                         }
5070
5071                         Graphics dc;
5072
5073                         if (client) {
5074                                 dc = Graphics.FromHwnd (paint_hwnd.client_window);
5075
5076                                 Region clip_region = new Region ();
5077                                 clip_region.MakeEmpty();
5078
5079                                 foreach (Rectangle r in hwnd.ClipRectangles) {
5080                                         /* Expand the region slightly.
5081                                          * See bug 464464.
5082                                          */
5083                                         Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
5084                                         clip_region.Union (r2);
5085                                 }
5086
5087                                 if (hwnd.UserClip != null) {
5088                                         clip_region.Intersect(hwnd.UserClip);
5089                                 }
5090
5091                                 dc.Clip = clip_region;
5092                                 paint_event = new PaintEventArgs(dc, hwnd.Invalid);
5093                                 hwnd.expose_pending = false;
5094
5095                                 hwnd.ClearInvalidArea();
5096
5097                                 hwnd.drawing_stack.Push (paint_event);
5098                                 hwnd.drawing_stack.Push (dc);
5099
5100                                 return paint_event;
5101                         } else {
5102                                 dc = Graphics.FromHwnd (paint_hwnd.whole_window);
5103
5104                                 if (!hwnd.nc_invalid.IsEmpty) {
5105                                         dc.SetClip (hwnd.nc_invalid);
5106                                         paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
5107                                 } else {
5108                                         paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
5109                                 }
5110                                 hwnd.nc_expose_pending = false;
5111
5112                                 hwnd.ClearNcInvalidArea ();
5113
5114                                 hwnd.drawing_stack.Push (paint_event);
5115                                 hwnd.drawing_stack.Push (dc);
5116
5117                                 return paint_event;
5118                         }
5119                 }
5120
5121                 internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client)
5122                 {
5123                         Hwnd    hwnd;
5124
5125                         hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
5126
5127                         Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
5128                         dc.Flush();
5129                         dc.Dispose();
5130                         
5131                         PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
5132                         pe.SetGraphics (null);
5133                         pe.Dispose ();
5134
5135                         if (Caret.Visible == true) {
5136                                 ShowCaret();
5137                                 Caret.Paused = false;
5138                         }
5139                 }
5140
5141                 [MonoTODO("Implement filtering and PM_NOREMOVE")]
5142                 internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
5143                 {
5144                         XEventQueue queue = (XEventQueue) queue_id;
5145                         bool    pending;
5146
5147                         if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
5148                                 throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet");    // FIXME - Implement PM_NOREMOVE flag
5149                         }
5150
5151                         pending = false;
5152                         if (queue.Count > 0) {
5153                                 pending = true;
5154                         } else {
5155                                 // Only call UpdateMessageQueue if real events are pending 
5156                                 // otherwise we go to sleep on the socket
5157                                 if (XPending(DisplayHandle) != 0) {
5158                                         UpdateMessageQueue((XEventQueue)queue_id);
5159                                         pending = true;
5160                                 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
5161                                         pending = true;
5162                                 }
5163                         }
5164
5165                         CheckTimers(queue.timer_list, DateTime.UtcNow);
5166
5167                         if (!pending) {
5168                                 return false;
5169                         }
5170                         return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
5171                 }
5172
5173                 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
5174                 {
5175                         XEvent xevent = new XEvent ();
5176                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5177
5178                         xevent.type = XEventName.ClientMessage;
5179                         xevent.ClientMessageEvent.display = DisplayHandle;
5180
5181                         if (hwnd != null) {
5182                                 xevent.ClientMessageEvent.window = hwnd.whole_window;
5183                         } else {
5184                                 xevent.ClientMessageEvent.window = IntPtr.Zero;
5185                         }
5186
5187                         xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
5188                         xevent.ClientMessageEvent.format = 32;
5189                         xevent.ClientMessageEvent.ptr1 = handle;
5190                         xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
5191                         xevent.ClientMessageEvent.ptr3 = wparam;
5192                         xevent.ClientMessageEvent.ptr4 = lparam;
5193
5194                         if (hwnd != null)
5195                                 hwnd.Queue.EnqueueLocked (xevent);
5196                         else
5197                                 ThreadQueue(Thread.CurrentThread).EnqueueLocked (xevent);
5198
5199                         return true;
5200                 }
5201
5202                 internal override void PostQuitMessage(int exitCode)
5203                 {
5204                         ApplicationContext ctx = Application.MWFThread.Current.Context;
5205                         Form f = ctx != null ? ctx.MainForm : null;
5206                         if (f != null)
5207                                 PostMessage (Application.MWFThread.Current.Context.MainForm.window.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5208                         else
5209                                 PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5210                         XFlush(DisplayHandle);
5211                 }
5212
5213                 internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
5214                 {
5215                         // TODO
5216                 }
5217
5218                 internal override void RequestNCRecalc(IntPtr handle)
5219                 {
5220                         Hwnd                            hwnd;
5221
5222                         hwnd = Hwnd.ObjectFromHandle(handle);
5223
5224                         if (hwnd == null) {
5225                                 return;
5226                         }
5227
5228                         PerformNCCalc(hwnd);
5229                         SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5230                         InvalidateNC(handle);
5231                 }
5232
5233                 internal override void ResetMouseHover(IntPtr handle)
5234                 {
5235                         Hwnd    hwnd;
5236
5237                         hwnd = Hwnd.ObjectFromHandle(handle);
5238                         if (hwnd == null) {
5239                                 return;
5240                         }
5241
5242                         HoverState.Timer.Enabled = true;
5243                         HoverState.X = mouse_position.X;
5244                         HoverState.Y = mouse_position.Y;
5245                         HoverState.Window = handle;
5246                 }
5247
5248
5249                 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
5250                 {
5251                         int     dest_x_return;
5252                         int     dest_y_return;
5253                         IntPtr  child;
5254                         Hwnd    hwnd;
5255
5256                         hwnd = Hwnd.ObjectFromHandle(handle);
5257
5258                         lock (XlibLock) {
5259                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
5260                         }
5261
5262                         x = dest_x_return;
5263                         y = dest_y_return;
5264                 }
5265
5266                 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y)
5267                 {
5268                         int     dest_x_return;
5269                         int     dest_y_return;
5270                         IntPtr  child;
5271                         Hwnd    hwnd;
5272
5273                         hwnd = Hwnd.ObjectFromHandle(handle);
5274
5275                         lock (XlibLock) {
5276                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
5277                         }
5278
5279                         Form form = Control.FromHandle (handle) as Form;
5280                         if (form != null && form.window_manager != null) {
5281                                 dest_y_return -= form.window_manager.TitleBarHeight;
5282                         }
5283
5284                         x = dest_x_return;
5285                         y = dest_y_return;
5286                 }
5287
5288                 bool GraphicsExposePredicate (IntPtr display, ref XEvent xevent, IntPtr arg)
5289                 {
5290                         return (xevent.type == XEventName.GraphicsExpose || xevent.type == XEventName.NoExpose) &&
5291                                 arg == xevent.GraphicsExposeEvent.drawable;
5292                 }
5293
5294                 delegate bool EventPredicate (IntPtr display, ref XEvent xevent, IntPtr arg);
5295
5296                 void ProcessGraphicsExpose (Hwnd hwnd)
5297                 {
5298                         XEvent xevent = new XEvent ();
5299                         IntPtr handle = Hwnd.HandleFromObject (hwnd);
5300                         EventPredicate predicate = GraphicsExposePredicate;
5301
5302                         for (;;) {
5303                                 XIfEvent (Display, ref xevent, predicate, handle);
5304                                 if (xevent.type != XEventName.GraphicsExpose)
5305                                         break;
5306
5307                                 AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.GraphicsExposeEvent.x, xevent.GraphicsExposeEvent.y,
5308                                                 xevent.GraphicsExposeEvent.width, xevent.GraphicsExposeEvent.height);
5309
5310                                 if (xevent.GraphicsExposeEvent.count == 0)
5311                                         break;
5312                         }
5313                 }
5314
5315                 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
5316                 {
5317                         Hwnd            hwnd;
5318                         IntPtr          gc;
5319                         XGCValues       gc_values;
5320
5321                         hwnd = Hwnd.ObjectFromHandle(handle);
5322
5323                         Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
5324                         if (!r.IsEmpty) {
5325                                 /* We have an invalid area in the window we're scrolling. 
5326                                    Adjust our stored invalid rectangle to to match the scrolled amount */
5327
5328                                 r.X += XAmount;
5329                                 r.Y += YAmount;
5330
5331                                 if (r.X < 0) {
5332                                         r.Width += r.X;
5333                                         r.X =0;
5334                                 }
5335
5336                                 if (r.Y < 0) {
5337                                         r.Height += r.Y;
5338                                         r.Y =0;
5339                                 }
5340
5341                                 if (area.Contains (hwnd.Invalid))
5342                                         hwnd.ClearInvalidArea ();
5343                                 hwnd.AddInvalidArea(r);
5344                         }
5345
5346                         gc_values = new XGCValues();
5347
5348                         if (with_children) {
5349                                 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
5350                         }
5351
5352                         gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
5353
5354                         Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
5355                         visible_rect.Intersect (area);
5356
5357                         Rectangle dest_rect = visible_rect;
5358                         dest_rect.Y += YAmount;
5359                         dest_rect.X += XAmount;
5360                         dest_rect.Intersect (area);
5361
5362                         Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
5363                         XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y, 
5364                                         dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
5365
5366                         Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
5367                         AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
5368
5369                         ProcessGraphicsExpose (hwnd);
5370
5371                         XFreeGC(DisplayHandle, gc);
5372                 }
5373
5374                 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children)
5375                 {
5376                         Hwnd            hwnd;
5377                         Rectangle       rect;
5378
5379                         hwnd = Hwnd.GetObjectFromWindow(handle);
5380
5381                         rect = hwnd.ClientRect;
5382                         rect.X = 0;
5383                         rect.Y = 0;
5384                         ScrollWindow(handle, rect, XAmount, YAmount, with_children);
5385                 }
5386
5387                 Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
5388                 {
5389                         Rectangle dirty_area = total_area;
5390
5391                         if (YAmount > 0)
5392                                 dirty_area.Height -= valid_area.Height;
5393                         else if (YAmount < 0) {
5394                                 dirty_area.Height -= valid_area.Height;
5395                                 dirty_area.Y += valid_area.Height;
5396                         }
5397
5398                         if (XAmount > 0)
5399                                 dirty_area.Width -= valid_area.Width;
5400                         else if (XAmount < 0) {
5401                                 dirty_area.Width -= valid_area.Width;
5402                                 dirty_area.X += valid_area.Width;
5403                         }
5404
5405                         return dirty_area;
5406                 }
5407
5408                 Rectangle GetTotalVisibleArea (IntPtr handle)
5409                 {
5410                         Control c = Control.FromHandle (handle);
5411
5412                         Rectangle visible_area = c.ClientRectangle;
5413                         visible_area.Location = c.PointToScreen (Point.Empty);
5414
5415                         for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
5416                                 if (!parent.IsHandleCreated || !parent.Visible)
5417                                         return visible_area; // Non visible, not need to finish computations
5418
5419                                 Rectangle r = parent.ClientRectangle;
5420                                 r.Location = parent.PointToScreen (Point.Empty);
5421
5422                                 visible_area.Intersect (r);
5423                         }
5424
5425                         visible_area.Location = c.PointToClient (visible_area.Location);
5426                         return visible_area;
5427                 }
5428
5429                 internal override void SendAsyncMethod (AsyncMethodData method)
5430                 {
5431                         Hwnd    hwnd;
5432                         XEvent  xevent = new XEvent ();
5433
5434                         hwnd = Hwnd.ObjectFromHandle(method.Handle);
5435
5436                         xevent.type = XEventName.ClientMessage;
5437                         xevent.ClientMessageEvent.display = DisplayHandle;
5438                         xevent.ClientMessageEvent.window = method.Handle;
5439                         xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
5440                         xevent.ClientMessageEvent.format = 32;
5441                         xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
5442
5443                         hwnd.Queue.EnqueueLocked (xevent);
5444
5445                         WakeupMain ();
5446                 }
5447
5448                 delegate IntPtr WndProcDelegate (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam);
5449
5450                 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
5451                 {
5452                         Hwnd    h;
5453                         h = Hwnd.ObjectFromHandle(hwnd);
5454
5455                         if (h != null && h.queue != ThreadQueue (Thread.CurrentThread)) {
5456                                 AsyncMethodResult       result;
5457                                 AsyncMethodData         data;
5458
5459                                 result = new AsyncMethodResult ();
5460                                 data = new AsyncMethodData ();
5461
5462                                 data.Handle = hwnd;
5463                                 data.Method = new WndProcDelegate (NativeWindow.WndProc);
5464                                 data.Args = new object[] { hwnd, message, wParam, lParam };
5465                                 data.Result = result;
5466                                 
5467                                 SendAsyncMethod (data);
5468                                 DriverDebug("Sending {0} message across.", message);
5469
5470                                 return IntPtr.Zero;
5471                         }
5472                         string key = hwnd + ":" + message;
5473                         if (messageHold[key] != null)
5474                                 messageHold[key] = ((int)messageHold[key]) - 1;
5475                         return NativeWindow.WndProc(hwnd, message, wParam, lParam);
5476                 }
5477
5478                 internal override int SendInput(IntPtr handle, Queue keys)
5479                 { 
5480                         if (handle == IntPtr.Zero)
5481                                 return 0;
5482
5483                         int count = keys.Count;
5484                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5485
5486                         while (keys.Count > 0) {
5487                         
5488                                 MSG msg = (MSG)keys.Dequeue();
5489
5490                                 XEvent xevent = new XEvent ();
5491
5492                                 xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
5493                                 xevent.KeyEvent.display = DisplayHandle;
5494
5495                                 if (hwnd != null) {
5496                                         xevent.KeyEvent.window = hwnd.whole_window;
5497                                 } else {
5498                                         xevent.KeyEvent.window = IntPtr.Zero;
5499                                 }
5500
5501                                 xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
5502
5503                                 hwnd.Queue.EnqueueLocked (xevent);
5504                         }
5505                         return count;
5506                 }
5507
5508                 internal override void SetAllowDrop (IntPtr handle, bool value)
5509                 {
5510                         // We allow drop on all windows
5511                 }
5512
5513                 internal override DragDropEffects StartDrag (IntPtr handle, object data,
5514                                 DragDropEffects allowed_effects)
5515                 {
5516                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5517
5518                         if (hwnd == null)
5519                                 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
5520
5521                         return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
5522                 }
5523
5524                 internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style)
5525                 {
5526                         Form form = Control.FromHandle (handle) as Form;
5527                         if (form != null && form.window_manager == null) {
5528                                 CreateParams cp = form.GetCreateParams ();
5529                                 if (border_style == FormBorderStyle.FixedToolWindow ||
5530                                      border_style == FormBorderStyle.SizableToolWindow || 
5531                                      cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
5532                                         form.window_manager = new ToolWindowManager (form);
5533                                 }
5534                         }
5535                         
5536                         RequestNCRecalc(handle);
5537                 }
5538
5539                 internal override void SetCaretPos(IntPtr handle, int x, int y)
5540                 {
5541                         if (Caret.Hwnd == handle) {
5542                                 Caret.Timer.Stop();
5543                                 HideCaret();
5544
5545                                 Caret.X = x;
5546                                 Caret.Y = y;
5547
5548                                 Keyboard.SetCaretPos (Caret, handle, x, y);
5549
5550                                 if (Caret.Visible == true) {
5551                                         ShowCaret();
5552                                         Caret.Timer.Start();
5553                                 }
5554                         }
5555                 }
5556
5557                 internal override void SetClipRegion(IntPtr handle, Region region)
5558                 {
5559                         Hwnd    hwnd;
5560
5561                         hwnd = Hwnd.ObjectFromHandle(handle);
5562                         if (hwnd == null) {
5563                                 return;
5564                         }
5565
5566                         hwnd.UserClip = region;
5567                 }
5568
5569                 internal override void SetCursor(IntPtr handle, IntPtr cursor)
5570                 {
5571                         Hwnd    hwnd;
5572
5573                         if (OverrideCursorHandle == IntPtr.Zero) {
5574                                 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
5575                                         return;
5576                                 }
5577
5578                                 LastCursorHandle = cursor;
5579                                 LastCursorWindow = handle;
5580
5581                                 hwnd = Hwnd.ObjectFromHandle(handle);
5582                                 lock (XlibLock) {
5583                                         if (cursor != IntPtr.Zero) {
5584                                                 XDefineCursor(DisplayHandle, hwnd.whole_window, cursor);
5585                                         } else {
5586                                                 XUndefineCursor(DisplayHandle, hwnd.whole_window);
5587                                         }
5588                                         XFlush(DisplayHandle);
5589                                 }
5590                                 return;
5591                         }
5592
5593                         hwnd = Hwnd.ObjectFromHandle(handle);
5594                         lock (XlibLock) {
5595                                 XDefineCursor(DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
5596                         }
5597                 }
5598
5599                 void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
5600                                            out int root_x, out int root_y, out int child_x, out int child_y,
5601                                            out int mask)
5602                 {
5603                         /* this code was written with the help of
5604                         glance at gdk.  I never would have realized we
5605                         needed a loop in order to traverse down in the
5606                         hierarchy.  I would have assumed you'd get the
5607                         most deeply nested child and have to do
5608                         XQueryTree to move back up the hierarchy..
5609                         stupid me, of course. */
5610                         IntPtr c;
5611
5612                         XGrabServer (display);
5613
5614                         XQueryPointer(display, w, out root, out c,
5615                                       out root_x, out root_y, out child_x, out child_y,
5616                                       out mask);
5617
5618                         if (root != w)
5619                                 c = root;
5620
5621                         IntPtr child_last = IntPtr.Zero;
5622                         while (c != IntPtr.Zero) {
5623                                 child_last = c;
5624                                 XQueryPointer(display, c, out root, out c,
5625                                               out root_x, out root_y, out child_x, out child_y,
5626                                               out mask);
5627                         }
5628                         XUngrabServer (display);
5629                         XFlush (display);
5630
5631                         child = child_last;
5632                 }
5633
5634                 internal override void SetCursorPos(IntPtr handle, int x, int y)
5635                 {
5636                         if (handle == IntPtr.Zero) {
5637                                 lock (XlibLock) {
5638                                         IntPtr root, child;
5639                                         int root_x, root_y, child_x, child_y, mask;
5640
5641                                         /* we need to do a
5642                                          * QueryPointer before warping
5643                                          * because if the warp is on
5644                                          * the RootWindow, the x/y are
5645                                          * relative to the current
5646                                          * mouse position
5647                                          */
5648                                         QueryPointer (DisplayHandle, RootWindow,
5649                                                       out root,
5650                                                       out child,
5651                                                       out root_x, out root_y,
5652                                                       out child_x, out child_y,
5653                                                       out mask);
5654
5655                                         XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x - root_x, y - root_y);
5656
5657                                         XFlush (DisplayHandle);
5658
5659                                         /* then we need to a
5660                                          * QueryPointer after warping
5661                                          * to manually generate a
5662                                          * motion event for the window
5663                                          * we move into.
5664                                          */
5665                                         QueryPointer (DisplayHandle, RootWindow,
5666                                                       out root,
5667                                                       out child,
5668                                                       out root_x, out root_y,
5669                                                       out child_x, out child_y,
5670                                                       out mask);
5671
5672                                         Hwnd child_hwnd = Hwnd.ObjectFromHandle(child);
5673                                         if (child_hwnd == null) {
5674                                                 return;
5675                                         }
5676
5677                                         XEvent xevent = new XEvent ();
5678
5679                                         xevent.type = XEventName.MotionNotify;
5680                                         xevent.MotionEvent.display = DisplayHandle;
5681                                         xevent.MotionEvent.window = child_hwnd.client_window;
5682                                         xevent.MotionEvent.root = RootWindow;
5683                                         xevent.MotionEvent.x = child_x;
5684                                         xevent.MotionEvent.y = child_y;
5685                                         xevent.MotionEvent.x_root = root_x;
5686                                         xevent.MotionEvent.y_root = root_y;
5687                                         xevent.MotionEvent.state = mask;
5688
5689                                         child_hwnd.Queue.EnqueueLocked (xevent);
5690                                 }
5691                         } else {
5692                                 Hwnd    hwnd;
5693
5694                                 hwnd = Hwnd.ObjectFromHandle(handle);
5695                                 lock (XlibLock) {
5696                                         XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
5697                                 }
5698                         }
5699                 }
5700
5701                 internal override void SetFocus(IntPtr handle)
5702                 {
5703                         Hwnd    hwnd;
5704                         IntPtr  prev_focus_window;
5705
5706                         hwnd = Hwnd.ObjectFromHandle(handle);
5707
5708                         if (hwnd.client_window == FocusWindow) {
5709                                 return;
5710                         }
5711
5712                         // Win32 doesn't do anything if disabled
5713                         if (!hwnd.enabled)
5714                                 return;
5715
5716                         prev_focus_window = FocusWindow;
5717                         FocusWindow = hwnd.client_window;
5718
5719                         if (prev_focus_window != IntPtr.Zero) {
5720                                 SendMessage(prev_focus_window, Msg.WM_KILLFOCUS, FocusWindow, IntPtr.Zero);
5721                         }                       
5722                         Keyboard.FocusIn (FocusWindow);
5723                         SendMessage(FocusWindow, Msg.WM_SETFOCUS, prev_focus_window, IntPtr.Zero);
5724
5725                         //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
5726                 }
5727
5728                 internal override void SetIcon(IntPtr handle, Icon icon)
5729                 {
5730                         Hwnd    hwnd;
5731
5732                         hwnd = Hwnd.ObjectFromHandle(handle);
5733                         if (hwnd != null) {
5734                                 SetIcon(hwnd, icon);
5735                         }
5736                 }
5737
5738                 internal override void SetMenu(IntPtr handle, Menu menu)
5739                 {
5740                         Hwnd    hwnd;
5741
5742                         hwnd = Hwnd.ObjectFromHandle(handle);
5743                         hwnd.menu = menu;
5744
5745                         RequestNCRecalc(handle);
5746                 }
5747
5748                 internal override void SetModal(IntPtr handle, bool Modal)
5749                 {
5750                         if (Modal) {
5751                                 ModalWindows.Push(handle);
5752                         } else {
5753                                 if (ModalWindows.Contains(handle)) {
5754                                         ModalWindows.Pop();
5755                                 }
5756                                 if (ModalWindows.Count > 0) {
5757                                         Activate((IntPtr)ModalWindows.Peek());
5758                                 }
5759                         }
5760
5761                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5762                         Control ctrl = Control.FromHandle (handle);
5763                         SetWMStyles (hwnd, ctrl.GetCreateParams ());
5764                 }
5765
5766                 internal override IntPtr SetParent(IntPtr handle, IntPtr parent)
5767                 {
5768                         Hwnd    hwnd;
5769
5770                         hwnd = Hwnd.ObjectFromHandle(handle);
5771                         hwnd.parent = Hwnd.ObjectFromHandle(parent);
5772
5773                         lock (XlibLock) {
5774                                 DriverDebug("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
5775                                 XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent == null ? FosterParent : hwnd.parent.client_window, hwnd.x, hwnd.y);
5776                         }
5777
5778                         return IntPtr.Zero;
5779                 }
5780
5781                 internal override void SetTimer (Timer timer)
5782                 {
5783                         XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5784
5785                         if (queue == null) {
5786                                 // This isn't really an error, MS doesn't start the timer if
5787                                 // it has no assosciated queue at this stage (it will be
5788                                 // enabled when a window is activated).
5789                                 unattached_timer_list.Add (timer);
5790                                 return;
5791                         }
5792                         queue.timer_list.Add (timer);
5793                         WakeupMain ();
5794                 }
5795
5796                 internal override bool SetTopmost(IntPtr handle, bool enabled)
5797                 {
5798
5799                         Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5800
5801                         if (enabled) {
5802                                 lock (XlibLock) {
5803                                         if (hwnd.Mapped) {
5804                                                 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_ADD, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5805                                         } else {
5806                                                 int[] atoms = new int[8];
5807                                                 atoms[0] = _NET_WM_STATE_ABOVE.ToInt32();
5808                                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5809                                         }
5810                                 }
5811                         } else {
5812                                 lock (XlibLock) {
5813                                         if (hwnd.Mapped)
5814                                                 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_REMOVE, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5815                                         else
5816                                                 XDeleteProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE);
5817                                 }
5818                         }
5819                         return true;
5820                 }
5821
5822                 internal override bool SetOwner(IntPtr handle, IntPtr handle_owner)
5823                 {
5824                         Hwnd hwnd;
5825                         Hwnd hwnd_owner;
5826
5827                         hwnd = Hwnd.ObjectFromHandle(handle);
5828
5829                         if (handle_owner != IntPtr.Zero) {
5830                                 hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
5831                                 lock (XlibLock) {
5832                                         int[]   atoms;
5833
5834                                         atoms = new int[8];
5835
5836                                         atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
5837                                         XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5838
5839                                         if (hwnd_owner != null) {
5840                                                 XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
5841                                         } else {
5842                                                 XSetTransientForHint(DisplayHandle, hwnd.whole_window, RootWindow);
5843                                         }
5844                                 }
5845                         } else {
5846                                 lock (XlibLock) {
5847                                         XDeleteProperty(DisplayHandle, hwnd.whole_window, (IntPtr)Atom.XA_WM_TRANSIENT_FOR);
5848                                 }
5849                         }
5850                         return true;
5851                 }
5852
5853                 internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
5854                 {
5855                         Hwnd    hwnd;
5856
5857                         hwnd = Hwnd.ObjectFromHandle(handle);
5858                         hwnd.visible = visible;
5859
5860                         lock (XlibLock) {
5861                                 if (visible) {
5862                                         MapWindow(hwnd, WindowType.Both);
5863
5864                                         if (Control.FromHandle(handle) is Form) {
5865                                                 FormWindowState s;
5866
5867                                                 s = ((Form)Control.FromHandle(handle)).WindowState;
5868
5869                                                 switch(s) {
5870                                                         case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
5871                                                         case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
5872                                                 }
5873                                         }
5874
5875                                         SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5876                                 }
5877                                 else {
5878                                         UnmapWindow(hwnd, WindowType.Both);
5879                                 }
5880                         }
5881                         return true;
5882                 }
5883
5884                 internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max)
5885                 {
5886                         Control ctrl = Control.FromHandle (handle);
5887                         SetWindowMinMax (handle, maximized, min, max, ctrl != null ? ctrl.GetCreateParams () : null);
5888                 }
5889
5890                 internal void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max, CreateParams cp)
5891                 {
5892                         Hwnd            hwnd;
5893                         XSizeHints      hints;
5894                         IntPtr          dummy;
5895
5896                         hwnd = Hwnd.ObjectFromHandle(handle);
5897                         if (hwnd == null) {
5898                                 return;
5899                         }
5900
5901                         min.Width = Math.Max (min.Width, SystemInformation.MinimumWindowSize.Width);
5902                         min.Height = Math.Max (min.Height, SystemInformation.MinimumWindowSize.Height);
5903                         
5904                         hints = new XSizeHints();
5905
5906                         XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
5907                         if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
5908                                 if (cp != null)
5909                                         min = TranslateWindowSizeToXWindowSize (cp, min);
5910                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
5911                                 hints.min_width = min.Width;
5912                                 hints.min_height = min.Height;
5913                         }
5914
5915                         if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
5916                                 if (cp != null)
5917                                         max = TranslateWindowSizeToXWindowSize (cp, max);
5918                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
5919                                 hints.max_width = max.Width;
5920                                 hints.max_height = max.Height;
5921                         }
5922
5923                         if (hints.flags != IntPtr.Zero) {
5924                                 // The Metacity team has decided that they won't care about this when clicking the maximize icon, 
5925                                 // they will maximize the window to fill the screen/parent no matter what.
5926                                 // http://bugzilla.ximian.com/show_bug.cgi?id=80021
5927                                 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
5928                         }
5929
5930                         if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
5931                                 if (cp != null)
5932                                         maximized.Size = TranslateWindowSizeToXWindowSize (cp);
5933                                 hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
5934                                 hints.x = maximized.X;
5935                                 hints.y = maximized.Y;
5936                                 hints.width = maximized.Width;
5937                                 hints.height = maximized.Height;
5938
5939                                 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
5940                                 XSetZoomHints(DisplayHandle, hwnd.whole_window, ref hints);
5941                         }
5942                 }
5943
5944
5945                 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height)
5946                 {
5947                         Hwnd            hwnd;
5948
5949                         hwnd = Hwnd.ObjectFromHandle(handle);
5950
5951                         if (hwnd == null) {
5952                                 return;
5953                         }
5954
5955                         // Win32 automatically changes negative width/height to 0.
5956                         if (width < 0)
5957                                 width = 0;
5958                         if (height < 0)
5959                                 height = 0;
5960                                 
5961                         // X requires a sanity check for width & height; otherwise it dies
5962                         if (hwnd.zero_sized && width > 0 && height > 0) {
5963                                 if (hwnd.visible) {
5964                                         MapWindow(hwnd, WindowType.Whole);
5965                                 }
5966                                 hwnd.zero_sized = false;
5967                         }
5968
5969                         if ((width < 1) || (height < 1)) {
5970                                 hwnd.zero_sized = true;
5971                                 UnmapWindow(hwnd, WindowType.Whole);
5972                         }
5973
5974                         // Save a server roundtrip (and prevent a feedback loop)
5975                         if ((hwnd.x == x) && (hwnd.y == y) && 
5976                                 (hwnd.width == width) && (hwnd.height == height)) {
5977                                 return;
5978                         }
5979
5980                         if (!hwnd.zero_sized) {
5981                                 //Hack?
5982                                 hwnd.x = x;
5983                                 hwnd.y = y;
5984                                 hwnd.width = width;
5985                                 hwnd.height = height;
5986                                 SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5987
5988                                 if (hwnd.fixed_size) {
5989                                         SetWindowMinMax(handle, Rectangle.Empty, new Size(width, height), new Size(width, height));
5990                                 }
5991
5992                                 lock (XlibLock) {
5993                                         Control ctrl = Control.FromHandle (handle);
5994                                         Size TranslatedSize = TranslateWindowSizeToXWindowSize (ctrl.GetCreateParams (), new Size (width, height));
5995                                         MoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, TranslatedSize.Width, TranslatedSize.Height);
5996                                         PerformNCCalc(hwnd);
5997                                 }
5998                         }
5999
6000                         // Update our position/size immediately, so
6001                         // that future calls to SetWindowPos aren't
6002                         // kept from calling XMoveResizeWindow (by the
6003                         // "Save a server roundtrip" block above).
6004                         hwnd.x = x;
6005                         hwnd.y = y;
6006                         hwnd.width = width;
6007                         hwnd.height = height;
6008                         hwnd.ClientRect = Rectangle.Empty;
6009                 }
6010
6011                 internal override void SetWindowState(IntPtr handle, FormWindowState state)
6012                 {
6013                         FormWindowState current_state;
6014                         Hwnd            hwnd;
6015
6016                         hwnd = Hwnd.ObjectFromHandle(handle);
6017
6018                         current_state = GetWindowState(handle);
6019
6020                         if (current_state == state) {
6021                                 return;
6022                         }
6023
6024                         switch(state) {
6025                                 case FormWindowState.Normal: {
6026                                         lock (XlibLock) {
6027                                                 if (current_state == FormWindowState.Minimized) {
6028                                                         MapWindow(hwnd, WindowType.Both);
6029                                                 } else if (current_state == FormWindowState.Maximized) {
6030                                                         SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6031                                                 }
6032                                         }
6033                                         Activate(handle);
6034                                         return;
6035                                 }
6036
6037                                 case FormWindowState.Minimized: {
6038                                         lock (XlibLock) {
6039                                                 if (current_state == FormWindowState.Maximized) {
6040                                                         SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6041                                                 }
6042                                                 XIconifyWindow(DisplayHandle, hwnd.whole_window, ScreenNo);
6043                                         }
6044                                         return;
6045                                 }
6046
6047                                 case FormWindowState.Maximized: {
6048                                         lock (XlibLock) {
6049                                                 if (current_state == FormWindowState.Minimized) {
6050                                                         MapWindow(hwnd, WindowType.Both);
6051                                                 }
6052
6053                                                 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)1 /* Add */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6054                                         }
6055                                         Activate(handle);
6056                                         return;
6057                                 }
6058                         }
6059                 }
6060
6061                 internal override void SetWindowStyle(IntPtr handle, CreateParams cp)
6062                 {
6063                         Hwnd    hwnd;
6064
6065                         hwnd = Hwnd.ObjectFromHandle(handle);
6066                         SetHwndStyles(hwnd, cp);
6067                         SetWMStyles(hwnd, cp);
6068                 }
6069
6070                 internal override double GetWindowTransparency(IntPtr handle)
6071                 {
6072                         return 1.0;
6073                 }
6074
6075                 internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key)
6076                 {
6077                         Hwnd    hwnd;
6078                         IntPtr  opacity;
6079
6080                         hwnd = Hwnd.ObjectFromHandle(handle);
6081
6082                         if (hwnd == null) {
6083                                 return;
6084                         }
6085
6086                         hwnd.opacity = (uint)(0xffffffff * transparency);
6087                         opacity = (IntPtr)((int)hwnd.opacity);
6088
6089                         IntPtr w = hwnd.whole_window;
6090                         if (hwnd.reparented)
6091                                 w = XGetParent (hwnd.whole_window);
6092                         XChangeProperty(DisplayHandle, w, _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
6093                 }
6094
6095                 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom)
6096                 {
6097                         Hwnd    hwnd = Hwnd.ObjectFromHandle(handle);
6098
6099                         if (!hwnd.mapped) {
6100                                 return false;
6101                         }
6102
6103                         if (top) {
6104                                 lock (XlibLock) {
6105                                         XRaiseWindow(DisplayHandle, hwnd.whole_window);
6106                                 }
6107                                 return true;
6108                         } else if (!bottom) {
6109                                 Hwnd    after_hwnd = null;
6110
6111                                 if (after_handle != IntPtr.Zero) {
6112                                         after_hwnd = Hwnd.ObjectFromHandle(after_handle);
6113                                 }
6114
6115                                 XWindowChanges  values = new XWindowChanges();
6116
6117                                 if (after_hwnd == null) {
6118                                         // Work around metacity 'issues'
6119                                         int[]   atoms;
6120
6121                                         atoms = new int[2];
6122                                         atoms[0] = unixtime();
6123                                         XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_USER_TIME, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, atoms, 1);
6124
6125                                         XRaiseWindow(DisplayHandle, hwnd.whole_window);
6126                                         SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
6127                                         return true;
6128                                         //throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
6129                                 }
6130
6131                                 values.sibling = after_hwnd.whole_window;
6132                                 values.stack_mode = StackMode.Below;
6133
6134                                 lock (XlibLock) {
6135                                         XConfigureWindow(DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
6136                                 }
6137                         } else {
6138                                 // Bottom
6139                                 lock (XlibLock) {
6140                                         XLowerWindow(DisplayHandle, hwnd.whole_window);
6141                                 }
6142                                 return true;
6143                         }
6144                         return false;
6145                 }
6146
6147                 internal override void ShowCursor(bool show)
6148                 {
6149                         ;       // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
6150                 }
6151
6152                 internal override object StartLoop(Thread thread)
6153                 {
6154                         XEventQueue q = ThreadQueue(thread);
6155                         return q;
6156                 }
6157
6158                 internal override TransparencySupport SupportsTransparency()
6159                 {
6160                         // We need to check if the x compositing manager is running
6161                         return TransparencySupport.Set;
6162                 }
6163
6164                 internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt)
6165                 {
6166                         GetSystrayManagerWindow();
6167
6168                         if (SystrayMgrWindow != IntPtr.Zero) {
6169                                 XSizeHints      size_hints;
6170                                 Hwnd            hwnd;
6171
6172                                 hwnd = Hwnd.ObjectFromHandle(handle);
6173                                 DriverDebug("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
6174
6175                                 // Oh boy.
6176                                 if (hwnd.client_window != hwnd.whole_window) {
6177                                         Keyboard.DestroyICForWindow (hwnd.client_window);
6178                                         XDestroyWindow(DisplayHandle, hwnd.client_window);
6179                                         hwnd.client_window = hwnd.whole_window;
6180                                 }       
6181
6182                                 /* by virtue of the way the tests are ordered when determining if it's PAINT
6183                                    or NCPAINT, client_window == whole_window will always be PAINT.  So, if we're
6184                                    waiting on an nc_expose, drop it and remove the hwnd from the list (unless
6185                                    there's a pending expose). */
6186                                 if (hwnd.nc_expose_pending) {
6187                                         hwnd.nc_expose_pending = false;
6188                                         if (!hwnd.expose_pending)
6189                                                 hwnd.Queue.Paint.Remove (hwnd);
6190                                 }
6191
6192                                 // We are going to be directly mapped by the system tray, so mark as mapped
6193                                 // so we can later properly unmap it.
6194                                 hwnd.mapped = true;
6195
6196                                 size_hints = new XSizeHints();
6197
6198                                 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
6199
6200                                 size_hints.min_width = 24;
6201                                 size_hints.min_height = 24;
6202                                 size_hints.max_width = 24;
6203                                 size_hints.max_height = 24;
6204                                 size_hints.base_width = 24;
6205                                 size_hints.base_height = 24;
6206
6207                                 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
6208
6209                                 int[] atoms = new int[2];
6210                                 atoms [0] = 1;                  // Version 1
6211                                 atoms [1] = 1;                  // we want to be mapped
6212
6213                                 // This line cost me 3 days...
6214                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _XEMBED_INFO, _XEMBED_INFO, 32, PropertyMode.Replace, atoms, 2);
6215
6216                                 // Need to pick some reasonable defaults
6217                                 tt = new ToolTip();
6218                                 tt.AutomaticDelay = 350;
6219                                 tt.InitialDelay = 250;
6220                                 tt.ReshowDelay = 250;
6221                                 tt.ShowAlways = true;
6222
6223                                 if ((tip != null) && (tip != string.Empty)) {
6224                                         tt.SetToolTip(Control.FromHandle(handle), tip);
6225                                         tt.Active = true;
6226                                 } else {
6227                                         tt.Active = false;
6228                                 }
6229
6230                                 SendNetClientMessage(SystrayMgrWindow, _NET_SYSTEM_TRAY_OPCODE, IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
6231
6232                                 return true;
6233                         }
6234                         tt = null;
6235                         return false;
6236                 }
6237
6238                 internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt)
6239                 {
6240                         Control control;
6241
6242                         control = Control.FromHandle(handle);
6243                         if (control != null && tt != null) {
6244                                 tt.SetToolTip(control, tip);
6245                                 tt.Active = true;
6246                                 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6247                                 return true;
6248                         } else {
6249                                 return false;
6250                         }
6251                 }
6252
6253                 internal override void SystrayRemove(IntPtr handle, ref ToolTip tt)
6254                 {
6255
6256                         SetVisible (handle, false, false);
6257
6258                         // The caller can now re-dock it later...
6259                         if (tt != null) {
6260                                 tt.Dispose();
6261                                 tt = null;
6262                         }
6263                         // Close any balloon window *we* fired.
6264                         ThemeEngine.Current.HideBalloonWindow (handle);
6265                 }
6266
6267                 internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
6268                 {
6269                         ThemeEngine.Current.ShowBalloonWindow (handle, timeout, title, text, icon);
6270                         SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);    
6271                 }
6272
6273                 internal override bool Text(IntPtr handle, string text)
6274 {
6275                         Hwnd    hwnd;
6276
6277                         hwnd = Hwnd.ObjectFromHandle(handle);
6278
6279                         lock (XlibLock) {
6280                                 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UTF8_STRING, 8,
6281                                                 PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
6282
6283                                 // XXX this has problems with UTF8.
6284                                 // we need to either use the actual
6285                                 // text if it's latin-1, or convert it
6286                                 // to compound text if it's in a
6287                                 // different charset.
6288                                 XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
6289                         }
6290                         return true;
6291                 }
6292
6293                 internal override bool TranslateMessage(ref MSG msg)
6294                 {
6295                         return Keyboard.TranslateMessage (ref msg);
6296                 }
6297
6298                 internal override void UpdateWindow(IntPtr handle)
6299                 {
6300                         Hwnd    hwnd;
6301
6302                         hwnd = Hwnd.ObjectFromHandle(handle);
6303
6304                         if (!hwnd.visible || !hwnd.expose_pending || !hwnd.Mapped) {
6305                                 return;
6306                         }
6307
6308                         SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6309                         hwnd.Queue.Paint.Remove(hwnd);
6310                 }
6311
6312                 internal override void CreateOffscreenDrawable (IntPtr handle,
6313                                                                 int width, int height,
6314                                                                 out object offscreen_drawable)
6315                 {
6316                         IntPtr root_out;
6317                         int x_out, y_out, width_out, height_out, border_width_out, depth_out;
6318
6319                         XGetGeometry (DisplayHandle, handle,
6320                                       out root_out,
6321                                       out x_out, out y_out,
6322                                       out width_out, out height_out,
6323                                       out border_width_out, out depth_out);
6324
6325                         IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
6326
6327                         offscreen_drawable = pixmap;
6328
6329                 }
6330
6331                 internal override void DestroyOffscreenDrawable (object offscreen_drawable)
6332                 {
6333                         XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
6334                 }
6335
6336                 internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
6337                 {
6338                         return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
6339                 }
6340                 
6341                 internal override void BlitFromOffscreen (IntPtr dest_handle,
6342                                                           Graphics dest_dc,
6343                                                           object offscreen_drawable,
6344                                                           Graphics offscreen_dc,
6345                                                           Rectangle r)
6346                 {
6347                         XGCValues gc_values;
6348                         IntPtr gc;
6349
6350                         gc_values = new XGCValues();
6351
6352                         gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
6353
6354                         XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
6355                                    gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
6356
6357                         XFreeGC (DisplayHandle, gc);
6358                 }
6359
6360                 #endregion      // Public Static Methods
6361
6362                 #region Events
6363                 #endregion      // Events
6364
6365                 
6366 #if TRACE
6367                 
6368 #region Xcursor imports
6369                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
6370                 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
6371
6372                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
6373                 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
6374                 
6375                 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
6376                 internal extern static void XcursorImagesDestroy (IntPtr images);
6377                 
6378                 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
6379                 internal extern static int XcursorGetDefaultSize (IntPtr display);
6380
6381                 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
6382                 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
6383
6384                 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
6385                 internal extern static IntPtr XcursorGetTheme (IntPtr display);
6386 #endregion
6387 #region X11 Imports
6388                 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
6389                 internal extern static IntPtr XOpenDisplay(IntPtr display);
6390                 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
6391                 internal extern static int XCloseDisplay(IntPtr display);                                                   
6392                 [DllImport ("libX11", EntryPoint="XSynchronize")]
6393                 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
6394
6395                 [DllImport ("libX11", EntryPoint="XCreateWindow")]
6396                 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);
6397                 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)
6398                 {
6399                         DebugHelper.TraceWriteLine ("XCreateWindow");
6400                         return _XCreateWindow(display, parent, x, y, width, height, 
6401                                        border_width, depth, xclass, visual, valuemask, ref attributes);
6402                 }
6403                 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
6404                 internal extern static IntPtr _XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
6405                 internal static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background)
6406                 {
6407                         DebugHelper.TraceWriteLine ("XCreateSimpleWindow");
6408                         return _XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background);
6409                 }
6410                 [DllImport ("libX11", EntryPoint="XMapWindow")]
6411                 internal extern static int _XMapWindow(IntPtr display, IntPtr window);
6412                 internal static int XMapWindow(IntPtr display, IntPtr window)
6413                 {
6414                         DebugHelper.TraceWriteLine ("XMapWindow");
6415                         return _XMapWindow(display, window);
6416                 }
6417                 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
6418                 internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
6419                 internal static int XUnmapWindow(IntPtr display, IntPtr window)
6420                 {
6421                         DebugHelper.TraceWriteLine ("XUnmapWindow");
6422                         return _XUnmapWindow(display, window);
6423                 }
6424                 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
6425                 internal extern static int _XMapSubindows(IntPtr display, IntPtr window);
6426                 internal static int XMapSubindows(IntPtr display, IntPtr window)
6427                 {
6428                         DebugHelper.TraceWriteLine ("XMapSubindows");
6429                         return _XMapSubindows(display, window);
6430                 }
6431                 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
6432                 internal extern static int _XUnmapSubwindows(IntPtr display, IntPtr window);
6433                 internal static int XUnmapSubwindows(IntPtr display, IntPtr window)
6434                 {
6435                         DebugHelper.TraceWriteLine ("XUnmapSubwindows");
6436                         return _XUnmapSubwindows(display, window);
6437                 }
6438                 [DllImport ("libX11", EntryPoint="XRootWindow")]
6439                 internal extern static IntPtr _XRootWindow(IntPtr display, int screen_number);
6440                 internal static IntPtr XRootWindow(IntPtr display, int screen_number)
6441                 {
6442                         DebugHelper.TraceWriteLine ("XRootWindow");
6443                         return _XRootWindow(display, screen_number);
6444                 }
6445                 [DllImport ("libX11", EntryPoint="XNextEvent")]
6446                 internal extern static IntPtr _XNextEvent(IntPtr display, ref XEvent xevent);
6447                 internal static IntPtr XNextEvent(IntPtr display, ref XEvent xevent)
6448                 {
6449                         DebugHelper.TraceWriteLine ("XNextEvent");
6450                         return _XNextEvent(display, ref xevent);
6451                 }
6452                 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
6453                 internal extern static int _XConnectionNumber (IntPtr display);
6454                 internal static int XConnectionNumber (IntPtr display)
6455                 {
6456                         DebugHelper.TraceWriteLine ("XConnectionNumber");
6457                         return _XConnectionNumber (display);
6458                 }
6459                 [DllImport ("libX11", EntryPoint="XPending")]
6460                 internal extern static int _XPending (IntPtr display);
6461                 internal static int XPending (IntPtr display)
6462                 {
6463                         DebugHelper.TraceWriteLine ("XPending");
6464                         DebugHelper.DumpCallers (3);
6465                         return _XPending (display);
6466                 }
6467                 [DllImport ("libX11", EntryPoint="XSelectInput")]
6468                 internal extern static IntPtr _XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
6469                 internal static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask)
6470                 {
6471                         DebugHelper.TraceWriteLine ("XSelectInput");
6472                         return _XSelectInput(display, window, mask);
6473                 }
6474
6475                 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
6476                 internal extern static int _XDestroyWindow(IntPtr display, IntPtr window);
6477                 internal static int XDestroyWindow(IntPtr display, IntPtr window)
6478                 {
6479                         DebugHelper.TraceWriteLine ("XDestroyWindow 0x{0:x}", window.ToInt32());
6480                         return _XDestroyWindow(display, window);
6481                 }
6482
6483                 [DllImport ("libX11", EntryPoint="XReparentWindow")]
6484                 internal extern static int _XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
6485                 internal static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y)
6486                 {
6487                         DebugHelper.TraceWriteLine ("XReparentWindow");
6488                         return _XReparentWindow(display, window, parent, x, y);
6489                 }
6490                 
6491                 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
6492                 extern static int _XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
6493                 static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height) {
6494                         DebugHelper.TraceWriteLine ("XMoveResizeWindow");
6495                         return _XMoveResizeWindow(display, window, x, y, width, height);
6496                 }
6497
6498                 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
6499                 {
6500                         int ret = XMoveResizeWindow (display, window, x, y, width, height);
6501                         Keyboard.MoveCurrentCaretPos ();
6502                         return ret;
6503                 }
6504
6505                 [DllImport ("libX11", EntryPoint="XResizeWindow")]
6506                 internal extern static int _XResizeWindow(IntPtr display, IntPtr window, int width, int height);
6507                 internal static int XResizeWindow(IntPtr display, IntPtr window, int width, int height)
6508                 {
6509                         DebugHelper.TraceWriteLine ("XResizeWindow");
6510                         return _XResizeWindow(display, window, width, height);
6511                 }
6512
6513                 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
6514                 internal extern static int _XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
6515                 internal static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes)
6516                 {
6517                         DebugHelper.TraceWriteLine ("XGetWindowAttributes");
6518                         return _XGetWindowAttributes(display, window, ref attributes);
6519                 }
6520
6521                 [DllImport ("libX11", EntryPoint="XFlush")]
6522                 internal extern static int _XFlush(IntPtr display);
6523                 internal static int XFlush(IntPtr display)
6524                 {
6525                         DebugHelper.TraceWriteLine ("XFlush");
6526                         return _XFlush(display);
6527                 }
6528
6529                 [DllImport ("libX11", EntryPoint="XSetWMName")]
6530                 internal extern static int _XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
6531                 internal static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop)
6532                 {
6533                         DebugHelper.TraceWriteLine ("XSetWMName");
6534                         return _XSetWMName(display, window, ref text_prop);
6535                 }
6536
6537                 [DllImport ("libX11", EntryPoint="XStoreName")]
6538                 internal extern static int _XStoreName(IntPtr display, IntPtr window, string window_name);
6539                 internal static int XStoreName(IntPtr display, IntPtr window, string window_name)
6540                 {
6541                         DebugHelper.TraceWriteLine ("XStoreName");
6542                         return _XStoreName(display, window, window_name);
6543                 }
6544
6545                 [DllImport ("libX11", EntryPoint="XFetchName")]
6546                 internal extern static int _XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
6547                 internal static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name)
6548                 {
6549                         DebugHelper.TraceWriteLine ("XFetchName");
6550                         return _XFetchName(display, window, ref window_name);
6551                 }
6552
6553                 [DllImport ("libX11", EntryPoint="XSendEvent")]
6554                 internal extern static int _XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
6555                 internal static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event)
6556                 {
6557                         DebugHelper.TraceWriteLine ("XSendEvent");
6558                         return _XSendEvent(display, window, propagate, event_mask, ref send_event);
6559                 }
6560
6561                 [DllImport ("libX11", EntryPoint="XQueryTree")]
6562                 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);
6563                 internal static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return)
6564                 {
6565                         DebugHelper.TraceWriteLine ("XQueryTree");
6566                         return _XQueryTree(display, window, out root_return, out parent_return, out children_return, out nchildren_return);
6567                 }
6568
6569                 [DllImport ("libX11", EntryPoint="XFree")]
6570                 internal extern static int _XFree(IntPtr data);
6571                 internal static int XFree(IntPtr data)
6572                 {
6573                         DebugHelper.TraceWriteLine ("XFree");
6574                         return _XFree(data);
6575                 }
6576
6577                 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
6578                 internal extern static int _XRaiseWindow(IntPtr display, IntPtr window);
6579                 internal static int XRaiseWindow(IntPtr display, IntPtr window)
6580                 {
6581                         DebugHelper.TraceWriteLine ("XRaiseWindow");
6582                         return _XRaiseWindow(display, window);
6583                 }
6584
6585                 [DllImport ("libX11", EntryPoint="XLowerWindow")]
6586                 internal extern static uint _XLowerWindow(IntPtr display, IntPtr window);
6587                 internal static uint XLowerWindow(IntPtr display, IntPtr window)
6588                 {
6589                         DebugHelper.TraceWriteLine ("XLowerWindow");
6590                         return _XLowerWindow(display, window);
6591                 }
6592
6593                 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
6594                 internal extern static uint _XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
6595                 internal static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values)
6596                 {
6597                         DebugHelper.TraceWriteLine ("XConfigureWindow");
6598                         return _XConfigureWindow(display, window, value_mask, ref values);
6599                 }
6600
6601                 [DllImport ("libX11", EntryPoint="XInternAtom")]
6602                 internal extern static IntPtr _XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
6603                 internal static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists)
6604                 {
6605                         DebugHelper.TraceWriteLine ("XInternAtom");
6606                         return _XInternAtom(display, atom_name, only_if_exists);
6607                 }
6608
6609                 [DllImport ("libX11", EntryPoint="XInternAtoms")]
6610                 internal extern static int _XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
6611                 internal static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms)
6612                 {
6613                         DebugHelper.TraceWriteLine ("XInternAtoms");
6614                         return _XInternAtoms(display, atom_names, atom_count, only_if_exists, atoms);
6615                 }
6616
6617                 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
6618                 internal extern static int _XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
6619                 internal static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count)
6620                 {
6621                         DebugHelper.TraceWriteLine ("XSetWMProtocols");
6622                         return _XSetWMProtocols(display, window, protocols, count);
6623                 }
6624
6625                 [DllImport ("libX11", EntryPoint="XGrabPointer")]
6626                 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);
6627                 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)
6628                 {
6629                         DebugHelper.TraceWriteLine ("XGrabPointer");
6630                         return _XGrabPointer(display, window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, timestamp);
6631                 }
6632
6633                 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
6634                 internal extern static int _XUngrabPointer(IntPtr display, IntPtr timestamp);
6635                 internal static int XUngrabPointer(IntPtr display, IntPtr timestamp)
6636                 {
6637                         DebugHelper.TraceWriteLine ("XUngrabPointer");
6638                         return _XUngrabPointer(display, timestamp);
6639                 }
6640
6641                 [DllImport ("libX11", EntryPoint="XQueryPointer")]
6642                 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);
6643                 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)
6644                 {
6645                         DebugHelper.TraceWriteLine ("XQueryPointer");
6646                         return _XQueryPointer(display, window, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
6647                 }
6648
6649                 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
6650                 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);
6651                 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)
6652                 {
6653                         DebugHelper.TraceWriteLine ("XTranslateCoordinates");
6654                         return _XTranslateCoordinates (display, src_w, dest_w, src_x, src_y, out intdest_x_return, out dest_y_return, out child_return);
6655                 }
6656
6657                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6658                 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);
6659                 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)
6660                 {
6661                         DebugHelper.TraceWriteLine ("XGetGeometry");
6662                         return _XGetGeometry(display, window, out root, out x, out y, out width, out height, out border_width, out depth);
6663                 }
6664
6665                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6666                 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);
6667                 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)
6668                 {
6669                         DebugHelper.TraceWriteLine ("XGetGeometry");
6670                         return _XGetGeometry(display, window, root, out x, out y, out width, out height, border_width, depth);
6671                 }
6672
6673                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6674                 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);
6675                 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)
6676                 {
6677                         DebugHelper.TraceWriteLine ("XGetGeometry");
6678                         return _XGetGeometry(display, window, root, out x, out y, width, height, border_width, depth);
6679                 }
6680
6681                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6682                 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);
6683                 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)
6684                 {
6685                         DebugHelper.TraceWriteLine ("XGetGeometry");
6686                         return _XGetGeometry(display, window, root, x, y, out width, out height, border_width, depth);
6687                 }
6688
6689                 [DllImport ("libX11", EntryPoint="XWarpPointer")]
6690                 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);
6691                 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)
6692                 {
6693                         DebugHelper.TraceWriteLine ("XWarpPointer");
6694                         return _XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y);
6695                 }
6696
6697                 [DllImport ("libX11", EntryPoint="XClearWindow")]
6698                 internal extern static int _XClearWindow(IntPtr display, IntPtr window);
6699                 internal static int XClearWindow(IntPtr display, IntPtr window)
6700                 {
6701                         DebugHelper.TraceWriteLine ("XClearWindow");
6702                         return _XClearWindow(display, window);
6703                 }
6704
6705                 [DllImport ("libX11", EntryPoint="XClearArea")]
6706                 internal extern static int _XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
6707                 internal static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures)
6708                 {
6709                         DebugHelper.TraceWriteLine ("XClearArea");
6710                         return _XClearArea(display, window, x, y, width, height, exposures);
6711                 }
6712
6713                 // Colormaps
6714                 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
6715                 internal extern static IntPtr _XDefaultScreenOfDisplay(IntPtr display);
6716                 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display)
6717                 {
6718                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6719                         return _XDefaultScreenOfDisplay(display);
6720                 }
6721
6722                 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
6723                 internal extern static int _XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
6724                 internal static int XDefaultScreenOfDisplay(IntPtr display, IntPtr Screen)
6725                 {
6726                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6727                         return _XScreenNumberOfScreen(display, Screen);
6728                 }
6729
6730                 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
6731                 internal extern static IntPtr _XDefaultVisual(IntPtr display, int screen_number);
6732                 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display, int screen_number)
6733                 {
6734                         DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6735                         return _XDefaultVisual(display, screen_number);
6736                 }
6737
6738                 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
6739                 internal extern static uint _XDefaultDepth(IntPtr display, int screen_number);
6740                 internal static uint XDefaultDepth(IntPtr display, int screen_number)
6741                 {
6742                         DebugHelper.TraceWriteLine ("XDefaultDepth");
6743                         return _XDefaultDepth(display, screen_number);
6744                 }
6745
6746                 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
6747                 internal extern static int _XDefaultScreen(IntPtr display);
6748                 internal static int XDefaultScreen(IntPtr display)
6749                 {
6750                         DebugHelper.TraceWriteLine ("XDefaultScreen");
6751                         return _XDefaultScreen(display);
6752                 }
6753
6754                 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
6755                 internal extern static IntPtr _XDefaultColormap(IntPtr display, int screen_number);
6756                 internal static IntPtr XDefaultColormap(IntPtr display, int screen_number)
6757                 {
6758                         DebugHelper.TraceWriteLine ("XDefaultColormap");
6759                         return _XDefaultColormap(display, screen_number);
6760                 }
6761
6762                 [DllImport ("libX11", EntryPoint="XLookupColor")]
6763                 internal extern static int _XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
6764                 internal static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color)
6765                 {
6766                         DebugHelper.TraceWriteLine ("XLookupColor");
6767                         return _XLookupColor(display, Colormap, Coloranem, ref exact_def_color, ref screen_def_color);
6768                 }
6769
6770                 [DllImport ("libX11", EntryPoint="XAllocColor")]
6771                 internal extern static int _XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
6772                 internal static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def)
6773                 {
6774                         DebugHelper.TraceWriteLine ("XAllocColor");
6775                         return _XAllocColor(display, Colormap, ref colorcell_def);
6776                 }
6777
6778                 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
6779                 internal extern static int _XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
6780                 internal static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window)
6781                 {
6782                         DebugHelper.TraceWriteLine ("XSetTransientForHint");
6783                         return _XSetTransientForHint(display, window, prop_window);
6784                 }
6785
6786                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6787                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
6788                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements)
6789                 {
6790                         DebugHelper.TraceWriteLine ("XChangeProperty");
6791                         return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
6792                 }
6793
6794                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6795                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
6796                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements)
6797                 {
6798                         DebugHelper.TraceWriteLine ("XChangeProperty");
6799                         return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6800                 }
6801
6802                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6803                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
6804                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements)
6805                 {
6806                         DebugHelper.TraceWriteLine ("XChangeProperty");
6807                         return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6808                 }
6809
6810                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6811                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
6812                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements)
6813                 {
6814                         DebugHelper.TraceWriteLine ("XChangeProperty");
6815                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6816                 }
6817
6818                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6819                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
6820                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements)
6821                 {
6822                         DebugHelper.TraceWriteLine ("XChangeProperty");
6823                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6824                 }
6825
6826                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6827                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
6828                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements)
6829                 {
6830                         DebugHelper.TraceWriteLine ("XChangeProperty");
6831                         return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6832                 }
6833
6834                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6835                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
6836                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements)
6837                 {
6838                         DebugHelper.TraceWriteLine ("XChangeProperty");
6839                         return _XChangeProperty(display, window, property, type, format, mode, atoms, nelements);
6840                 }
6841
6842                 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
6843                 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
6844                 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length)
6845                 {
6846                         DebugHelper.TraceWriteLine ("XChangeProperty");
6847                         return _XChangeProperty(display, window, property, type, format, mode, text, text_length);
6848                 }
6849
6850                 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
6851                 internal extern static int _XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
6852                 internal static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property)
6853                 {
6854                         DebugHelper.TraceWriteLine ("XDeleteProperty");
6855                         return _XDeleteProperty(display, window, property);
6856                 }
6857
6858                 // Drawing
6859                 [DllImport ("libX11", EntryPoint="XCreateGC")]
6860                 internal extern static IntPtr _XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
6861                 internal static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values)
6862                 {
6863                         DebugHelper.TraceWriteLine ("XCreateGC");
6864                         return _XCreateGC(display, window, valuemask, ref values);
6865                 }
6866
6867                 [DllImport ("libX11", EntryPoint="XFreeGC")]
6868                 internal extern static int _XFreeGC(IntPtr display, IntPtr gc);
6869                 internal static int XFreeGC(IntPtr display, IntPtr gc)
6870                 {
6871                         DebugHelper.TraceWriteLine ("XFreeGC");
6872                         return _XFreeGC(display, gc);
6873                 }
6874
6875                 [DllImport ("libX11", EntryPoint="XSetFunction")]
6876                 internal extern static int _XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
6877                 internal static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function)
6878                 {
6879                         DebugHelper.TraceWriteLine ("XSetFunction");
6880                         return _XSetFunction(display, gc, function);
6881                 }
6882
6883                 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
6884                 internal extern static int _XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
6885                 internal static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style)
6886                 {
6887                         DebugHelper.TraceWriteLine ("XSetLineAttributes");
6888                         return _XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
6889                 }
6890
6891                 [DllImport ("libX11", EntryPoint="XDrawLine")]
6892                 internal extern static int _XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
6893                 internal static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2)
6894                 {
6895                         DebugHelper.TraceWriteLine ("XDrawLine");
6896                         return _XDrawLine(display, drawable, gc, x1, y1, x2, y2);
6897                 }
6898
6899                 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
6900                 internal extern static int _XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6901                 internal static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
6902                 {
6903                         DebugHelper.TraceWriteLine ("XDrawRectangle");
6904                         return _XDrawRectangle(display, drawable, gc, x1, y1, width, height);
6905                 }
6906
6907                 [DllImport ("libX11", EntryPoint="XFillRectangle")]
6908                 internal extern static int _XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6909                 internal static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
6910                 {
6911                         DebugHelper.TraceWriteLine ("XFillRectangle");
6912                         return _XFillRectangle(display, drawable, gc, x1, y1, width, height);
6913                 }
6914
6915                 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
6916                 internal extern static int _XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
6917                 internal static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background)
6918                 {
6919                         DebugHelper.TraceWriteLine ("XSetWindowBackground");
6920                         return _XSetWindowBackground(display, window, background);
6921                 }
6922
6923                 [DllImport ("libX11", EntryPoint="XCopyArea")]
6924                 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);
6925                 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)
6926                 {
6927                         DebugHelper.TraceWriteLine ("XCopyArea");
6928                         return _XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
6929                 }
6930
6931                 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
6932                 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);
6933                 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)
6934                 {
6935                         DebugHelper.TraceWriteLine ("XGetWindowProperty");
6936                         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);
6937                 }
6938
6939                 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
6940                 internal extern static int _XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
6941                 internal static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time)
6942                 {
6943                         DebugHelper.TraceWriteLine ("XSetInputFocus");
6944                         return _XSetInputFocus(display, window, revert_to, time);
6945                 }
6946
6947                 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
6948                 internal extern static int _XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
6949                 internal static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number)
6950                 {
6951                         DebugHelper.TraceWriteLine ("XIconifyWindow");
6952                         return _XIconifyWindow(display, window, screen_number);
6953                 }
6954
6955                 [DllImport ("libX11", EntryPoint="XDefineCursor")]
6956                 internal extern static int _XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
6957                 internal static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor)
6958                 {
6959                         DebugHelper.TraceWriteLine ("XDefineCursor");
6960                         return _XDefineCursor(display, window, cursor);
6961                 }
6962
6963                 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
6964                 internal extern static int _XUndefineCursor(IntPtr display, IntPtr window);
6965                 internal static int XUndefineCursor(IntPtr display, IntPtr window)
6966                 {
6967                         DebugHelper.TraceWriteLine ("XUndefineCursor");
6968                         return _XUndefineCursor(display, window);
6969                 }
6970
6971                 [DllImport ("libX11", EntryPoint="XFreeCursor")]
6972                 internal extern static int _XFreeCursor(IntPtr display, IntPtr cursor);
6973                 internal static int XFreeCursor(IntPtr display, IntPtr cursor)
6974                 {
6975                         DebugHelper.TraceWriteLine ("XFreeCursor");
6976                         return _XFreeCursor(display, cursor);
6977                 }
6978
6979                 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
6980                 internal extern static IntPtr _XCreateFontCursor(IntPtr display, CursorFontShape shape);
6981                 internal static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape)
6982                 {
6983                         DebugHelper.TraceWriteLine ("XCreateFontCursor");
6984                         return _XCreateFontCursor(display, shape);
6985                 }
6986
6987                 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
6988                 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);
6989                 internal static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot)
6990                 {
6991                         DebugHelper.TraceWriteLine ("XCreatePixmapCursor");
6992                         return _XCreatePixmapCursor(display, source, mask, ref foreground_color, ref background_color, x_hot, y_hot);
6993                 }
6994
6995                 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
6996                 internal extern static IntPtr _XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
6997                 internal static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth)
6998                 {
6999                         DebugHelper.TraceWriteLine ("XCreatePixmapFromBitmapData");
7000                         return _XCreatePixmapFromBitmapData(display, drawable, data, width, height, fg, bg, depth);
7001                 }
7002
7003                 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7004                 internal extern static IntPtr _XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7005                 internal static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth)
7006                 {
7007                         DebugHelper.TraceWriteLine ("XCreatePixmap");
7008                         return _XCreatePixmap(display, d, width, height, depth);
7009                 }
7010
7011                 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7012                 internal extern static IntPtr _XFreePixmap(IntPtr display, IntPtr pixmap);
7013                 internal static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap)
7014                 {
7015                         DebugHelper.TraceWriteLine ("XFreePixmap");
7016                         return _XFreePixmap(display, pixmap);
7017                 }
7018
7019                 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7020                 internal extern static int _XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7021                 internal static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height)
7022                 {
7023                         DebugHelper.TraceWriteLine ("XQueryBestCursor");
7024                         return _XQueryBestCursor(display, drawable, width, height, out best_width, out best_height);
7025                 }
7026
7027                 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7028                 internal extern static int _XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7029                 internal static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error)
7030                 {
7031                         DebugHelper.TraceWriteLine ("XQueryExtension");
7032                         return _XQueryExtension(display, extension_name, ref major, ref first_event, ref first_error);
7033                 }
7034
7035                 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7036                 internal extern static IntPtr _XWhitePixel(IntPtr display, int screen_no);
7037                 internal static IntPtr XWhitePixel(IntPtr display, int screen_no)
7038                 {
7039                         DebugHelper.TraceWriteLine ("XWhitePixel");
7040                         return _XWhitePixel(display, screen_no);
7041                 }
7042
7043                 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7044                 internal extern static IntPtr _XBlackPixel(IntPtr display, int screen_no);
7045                 internal static IntPtr XBlackPixel(IntPtr display, int screen_no)
7046                 {
7047                         DebugHelper.TraceWriteLine ("XBlackPixel");
7048                         return _XBlackPixel(display, screen_no);
7049                 }
7050
7051                 [DllImport ("libX11", EntryPoint="XGrabServer")]
7052                 internal extern static void _XGrabServer(IntPtr display);
7053                 internal static void XGrabServer(IntPtr display)
7054                 {
7055                         DebugHelper.TraceWriteLine ("XGrabServer");
7056                         _XGrabServer(display);
7057                 }
7058
7059                 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7060                 internal extern static void _XUngrabServer(IntPtr display);
7061                 internal static void XUngrabServer(IntPtr display)
7062                 {
7063                         DebugHelper.TraceWriteLine ("XUngrabServer");
7064                         _XUngrabServer(display);
7065                 }
7066
7067                 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7068                 internal extern static void _XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7069                 internal static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return)
7070                 {
7071                         DebugHelper.TraceWriteLine ("XGetWMNormalHints");
7072                         _XGetWMNormalHints(display, window, ref hints, out supplied_return);
7073                 }
7074
7075                 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7076                 internal extern static void _XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7077                 internal static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints)
7078                 {
7079                         DebugHelper.TraceWriteLine ("XSetWMNormalHints");
7080                         _XSetWMNormalHints(display, window, ref hints);
7081                 }
7082
7083                 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7084                 internal extern static void _XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7085                 internal static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints)
7086                 {
7087                         DebugHelper.TraceWriteLine ("XSetZoomHints");
7088                         _XSetZoomHints(display, window, ref hints);
7089                 }
7090
7091                 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7092                 internal extern static void _XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7093                 internal static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints)
7094                 {
7095                         DebugHelper.TraceWriteLine ("XSetWMHints");
7096                         _XSetWMHints(display, window, ref wmhints);
7097                 }
7098
7099                 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7100                 internal extern static int _XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7101                 internal static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count)
7102                 {
7103                         DebugHelper.TraceWriteLine ("XGetIconSizes");
7104                         return _XGetIconSizes(display, window, out size_list, out count);
7105                 }
7106
7107                 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7108                 internal extern static IntPtr _XSetErrorHandler(XErrorHandler error_handler);
7109                 internal static IntPtr XSetErrorHandler(XErrorHandler error_handler)
7110                 {
7111                         DebugHelper.TraceWriteLine ("XSetErrorHandler");
7112                         return _XSetErrorHandler(error_handler);
7113                 }
7114
7115                 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7116                 internal extern static IntPtr _XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7117                 internal static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length)
7118                 {
7119                         DebugHelper.TraceWriteLine ("XGetErrorText");
7120                         return _XGetErrorText(display, code, buffer, length);
7121                 }
7122
7123                 [DllImport ("libX11", EntryPoint="XInitThreads")]
7124                 internal extern static int _XInitThreads();
7125                 internal static int XInitThreads()
7126                 {
7127                         DebugHelper.TraceWriteLine ("XInitThreads");
7128                         return _XInitThreads();
7129                 }
7130
7131                 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7132                 internal extern static int _XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7133                 internal static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time)
7134                 {
7135                         DebugHelper.TraceWriteLine ("XConvertSelection");
7136                         return _XConvertSelection(display, selection, target, property, requestor, time);
7137                 }
7138
7139                 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7140                 internal extern static IntPtr _XGetSelectionOwner(IntPtr display, IntPtr selection);
7141                 internal static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection)
7142                 {
7143                         DebugHelper.TraceWriteLine ("XGetSelectionOwner");
7144                         return _XGetSelectionOwner(display, selection);
7145                 }
7146
7147                 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7148                 internal extern static int _XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7149                 internal static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time)
7150                 {
7151                         DebugHelper.TraceWriteLine ("XSetSelectionOwner");
7152                         return _XSetSelectionOwner(display, selection, owner, time);
7153                 }
7154
7155                 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7156                 internal extern static int _XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7157                 internal static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask)
7158                 {
7159                         DebugHelper.TraceWriteLine ("XSetPlaneMask");
7160                         return _XSetPlaneMask(display, gc, mask);
7161                 }
7162
7163                 [DllImport ("libX11", EntryPoint="XSetForeground")]
7164                 internal extern static int _XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7165                 internal static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground)
7166                 {
7167                         DebugHelper.TraceWriteLine ("XSetForeground");
7168                         return _XSetForeground(display, gc, foreground);
7169                 }
7170
7171                 [DllImport ("libX11", EntryPoint="XSetBackground")]
7172                 internal extern static int _XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7173                 internal static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background)
7174                 {
7175                         DebugHelper.TraceWriteLine ("XSetBackground");
7176                         return _XSetBackground(display, gc, background);
7177                 }
7178
7179                 [DllImport ("libX11", EntryPoint="XBell")]
7180                 internal extern static int _XBell(IntPtr display, int percent);
7181                 internal static int XBell(IntPtr display, int percent)
7182                 {
7183                         DebugHelper.TraceWriteLine ("XBell");
7184                         return _XBell(display, percent);
7185                 }
7186
7187                 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7188                 internal extern static int _XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7189                 internal static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time)
7190                 {
7191                         DebugHelper.TraceWriteLine ("XChangeActivePointerGrab");
7192                         return _XChangeActivePointerGrab (display, event_mask, cursor, time);
7193                 }
7194
7195                 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7196                 internal extern static bool _XFilterEvent(ref XEvent xevent, IntPtr window);
7197                 internal static bool XFilterEvent(ref XEvent xevent, IntPtr window)
7198                 {
7199                         DebugHelper.TraceWriteLine ("XFilterEvent");
7200                         return _XFilterEvent(ref xevent, window);
7201                 }
7202
7203                 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7204                 internal extern static void _XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7205                 internal static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported)
7206                 {
7207                         DebugHelper.TraceWriteLine ("XkbSetDetectableAutoRepeat");
7208                         _XkbSetDetectableAutoRepeat (display, detectable, supported);
7209                 }
7210
7211                 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7212                 internal extern static void _XPeekEvent (IntPtr display, ref XEvent xevent);
7213                 internal static void XPeekEvent (IntPtr display, ref XEvent xevent)
7214                 {
7215                         DebugHelper.TraceWriteLine ("XPeekEvent");
7216                         _XPeekEvent (display, ref xevent);
7217                 }
7218
7219                 [DllImport ("libX11", EntryPoint="XIfEvent")]
7220                 internal extern static void _XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7221                 internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg)
7222                 {
7223                         DebugHelper.TraceWriteLine ("XIfEvent");
7224                         _XIfEvent (display, ref xevent, event_predicate, arg);
7225                 }
7226 #endregion
7227
7228
7229 #else //no TRACE defined
7230
7231 #region Xcursor imports
7232                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
7233                 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
7234
7235                 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
7236                 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
7237                 
7238                 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
7239                 internal extern static void XcursorImagesDestroy (IntPtr images);
7240                 
7241                 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
7242                 internal extern static int XcursorGetDefaultSize (IntPtr display);
7243
7244                 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
7245                 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
7246
7247                 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
7248                 internal extern static IntPtr XcursorGetTheme (IntPtr display);
7249 #endregion
7250                 #region X11 Imports
7251                 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
7252                 internal extern static IntPtr XOpenDisplay(IntPtr display);
7253                 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
7254                 internal extern static int XCloseDisplay(IntPtr display);                                                   
7255                 [DllImport ("libX11", EntryPoint="XSynchronize")]
7256                 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
7257
7258                 [DllImport ("libX11", EntryPoint="XCreateWindow")]
7259                 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);
7260                 
7261                 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
7262                 internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
7263                 
7264                 [DllImport ("libX11", EntryPoint="XMapWindow")]
7265                 internal extern static int XMapWindow(IntPtr display, IntPtr window);
7266                 
7267                 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
7268                 internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
7269                 
7270                 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
7271                 internal extern static int XMapSubindows(IntPtr display, IntPtr window);
7272                 
7273                 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
7274                 internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
7275                 
7276                 [DllImport ("libX11", EntryPoint="XRootWindow")]
7277                 internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
7278                 
7279                 [DllImport ("libX11", EntryPoint="XNextEvent")]
7280                 internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
7281
7282                 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
7283                 internal extern static int XConnectionNumber (IntPtr display);
7284                 
7285                 [DllImport ("libX11", EntryPoint="XPending")]
7286                 internal extern static int XPending (IntPtr display);
7287                 
7288                 [DllImport ("libX11", EntryPoint="XSelectInput")]
7289                 internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
7290                 
7291                 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
7292                 internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
7293                 
7294                 [DllImport ("libX11", EntryPoint="XReparentWindow")]
7295                 internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
7296                 
7297                 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
7298                 extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
7299                 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
7300                 {
7301                         int ret = XMoveResizeWindow (display, window, x, y, width, height);
7302                         Keyboard.MoveCurrentCaretPos ();
7303                         return ret;
7304                 }
7305
7306                 [DllImport ("libX11", EntryPoint="XResizeWindow")]
7307                 internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
7308
7309                 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
7310                 internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
7311
7312                 [DllImport ("libX11", EntryPoint="XFlush")]
7313                 internal extern static int XFlush(IntPtr display);
7314
7315                 [DllImport ("libX11", EntryPoint="XSetWMName")]
7316                 internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
7317
7318                 [DllImport ("libX11", EntryPoint="XStoreName")]
7319                 internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
7320
7321                 [DllImport ("libX11", EntryPoint="XFetchName")]
7322                 internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
7323
7324                 [DllImport ("libX11", EntryPoint="XSendEvent")]
7325                 internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
7326
7327                 [DllImport ("libX11", EntryPoint="XQueryTree")]
7328                 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);
7329
7330                 [DllImport ("libX11", EntryPoint="XFree")]
7331                 internal extern static int XFree(IntPtr data);
7332
7333                 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
7334                 internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
7335
7336                 [DllImport ("libX11", EntryPoint="XLowerWindow")]
7337                 internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
7338
7339                 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
7340                 internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
7341
7342                 [DllImport ("libX11", EntryPoint="XInternAtom")]
7343                 internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
7344
7345                 [DllImport ("libX11", EntryPoint="XInternAtoms")]
7346                 internal extern static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
7347
7348                 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
7349                 internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
7350
7351                 [DllImport ("libX11", EntryPoint="XGrabPointer")]
7352                 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);
7353
7354                 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
7355                 internal extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
7356
7357                 [DllImport ("libX11", EntryPoint="XQueryPointer")]
7358                 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);
7359
7360                 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
7361                 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);
7362
7363                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7364                 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);
7365
7366                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7367                 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);
7368
7369                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7370                 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);
7371
7372                 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7373                 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);
7374
7375                 [DllImport ("libX11", EntryPoint="XWarpPointer")]
7376                 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);
7377
7378                 [DllImport ("libX11", EntryPoint="XClearWindow")]
7379                 internal extern static int XClearWindow(IntPtr display, IntPtr window);
7380
7381                 [DllImport ("libX11", EntryPoint="XClearArea")]
7382                 internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
7383
7384                 // Colormaps
7385                 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
7386                 internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
7387
7388                 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
7389                 internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
7390
7391                 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
7392                 internal extern static IntPtr XDefaultVisual(IntPtr display, int screen_number);
7393
7394                 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
7395                 internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
7396
7397                 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
7398                 internal extern static int XDefaultScreen(IntPtr display);
7399
7400                 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
7401                 internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
7402
7403                 [DllImport ("libX11", EntryPoint="XLookupColor")]
7404                 internal extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
7405
7406                 [DllImport ("libX11", EntryPoint="XAllocColor")]
7407                 internal extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
7408
7409                 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
7410                 internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
7411
7412                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7413                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
7414
7415                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7416                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
7417
7418                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7419                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
7420
7421                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7422                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
7423
7424                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7425                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
7426
7427                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7428                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
7429
7430                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7431                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
7432
7433                 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
7434                 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
7435
7436                 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
7437                 internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
7438
7439                 // Drawing
7440                 [DllImport ("libX11", EntryPoint="XCreateGC")]
7441                 internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
7442
7443                 [DllImport ("libX11", EntryPoint="XFreeGC")]
7444                 internal extern static int XFreeGC(IntPtr display, IntPtr gc);
7445
7446                 [DllImport ("libX11", EntryPoint="XSetFunction")]
7447                 internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
7448
7449                 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
7450                 internal extern static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
7451
7452                 [DllImport ("libX11", EntryPoint="XDrawLine")]
7453                 internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
7454
7455                 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
7456                 internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7457
7458                 [DllImport ("libX11", EntryPoint="XFillRectangle")]
7459                 internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7460
7461                 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
7462                 internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
7463
7464                 [DllImport ("libX11", EntryPoint="XCopyArea")]
7465                 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);
7466
7467                 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
7468                 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);
7469
7470                 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
7471                 internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
7472
7473                 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
7474                 internal extern static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
7475
7476                 [DllImport ("libX11", EntryPoint="XDefineCursor")]
7477                 internal extern static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
7478
7479                 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
7480                 internal extern static int XUndefineCursor(IntPtr display, IntPtr window);
7481
7482                 [DllImport ("libX11", EntryPoint="XFreeCursor")]
7483                 internal extern static int XFreeCursor(IntPtr display, IntPtr cursor);
7484
7485                 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
7486                 internal extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
7487
7488                 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
7489                 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);
7490
7491                 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
7492                 internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
7493
7494                 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7495                 internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7496
7497                 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7498                 internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
7499
7500                 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7501                 internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7502
7503                 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7504                 internal extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7505
7506                 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7507                 internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
7508
7509                 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7510                 internal extern static IntPtr XBlackPixel(IntPtr display, int screen_no);
7511
7512                 [DllImport ("libX11", EntryPoint="XGrabServer")]
7513                 internal extern static void XGrabServer(IntPtr display);
7514
7515                 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7516                 internal extern static void XUngrabServer(IntPtr display);
7517
7518                 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7519                 internal extern static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7520
7521                 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7522                 internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7523
7524                 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7525                 internal extern static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7526
7527                 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7528                 internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7529
7530                 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7531                 internal extern static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7532
7533                 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7534                 internal extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
7535
7536                 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7537                 internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7538
7539                 [DllImport ("libX11", EntryPoint="XInitThreads")]
7540                 internal extern static int XInitThreads();
7541
7542                 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7543                 internal extern static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7544
7545                 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7546                 internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
7547
7548                 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7549                 internal extern static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7550
7551                 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7552                 internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7553
7554                 [DllImport ("libX11", EntryPoint="XSetForeground")]
7555                 internal extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7556
7557                 [DllImport ("libX11", EntryPoint="XSetBackground")]
7558                 internal extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7559
7560                 [DllImport ("libX11", EntryPoint="XBell")]
7561                 internal extern static int XBell(IntPtr display, int percent);
7562
7563                 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7564                 internal extern static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7565
7566                 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7567                 internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
7568
7569                 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7570                 internal extern static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7571
7572                 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7573                 internal extern static void XPeekEvent (IntPtr display, ref XEvent xevent);
7574
7575                 [DllImport ("libX11", EntryPoint="XIfEvent")]
7576                 internal extern static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7577
7578                 [DllImport ("libX11", EntryPoint="XGetInputFocus")]
7579                 internal extern static void XGetInputFocus (IntPtr display, out IntPtr focus, out IntPtr revert_to);
7580                 #endregion
7581 #region Gtk/Gdk imports
7582                 [DllImport("libgdk-x11-2.0")]
7583                 internal extern static IntPtr gdk_atom_intern (string atomName, bool onlyIfExists);
7584
7585                 [DllImport("libgtk-x11-2.0")]
7586                 internal extern static IntPtr gtk_clipboard_get (IntPtr atom);
7587
7588                 [DllImport("libgtk-x11-2.0")]
7589                 internal extern static void gtk_clipboard_store (IntPtr clipboard);
7590
7591                 [DllImport("libgtk-x11-2.0")]
7592                 internal extern static void gtk_clipboard_set_text (IntPtr clipboard, string text, int len);
7593 #endregion
7594
7595 #endif
7596         }
7597 }