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