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