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