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