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