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