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