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