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