merge -r 60814:60815
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUIX11GTK.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 //      Alexander Olk   alex.olk@googlemail.com
25 //
26 //
27
28 // NOTE:
29 //      This driver understands the following environment variables: (Set the var to enable feature)
30 //
31 //      MONO_XEXCEPTIONS        = throw an exception when a X11 error is encountered;
32 //                                by default a message is displayed but execution continues
33 //
34 //      MONO_XSYNC              = perform all X11 commands synchronous; this is slower but
35 //                                helps in debugging errors
36 //
37
38 // NOT COMPLETE - WORK IN PROGRESS
39
40 // One feature of the driver is, that PaintEventstart returns a graphics context created from a offscreen drawable (pixmap)
41
42 // define to log Window handles and relationships to stdout
43 #undef DriverDebug
44
45 // Extra detailed debug
46 #undef  DriverDebugExtra
47
48 using System;
49 using System.ComponentModel;
50 using System.Collections;
51 using System.Diagnostics;
52 using System.Drawing;
53 using System.Drawing.Drawing2D;
54 using System.Drawing.Imaging;
55 using System.IO;
56 using System.Net;
57 using System.Net.Sockets;
58 using System.Reflection;
59 using System.Runtime.InteropServices;
60 using System.Text;
61 using System.Threading;
62
63 // Only do the poll when building with mono for now
64 #if __MonoCS__
65 using Mono.Unix.Native;
66 #endif
67
68 /// X11 Version
69 namespace System.Windows.Forms {
70         internal class XplatUIX11GTK : XplatUIDriver {
71                 
72                 internal enum GdkWindowClass {
73                         GDK_INPUT_OUTPUT,
74                         GDK_INPUT_ONLY
75                 }
76                 
77                 internal enum GdkWindowType {
78                         GDK_WINDOW_ROOT,
79                         GDK_WINDOW_TOPLEVEL,
80                         GDK_WINDOW_CHILD,
81                         GDK_WINDOW_DIALOG,
82                         GDK_WINDOW_TEMP,
83                         GDK_WINDOW_FOREIGN
84                 }
85                 
86                 internal enum GdkWindowHints {
87                         GDK_HINT_POS         = 1 << 0,
88                         GDK_HINT_MIN_SIZE    = 1 << 1,
89                         GDK_HINT_MAX_SIZE    = 1 << 2,
90                         GDK_HINT_BASE_SIZE   = 1 << 3,
91                         GDK_HINT_ASPECT      = 1 << 4,
92                         GDK_HINT_RESIZE_INC  = 1 << 5,
93                         GDK_HINT_WIN_GRAVITY = 1 << 6,
94                         GDK_HINT_USER_POS    = 1 << 7,
95                         GDK_HINT_USER_SIZE   = 1 << 8
96                 }
97                 
98                 internal enum GdkGravity {
99                         GDK_GRAVITY_NORTH_WEST = 1,
100                         GDK_GRAVITY_NORTH,
101                         GDK_GRAVITY_NORTH_EAST,
102                         GDK_GRAVITY_WEST,
103                         GDK_GRAVITY_CENTER,
104                         GDK_GRAVITY_EAST,
105                         GDK_GRAVITY_SOUTH_WEST,
106                         GDK_GRAVITY_SOUTH,
107                         GDK_GRAVITY_SOUTH_EAST,
108                         GDK_GRAVITY_STATIC
109                 }
110                 
111                 internal enum GdkWindowEdge {
112                         GDK_WINDOW_EDGE_NORTH_WEST,
113                         GDK_WINDOW_EDGE_NORTH,
114                         GDK_WINDOW_EDGE_NORTH_EAST,
115                         GDK_WINDOW_EDGE_WEST,
116                         GDK_WINDOW_EDGE_EAST,
117                         GDK_WINDOW_EDGE_SOUTH_WEST,
118                         GDK_WINDOW_EDGE_SOUTH,
119                         GDK_WINDOW_EDGE_SOUTH_EAST  
120                 }
121                 
122                 internal enum GdkWindowTypeHint {
123                         GDK_WINDOW_TYPE_HINT_NORMAL,
124                         GDK_WINDOW_TYPE_HINT_DIALOG,
125                         GDK_WINDOW_TYPE_HINT_MENU,
126                         GDK_WINDOW_TYPE_HINT_TOOLBAR,
127                         GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
128                         GDK_WINDOW_TYPE_HINT_UTILITY,
129                         GDK_WINDOW_TYPE_HINT_DOCK,
130                         GDK_WINDOW_TYPE_HINT_DESKTOP
131                 }
132                 
133                 internal enum GdkWindowAttributesType {
134                         GDK_WA_TITLE    = 1 << 1,
135                         GDK_WA_X        = 1 << 2,
136                         GDK_WA_Y        = 1 << 3,
137                         GDK_WA_CURSOR   = 1 << 4,
138                         GDK_WA_COLORMAP = 1 << 5,
139                         GDK_WA_VISUAL   = 1 << 6,
140                         GDK_WA_WMCLASS  = 1 << 7,
141                         GDK_WA_NOREDIR  = 1 << 8
142                 }
143                 
144                 internal enum GdkEventMask {
145                         GDK_EXPOSURE_MASK               = 1 << 1,
146                         GDK_POINTER_MOTION_MASK         = 1 << 2,
147                         GDK_POINTER_MOTION_HINT_MASK    = 1 << 3,
148                         GDK_BUTTON_MOTION_MASK          = 1 << 4,
149                         GDK_BUTTON1_MOTION_MASK         = 1 << 5,
150                         GDK_BUTTON2_MOTION_MASK         = 1 << 6,
151                         GDK_BUTTON3_MOTION_MASK         = 1 << 7,
152                         GDK_BUTTON_PRESS_MASK           = 1 << 8,
153                         GDK_BUTTON_RELEASE_MASK         = 1 << 9,
154                         GDK_KEY_PRESS_MASK              = 1 << 10,
155                         GDK_KEY_RELEASE_MASK            = 1 << 11,
156                         GDK_ENTER_NOTIFY_MASK           = 1 << 12,
157                         GDK_LEAVE_NOTIFY_MASK           = 1 << 13,
158                         GDK_FOCUS_CHANGE_MASK           = 1 << 14,
159                         GDK_STRUCTURE_MASK              = 1 << 15,
160                         GDK_PROPERTY_CHANGE_MASK        = 1 << 16,
161                         GDK_VISIBILITY_NOTIFY_MASK      = 1 << 17,
162                         GDK_PROXIMITY_IN_MASK           = 1 << 18,
163                         GDK_PROXIMITY_OUT_MASK          = 1 << 19,
164                         GDK_SUBSTRUCTURE_MASK           = 1 << 20,
165                         GDK_SCROLL_MASK                 = 1 << 21,
166                         GDK_ALL_EVENTS_MASK             = 0x3FFFFE
167                 }
168                 
169                 internal enum GdkEventType {
170                         GDK_NOTHING             = -1,
171                         GDK_DELETE              = 0,
172                         GDK_DESTROY             = 1,
173                         GDK_EXPOSE              = 2,
174                         GDK_MOTION_NOTIFY       = 3,
175                         GDK_BUTTON_PRESS        = 4,
176                         GDK_2BUTTON_PRESS       = 5,
177                         GDK_3BUTTON_PRESS       = 6,
178                         GDK_BUTTON_RELEASE      = 7,
179                         GDK_KEY_PRESS           = 8,
180                         GDK_KEY_RELEASE         = 9,
181                         GDK_ENTER_NOTIFY        = 10,
182                         GDK_LEAVE_NOTIFY        = 11,
183                         GDK_FOCUS_CHANGE        = 12,
184                         GDK_CONFIGURE           = 13,
185                         GDK_MAP                 = 14,
186                         GDK_UNMAP               = 15,
187                         GDK_PROPERTY_NOTIFY     = 16,
188                         GDK_SELECTION_CLEAR     = 17,
189                         GDK_SELECTION_REQUEST   = 18,
190                         GDK_SELECTION_NOTIFY    = 19,
191                         GDK_PROXIMITY_IN        = 20,
192                         GDK_PROXIMITY_OUT       = 21,
193                         GDK_DRAG_ENTER          = 22,
194                         GDK_DRAG_LEAVE          = 23,
195                         GDK_DRAG_MOTION         = 24,
196                         GDK_DRAG_STATUS         = 25,
197                         GDK_DROP_START          = 26,
198                         GDK_DROP_FINISHED       = 27,
199                         GDK_CLIENT_EVENT        = 28,
200                         GDK_VISIBILITY_NOTIFY   = 29,
201                         GDK_NO_EXPOSE           = 30,
202                         GDK_SCROLL              = 31,
203                         GDK_WINDOW_STATE        = 32,
204                         GDK_SETTING             = 33,
205                         GDK_OWNER_CHANGE        = 34,
206                         GDK_GRAB_BROKEN         = 35
207                 }
208                 
209                 internal enum GdkWMDecoration {
210                         GDK_DECOR_ALL           = 1 << 0,
211                         GDK_DECOR_BORDER        = 1 << 1,
212                         GDK_DECOR_RESIZEH       = 1 << 2,
213                         GDK_DECOR_TITLE         = 1 << 3,
214                         GDK_DECOR_MENU          = 1 << 4,
215                         GDK_DECOR_MINIMIZE      = 1 << 5,
216                         GDK_DECOR_MAXIMIZE      = 1 << 6
217                 }
218                 
219                 internal enum GdkWMFunction {
220                         GDK_FUNC_ALL            = 1 << 0,
221                         GDK_FUNC_RESIZE         = 1 << 1,
222                         GDK_FUNC_MOVE           = 1 << 2,
223                         GDK_FUNC_MINIMIZE       = 1 << 3,
224                         GDK_FUNC_MAXIMIZE       = 1 << 4,
225                         GDK_FUNC_CLOSE          = 1 << 5
226                 }
227                 
228                 internal enum GdkCursorType {
229                         GDK_X_CURSOR              = 0,
230                         GDK_ARROW                 = 2,
231                         GDK_BASED_ARROW_DOWN      = 4,
232                         GDK_BASED_ARROW_UP        = 6,
233                         GDK_BOAT                  = 8,
234                         GDK_BOGOSITY              = 10,
235                         GDK_BOTTOM_LEFT_CORNER    = 12,
236                         GDK_BOTTOM_RIGHT_CORNER   = 14,
237                         GDK_BOTTOM_SIDE           = 16,
238                         GDK_BOTTOM_TEE            = 18,
239                         GDK_BOX_SPIRAL            = 20,
240                         GDK_CENTER_PTR            = 22,
241                         GDK_CIRCLE                = 24,
242                         GDK_CLOCK                 = 26,
243                         GDK_COFFEE_MUG            = 28,
244                         GDK_CROSS                 = 30,
245                         GDK_CROSS_REVERSE         = 32,
246                         GDK_CROSSHAIR             = 34,
247                         GDK_DIAMOND_CROSS         = 36,
248                         GDK_DOT                   = 38,
249                         GDK_DOTBOX                = 40,
250                         GDK_DOUBLE_ARROW          = 42,
251                         GDK_DRAFT_LARGE           = 44,
252                         GDK_DRAFT_SMALL           = 46,
253                         GDK_DRAPED_BOX            = 48,
254                         GDK_EXCHANGE              = 50,
255                         GDK_FLEUR                 = 52,
256                         GDK_GOBBLER               = 54,
257                         GDK_GUMBY                 = 56,
258                         GDK_HAND1                 = 58,
259                         GDK_HAND2                 = 60,
260                         GDK_HEART                 = 62,
261                         GDK_ICON                  = 64,
262                         GDK_IRON_CROSS            = 66,
263                         GDK_LEFT_PTR              = 68,
264                         GDK_LEFT_SIDE             = 70,
265                         GDK_LEFT_TEE              = 72,
266                         GDK_LEFTBUTTON            = 74,
267                         GDK_LL_ANGLE              = 76,
268                         GDK_LR_ANGLE              = 78,
269                         GDK_MAN                   = 80,
270                         GDK_MIDDLEBUTTON          = 82,
271                         GDK_MOUSE                 = 84,
272                         GDK_PENCIL                = 86,
273                         GDK_PIRATE                = 88,
274                         GDK_PLUS                  = 90,
275                         GDK_QUESTION_ARROW        = 92,
276                         GDK_RIGHT_PTR             = 94,
277                         GDK_RIGHT_SIDE            = 96,
278                         GDK_RIGHT_TEE             = 98,
279                         GDK_RIGHTBUTTON           = 100,
280                         GDK_RTL_LOGO              = 102,
281                         GDK_SAILBOAT              = 104,
282                         GDK_SB_DOWN_ARROW         = 106,
283                         GDK_SB_H_DOUBLE_ARROW     = 108,
284                         GDK_SB_LEFT_ARROW         = 110,
285                         GDK_SB_RIGHT_ARROW        = 112,
286                         GDK_SB_UP_ARROW           = 114,
287                         GDK_SB_V_DOUBLE_ARROW     = 116,
288                         GDK_SHUTTLE               = 118,
289                         GDK_SIZING                = 120,
290                         GDK_SPIDER                = 122,
291                         GDK_SPRAYCAN              = 124,
292                         GDK_STAR                  = 126,
293                         GDK_TARGET                = 128,
294                         GDK_TCROSS                = 130,
295                         GDK_TOP_LEFT_ARROW        = 132,
296                         GDK_TOP_LEFT_CORNER       = 134,
297                         GDK_TOP_RIGHT_CORNER      = 136,
298                         GDK_TOP_SIDE              = 138,
299                         GDK_TOP_TEE               = 140,
300                         GDK_TREK                  = 142,
301                         GDK_UL_ANGLE              = 144,
302                         GDK_UMBRELLA              = 146,
303                         GDK_UR_ANGLE              = 148,
304                         GDK_WATCH                 = 150,
305                         GDK_XTERM                 = 152,
306                         GDK_LAST_CURSOR,
307                         GDK_CURSOR_IS_PIXMAP      = -1
308                 }
309                 
310                 internal enum GdkPropMode {
311                         GDK_PROP_MODE_REPLACE,
312                         GDK_PROP_MODE_PREPEND,
313                         GDK_PROP_MODE_APPEND
314                 }
315                 
316                 [StructLayout (LayoutKind.Sequential)] 
317                 internal struct GdkGeometry {
318                         internal int min_width;
319                         internal int min_height;
320                         internal int max_width;
321                         internal int max_height;
322                         internal int base_width;
323                         internal int base_height;
324                         internal int width_inc;
325                         internal int height_inc;
326                         internal double min_aspect;
327                         internal double max_aspect;
328                         internal GdkGravity win_gravity;
329                 }
330                 
331                 [StructLayout (LayoutKind.Sequential)] 
332                 internal struct GdkWindowAttr {
333                         internal string title;
334                         internal int event_mask;
335                         internal int x, y;
336                         internal int width;
337                         internal int height;
338                         internal GdkWindowClass wclass;
339                         internal IntPtr visual;
340                         internal IntPtr colormap;
341                         internal GdkWindowType window_type;
342                         internal IntPtr cursor;
343                         internal string wmclass_name;
344                         internal string wmclass_class;
345                         internal bool override_redirect;
346                 }
347                 
348                 #region Local Variables
349                 // General
350                 static volatile XplatUIX11GTK   Instance;
351                 private static int              RefCount;
352                 private static object           XlibLock;               // Our locking object
353                 private static bool             ThemesEnabled;
354                 
355                 // General X11
356                 private static IntPtr           DisplayHandle;          // X11 handle to display
357                 private static IntPtr           GdkDisplayHandle;       // gdk handle to display
358                 private static int              ScreenNo;               // Screen number used
359                 private static IntPtr           GdkScreen;
360                 private static IntPtr           DefaultColormap;        // Colormap for screen
361                 private static IntPtr           GdkDefaultColormap;     // Gdk Colormap for screen
362                 private static IntPtr           CustomVisual;           // Visual for window creation
363                 private static IntPtr           GdkCustomVisual;
364                 private static IntPtr           CustomColormap;         // Colormap for window creation
365                 private static IntPtr           GdkCustomColormap;
366                 private static int              VisualBestDepth;
367                 private static IntPtr           RootWindow;             // Handle of the root window for the screen/display
368                 private static IntPtr           GdkRootWindow;          // Gdk handle of the root window for the screen/display
369                 private static IntPtr           FosterParent;           // Container to hold child windows until their parent exists
370                 private static IntPtr           GdkFosterParent;        // Container to hold child windows until their parent exists
371                 private static XErrorHandler    ErrorHandler;           // Error handler delegate
372                 private static bool             ErrorExceptions;        // Throw exceptions on X errors
373                 private static bool             PostQuitState;          // True if we've got an pending exit
374                 
375                 // Clipboard
376                 private static IntPtr           ClipMagic = new IntPtr(27051977);
377                 private static ClipboardStruct  Clipboard;              // Our clipboard
378                 
379                 // Communication
380                 private static int              PostAtom;               // PostMessage atom
381                 private static int              AsyncAtom;              // Support for async messages
382                 
383                 // Message Loop
384                 private static XEventQueue      MessageQueue;           // Holds our queued up events
385                 #if __MonoCS__                                          //
386                 private static Pollfd[]         pollfds;                // For watching the X11 socket
387                 #endif                                                  //
388                 private static X11Keyboard      Keyboard;               //
389                 private static X11Dnd           Dnd;
390                 private static Socket           listen;                 //
391                 private static Socket           wake;                   //
392                 private static Socket           wake_receive;           //
393                 private static byte[]           network_buffer;         //
394                 
395                 
396                 // Focus tracking
397                 private static IntPtr           ActiveWindow;           // Handle of the active window
398                 private static IntPtr           FocusWindow;            // Handle of the window with keyboard focus (if any)
399                 
400                 // Modality support
401                 private static Stack            ModalWindows;           // Stack of our modal windows
402                 
403                 // Systray
404                 private static IntPtr           SystrayMgrWindow;       // Handle of the Systray Manager window
405                 
406                 // Cursors
407                 private static IntPtr           LastCursorWindow;       // The last window we set the cursor on
408                 private static IntPtr           LastCursorHandle;       // The handle that was last set on LastCursorWindow
409                 private static IntPtr           OverrideCursorHandle;   // The cursor that is set to override any other cursors
410                 
411                 // Caret
412                 private static CaretStruct      Caret;                  //
413                 
414                 // Support for Window Styles
415                 private static int[]            NetAtoms;               // All atoms we know
416                 
417                 // mouse hover message generation
418                 private static HoverStruct      HoverState;             //
419                 
420                 // double click message generation
421                 private static ClickStruct      ClickPending;           //
422                 
423                 // Support for mouse grab
424                 private static GrabStruct       Grab;                   //
425                 
426                 // State
427                 private static Point            MousePosition;          // Last position of mouse, in screen coords
428                 internal static MouseButtons    MouseState;             // Last state of mouse buttons
429                 
430                 // Timers
431                 private static ArrayList        TimerList;              // Holds SWF.Timers
432                 
433                 // 'Constants'
434                 private static int              DoubleClickInterval;    // msec; max interval between clicks to count as double click
435                 
436                 const GdkEventMask GdkSelectInputMask = GdkEventMask.GDK_BUTTON_PRESS_MASK | 
437                 GdkEventMask.GDK_BUTTON_RELEASE_MASK | 
438                 GdkEventMask.GDK_KEY_PRESS_MASK | 
439                 GdkEventMask.GDK_KEY_RELEASE_MASK | 
440                 GdkEventMask.GDK_ENTER_NOTIFY_MASK | 
441                 GdkEventMask.GDK_LEAVE_NOTIFY_MASK |
442                 GdkEventMask.GDK_EXPOSURE_MASK |
443                 GdkEventMask.GDK_FOCUS_CHANGE_MASK |
444                 GdkEventMask.GDK_POINTER_MOTION_MASK | 
445                 GdkEventMask.GDK_VISIBILITY_NOTIFY_MASK |
446                 GdkEventMask.GDK_SUBSTRUCTURE_MASK |
447                 GdkEventMask.GDK_STRUCTURE_MASK;
448                 
449                 static readonly object lockobj = new object ();
450                 
451                 static Hashtable backing_store = new Hashtable (5);
452                 
453                 #endregion      // Local Variables
454                 #region Constructors
455                 private XplatUIX11GTK ()
456                 {
457                         Console.WriteLine ("XplatUIX11GTK ctor...");
458                         // Handle singleton stuff first
459                         RefCount = 0;
460                         
461                         // init gdk
462                         int argc = 0;
463                         string argv = "";
464                         
465                         gdk_init_check (out argc, argv);
466                         
467                         // Now regular initialization
468                         XlibLock = new object ();
469                         MessageQueue = new XEventQueue ();
470                         TimerList = new ArrayList ();
471                         XInitThreads ();
472                         
473                         ErrorExceptions = false;
474                         
475                         // X11 Initialization
476                         SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
477                         X11DesktopColors.Initialize ();
478                         
479                         // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
480                         ErrorHandler = new XErrorHandler (HandleError);
481                         XSetErrorHandler (ErrorHandler);
482                 }
483                 #endregion      // Constructors
484                 
485                 #region Singleton Specific Code
486                 public static XplatUIX11GTK GetInstance ()
487                 {
488                         lock (lockobj) {
489                                 if (Instance == null) {
490                                         Instance = new XplatUIX11GTK ();
491                                 }
492                                 RefCount++;
493                         }
494                         return Instance;
495                 }
496                 
497                 public int Reference {
498                         get {
499                                 return RefCount;
500                         }
501                 }
502                 #endregion
503                 
504                 #region Internal Properties
505                 internal static IntPtr Display {
506                         get {
507                                 return DisplayHandle;
508                         }
509                         
510                         set {
511                                 XplatUIX11GTK.GetInstance ().SetDisplay (value);
512                         }
513                 }
514                 
515                 internal static int Screen {
516                         get {
517                                 return ScreenNo;
518                         }
519                         
520                         set {
521                                 ScreenNo = value;
522                         }
523                 }
524                 
525                 internal static IntPtr RootWindowHandle {
526                         get {
527                                 return RootWindow;
528                         }
529                         
530                         set {
531                                 RootWindow = value;
532                         }
533                 }
534                 
535                 internal static IntPtr Visual {
536                         get {
537                                 return CustomVisual;
538                         }
539                         
540                         set {
541                                 CustomVisual = value;
542                         }
543                 }
544                 
545                 internal static IntPtr ColorMap {
546                         get {
547                                 return CustomColormap;
548                         }
549                         
550                         set {
551                                 CustomColormap = value;
552                         }
553                 }
554                 #endregion
555                 
556                 #region XExceptionClass
557                 internal class XException : ApplicationException {
558                         IntPtr          Display;
559                         IntPtr          ResourceID;
560                         IntPtr          Serial;
561                         XRequest        RequestCode;
562                         byte            ErrorCode;
563                         byte            MinorCode;
564                         
565                         public XException (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
566                         {
567                                 this.Display = Display;
568                                 this.ResourceID = ResourceID;
569                                 this.Serial = Serial;
570                                 this.RequestCode = RequestCode;
571                                 this.ErrorCode = ErrorCode;
572                                 this.MinorCode = MinorCode;
573                         }
574                         
575                         public override string Message {
576                                 get {
577                                         return GetMessage (Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
578                                 }
579                         }
580                         
581                         public static string GetMessage (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
582                         {
583                                 StringBuilder   sb;
584                                 string          x_error_text;
585                                 string          error;
586                                 
587                                 sb = new StringBuilder (160);
588                                 XGetErrorText (Display, ErrorCode, sb, sb.Capacity);
589                                 x_error_text = sb.ToString ();
590                                 
591                                 error = String.Format ("\n  Error: {0}\n  Request:     {1:D} ({2})\n  Resource ID: 0x{3:x}\n  Serial:      {4}", x_error_text, RequestCode, RequestCode, ResourceID.ToInt32 (), Serial);
592                                 return error;
593                         }
594                 }
595                 #endregion      // XExceptionClass
596                 
597                 #region Internal Methods
598                 // native X display handle
599                 internal void SetDisplay (IntPtr display_handle)
600                 {
601                         if (display_handle != IntPtr.Zero) {
602                                 Hwnd    hwnd;
603                                 
604                                 if ((GdkDisplayHandle != IntPtr.Zero) && (GdkFosterParent != IntPtr.Zero)) {
605                                         hwnd = Hwnd.ObjectFromHandle (gdk_x11_drawable_get_xid (GdkFosterParent));
606                                         gdk_window_destroy (GdkFosterParent);
607                                         hwnd.Dispose ();
608                                 }
609                                 
610                                 if (GdkDisplayHandle != IntPtr.Zero) {
611                                         gdk_display_close (GdkDisplayHandle);
612                                 }
613                                 
614                                 DisplayHandle = display_handle;
615                                 GdkDisplayHandle = gdk_x11_lookup_xdisplay (display_handle);
616                                 
617                                 // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
618                                 // been hacked to do this for us.
619                                 Graphics.FromHdcInternal (DisplayHandle);
620                                 
621                                 // Debugging support
622                                 if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
623                                         XSynchronize (DisplayHandle, true);                                     
624                                 }
625                                 
626                                 if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
627                                         ErrorExceptions = true;
628                                 }
629                                 
630                                 // Generic X11 setup
631                                 GdkScreen = gdk_screen_get_default ();
632                                 // or gdk_x11_get_default_screen
633                                 ScreenNo = gdk_screen_get_number (GdkScreen);
634                                 GdkRootWindow = gdk_get_default_root_window ();
635                                 RootWindow = gdk_x11_drawable_get_xid (GdkRootWindow);
636                                 GdkDefaultColormap = gdk_colormap_get_system ();
637                                 DefaultColormap = gdk_x11_colormap_get_xcolormap (GdkDefaultColormap);
638                                 
639                                 VisualBestDepth = gdk_visual_get_best_depth ();
640                                 //Console.WriteLine (VisualBestDepth);
641                                 
642                                 // Create the foster parent
643                                 FosterParent = XCreateSimpleWindow (DisplayHandle, RootWindow, 0, 0, 1, 1, 4, 0, 0);
644                                 GdkFosterParent = gdk_window_foreign_new (FosterParent);
645                                 
646                                 if (GdkFosterParent == IntPtr.Zero) {
647                                         Console.WriteLine ("XplatUIX11GTK Constructor failed to create FosterParent");
648                                 }
649                                 
650                                 hwnd = new Hwnd ();
651                                 
652                                 hwnd.WholeWindow = FosterParent;
653                                 hwnd.ClientWindow = FosterParent;
654                                 
655                                 // For sleeping on the X11 socket
656                                 listen = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
657                                 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 0);
658                                 listen.Bind (ep);
659                                 listen.Listen (1);
660                                 
661                                 // To wake up when a timer is ready
662                                 network_buffer = new byte [10];
663                                 
664                                 wake = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
665                                 wake.Connect (listen.LocalEndPoint);
666                                 wake_receive = listen.Accept ();
667                                 
668                                 #if __MonoCS__
669                                 pollfds = new Pollfd [2];
670                                 pollfds [0] = new Pollfd ();
671                                 pollfds [0].fd = XConnectionNumber (DisplayHandle);
672                                 pollfds [0].events = PollEvents.POLLIN;
673
674                                 pollfds [1] = new Pollfd ();
675                                 pollfds [1].fd = wake_receive.Handle.ToInt32 ();
676                                 pollfds [1].events = PollEvents.POLLIN;
677                                 #endif
678                                 
679                                 Keyboard = new X11Keyboard (DisplayHandle);
680                                 Dnd = new X11Dnd (DisplayHandle);
681                                 
682                                 PostQuitState = false;
683                                 
684                                 DoubleClickInterval = 500;
685                                 
686                                 HoverState.Interval = 500;
687                                 HoverState.Timer = new Timer ();
688                                 HoverState.Timer.Enabled = false;
689                                 HoverState.Timer.Interval = HoverState.Interval;
690                                 HoverState.Timer.Tick += new EventHandler (MouseHover);
691                                 HoverState.X = -1;
692                                 HoverState.Y = -1;
693                                 
694                                 ActiveWindow = IntPtr.Zero;
695                                 FocusWindow = IntPtr.Zero;
696                                 ModalWindows = new Stack (3);
697                                 
698                                 MouseState = MouseButtons.None;
699                                 MousePosition = new Point (0, 0);
700                                 
701                                 Caret.Timer = new Timer ();
702                                 Caret.Timer.Interval = 500;             // FIXME - where should this number come from?
703                                 Caret.Timer.Tick += new EventHandler (CaretCallback);
704                                 
705                                 SetupAtoms ();
706                                 
707                                 // Grab atom changes off the root window to catch certain WM events
708                                 gdk_window_set_events (GdkRootWindow, (int)GdkEventMask.GDK_PROPERTY_CHANGE_MASK);
709                                 
710                                 // Handle any upcoming errors
711                                 ErrorHandler = new XErrorHandler (HandleError);
712                                 XSetErrorHandler (ErrorHandler);
713                         } else {
714                                 throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
715                         }
716                 }
717                 
718                 internal static void Where ()
719                 {
720                         Console.WriteLine ("Here: {0}\n", WhereString ());
721                 }
722                 
723                 internal static string WhereString ()
724                 {
725                         StackTrace      stack;
726                         StackFrame      frame;
727                         string          newline;
728                         string          unknown;
729                         StringBuilder   sb;
730                         MethodBase      method;
731                         
732                         newline = String.Format ("{0}\t {1} ", Environment.NewLine, Locale.GetText ("at"));
733                         unknown = Locale.GetText ("<unknown method>");
734                         sb = new StringBuilder ();
735                         stack = new StackTrace (true);
736                         
737                         for (int i = 0; i < stack.FrameCount; i++) {
738                                 frame = stack.GetFrame (i);
739                                 sb.Append (newline);
740                                 
741                                 method = frame.GetMethod ();
742                                 if (method != null) {
743                                         #if not
744                                                 sb.AppendFormat(frame.ToString());
745                                         #endif
746                                         if (frame.GetFileLineNumber () != 0) {
747                                                 sb.AppendFormat ("{0}.{1} () [{2}:{3}]", method.DeclaringType.FullName, method.Name, Path.GetFileName (frame.GetFileName ()), frame.GetFileLineNumber ());
748                                         } else {
749                                                 sb.AppendFormat ("{0}.{1} ()", method.DeclaringType.FullName, method.Name);
750                                         }
751                                 } else { 
752                                         sb.Append (unknown);
753                                 }
754                         }
755                         return sb.ToString ();
756                 }
757                 #endregion      // Internal Methods
758                 
759                 #region Private Methods
760                 private static void SetupAtoms ()
761                 {
762                         NetAtoms = new int [(int)NA.LAST_NET_ATOM];
763                         
764                         NetAtoms [(int)NA.WM_PROTOCOLS] = XInternAtom (DisplayHandle, "WM_PROTOCOLS", false);
765                         NetAtoms [(int)NA.WM_DELETE_WINDOW] = XInternAtom (DisplayHandle, "WM_DELETE_WINDOW", false);
766                         NetAtoms [(int)NA.WM_TAKE_FOCUS] = XInternAtom (DisplayHandle, "WM_TAKE_FOCUS", false);
767                         
768                         NetAtoms [(int)NA._NET_SUPPORTED] = XInternAtom (DisplayHandle, "_NET_SUPPORTED", false);
769                         NetAtoms [(int)NA._NET_CLIENT_LIST] = XInternAtom (DisplayHandle, "_NET_CLIENT_LIST", false);
770                         NetAtoms [(int)NA._NET_NUMBER_OF_DESKTOPS] = XInternAtom (DisplayHandle, "_NET_NUMBER_OF_DESKTOPS", false);
771                         NetAtoms [(int)NA._NET_DESKTOP_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_DESKTOP_GEOMETRY", false);
772                         NetAtoms [(int)NA._NET_DESKTOP_VIEWPORT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_VIEWPORT", false);
773                         NetAtoms [(int)NA._NET_CURRENT_DESKTOP] = XInternAtom (DisplayHandle, "_NET_CURRENT_DESKTOP", false);
774                         NetAtoms [(int)NA._NET_DESKTOP_NAMES] = XInternAtom (DisplayHandle, "_NET_DESKTOP_NAMES", false);
775                         NetAtoms [(int)NA._NET_ACTIVE_WINDOW] = XInternAtom (DisplayHandle, "_NET_ACTIVE_WINDOW", false);
776                         NetAtoms [(int)NA._NET_WORKAREA] = XInternAtom (DisplayHandle, "_NET_WORKAREA", false);
777                         NetAtoms [(int)NA._NET_SUPPORTING_WM_CHECK] = XInternAtom (DisplayHandle, "_NET_SUPPORTING_WM_CHECK", false);
778                         NetAtoms [(int)NA._NET_VIRTUAL_ROOTS] = XInternAtom (DisplayHandle, "_NET_VIRTUAL_ROOTS", false);
779                         NetAtoms [(int)NA._NET_DESKTOP_LAYOUT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_LAYOUT", false);
780                         NetAtoms [(int)NA._NET_SHOWING_DESKTOP] = XInternAtom (DisplayHandle, "_NET_SHOWING_DESKTOP", false);
781                         
782                         NetAtoms [(int)NA._NET_CLOSE_WINDOW] = XInternAtom (DisplayHandle, "_NET_CLOSE_WINDOW", false);
783                         NetAtoms [(int)NA._NET_MOVERESIZE_WINDOW] = XInternAtom (DisplayHandle, "_NET_MOVERESIZE_WINDOW", false);
784                         NetAtoms [(int)NA._NET_WM_MOVERESIZE] = XInternAtom (DisplayHandle, "_NET_WM_MOVERESIZE", false);
785                         NetAtoms [(int)NA._NET_RESTACK_WINDOW] = XInternAtom (DisplayHandle, "_NET_RESTACK_WINDOW", false);
786                         NetAtoms [(int)NA._NET_REQUEST_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_REQUEST_FRAME_EXTENTS", false);
787                         
788                         NetAtoms [(int)NA._NET_WM_NAME] = XInternAtom (DisplayHandle, "_NET_WM_NAME", false);
789                         NetAtoms [(int)NA._NET_WM_VISIBLE_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_NAME", false);
790                         NetAtoms [(int)NA._NET_WM_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_ICON_NAME", false);
791                         NetAtoms [(int)NA._NET_WM_VISIBLE_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_ICON_NAME", false);
792                         NetAtoms [(int)NA._NET_WM_DESKTOP] = XInternAtom (DisplayHandle, "_NET_WM_DESKTOP", false);
793                         NetAtoms [(int)NA._NET_WM_WINDOW_TYPE] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_TYPE", false);
794                         NetAtoms [(int)NA._NET_WM_STATE] = XInternAtom (DisplayHandle, "_NET_WM_STATE", false);
795                         NetAtoms [(int)NA._NET_WM_ALLOWED_ACTIONS] = XInternAtom (DisplayHandle, "_NET_WM_ALLOWED_ACTIONS", false);
796                         NetAtoms [(int)NA._NET_WM_STRUT] = XInternAtom (DisplayHandle, "_NET_WM_STRUT", false);
797                         NetAtoms [(int)NA._NET_WM_STRUT_PARTIAL] = XInternAtom (DisplayHandle, "_NET_WM_STRUT_PARTIAL", false);
798                         NetAtoms [(int)NA._NET_WM_ICON_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_WM_ICON_GEOMETRY", false);
799                         NetAtoms [(int)NA._NET_WM_ICON] = XInternAtom (DisplayHandle, "_NET_WM_ICON", false);
800                         NetAtoms [(int)NA._NET_WM_PID] = XInternAtom (DisplayHandle, "_NET_WM_PID", false);
801                         NetAtoms [(int)NA._NET_WM_HANDLED_ICONS] = XInternAtom (DisplayHandle, "_NET_WM_HANDLED_ICONS", false);
802                         NetAtoms [(int)NA._NET_WM_USER_TIME] = XInternAtom (DisplayHandle, "_NET_WM_USER_TIME", false);
803                         NetAtoms [(int)NA._NET_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_FRAME_EXTENTS", false);
804                         
805                         NetAtoms [(int)NA._NET_WM_PING] = XInternAtom (DisplayHandle, "_NET_WM_PING", false);
806                         NetAtoms [(int)NA._NET_WM_SYNC_REQUEST] = XInternAtom (DisplayHandle, "_NET_WM_SYNC_REQUEST", false);
807                         
808                         NetAtoms [(int)NA._NET_SYSTEM_TRAY_S] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString (), false);
809                         NetAtoms [(int)NA._NET_SYSTEM_TRAY_OPCODE] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_OPCODE", false);
810                         NetAtoms [(int)NA._NET_SYSTEM_TRAY_ORIENTATION] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_ORIENTATION", false);
811                         
812                         NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
813                         NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
814                         NetAtoms [(int)NA._NET_WM_STATE_HIDDEN] = XInternAtom (DisplayHandle, "_NET_WM_STATE_HIDDEN", false);
815                         
816                         NetAtoms [(int)NA._XEMBED] = XInternAtom (DisplayHandle, "_XEMBED", false);
817                         NetAtoms [(int)NA._XEMBED_INFO] = XInternAtom (DisplayHandle, "_XEMBED_INFO", false);
818                         
819                         NetAtoms [(int)NA._MOTIF_WM_HINTS] = XInternAtom (DisplayHandle, "_MOTIF_WM_HINTS", false);
820                         
821                         NetAtoms [(int)NA._NET_WM_STATE_NO_TASKBAR] = XInternAtom (DisplayHandle, "_NET_WM_STATE_NO_TASKBAR", false);
822                         NetAtoms [(int)NA._NET_WM_STATE_ABOVE] = XInternAtom (DisplayHandle, "_NET_WM_STATE_ABOVE", false);
823                         NetAtoms [(int)NA._NET_WM_STATE_MODAL] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MODAL", false);
824                         NetAtoms [(int)NA._NET_WM_CONTEXT_HELP] = XInternAtom (DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
825                         NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_OPACITY", false);
826                         
827                         // Clipboard support
828                         NetAtoms [(int)NA.CLIPBOARD] = XInternAtom (DisplayHandle, "CLIPBOARD", false);
829                         NetAtoms [(int)NA.DIB] = (int)Atom.XA_PIXMAP;
830                         NetAtoms [(int)NA.OEMTEXT] = XInternAtom (DisplayHandle, "COMPOUND_TEXT", false);
831                         NetAtoms [(int)NA.UNICODETEXT] = XInternAtom (DisplayHandle, "UTF8_STRING", false);
832                         NetAtoms [(int)NA.TARGETS] = XInternAtom (DisplayHandle, "TARGETS", false);
833                         
834                         // Special Atoms
835                         AsyncAtom = XInternAtom (DisplayHandle, "_SWF_AsyncAtom", false);
836                         PostAtom = XInternAtom (DisplayHandle, "_SWF_PostMessageAtom", false);
837                         HoverState.Atom = XInternAtom (DisplayHandle, "_SWF_HoverAtom", false);
838                 }
839                 
840                 private void GetSystrayManagerWindow ()
841                 {
842                         gdk_x11_grab_server ();
843                         SystrayMgrWindow = XGetSelectionOwner (DisplayHandle, NetAtoms [(int)NA._NET_SYSTEM_TRAY_S]);
844                         gdk_x11_ungrab_server ();
845                         gdk_display_flush (GdkDisplayHandle);
846                 }
847                 
848                 private void SendNetWMMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
849                 {
850                         XEvent  xev;
851                         
852                         xev = new XEvent ();
853                         xev.ClientMessageEvent.type = XEventName.ClientMessage;
854                         xev.ClientMessageEvent.send_event = true;
855                         xev.ClientMessageEvent.window = window;
856                         xev.ClientMessageEvent.message_type = message_type;
857                         xev.ClientMessageEvent.format = 32;
858                         xev.ClientMessageEvent.ptr1 = l0;
859                         xev.ClientMessageEvent.ptr2 = l1;
860                         xev.ClientMessageEvent.ptr3 = l2;
861                         XSendEvent (DisplayHandle, RootWindow, false, EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask, ref xev);
862                 }
863                 
864                 private void SendNetClientMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
865                 {
866                         XEvent  xev;
867                         
868                         xev = new XEvent ();
869                         xev.ClientMessageEvent.type = XEventName.ClientMessage;
870                         xev.ClientMessageEvent.send_event = true;
871                         xev.ClientMessageEvent.window = window;
872                         xev.ClientMessageEvent.message_type = message_type;
873                         xev.ClientMessageEvent.format = 32;
874                         xev.ClientMessageEvent.ptr1 = l0;
875                         xev.ClientMessageEvent.ptr2 = l1;
876                         xev.ClientMessageEvent.ptr3 = l2;
877                         XSendEvent (DisplayHandle, window, false, EventMask.NoEventMask, ref xev);
878                 }
879                 
880                 private void DeriveStyles (IntPtr handle, int Style, int ExStyle, out FormBorderStyle border_style, out TitleStyle title_style, out int caption_height, out int tool_caption_height)
881                 {
882                         
883                         // Only MDI windows get caption_heights
884                         caption_height = 0;
885                         tool_caption_height = 19;
886                         
887                         if ((Style & (int) WindowStyles.WS_CHILD) != 0) {
888                                 if ((Style & (int) WindowStyles.WS_BORDER) == 0) {
889                                         border_style = FormBorderStyle.None;
890                                 } else if ((ExStyle & (int) WindowStyles.WS_EX_CLIENTEDGE) != 0) {
891                                         border_style = FormBorderStyle.Fixed3D;
892                                 } else {
893                                         border_style = FormBorderStyle.FixedSingle;
894                                 }
895                                 title_style = TitleStyle.None;
896                         } else {
897                                 bool is_mdi = false;
898                                 
899                                 if ((ExStyle & (int) WindowStyles.WS_EX_MDICHILD) != 0) {
900                                         caption_height = 26;
901                                         is_mdi = true;
902                                 }
903                                 
904                                 title_style = TitleStyle.None;
905                                 if ((Style & (int)WindowStyles.WS_CAPTION) != 0) {
906                                         if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
907                                                 title_style = TitleStyle.Tool;
908                                         } else {
909                                                 title_style = TitleStyle.Normal;
910                                         }
911                                 }
912                                 
913                                 if (!is_mdi) {
914                                         border_style = FormBorderStyle.None;
915                                         
916                                         if ((Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
917                                                 if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
918                                                         border_style = FormBorderStyle.SizableToolWindow;
919                                                 } else {
920                                                         border_style = FormBorderStyle.Sizable;
921                                                 }
922                                         } else {
923                                                 if ((ExStyle & (int)WindowStyles.WS_EX_CLIENTEDGE) != 0) {
924                                                         border_style = FormBorderStyle.Fixed3D;
925                                                 } else if ((ExStyle & (int)WindowStyles.WS_EX_DLGMODALFRAME) != 0) {
926                                                         border_style = FormBorderStyle.FixedDialog;
927                                                 } else if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
928                                                         border_style = FormBorderStyle.FixedToolWindow;
929                                                 } else if ((Style & (int)WindowStyles.WS_BORDER) != 0) {
930                                                         border_style = FormBorderStyle.Sizable;
931                                                 } else {
932                                                         border_style = FormBorderStyle.None;
933                                                 }
934                                         }
935                                 } else {
936                                         if ((Style & (int) WindowStyles.WS_OVERLAPPEDWINDOW) != 0 ||
937                                             (ExStyle & (int) WindowStyles.WS_EX_TOOLWINDOW) != 0) {
938                                                 border_style = (FormBorderStyle) 0xFFFF;
939                                         } else {
940                                                 border_style = FormBorderStyle.None;
941                                         }
942                                 }
943                         }
944                 }
945                 
946                 private void SetHwndStyles (Hwnd hwnd, CreateParams cp)
947                 {
948                         DeriveStyles (hwnd.Handle, cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
949                 }
950                 
951                 private void SetWMStyles (Hwnd hwnd, CreateParams cp)
952                 {
953                         GdkWMDecoration decorations = GdkWMDecoration.GDK_DECOR_ALL;
954                         
955                         if ((cp.Style & (int)WindowStyles.WS_CAPTION) != 0) {
956                                 decorations |= GdkWMDecoration.GDK_DECOR_TITLE | GdkWMDecoration.GDK_DECOR_MENU;
957                         }
958                         
959                         if ((cp.Style & ((int)WindowStyles.WS_THICKFRAME)) != 0) {
960                                 decorations |= GdkWMDecoration.GDK_DECOR_BORDER | GdkWMDecoration.GDK_DECOR_RESIZEH;
961                         }
962                         if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
963                                 decorations |= GdkWMDecoration.GDK_DECOR_MINIMIZE;
964                         }
965                         
966                         if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
967                                 decorations |= GdkWMDecoration.GDK_DECOR_MAXIMIZE;
968                         }
969                         
970                         // is this needed ? most window managers do not even honour any MotifFunctions...
971 //                      if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
972 //                              functions |= MotifFunctions.Close;
973 //                      }
974                         
975                         if ((cp.ExStyle & ((int)WindowStyles.WS_EX_DLGMODALFRAME)) != 0) {
976                                 decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
977                         }
978                         
979                         if ((cp.Style & ((int)WindowStyles.WS_DLGFRAME)) != 0) {
980                                 decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
981                         }
982                         
983                         if ((cp.Style & ((int)WindowStyles.WS_BORDER)) != 0) {
984                                 decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
985                         }
986                         
987                         if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
988                                 decorations = 0;
989                         }
990                         
991                         gdk_window_set_decorations (gdk_window_foreign_new (hwnd.whole_window), (int)decorations);
992                 }
993                 
994                 private void SetIcon (Hwnd hwnd, Icon icon)
995                 {
996                         Bitmap          bitmap;
997                         int             size;
998                         uint[]          data;
999                         int             index;
1000                         
1001                         bitmap = icon.ToBitmap ();
1002                         index = 0;
1003                         size = bitmap.Width * bitmap.Height + 2;
1004                         data = new uint [size];
1005                         
1006                         data [index++] = (uint)bitmap.Width;
1007                         data [index++] = (uint)bitmap.Height;
1008                         
1009                         for (int y = 0; y < bitmap.Height; y++) {
1010                                 for (int x = 0; x < bitmap.Width; x++) {
1011                                         data [index++] = (uint)bitmap.GetPixel (x, y).ToArgb ();
1012                                 }
1013                         }
1014                         XChangeProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._NET_WM_ICON], Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
1015                 }
1016                 
1017                 private IntPtr ImageToPixmap (Image image)
1018                 {
1019                         return IntPtr.Zero;
1020                 }
1021                 
1022                 private void WakeupMain ()
1023                 {
1024                         wake.Send (new byte    [] { 0xFF });
1025                 }
1026                 
1027                 private void TranslatePropertyToClipboard (int property)
1028                 {
1029                         Atom                    actual_atom;
1030                         int                     actual_format;
1031                         int                     nitems;
1032                         int                     bytes_after;
1033                         IntPtr                  prop = IntPtr.Zero;
1034                         
1035                         Clipboard.Item = null;
1036                         
1037                         XGetWindowProperty (DisplayHandle, FosterParent, property, 0, 0x7fffffff, true, Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1038                         
1039                         if (nitems > 0) {
1040                                 if (property == (int)Atom.XA_STRING) {
1041                                         Clipboard.Item = Marshal.PtrToStringAnsi (prop);
1042                                 } else if (property == (int)Atom.XA_BITMAP) {
1043                                         // FIXME - convert bitmap to image
1044                                 } else if (property == (int)Atom.XA_PIXMAP) {
1045                                         // FIXME - convert pixmap to image
1046                                 } else if (property == NetAtoms [(int)NA.OEMTEXT]) {
1047                                         Clipboard.Item = Marshal.PtrToStringAnsi (prop);
1048                                 } else if (property == NetAtoms [(int)NA.UNICODETEXT]) {
1049                                         Clipboard.Item = Marshal.PtrToStringAnsi (prop);
1050                                 }
1051                                 
1052                                 XFree (prop);
1053                         }
1054                 }
1055                 
1056                 private void AddExpose (XEvent xevent)
1057                 {
1058                         Hwnd    hwnd;
1059                         
1060                         hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
1061                         
1062                         // Don't waste time
1063                         if (hwnd == null) {     
1064                                 return;
1065                         }
1066                         
1067                         if (xevent.AnyEvent.window == hwnd.client_window) {
1068                                 hwnd.AddInvalidArea (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
1069                                 if (!hwnd.expose_pending) {
1070                                         MessageQueue.Enqueue (xevent);
1071                                         hwnd.expose_pending = true;
1072                                 }
1073                         } else {
1074                                 if (!hwnd.nc_expose_pending) {
1075                                         MessageQueue.Enqueue (xevent);
1076                                         hwnd.nc_expose_pending = true;
1077                                 }
1078                         }
1079                 }
1080                 
1081                 private void InvalidateWholeWindow (IntPtr handle)
1082                 {
1083                         Hwnd    hwnd;
1084                         
1085                         hwnd = Hwnd.ObjectFromHandle (handle);
1086                         
1087                         InvalidateWholeWindow (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
1088                 }
1089                 
1090                 private void InvalidateWholeWindow (IntPtr handle, Rectangle rectangle)
1091                 {
1092                         Hwnd    hwnd;
1093                         XEvent  xevent;
1094                         
1095                         hwnd = Hwnd.ObjectFromHandle (handle);
1096                         
1097                         
1098                         xevent = new XEvent ();
1099                         xevent.type = XEventName.Expose;
1100                         xevent.ExposeEvent.display = DisplayHandle;
1101                         xevent.ExposeEvent.window = hwnd.whole_window;
1102                         
1103                         xevent.ExposeEvent.x = rectangle.X;
1104                         xevent.ExposeEvent.y = rectangle.Y;
1105                         xevent.ExposeEvent.width = rectangle.Width;
1106                         xevent.ExposeEvent.height = rectangle.Height;
1107                         
1108                         AddExpose (xevent);
1109                 }
1110                 
1111                 private void WholeToScreen (IntPtr handle, ref int x, ref int y)
1112                 {
1113                         int     dest_x_return;
1114                         int     dest_y_return;
1115                         Hwnd    hwnd;
1116                         
1117                         hwnd = Hwnd.ObjectFromHandle (handle);
1118                         
1119                         lock (XlibLock) {
1120                                 gdk_window_get_origin (gdk_window_lookup (hwnd.whole_window), out dest_x_return, out dest_y_return);
1121                         }
1122                         
1123                         x = dest_x_return;
1124                         y = dest_y_return;
1125                 }
1126                 
1127                 private void AddConfigureNotify (XEvent xevent)
1128                 {
1129                         Hwnd    hwnd;
1130                         
1131                         hwnd = Hwnd.GetObjectFromWindow (xevent.ConfigureEvent.window);
1132                         
1133                         // Don't waste time
1134                         if (hwnd == null) {
1135                                 return;
1136                         }
1137                         
1138                         if (xevent.ConfigureEvent.window == hwnd.whole_window) {
1139                                 if (!hwnd.reparented) {
1140                                         hwnd.x = xevent.ConfigureEvent.x;
1141                                         hwnd.y = xevent.ConfigureEvent.y;
1142                                 } else {
1143                                         int     dummy_int;
1144                                         
1145                                         gdk_window_get_geometry (gdk_window_lookup (hwnd.whole_window), out hwnd.x, out hwnd.y, out dummy_int, out dummy_int, out dummy_int);
1146                                 }
1147                                 
1148                                 hwnd.width = xevent.ConfigureEvent.width;
1149                                 hwnd.height = xevent.ConfigureEvent.height;
1150                                 
1151                                 if (!hwnd.configure_pending) {
1152                                         MessageQueue.Enqueue (xevent);
1153                                         hwnd.configure_pending = true;
1154                                 }
1155                         }
1156                         // We drop configure events for Client windows
1157                 }
1158                 
1159                 private void ShowCaret ()
1160                 {
1161                         if ((Caret.gc == IntPtr.Zero) || Caret.On) {
1162                                 return;
1163                         }
1164                         Caret.On = true;
1165                         
1166                         // gdk_gc_set_foreground
1167                         // gdk_draw_line
1168                         lock (XlibLock) {
1169                                 XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1170                         }
1171                 }
1172                 
1173                 private void HideCaret ()
1174                 {
1175                         if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
1176                                 return;
1177                         }
1178                         Caret.On = false;
1179                         
1180                         // gdk_gc_set_foreground
1181                         // gdk_draw_text_wc
1182                         lock (XlibLock) {
1183                                 XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1184                         }
1185                 }
1186                 
1187                 private int NextTimeout (DateTime now)
1188                 {
1189                         int timeout = Int32.MaxValue; 
1190                         lock (TimerList) {
1191                                 foreach (Timer timer in TimerList) {
1192                                         int next = (int) (timer.Expires - now).TotalMilliseconds;
1193                                         if (next < 0) {
1194                                                 return 0; // Have a timer that has already expired
1195                                         }
1196                                         
1197                                         if (next < timeout) {
1198                                                 timeout = next;
1199                                         }
1200                                 }
1201                         }
1202                         if (timeout < Timer.Minimum) {
1203                                 timeout = Timer.Minimum;
1204                         }
1205                         
1206                         return timeout;
1207                 }
1208                 
1209                 private void CheckTimers (DateTime now)
1210                 {
1211                         lock (TimerList) {
1212                                 int count;
1213                                 
1214                                 count = TimerList.Count;
1215                                 
1216                                 if (count == 0) {
1217                                         return;
1218                                 }
1219                                 
1220                                 for (int i = 0; i < TimerList.Count; i++) {
1221                                         Timer timer;
1222                                         
1223                                         timer = (Timer) TimerList [i];
1224                                         
1225                                         if (timer.Enabled && timer.Expires <= now) {
1226                                                 timer.Update (now);
1227                                                 timer.FireTick ();
1228                                         }
1229                                 }
1230                         }
1231                 }
1232                 
1233                 private void UpdateMessageQueue ()
1234                 {
1235                         DateTime        now;
1236                         int             pending;
1237                         
1238                         now = DateTime.Now;
1239                         
1240                         lock (XlibLock) {
1241                                 pending = XPending (DisplayHandle);
1242                         }
1243                         
1244                         if (pending == 0) {
1245                                 if (Idle != null) {
1246                                         Idle (this, EventArgs.Empty);
1247                                 }
1248                                 
1249                                 lock (XlibLock) {
1250                                         pending = XPending (DisplayHandle);
1251                                 }
1252                         }
1253                         
1254                         if (pending == 0) {
1255                                 int     timeout;
1256                                 
1257                                 timeout = NextTimeout (now);
1258                                 if (timeout > 0) {
1259                                         #if __MonoCS__
1260                                         Syscall.poll (pollfds, (uint) pollfds.Length, timeout);
1261                                         // Clean out buffer, so we're not busy-looping on the same data
1262                                         if (pollfds[1].revents != 0) {
1263                                                 wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
1264                                         }
1265                                         #endif
1266                                         lock (XlibLock) {
1267                                                 pending = XPending (DisplayHandle);
1268                                         }
1269                                 }
1270                         }
1271                         
1272                         CheckTimers (now);
1273                         
1274                         if (pending == 0) {
1275                                 lock (XlibLock) {
1276                                         pending = XPending (DisplayHandle);
1277                                 }
1278                         }
1279                         
1280                         while (pending > 0) {
1281                                 XEvent xevent = new XEvent ();
1282                                 
1283                                 lock (XlibLock) {
1284                                         XNextEvent (DisplayHandle, ref xevent);
1285                                 }
1286 //Console.WriteLine("Got x event {0}", xevent);
1287                                 switch (xevent.type) {
1288                                 case XEventName.Expose:
1289                                         AddExpose (xevent);
1290                                         break;
1291                                         
1292                                 case XEventName.SelectionClear: {
1293                                                 // Should we do something?
1294                                                 break;
1295                                         }
1296                                         
1297                                 case XEventName.SelectionRequest: {
1298                                                 if (Dnd.HandleSelectionRequestEvent (ref xevent))
1299                                                         break;
1300                                                 XEvent sel_event;
1301                                                 
1302                                                 sel_event = new XEvent ();
1303                                                 sel_event.SelectionEvent.type = XEventName.SelectionNotify;
1304                                                 sel_event.SelectionEvent.send_event = true;
1305                                                 sel_event.SelectionEvent.display = DisplayHandle;
1306                                                 sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
1307                                                 sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
1308                                                 sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
1309                                                 sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
1310                                                 sel_event.SelectionEvent.property = 0;
1311                                                 
1312                                                 // Seems that some apps support asking for supported types
1313                                                 if (xevent.SelectionEvent.target == NetAtoms [(int)NA.TARGETS]) {
1314                                                         uint[]  atoms;
1315                                                         int     atom_count;
1316                                                         
1317                                                         atoms = new uint [5];
1318                                                         atom_count = 0;
1319                                                         
1320                                                         if (Clipboard.Item is String) {
1321                                                                 atoms [atom_count++] = (uint)Atom.XA_STRING;
1322                                                                 atoms [atom_count++] = (uint)NetAtoms [(int)NA.OEMTEXT];
1323                                                                 atoms [atom_count++] = (uint)NetAtoms [(int)NA.UNICODETEXT];
1324                                                         } else if (Clipboard.Item is Image) {
1325                                                                 atoms [atom_count++] = (uint)Atom.XA_PIXMAP;
1326                                                                 atoms [atom_count++] = (uint)Atom.XA_BITMAP;
1327                                                         } else {
1328                                                                 // FIXME - handle other types
1329                                                         }
1330                                                         
1331                                                         XChangeProperty (DisplayHandle, xevent.SelectionEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
1332                                                 } else if (Clipboard.Item is string) {
1333                                                         IntPtr  buffer;
1334                                                         int     buflen;
1335                                                         
1336                                                         buflen = 0;
1337                                                         
1338                                                         if (xevent.SelectionRequestEvent.target == (int)Atom.XA_STRING) {
1339                                                                 Byte[] bytes;
1340                                                                 
1341                                                                 bytes = new ASCIIEncoding ().GetBytes ((string)Clipboard.Item);
1342                                                                 buffer = Marshal.AllocHGlobal (bytes.Length);
1343                                                                 buflen = bytes.Length;
1344                                                                 
1345                                                                 for (int i = 0; i < buflen; i++) {
1346                                                                         Marshal.WriteByte (buffer, i, bytes [i]);
1347                                                                 }
1348                                                         } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.OEMTEXT]) {
1349                                                                 // FIXME - this should encode into ISO2022
1350                                                                 buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
1351                                                                 while (Marshal.ReadByte (buffer, buflen) != 0) {
1352                                                                         buflen++;
1353                                                                 }
1354                                                         } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.UNICODETEXT]) {
1355                                                                 buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
1356                                                                 while (Marshal.ReadByte (buffer, buflen) != 0) {
1357                                                                         buflen++;
1358                                                                 }
1359                                                         } else {
1360                                                                 buffer = IntPtr.Zero;
1361                                                         }
1362                                                         
1363                                                         if (buffer != IntPtr.Zero) {
1364                                                                 XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1365                                                                 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1366                                                                 Marshal.FreeHGlobal (buffer);
1367                                                         }
1368                                                 } else if (Clipboard.Item is Image) {
1369                                                         if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
1370                                                                 // FIXME - convert image and store as property
1371                                                         } else if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
1372                                                                 // FIXME - convert image and store as property
1373                                                         }
1374                                                 }
1375                                                 
1376                                                 XSendEvent (DisplayHandle, xevent.SelectionRequestEvent.requestor, false, EventMask.NoEventMask, ref sel_event);
1377                                                 break;
1378                                         }
1379                                         
1380                                 case XEventName.SelectionNotify: {
1381                                                 if (Clipboard.Enumerating) {
1382                                                         Clipboard.Enumerating = false;
1383                                                         if (xevent.SelectionEvent.property != 0) {
1384                                                                 XDeleteProperty (DisplayHandle, FosterParent, xevent.SelectionEvent.property);
1385                                                                 if (!Clipboard.Formats.Contains (xevent.SelectionEvent.property)) {
1386                                                                         Clipboard.Formats.Add (xevent.SelectionEvent.property);
1387                                                                         #if DriverDebugExtra
1388                                                                                 Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
1389                                                                         #endif
1390                                                                 }
1391                                                         }
1392                                                 } else if (Clipboard.Retrieving) {
1393                                                         Clipboard.Retrieving = false;
1394                                                         if (xevent.SelectionEvent.property != 0) {
1395                                                                 TranslatePropertyToClipboard (xevent.SelectionEvent.property);
1396                                                         } else {
1397                                                                 Clipboard.Item = null;
1398                                                         }
1399                                                 } else {
1400                                                         Dnd.HandleSelectionNotifyEvent (ref xevent);
1401                                                 }
1402                                                 break;
1403                                         }
1404                                         
1405                                 case XEventName.KeyPress:
1406                                 case XEventName.KeyRelease:
1407                                 case XEventName.ButtonPress:
1408                                 case XEventName.ButtonRelease:
1409                                 case XEventName.MotionNotify:
1410                                 case XEventName.EnterNotify:
1411                                 case XEventName.LeaveNotify:
1412                                 case XEventName.CreateNotify:
1413                                 case XEventName.DestroyNotify:
1414                                 case XEventName.FocusIn:
1415                                 case XEventName.FocusOut:
1416                                 case XEventName.ClientMessage:
1417                                 case XEventName.ReparentNotify:
1418                                         MessageQueue.Enqueue (xevent);
1419                                         break;
1420                                         
1421                                 case XEventName.ConfigureNotify:
1422                                         AddConfigureNotify (xevent);
1423                                         break;
1424                                         
1425                                 case XEventName.PropertyNotify:
1426                                         if (xevent.PropertyEvent.atom == NetAtoms [(int)NA._NET_ACTIVE_WINDOW]) {
1427                                                 Atom    actual_atom;
1428                                                 int     actual_format;
1429                                                 int     nitems;
1430                                                 int     bytes_after;
1431                                                 IntPtr  prop = IntPtr.Zero;
1432                                                 IntPtr  prev_active;;
1433                                                 
1434                                                 prev_active = ActiveWindow;
1435                                                 XGetWindowProperty (DisplayHandle, RootWindow, NetAtoms [(int)NA._NET_ACTIVE_WINDOW], 0, 1, false, Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1436                                                 if ((nitems > 0) && (prop != IntPtr.Zero)) {
1437                                                         ActiveWindow = Hwnd.GetHandleFromWindow ((IntPtr)Marshal.ReadInt32 (prop));
1438                                                         XFree (prop);
1439                                                         
1440                                                         if (prev_active != ActiveWindow) {
1441                                                                 if (prev_active != IntPtr.Zero) {
1442                                                                         PostMessage (prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
1443                                                                 }
1444                                                                 if (ActiveWindow != IntPtr.Zero) {
1445                                                                         PostMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
1446                                                                 }
1447                                                         }
1448                                                         if (ModalWindows.Count == 0) {
1449                                                                 break;
1450                                                         } else {
1451                                                                 // Modality handling, if we are modal and the new active window is one
1452                                                                 // of ours but not the modal one, switch back to the modal window
1453                                                                 
1454                                                                 if (NativeWindow.FindWindow (ActiveWindow) != null) {
1455                                                                         if (ActiveWindow != (IntPtr)ModalWindows.Peek ()) {
1456                                                                                 Activate ((IntPtr)ModalWindows.Peek ());
1457                                                                         }
1458                                                                 }
1459                                                                 break;
1460                                                         }
1461                                                 }
1462                                         }
1463                                         break;
1464                                         
1465                                 }
1466                                 
1467                                 lock (XlibLock) {
1468                                         pending = XPending (DisplayHandle);
1469                                 }
1470                         }
1471                 }
1472                 
1473                 private IntPtr GetMousewParam (int Delta)
1474                 {
1475                         int     result = 0;
1476                         
1477                         if ((MouseState & MouseButtons.Left) != 0) {
1478                                 result |= (int)MsgButtons.MK_LBUTTON;
1479                         }
1480                         
1481                         if ((MouseState & MouseButtons.Middle) != 0) {
1482                                 result |= (int)MsgButtons.MK_MBUTTON;
1483                         }
1484                         
1485                         if ((MouseState & MouseButtons.Right) != 0) {
1486                                 result |= (int)MsgButtons.MK_RBUTTON;
1487                         }
1488                         
1489                         Keys mods = ModifierKeys;
1490                         if ((mods & Keys.Control) != 0) {
1491                                 result |= (int)MsgButtons.MK_CONTROL;
1492                         }
1493                         
1494                         if ((mods & Keys.Shift) != 0) {
1495                                 result |= (int)MsgButtons.MK_SHIFT;
1496                         }
1497                         
1498                         result |= Delta << 16;
1499                         
1500                         return (IntPtr)result;
1501                 }
1502                 private IntPtr XGetParent (IntPtr handle)
1503                 {
1504                         return gdk_x11_drawable_get_xid (gdk_window_get_parent (gdk_window_lookup (handle)));
1505                 }
1506                 
1507                 private int HandleError (IntPtr display, ref XErrorEvent error_event)
1508                 {
1509                         if (ErrorExceptions) {
1510                                 throw new XException (error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code);
1511                         } else {
1512                                 Console.WriteLine ("X11 Error encountered: {0}{1}\n", XException.GetMessage (error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code), WhereString ());
1513                         }
1514                         return 0;
1515                 }
1516                 
1517                 private void DestroyChildWindow (Control c)
1518                 {
1519                         Hwnd            hwnd;
1520                         int             i;
1521                         Control[]       controls;
1522                         
1523                         if (c != null) {
1524                                 controls = c.child_controls.GetAllControls ();
1525                                 
1526                                 for (i = 0; i < controls.Length; i++) {
1527                                         if (controls [i].IsHandleCreated) {
1528                                                 hwnd = Hwnd.ObjectFromHandle (controls [i].Handle);
1529                                                 SendMessage (controls [i].Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
1530                                                 hwnd.Dispose ();
1531                                         }
1532                                         DestroyChildWindow (controls [i]);
1533                                 }
1534                         }
1535                 }
1536                 
1537                 #endregion      // Private Methods
1538                 
1539                 #region Callbacks
1540                 private void MouseHover (object sender, EventArgs e)
1541                 {
1542                         if ((HoverState.X == MousePosition.X) && (HoverState.Y == MousePosition.Y)) {
1543                                 XEvent xevent;
1544                                 
1545                                 HoverState.Timer.Enabled = false;
1546                                 
1547                                 if (HoverState.Window != IntPtr.Zero) {
1548                                         xevent = new XEvent ();
1549                                         
1550                                         xevent.type = XEventName.ClientMessage;
1551                                         xevent.ClientMessageEvent.display = DisplayHandle;
1552                                         xevent.ClientMessageEvent.window = (IntPtr)HoverState.Window;
1553                                         xevent.ClientMessageEvent.message_type = (IntPtr)HoverState.Atom;
1554                                         xevent.ClientMessageEvent.format = 32;
1555                                         xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
1556                                         
1557                                         MessageQueue.EnqueueLocked (xevent);
1558                                         
1559                                         WakeupMain ();
1560                                 }
1561                         }
1562                 }
1563                 
1564                 private void CaretCallback (object sender, EventArgs e)
1565                 {
1566                         if (Caret.Paused) {
1567                                 return;
1568                         }
1569                         Caret.On = !Caret.On;
1570                         
1571                         XDrawLine (DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1572                 }
1573                 #endregion      // Callbacks
1574                 
1575                 #region Public Properties
1576                 
1577                 internal override int Caption {
1578                         get {
1579                                 return 25; 
1580                         }
1581                 }
1582                 
1583                 internal override Size CursorSize {
1584                         get {
1585                                 uint    x;
1586                                 uint    y;
1587                                 gdk_display_get_maximal_cursor_size (GdkDisplayHandle, out x, out y);
1588                                 
1589                                 return new Size ((int)x, (int)y);
1590                         }
1591                 } 
1592                 
1593                 internal override  bool DragFullWindows {
1594                         get {
1595                                 return true;
1596                         }
1597                 } 
1598                 
1599                 internal override  Size DragSize {
1600                         get {
1601                                 return new Size (4, 4);
1602                         }
1603                 } 
1604                 
1605                 internal override  Size FrameBorderSize { 
1606                         get {
1607                                 throw new NotImplementedException (); 
1608                         }
1609                 }
1610                 
1611                 internal override  Size IconSize {
1612                         get {
1613                                 IntPtr          list;
1614                                 XIconSize       size;
1615                                 int             count;
1616                                 
1617                                 if (XGetIconSizes (DisplayHandle, RootWindow, out list, out count) != 0) {
1618                                         long            current;
1619                                         int             largest;
1620                                         
1621                                         current = (long)list;
1622                                         largest = 0;
1623                                         
1624                                         size = new XIconSize ();
1625                                         
1626                                         for (int i = 0; i < count; i++) {
1627                                                 size = (XIconSize)Marshal.PtrToStructure ((IntPtr)current, size.GetType ());
1628                                                 current += Marshal.SizeOf (size);
1629                                                 
1630                                                 // Look for our preferred size
1631                                                 if (size.min_width == 32) {
1632                                                         XFree (list);
1633                                                         return new Size (32, 32);
1634                                                 }
1635                                                 
1636                                                 if (size.max_width == 32) {
1637                                                         XFree (list);
1638                                                         return new Size (32, 32);
1639                                                 }
1640                                                 
1641                                                 if (size.min_width < 32 && size.max_width > 32) {
1642                                                         int     x;
1643                                                         
1644                                                         // check if we can fit one
1645                                                         x = size.min_width;
1646                                                         while (x < size.max_width) {
1647                                                                 x += size.width_inc;
1648                                                                 if (x == 32) {
1649                                                                         XFree (list);
1650                                                                         return new Size (32, 32);
1651                                                                 }
1652                                                         }
1653                                                 }
1654                                                 
1655                                                 if (largest < size.max_width) {
1656                                                         largest = size.max_width;
1657                                                 }
1658                                         }
1659                                         
1660                                         // We didn't find a match or we wouldn't be here
1661                                         return new Size (largest, largest);
1662                                         
1663                                 } else {
1664                                         return new Size (32, 32);
1665                                 }
1666                         }
1667                 } 
1668                 
1669                 internal override int KeyboardSpeed {
1670                         get {
1671                                 //
1672                                 // A lot harder: need to do:
1673                                 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58)       = 1
1674                                 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58)        = 0x080517a8
1675                                 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58)                   = 0
1676                                 //
1677                                 // And from that we can tell the repetition rate
1678                                 //
1679                                 // Notice, the values must map to:
1680                                 //   [0, 31] which maps to 2.5 to 30 repetitions per second.
1681                                 //
1682                                 return 0;
1683                         }
1684                 }
1685                 
1686                 internal override int KeyboardDelay {
1687                         get {
1688                                 //
1689                                 // Return values must range from 0 to 4, 0 meaning 250ms,
1690                                 // and 4 meaning 1000 ms.
1691                                 //
1692                                 return 1; // ie, 500 ms
1693                         }
1694                 } 
1695                 
1696                 internal override  Size MaxWindowTrackSize {
1697                         get {
1698                                 return new Size (WorkingArea.Width, WorkingArea.Height);
1699                         }
1700                 } 
1701                 
1702                 internal override  Size MinimizedWindowSize {
1703                         get {
1704                                 return new Size (1, 1);
1705                         }
1706                 } 
1707                 
1708                 internal override  Size MinimizedWindowSpacingSize {
1709                         get {
1710                                 return new Size (1, 1);
1711                         }
1712                 } 
1713                 
1714                 internal override  Size MinimumWindowSize {
1715                         get {
1716                                 return new Size (1, 1);
1717                         }
1718                 } 
1719                 
1720                 internal override  Size MinWindowTrackSize {
1721                         get {
1722                                 return new Size (1, 1);
1723                         }
1724                 }
1725                 
1726                 internal override Keys ModifierKeys {
1727                         get {
1728                                 return Keyboard.ModifierKeys;
1729                         }
1730                 }
1731                 
1732                 internal override  Size SmallIconSize {
1733                         get {
1734                                 IntPtr          list;
1735                                 XIconSize       size;
1736                                 int             count;
1737                                 
1738                                 if (XGetIconSizes (DisplayHandle, RootWindow, out list, out count) != 0) {
1739                                         long            current;
1740                                         int             smallest;
1741                                         
1742                                         current = (long)list;
1743                                         smallest = 0;
1744                                         
1745                                         size = new XIconSize ();
1746                                         
1747                                         for (int i = 0; i < count; i++) {
1748                                                 size = (XIconSize)Marshal.PtrToStructure ((IntPtr)current, size.GetType ());
1749                                                 current += Marshal.SizeOf (size);
1750                                                 
1751                                                 // Look for our preferred size
1752                                                 if (size.min_width == 16) {
1753                                                         XFree (list);
1754                                                         return new Size (16, 16);
1755                                                 }
1756                                                 
1757                                                 if (size.max_width == 16) {
1758                                                         XFree (list);
1759                                                         return new Size (16, 16);
1760                                                 }
1761                                                 
1762                                                 if (size.min_width < 16 && size.max_width > 16) {
1763                                                         int     x;
1764                                                         
1765                                                         // check if we can fit one
1766                                                         x = size.min_width;
1767                                                         while (x < size.max_width) {
1768                                                                 x += size.width_inc;
1769                                                                 if (x == 16) {
1770                                                                         XFree (list);
1771                                                                         return new Size (16, 16);
1772                                                                 }
1773                                                         }
1774                                                 }
1775                                                 
1776                                                 if (smallest == 0 || smallest > size.min_width) {
1777                                                         smallest = size.min_width;
1778                                                 }
1779                                         }
1780                                         
1781                                         // We didn't find a match or we wouldn't be here
1782                                         return new Size (smallest, smallest);
1783                                         
1784                                 } else {
1785                                         return new Size (16, 16);
1786                                 }
1787                         }
1788                 } 
1789                 
1790                 internal override  int MouseButtonCount {
1791                         get {
1792                                 return 3;
1793                         }
1794                 } 
1795                 
1796                 internal override  bool MouseButtonsSwapped {
1797                         get {
1798                                 return false;   // FIXME - how to detect?
1799                         }
1800                 } 
1801                 
1802                 internal override  bool MouseWheelPresent {
1803                         get {
1804                                 return true;    // FIXME - how to detect?
1805                         }
1806                 } 
1807                 
1808                 internal override  Rectangle VirtualScreen {
1809                         get {
1810                                 return WorkingArea;
1811                         }
1812                 } 
1813                 
1814                 internal override  Rectangle WorkingArea {
1815                         get {
1816                                 Atom                    actual_atom;
1817                                 int                     actual_format;
1818                                 int                     nitems;
1819                                 int                     bytes_after;
1820                                 IntPtr                  prop = IntPtr.Zero;
1821                                 int                     width;
1822                                 int                     height;
1823                                 
1824                                 XGetWindowProperty (DisplayHandle, RootWindow, NetAtoms [(int)NA._NET_DESKTOP_GEOMETRY], 0, 256, false, Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1825                                 if ((nitems == 2) && (prop != IntPtr.Zero)) {
1826                                         width = Marshal.ReadInt32 (prop, 0);
1827                                         height = Marshal.ReadInt32 (prop, 4);
1828                                         
1829                                         XFree (prop);
1830                                         return new Rectangle (0, 0, width, height);
1831                                 } else {
1832                                         XWindowAttributes       attributes=new XWindowAttributes ();
1833                                         
1834                                         lock (XlibLock) {
1835                                                 XGetWindowAttributes (DisplayHandle, XRootWindow (DisplayHandle, ScreenNo), ref attributes);
1836                                         }
1837                                         
1838                                         return new Rectangle (0, 0, attributes.width, attributes.height);
1839                                 }
1840                         }
1841                 } 
1842                 #endregion      // Public properties
1843                 
1844                 #region Public Static Methods
1845                 internal override IntPtr InitializeDriver ()
1846                 {
1847                         lock (this) {
1848                                 if (GdkDisplayHandle == IntPtr.Zero) {
1849                                         SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
1850                                 }
1851                         }
1852                         return IntPtr.Zero;
1853                 }
1854                 
1855                 internal override void ShutdownDriver (IntPtr token)
1856                 {
1857                         lock (this) {
1858                                 if (GdkDisplayHandle != IntPtr.Zero) {
1859                                         gdk_display_close (GdkDisplayHandle);
1860                                         DisplayHandle = IntPtr.Zero;
1861                                         GdkDisplayHandle = IntPtr.Zero;
1862                                 }
1863                         }
1864                 }
1865                 
1866                 internal override void EnableThemes ()
1867                 {
1868                         ThemesEnabled = true;
1869                 }
1870                 
1871                 
1872                 internal override void Activate (IntPtr handle)
1873                 {
1874                         Hwnd hwnd;
1875                         
1876                         hwnd = Hwnd.ObjectFromHandle (handle);
1877                         
1878                         if (hwnd != null) lock (XlibLock) {
1879                                         SendNetWMMessage (hwnd.whole_window, (IntPtr)NetAtoms [(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
1880                                         //XRaiseWindow(DisplayHandle, handle);
1881                                 }
1882                         return;
1883                 }
1884                 
1885                 internal override void AudibleAlert ()
1886                 {
1887                         gdk_display_beep (gdk_x11_lookup_xdisplay (DisplayHandle));
1888                         return;
1889                 }
1890                 
1891                 
1892                 internal override void CaretVisible (IntPtr handle, bool visible)
1893                 {
1894                         // Visible is cumulative; two hides require two shows before the caret is visible again
1895                         if (Caret.Hwnd == handle) {
1896                                 if (visible) {
1897                                         if (Caret.Visible < 1) {
1898                                                 Caret.Visible++;
1899                                                 Caret.On = false;
1900                                                 if (Caret.Visible == 1) {
1901                                                         ShowCaret ();
1902                                                         Caret.Timer.Start ();
1903                                                 }
1904                                         }
1905                                 } else {
1906                                         Caret.Visible--;
1907                                         if (Caret.Visible == 0) {
1908                                                 Caret.Timer.Stop ();
1909                                                 HideCaret ();
1910                                         }
1911                                 }
1912                         }
1913                 }
1914                 
1915                 internal override bool CalculateWindowRect (IntPtr handle, ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect)
1916                 {
1917                         FormBorderStyle border_style;
1918                         TitleStyle      title_style;
1919                         int caption_height;
1920                         int tool_caption_height;
1921                         
1922                         DeriveStyles (handle, Style, ExStyle, out border_style, out title_style,
1923                                       out caption_height, out tool_caption_height);
1924                         
1925                         WindowRect = Hwnd.GetWindowRectangle (border_style, menu, title_style,
1926                                                               caption_height, tool_caption_height,
1927                                                               ClientRect);
1928                         
1929                         return true;
1930                 }
1931                 
1932                 internal override void ClientToScreen (IntPtr handle, ref int x, ref int y)
1933                 {
1934                         int     dest_x_return;
1935                         int     dest_y_return;
1936                         IntPtr  child;
1937                         Hwnd    hwnd;
1938                         
1939                         hwnd = Hwnd.ObjectFromHandle (handle);
1940                         
1941                         lock (XlibLock) {
1942                                 XTranslateCoordinates (DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
1943                         }
1944                         
1945                         x = dest_x_return;
1946                         y = dest_y_return;
1947                 }
1948                 
1949                 internal override int[] ClipboardAvailableFormats (IntPtr handle)
1950                 {
1951                         DataFormats.Format      f;
1952                         int[]                   result;
1953                         
1954                         f = DataFormats.Format.List;
1955                         
1956                         if (XGetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD]) == IntPtr.Zero) {
1957                                 return null;
1958                         }
1959                         
1960                         Clipboard.Formats = new ArrayList ();
1961                         
1962                         while (f != null) {
1963                                 XConvertSelection (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], f.Id, f.Id, FosterParent, IntPtr.Zero);
1964                                 
1965                                 Clipboard.Enumerating = true;
1966                                 while (Clipboard.Enumerating) {
1967                                         UpdateMessageQueue ();
1968                                 }
1969                                 f = f.Next;
1970                         }
1971                         
1972                         result = new int [Clipboard.Formats.Count];
1973                         
1974                         for (int i = 0; i < Clipboard.Formats.Count; i++) {
1975                                 result [i] = (int)Clipboard.Formats [i];
1976                         }
1977                         
1978                         Clipboard.Formats = null;
1979                         return result;
1980                 }
1981                 
1982                 internal override void ClipboardClose (IntPtr handle)
1983                 {
1984                         if (handle != ClipMagic) {
1985                                 throw new ArgumentException ("handle is not a valid clipboard handle");
1986                         }
1987                         return;
1988                 }
1989                 
1990                 internal override int ClipboardGetID (IntPtr handle, string format)
1991                 {
1992                         if (handle != ClipMagic) {
1993                                 throw new ArgumentException ("handle is not a valid clipboard handle");
1994                         }
1995                         
1996                         if (format == "Text") return (int)Atom.XA_STRING;
1997                         else if (format == "Bitmap") return (int)Atom.XA_BITMAP;
1998                         //else if (format == "MetaFilePict" ) return 3;
1999                         //else if (format == "SymbolicLink" ) return 4;
2000                         //else if (format == "DataInterchangeFormat" ) return 5;
2001                         //else if (format == "Tiff" ) return 6;
2002                         else if (format == "OEMText") return XInternAtom (DisplayHandle, "COMPOUND_TEXT", false);
2003                         else if (format == "DeviceIndependentBitmap") return (int)Atom.XA_PIXMAP;
2004                         else if (format == "Palette") return (int)Atom.XA_COLORMAP;     // Useless
2005                         //else if (format == "PenData" ) return 10;
2006                         //else if (format == "RiffAudio" ) return 11;
2007                         //else if (format == "WaveAudio" ) return 12;
2008                         else if (format == "UnicodeText") return XInternAtom (DisplayHandle, "UTF8_STRING", false);
2009                         //else if (format == "EnhancedMetafile" ) return 14;
2010                         //else if (format == "FileDrop" ) return 15;
2011                         //else if (format == "Locale" ) return 16;
2012                         
2013                         return XInternAtom (DisplayHandle, format, false);
2014                 }
2015                 
2016                 internal override IntPtr ClipboardOpen ()
2017                 {
2018                         return ClipMagic;
2019                 }
2020                 
2021                 internal override object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
2022                 {
2023                         XConvertSelection (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], type, type, FosterParent, IntPtr.Zero);
2024                         
2025                         Clipboard.Retrieving = true;
2026                         while (Clipboard.Retrieving) {
2027                                 UpdateMessageQueue ();
2028                         }
2029                         
2030                         return Clipboard.Item;
2031                 }
2032                 
2033                 internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
2034                 {
2035                         Clipboard.Item = obj;
2036                         Clipboard.Type = type;
2037                         Clipboard.Converter = converter;
2038                         
2039                         if (obj != null) {
2040                                 XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], FosterParent, IntPtr.Zero);
2041                         } else {
2042                                 // Clearing the selection
2043                                 XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], IntPtr.Zero, IntPtr.Zero);
2044                         }
2045                 }
2046                 
2047                 internal override void CreateCaret (IntPtr handle, int width, int height)
2048                 {
2049                         XGCValues       gc_values;
2050                         Hwnd            hwnd;
2051                         
2052                         hwnd = Hwnd.ObjectFromHandle (handle);
2053                         
2054                         if (Caret.Hwnd != IntPtr.Zero) {
2055                                 DestroyCaret (Caret.Hwnd);
2056                         }
2057                         
2058                         Caret.Hwnd = handle;
2059                         Caret.Window = hwnd.client_window;
2060                         Caret.Width = width;
2061                         Caret.Height = height;
2062                         Caret.Visible = 0;
2063                         Caret.On = false;
2064                         
2065                         gc_values = new XGCValues ();
2066                         gc_values.line_width = width;
2067                         
2068                         Caret.gc = XCreateGC (DisplayHandle, Caret.Window, GCFunction.GCLineWidth, ref gc_values);
2069                         if (Caret.gc == IntPtr.Zero) {
2070                                 Caret.Hwnd = IntPtr.Zero;
2071                                 return;
2072                         }
2073                         
2074                         XSetFunction (DisplayHandle, Caret.gc, GXFunction.GXinvert);
2075                 }
2076                 
2077                 internal override IntPtr CreateWindow (CreateParams cp) 
2078                 {
2079                         GdkWindowAttr           gdk_window_attributes;
2080                         GdkWindowAttributesType attributes_mask = 0;
2081                         Hwnd                    hwnd;
2082                         int                     X;
2083                         int                     Y;
2084                         int                     Width;
2085                         int                     Height;
2086                         IntPtr                  GdkParentHandle;
2087                         IntPtr                  GdkWholeWindow;
2088                         IntPtr                  GdkClientWindow;
2089                         Rectangle               ClientRect;
2090                         GdkWindowType           gdk_window_type;
2091                         
2092                         
2093                         hwnd = new Hwnd ();
2094                         
2095                         gdk_window_attributes = new GdkWindowAttr ();
2096                         
2097                         X = cp.X;
2098                         Y = cp.Y;
2099                         Width = cp.Width;
2100                         Height = cp.Height;
2101                         
2102                         if (Width < 1) Width = 1;
2103                         if (Height < 1) Height = 1;
2104                         
2105                         gdk_window_type = GdkWindowType.GDK_WINDOW_CHILD;
2106                         
2107                         if (cp.Parent != IntPtr.Zero) {
2108                                 GdkParentHandle = gdk_window_lookup (Hwnd.ObjectFromHandle (cp.Parent).client_window);
2109                         } else {
2110                                 if ((cp.Style & (int)WindowStyles.WS_CHILD) != 0) {
2111                                         // We need to use our foster parent window until this poor child gets it's parent assigned
2112                                         GdkParentHandle = GdkFosterParent;
2113                                 } else if ((cp.Style & (int)WindowStyles.WS_POPUP) != 0) {
2114                                         GdkParentHandle = GdkRootWindow;
2115                                 } else {
2116                                         // Default position on screen, if window manager doesn't place us somewhere else
2117                                         if (X < 1) X = 50;
2118                                         if (Y < 1) Y = 50;
2119                                         GdkParentHandle = GdkRootWindow;
2120                                 }
2121                         }
2122                         
2123 //                      ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
2124                         
2125 //                      Attributes.bit_gravity = Gravity.NorthWestGravity;
2126 //                      Attributes.win_gravity = Gravity.NorthWestGravity;
2127                         
2128                         // FIXME: does gdk need that ?
2129                         // Save what's under the toolwindow
2130                         if ((cp.ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
2131 //                              Attributes.save_under = true;
2132 //                              ValueMask |= SetWindowValuemask.SaveUnder;
2133                         }
2134                         
2135                         // If we're a popup without caption we override the WM
2136                         if ((cp.Style & ((int)WindowStyles.WS_POPUP)) != 0) {
2137                                 if ((cp.Style & (int)WindowStyles.WS_CAPTION) == 0) {
2138                                         gdk_window_attributes.override_redirect = true;
2139                                         attributes_mask |= GdkWindowAttributesType.GDK_WA_NOREDIR;
2140                                 }
2141                         }
2142                         
2143                         hwnd.x = X;
2144                         hwnd.y = Y;
2145                         hwnd.width = Width;
2146                         hwnd.height = Height;
2147                         hwnd.parent = Hwnd.ObjectFromHandle (cp.Parent);
2148                         
2149                         if ((cp.Style & ((int)WindowStyles.WS_DISABLED)) != 0) {
2150                                 hwnd.enabled = false;
2151                         }
2152                         
2153                         ClientRect = hwnd.ClientRect;
2154                         GdkClientWindow = IntPtr.Zero;
2155                         
2156                         gdk_window_attributes.x = X;
2157                         gdk_window_attributes.y = Y;
2158                         gdk_window_attributes.width = Width;
2159                         gdk_window_attributes.height = Height;
2160                         gdk_window_attributes.window_type = gdk_window_type;
2161                         
2162                         attributes_mask |= GdkWindowAttributesType.GDK_WA_X | GdkWindowAttributesType.GDK_WA_Y;
2163                         
2164                         gdk_window_attributes.wclass = GdkWindowClass.GDK_INPUT_OUTPUT;
2165                         
2166                         lock (XlibLock) {
2167                                 GdkWholeWindow = gdk_window_new (GdkParentHandle, ref gdk_window_attributes, (int)attributes_mask);
2168                                 
2169                                 if (GdkWholeWindow != IntPtr.Zero) {
2170                                         attributes_mask &= ~GdkWindowAttributesType.GDK_WA_NOREDIR;
2171                                         
2172                                         if (GdkCustomVisual != IntPtr.Zero && GdkCustomColormap != IntPtr.Zero) {
2173                                                 attributes_mask |= GdkWindowAttributesType.GDK_WA_COLORMAP | GdkWindowAttributesType.GDK_WA_VISUAL;
2174                                                 gdk_window_attributes.colormap = GdkCustomColormap;
2175                                                 gdk_window_attributes.visual = GdkCustomVisual;
2176                                         }
2177                                         
2178                                         gdk_window_attributes.x = ClientRect.X;
2179                                         gdk_window_attributes.y = ClientRect.Y;
2180                                         gdk_window_attributes.width = ClientRect.Width;
2181                                         gdk_window_attributes.height = ClientRect.Height;
2182                                         
2183                                         GdkClientWindow = gdk_window_new (GdkWholeWindow, ref gdk_window_attributes, (int)attributes_mask);
2184                                 }
2185                         }
2186                         
2187                         if ((GdkWholeWindow == IntPtr.Zero) || (GdkClientWindow == IntPtr.Zero)) {
2188                                 throw new Exception ("Could not create X11 Gdk windows");
2189                         }
2190                         
2191                         hwnd.WholeWindow = gdk_x11_drawable_get_xid (GdkWholeWindow);
2192                         hwnd.ClientWindow = gdk_x11_drawable_get_xid (GdkClientWindow);
2193                         
2194                         #if DriverDebug
2195                                 Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0);
2196                         #endif
2197                         
2198                         lock (XlibLock) {
2199                                 gdk_window_set_events (GdkWholeWindow, (int)GdkSelectInputMask);
2200                                 gdk_window_set_events (GdkClientWindow, (int)GdkSelectInputMask);
2201                                 
2202                                 if ((cp.Style & (int)WindowStyles.WS_VISIBLE) != 0) {
2203                                         gdk_window_show (GdkWholeWindow);
2204                                         gdk_window_show (GdkClientWindow);
2205                                         hwnd.visible = true;
2206                                 }
2207                         }
2208                         
2209                         SetWMStyles (hwnd, cp);
2210                         
2211                         if ((cp.Style & (int)WindowStyles.WS_MINIMIZE) != 0) {
2212                                 SetWindowState (hwnd.Handle, FormWindowState.Minimized);
2213                         } else if ((cp.Style & (int)WindowStyles.WS_MAXIMIZE) != 0) {
2214                                 SetWindowState (hwnd.Handle, FormWindowState.Maximized);
2215                         }
2216                         
2217                         // for now make all windows dnd enabled
2218                         Dnd.SetAllowDrop (hwnd, true);
2219                         
2220                         // Set caption/window title
2221                         Text (hwnd.Handle, cp.Caption);
2222                         
2223                         return hwnd.Handle;
2224                 }
2225                 
2226                 internal override IntPtr CreateWindow (IntPtr Parent, int X, int Y, int Width, int Height)
2227                 {
2228                         CreateParams create_params = new CreateParams ();
2229                         
2230                         create_params.Caption = "";
2231                         create_params.X = X;
2232                         create_params.Y = Y;
2233                         create_params.Width = Width;
2234                         create_params.Height = Height;
2235                         
2236                         create_params.ClassName = XplatUI.DefaultClassName;
2237                         create_params.ClassStyle = 0;
2238                         create_params.ExStyle = 0;
2239                         create_params.Parent = IntPtr.Zero;
2240                         create_params.Param = 0;
2241                         
2242                         return CreateWindow (create_params);
2243                 }
2244                 
2245                 internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
2246                 {
2247                         IntPtr  cursor;
2248                         Bitmap  cursor_bitmap;
2249                         Bitmap  cursor_mask;
2250                         Byte[]  cursor_bits;
2251                         Byte[]  mask_bits;
2252                         Color   c_pixel;
2253                         Color   m_pixel;
2254                         int     width;
2255                         int     height;
2256                         IntPtr  cursor_pixmap;
2257                         IntPtr  mask_pixmap;
2258                         XColor  fg;
2259                         XColor  bg;
2260                         bool    and;
2261                         bool    xor;
2262                         
2263                         Size cursor_size = CursorSize;
2264                         width = cursor_size.Width;
2265                         height = cursor_size.Height;
2266                         
2267                         // Win32 only allows creation cursors of a certain size
2268                         if ((bitmap.Width != width) || (bitmap.Width != height)) {
2269                                 cursor_bitmap = new Bitmap (bitmap, new Size (width, height));
2270                                 cursor_mask = new Bitmap (mask, new Size (width, height));
2271                         } else {
2272                                 cursor_bitmap = bitmap;
2273                                 cursor_mask = mask;
2274                         }
2275                         
2276                         width = cursor_bitmap.Width;
2277                         height = cursor_bitmap.Height;
2278                         
2279                         cursor_bits = new Byte [(width / 8) * height];
2280                         mask_bits = new Byte [(width / 8) * height];
2281                         
2282                         for (int y = 0; y < height; y++) {
2283                                 for (int x = 0; x < width; x++) {
2284                                         c_pixel = cursor_bitmap.GetPixel (x, y);
2285                                         m_pixel = cursor_mask.GetPixel (x, y);
2286                                         
2287                                         and = c_pixel == cursor_pixel;
2288                                         xor = m_pixel == mask_pixel;
2289                                         
2290                                         if (!and && !xor) {
2291                                                 // Black
2292                                                 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));       // The bit already is 0
2293                                                 mask_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2294                                         } else if (and && !xor) {
2295                                                 // White
2296                                                 cursor_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2297                                                 mask_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2298                                                 #if notneeded
2299                                         } else if (and && !xor) {
2300                                                 // Screen
2301                                         } else if (and && xor) {
2302                                                 // Inverse Screen
2303
2304                                                 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
2305                                                 // we want both to be 0 so nothing to be done
2306                                                 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
2307                                                 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
2308                                                 #endif
2309                                         }
2310                                 }
2311                         }
2312                         
2313                         cursor_pixmap = XCreatePixmapFromBitmapData (DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
2314                         mask_pixmap = XCreatePixmapFromBitmapData (DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
2315                         fg = new XColor ();
2316                         bg = new XColor ();
2317                         
2318                         fg.pixel = XWhitePixel (DisplayHandle, ScreenNo);
2319                         fg.red = (ushort)65535;
2320                         fg.green = (ushort)65535;
2321                         fg.blue = (ushort)65535;
2322                         
2323                         bg.pixel = XBlackPixel (DisplayHandle, ScreenNo);
2324                         
2325                         cursor = XCreatePixmapCursor (DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
2326                         
2327                         XFreePixmap (DisplayHandle, cursor_pixmap);
2328                         XFreePixmap (DisplayHandle, mask_pixmap);
2329                         
2330                         return cursor;
2331                 }
2332                 
2333                 internal override IntPtr DefineStdCursor (StdCursor id)
2334                 {
2335                         CursorFontShape shape;
2336                         IntPtr          cursor;
2337                         
2338                         // FIXME - define missing shapes
2339                         
2340                         switch (id) {
2341                         case StdCursor.AppStarting: {
2342                                         shape = CursorFontShape.XC_watch;
2343                                         break;
2344                                 }
2345                                 
2346                         case StdCursor.Arrow: {
2347                                         return IntPtr.Zero;
2348                                 }
2349                                 
2350                         case StdCursor.Cross: {
2351                                         shape = CursorFontShape.XC_crosshair;
2352                                         break;
2353                                 }
2354                                 
2355                         case StdCursor.Default: {
2356                                         return IntPtr.Zero;
2357                                 }
2358                                 
2359                         case StdCursor.Hand: {
2360                                         shape = CursorFontShape.XC_hand1;
2361                                         break;
2362                                 }
2363                                 
2364                         case StdCursor.Help: {
2365                                         shape = CursorFontShape.XC_question_arrow;
2366                                         break;
2367                                 }
2368                                 
2369                         case StdCursor.HSplit: {
2370                                         shape = CursorFontShape.XC_sb_v_double_arrow; 
2371                                         break;
2372                                 }
2373                                 
2374                         case StdCursor.IBeam: {
2375                                         shape = CursorFontShape.XC_xterm; 
2376                                         break;
2377                                 }
2378                                 
2379                         case StdCursor.No: {
2380                                         shape = CursorFontShape.XC_circle; 
2381                                         break;
2382                                 }
2383                                 
2384                         case StdCursor.NoMove2D: {
2385                                         shape = CursorFontShape.XC_fleur; 
2386                                         break;
2387                                 }
2388                                 
2389                         case StdCursor.NoMoveHoriz: {
2390                                         shape = CursorFontShape.XC_fleur; 
2391                                         break;
2392                                 }
2393                                 
2394                         case StdCursor.NoMoveVert: {
2395                                         shape = CursorFontShape.XC_fleur; 
2396                                         break;
2397                                 }
2398                                 
2399                         case StdCursor.PanEast: {
2400                                         shape = CursorFontShape.XC_fleur; 
2401                                         break;
2402                                 }
2403                                 
2404                         case StdCursor.PanNE: {
2405                                         shape = CursorFontShape.XC_fleur; 
2406                                         break;
2407                                 }
2408                                 
2409                         case StdCursor.PanNorth: {
2410                                         shape = CursorFontShape.XC_fleur; 
2411                                         break;
2412                                 }
2413                                 
2414                         case StdCursor.PanNW: {
2415                                         shape = CursorFontShape.XC_fleur; 
2416                                         break;
2417                                 }
2418                                 
2419                         case StdCursor.PanSE: {
2420                                         shape = CursorFontShape.XC_fleur; 
2421                                         break;
2422                                 }
2423                                 
2424                         case StdCursor.PanSouth: {
2425                                         shape = CursorFontShape.XC_fleur; 
2426                                         break;
2427                                 }
2428                                 
2429                         case StdCursor.PanSW: {
2430                                         shape = CursorFontShape.XC_fleur; 
2431                                         break;
2432                                 }
2433                                 
2434                         case StdCursor.PanWest: {
2435                                         shape = CursorFontShape.XC_sizing; 
2436                                         break;
2437                                 }
2438                                 
2439                         case StdCursor.SizeAll: {
2440                                         shape = CursorFontShape.XC_fleur; 
2441                                         break;
2442                                 }
2443                                 
2444                         case StdCursor.SizeNESW: {
2445                                         shape = CursorFontShape.XC_top_right_corner; 
2446                                         break;
2447                                 }
2448                                 
2449                         case StdCursor.SizeNS: {
2450                                         shape = CursorFontShape.XC_sb_v_double_arrow;
2451                                         break;
2452                                 }
2453                                 
2454                         case StdCursor.SizeNWSE: {
2455                                         shape = CursorFontShape.XC_top_left_corner; 
2456                                         break;
2457                                 }
2458                                 
2459                         case StdCursor.SizeWE: {
2460                                         shape = CursorFontShape.XC_sb_h_double_arrow; 
2461                                         break;
2462                                 }
2463                                 
2464                         case StdCursor.UpArrow: {
2465                                         shape = CursorFontShape.XC_center_ptr; 
2466                                         break;
2467                                 }
2468                                 
2469                         case StdCursor.VSplit: {
2470                                         shape = CursorFontShape.XC_sb_h_double_arrow;
2471                                         break;
2472                                 }
2473                                 
2474                         case StdCursor.WaitCursor: {
2475                                         shape = CursorFontShape.XC_watch; 
2476                                         break;
2477                                 }
2478                                 
2479                         default: {
2480                                         return IntPtr.Zero;
2481                                 }
2482                         }
2483                         
2484                         lock (XlibLock) {
2485                                 cursor = XCreateFontCursor (DisplayHandle, shape);
2486                         }
2487                         return cursor;
2488                 }
2489                 
2490                 internal override IntPtr DefWndProc (ref Message msg)
2491                 {
2492                         return IntPtr.Zero;
2493                 }
2494                 
2495                 internal override void DestroyCaret (IntPtr handle)
2496                 {
2497                         if (Caret.Hwnd == handle) {
2498                                 if (Caret.Visible == 1) {
2499                                         Caret.Timer.Stop ();
2500                                         HideCaret ();
2501                                 }
2502                                 if (Caret.gc != IntPtr.Zero) {
2503                                         XFreeGC (DisplayHandle, Caret.gc);
2504                                         Caret.gc = IntPtr.Zero;
2505                                 }
2506                                 Caret.Hwnd = IntPtr.Zero;
2507                                 Caret.Visible = 0;
2508                                 Caret.On = false;
2509                         }
2510                 }
2511                 
2512                 internal override void DestroyCursor (IntPtr cursor)
2513                 {
2514                         lock (XlibLock) {
2515                                 XFreeCursor (DisplayHandle, cursor);
2516                         }
2517                 }
2518                 
2519                 internal override void DestroyWindow (IntPtr handle)
2520                 {
2521                         Hwnd    hwnd;
2522                         
2523                         hwnd = Hwnd.ObjectFromHandle (handle);
2524                         
2525                         if (hwnd == null) {
2526                                 #if DriverDebug
2527                                         Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
2528                                 #endif
2529                                 return;
2530                         }
2531                         
2532                         #if DriverDebug
2533                                 Console.WriteLine("Destroying window {0:X}", handle.ToInt32());
2534                         #endif
2535                         
2536                         // Make sure if the caret is in the window, that we destroy the caret, too
2537                         if (Caret.Hwnd == hwnd.client_window) {
2538                                 DestroyCaret (handle);
2539                         }
2540                         
2541                         // Mark our children as gone as well
2542                         DestroyChildWindow (Control.ControlNativeWindow.ControlFromHandle (handle));
2543                         
2544                         // Send destroy message
2545                         SendMessage (handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
2546                         
2547                         lock (XlibLock) {
2548                                 if (hwnd.client_window != IntPtr.Zero) {
2549                                         gdk_window_destroy (gdk_window_lookup (hwnd.client_window));
2550                                 }
2551                                 
2552                                 if ((hwnd.whole_window != IntPtr.Zero) && (hwnd.whole_window != hwnd.client_window)) {
2553                                         gdk_window_destroy (gdk_window_lookup (hwnd.whole_window));
2554                                 }
2555                         }
2556                         hwnd.Dispose ();
2557                 }
2558                 
2559                 internal override IntPtr DispatchMessage (ref MSG msg)
2560                 {
2561                         return NativeWindow.WndProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2562                 }
2563                 
2564                 internal override void DrawReversibleRectangle (IntPtr handle, Rectangle rect, int line_width)
2565                 {
2566                         Hwnd            hwnd;
2567                         XGCValues       gc_values;
2568                         IntPtr          gc;
2569                         
2570                         hwnd = Hwnd.ObjectFromHandle (handle);
2571                         
2572                         gc_values = new XGCValues ();
2573                         
2574                         gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
2575                         gc_values.line_width = line_width;
2576                         gc_values.foreground = XBlackPixel (DisplayHandle, ScreenNo);
2577                         
2578                         // This logic will give us true rubber bands: (libsx, SANE_XOR)
2579                         //mask = foreground ^ background; 
2580                         //XSetForeground(DisplayHandle, gc, 0xffffffff);
2581                         //XSetBackground(DisplayHandle, gc, background);
2582                         //XSetFunction(DisplayHandle,   gc, GXxor);
2583                         //XSetPlaneMask(DisplayHandle,  gc, mask);
2584                         
2585                         
2586                         gc = XCreateGC (DisplayHandle, hwnd.client_window, GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground, ref gc_values);
2587                         uint foreground;
2588                         uint background;
2589                         
2590                         Control control;
2591                         control = Control.FromHandle (handle);
2592                         
2593                         XColor xcolor = new XColor ();
2594                         
2595                         xcolor.red = (ushort)(control.ForeColor.R * 257);
2596                         xcolor.green = (ushort)(control.ForeColor.G * 257);
2597                         xcolor.blue = (ushort)(control.ForeColor.B * 257);
2598                         XAllocColor (DisplayHandle, DefaultColormap, ref xcolor);
2599                         foreground = (uint)xcolor.pixel.ToInt32 ();
2600                         
2601                         xcolor.red = (ushort)(control.BackColor.R * 257);
2602                         xcolor.green = (ushort)(control.BackColor.G * 257);
2603                         xcolor.blue = (ushort)(control.BackColor.B * 257);
2604                         XAllocColor (DisplayHandle, DefaultColormap, ref xcolor);
2605                         background = (uint)xcolor.pixel.ToInt32 ();
2606                         
2607                         uint mask = foreground ^ background; 
2608                         
2609                         XSetForeground (DisplayHandle, gc, 0xffffffff);
2610                         XSetBackground (DisplayHandle, gc, background);
2611                         XSetFunction (DisplayHandle,   gc, GXFunction.GXxor);
2612                         XSetPlaneMask (DisplayHandle,  gc, mask);
2613                         
2614                         if ((rect.Width > 0) && (rect.Height > 0)) {
2615                                 XDrawRectangle (DisplayHandle, hwnd.client_window, gc, rect.Left, rect.Top, rect.Width, rect.Height);
2616                         } else {
2617                                 if (rect.Width > 0) {
2618                                         XDrawLine (DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.Right, rect.Y);
2619                                 } else {
2620                                         XDrawLine (DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.X, rect.Bottom);
2621                                 }
2622                         }
2623                         XFreeGC (DisplayHandle, gc);
2624                 }
2625                 
2626                 internal override void DoEvents ()
2627                 {
2628                         MSG msg = new MSG ();
2629                         
2630                         if (OverrideCursorHandle != IntPtr.Zero) {
2631                                 OverrideCursorHandle = IntPtr.Zero;
2632                         }
2633                         
2634                         while (PeekMessage (ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
2635                                 TranslateMessage (ref msg);
2636                                 DispatchMessage (ref msg);
2637                         }
2638                 }
2639                 
2640                 internal override void EnableWindow (IntPtr handle, bool Enable)
2641                 {
2642                         Hwnd    hwnd;
2643                         
2644                         hwnd = Hwnd.ObjectFromHandle (handle);
2645                         if (hwnd != null) {
2646                                 hwnd.Enabled = Enable;
2647                         }
2648                 }
2649                 
2650                 internal override void EndLoop (Thread thread)
2651                 {
2652                         // This is where we one day will shut down the loop for the thread
2653                 }
2654                 
2655                 
2656                 internal override IntPtr GetActive ()
2657                 {
2658                         Atom    actual_atom;
2659                         int     actual_format;
2660                         int     nitems;
2661                         int     bytes_after;
2662                         IntPtr  prop = IntPtr.Zero;
2663                         IntPtr  active = IntPtr.Zero;
2664                         
2665                         XGetWindowProperty (DisplayHandle, RootWindow, NetAtoms [(int)NA._NET_ACTIVE_WINDOW], 0, 1, false, Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2666                         if ((nitems > 0) && (prop != IntPtr.Zero)) {
2667                                 active = (IntPtr)Marshal.ReadInt32 (prop);
2668                                 XFree (prop);
2669                         }
2670                         
2671                         if (active != IntPtr.Zero) {
2672                                 Hwnd    hwnd;
2673                                 
2674                                 hwnd = Hwnd.GetObjectFromWindow (active);
2675                                 if (hwnd != null) {
2676                                         active = hwnd.Handle;
2677                                 } else {
2678                                         active = IntPtr.Zero;
2679                                 }
2680                         }
2681                         return active;
2682                 }
2683                 
2684                 internal override void GetCursorInfo (IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
2685                 {
2686                         throw new NotImplementedException ();
2687                 }
2688                 
2689                 internal override void GetDisplaySize (out Size size)
2690                 {
2691                         XWindowAttributes       attributes=new XWindowAttributes ();
2692                         
2693                         lock (XlibLock) {
2694                                 // FIXME - use _NET_WM messages instead?
2695                                 XGetWindowAttributes (DisplayHandle, XRootWindow (DisplayHandle, ScreenNo), ref attributes);
2696                         }
2697                         
2698                         size = new Size (attributes.width, attributes.height);
2699                 }
2700                 
2701                 internal override SizeF GetAutoScaleSize (Font font)
2702                 {
2703                         Graphics        g;
2704                         float           width;
2705                         string          magic_string = "The quick brown fox jumped over the lazy dog.";
2706                         double          magic_number = 44.549996948242189;
2707                         
2708                         g = Graphics.FromHwnd (FosterParent);
2709                         
2710                         width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
2711                         return new SizeF (width, font.Height);
2712                 }
2713                 
2714                 internal override IntPtr GetParent (IntPtr handle)
2715                 {
2716                         Hwnd    hwnd;
2717                         
2718                         hwnd = Hwnd.ObjectFromHandle (handle);
2719                         if (hwnd != null && hwnd.parent != null) {
2720                                 return hwnd.parent.Handle;
2721                         }
2722                         return IntPtr.Zero;
2723                 }
2724                 
2725                 internal override void GetCursorPos (IntPtr handle, out int x, out int y)
2726                 {
2727                         IntPtr  use_handle;
2728                         IntPtr  root;
2729                         IntPtr  child;
2730                         int     root_x;
2731                         int     root_y;
2732                         int     win_x;
2733                         int     win_y;
2734                         int     keys_buttons;
2735                         
2736                         if (handle != IntPtr.Zero) {
2737                                 use_handle = Hwnd.ObjectFromHandle (handle).client_window;
2738                         } else {
2739                                 use_handle = RootWindow;
2740                         }
2741                         
2742                         lock (XlibLock) {
2743                                 XQueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
2744                         }
2745                         
2746                         if (handle != IntPtr.Zero) {
2747                                 x = win_x;
2748                                 y = win_y;
2749                         } else {
2750                                 x = root_x;
2751                                 y = root_y;
2752                         }
2753                 }
2754                 
2755                 internal override bool GetFontMetrics (Graphics g, Font font, out int ascent, out int descent)
2756                 {
2757                         return GetFontMetrics (g.GetHdc (), font.ToHfont (), out ascent, out descent);
2758                 }
2759                 
2760                 internal override Point GetMenuOrigin (IntPtr handle)
2761                 {
2762                         Hwnd    hwnd;
2763                         
2764                         hwnd = Hwnd.ObjectFromHandle (handle);
2765                         
2766                         if (hwnd != null) {
2767                                 return hwnd.MenuOrigin;
2768                         }
2769                         return Point.Empty;
2770                 }
2771                 
2772                 internal override bool GetMessage (ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
2773                 {
2774                         XEvent  xevent;
2775                         bool    client;
2776                         Hwnd    hwnd;
2777                         
2778                         ProcessNextMessage:
2779                         
2780                         if (MessageQueue.Count > 0) {
2781                                 xevent = (XEvent) MessageQueue.Dequeue ();
2782                         } else {
2783                                 UpdateMessageQueue ();
2784                                 
2785                                 if (MessageQueue.Count > 0) {
2786                                         xevent = (XEvent) MessageQueue.Dequeue ();
2787                                 } else {
2788                                         if (!PostQuitState) {
2789                                                 msg.hwnd = IntPtr.Zero;
2790                                                 msg.message = Msg.WM_ENTERIDLE;
2791                                                 return true;
2792                                         }
2793                                         
2794                                         // We reset ourselves so GetMessage can be called again
2795                                         PostQuitState = false;
2796                                         
2797                                         return false;
2798                                 }
2799                         }
2800                         
2801                         // FIXME - handle filtering
2802                         
2803                         hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
2804                         
2805                         // Handle messages for windows that are already or are about to be destroyed
2806                         if (hwnd == null) {
2807                                 #if DriverDebug
2808                                         Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
2809                                 #endif
2810                                 goto ProcessNextMessage;
2811                         }
2812                         
2813                         if (hwnd.client_window == xevent.AnyEvent.window) {
2814                                 client = true;
2815                                 //Console.WriteLine("Client message, sending to window {0:X}", msg.hwnd.ToInt32());
2816                         } else {
2817                                 client = false;
2818                                 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
2819                         }
2820                         
2821                         msg.hwnd = hwnd.Handle;
2822                         
2823                         //
2824                         // If you add a new event to this switch make sure to add it in
2825                         // UpdateMessage also unless it is not coming through the X event system.
2826                         //
2827                         switch (xevent.type) {
2828                         case XEventName.KeyPress: {
2829                                         Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
2830                                         break;
2831                                 }
2832                                 
2833                         case XEventName.KeyRelease: {
2834                                         Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
2835                                         break;
2836                                 }
2837                                 
2838                         case XEventName.ButtonPress: {
2839                                         switch (xevent.ButtonEvent.button) {
2840                                         case 1: {
2841                                                         MouseState |= MouseButtons.Left;
2842                                                         if (client) {
2843                                                                 msg.message = Msg.WM_LBUTTONDOWN;
2844                                                         } else {
2845                                                                 msg.message = Msg.WM_NCLBUTTONDOWN;
2846                                                                 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2847                                                         }
2848                                                         // TODO: For WM_NCLBUTTONDOWN wParam specifies a hit-test value not the virtual keys down
2849                                                         msg.wParam = GetMousewParam (0);
2850                                                         break;
2851                                                 }
2852                                                 
2853                                         case 2: {
2854                                                         MouseState |= MouseButtons.Middle;
2855                                                         if (client) {
2856                                                                 msg.message = Msg.WM_MBUTTONDOWN;
2857                                                         } else {
2858                                                                 msg.message = Msg.WM_NCMBUTTONDOWN;
2859                                                                 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2860                                                         }
2861                                                         msg.wParam = GetMousewParam (0);
2862                                                         break;
2863                                                 }
2864                                                 
2865                                         case 3: {
2866                                                         MouseState |= MouseButtons.Right;
2867                                                         if (client) {
2868                                                                 msg.message = Msg.WM_RBUTTONDOWN;
2869                                                         } else {
2870                                                                 msg.message = Msg.WM_NCRBUTTONDOWN;
2871                                                                 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2872                                                         }
2873                                                         msg.wParam = GetMousewParam (0);
2874                                                         break;
2875                                                 }
2876                                                 
2877                                         case 4: {
2878                                                         msg.message = Msg.WM_MOUSEWHEEL;
2879                                                         msg.wParam = GetMousewParam (120);
2880                                                         break;
2881                                                 }
2882                                                 
2883                                         case 5: {
2884                                                         msg.message = Msg.WM_MOUSEWHEEL;
2885                                                         msg.wParam = GetMousewParam (-120);
2886                                                         break;
2887                                                 }
2888                                                 
2889                                         }
2890                                         
2891                                         msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
2892                                         MousePosition.X = xevent.ButtonEvent.x;
2893                                         MousePosition.Y = xevent.ButtonEvent.y;
2894                                         
2895                                         if (!hwnd.Enabled) {
2896                                                 IntPtr dummy;
2897                                                 
2898                                                 msg.hwnd = hwnd.EnabledHwnd;
2899                                                 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);
2900                                                 msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
2901                                         }
2902                                         
2903                                         if (Grab.Hwnd != IntPtr.Zero) {
2904                                                 msg.hwnd = Grab.Hwnd;
2905                                         }
2906                                         
2907                                         if (!ClickPending.Pending) {
2908                                                 ClickPending.Pending = true;
2909                                                 ClickPending.Hwnd = msg.hwnd;
2910                                                 ClickPending.Message = msg.message;
2911                                                 ClickPending.wParam = msg.wParam;
2912                                                 ClickPending.lParam = msg.lParam;
2913                                                 ClickPending.Time = (long)xevent.ButtonEvent.time;
2914                                         } else {
2915                                                 if ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message)) {
2916                                                         // Looks like a genuine double click, clicked twice on the same spot with the same keys
2917                                                         switch (xevent.ButtonEvent.button) {
2918                                                         case 1: {
2919                                                                         msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
2920                                                                         break;
2921                                                                 }
2922                                                                 
2923                                                         case 2: {
2924                                                                         msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
2925                                                                         break;
2926                                                                 }
2927                                                                 
2928                                                         case 3: {
2929                                                                         msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
2930                                                                         break;
2931                                                                 }
2932                                                         }
2933                                                 }
2934                                                 ClickPending.Pending = false;
2935                                         }
2936                                         
2937                                         break;
2938                                 }
2939                                 
2940                         case XEventName.ButtonRelease: {
2941                                         Dnd.HandleButtonRelease (ref xevent);
2942                                         switch (xevent.ButtonEvent.button) {
2943                                         case 1: {
2944                                                         MouseState &= ~MouseButtons.Left;
2945                                                         if (client) {
2946                                                                 msg.message = Msg.WM_LBUTTONUP;
2947                                                         } else {
2948                                                                 msg.message = Msg.WM_NCLBUTTONUP;
2949                                                                 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2950                                                         }
2951                                                         msg.wParam = GetMousewParam (0);
2952                                                         break;
2953                                                 }
2954                                                 
2955                                         case 2: {
2956                                                         MouseState &= ~MouseButtons.Middle;
2957                                                         if (client) {
2958                                                                 msg.message = Msg.WM_MBUTTONUP;
2959                                                         } else {
2960                                                                 msg.message = Msg.WM_NCMBUTTONUP;
2961                                                                 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2962                                                         }
2963                                                         msg.wParam = GetMousewParam (0);
2964                                                         break;
2965                                                 }
2966                                                 
2967                                         case 3: {
2968                                                         MouseState &= ~MouseButtons.Right;
2969                                                         if (client) {
2970                                                                 msg.message = Msg.WM_RBUTTONUP;
2971                                                         } else {
2972                                                                 msg.message = Msg.WM_NCRBUTTONUP;
2973                                                                 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2974                                                         }
2975                                                         msg.wParam = GetMousewParam (0);
2976                                                         break;
2977                                                 }
2978                                                 
2979                                         case 4: {
2980                                                         goto ProcessNextMessage;
2981                                                 }
2982                                                 
2983                                         case 5: {
2984                                                         goto ProcessNextMessage;
2985                                                 }
2986                                         }
2987                                         
2988                                         if (!hwnd.Enabled) {
2989                                                 IntPtr dummy;
2990                                                 
2991                                                 msg.hwnd = hwnd.EnabledHwnd;
2992                                                 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);
2993                                                 msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
2994                                         }
2995                                         
2996                                         if (Grab.Hwnd != IntPtr.Zero) {
2997                                                 msg.hwnd = Grab.Hwnd;
2998                                         }
2999                                         
3000                                         msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
3001                                         MousePosition.X = xevent.ButtonEvent.x;
3002                                         MousePosition.Y = xevent.ButtonEvent.y;
3003                                         break;
3004                                 }
3005                                 
3006                         case XEventName.MotionNotify: {
3007                                         if (client) {
3008                                                 #if DriverDebugExtra
3009                                                         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);
3010                                                 #endif
3011                                                 
3012                                                 if (Dnd.HandleMotionNotify (ref xevent))
3013                                                         goto ProcessNextMessage;
3014                                                 if (Grab.Hwnd != IntPtr.Zero) {
3015                                                         msg.hwnd = Grab.Hwnd;
3016                                                 } else {
3017                                                         NativeWindow.WndProc (msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
3018                                                 }
3019                                                 
3020                                                 msg.message = Msg.WM_MOUSEMOVE;
3021                                                 msg.wParam = GetMousewParam (0);
3022                                                 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
3023                                                 
3024                                                 if (!hwnd.Enabled) {
3025                                                         IntPtr dummy;
3026                                                         
3027                                                         msg.hwnd = hwnd.EnabledHwnd;
3028                                                         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);
3029                                                         msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
3030                                                 }
3031                                                 
3032                                                 HoverState.X = MousePosition.X = xevent.MotionEvent.x;
3033                                                 HoverState.Y = MousePosition.Y = xevent.MotionEvent.y;
3034                                                 
3035                                                 break;
3036                                         } else {
3037                                                 #if DriverDebugExtra
3038                                                         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);
3039                                                 #endif
3040                                                 msg.message = Msg.WM_NCMOUSEMOVE;
3041                                                 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
3042                                                 
3043                                                 if (!hwnd.Enabled) {
3044                                                         IntPtr dummy;
3045                                                         
3046                                                         msg.hwnd = hwnd.EnabledHwnd;
3047                                                         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);
3048                                                         msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
3049                                                 }
3050                                                 
3051                                                 #if notyet
3052                                                         // Not sure we need this...
3053                                                         HitTest ht;
3054                                                         ht = NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, msg.lParam);
3055                                                 #endif
3056                                                 
3057                                                 MousePosition.X = xevent.MotionEvent.x;
3058                                                 MousePosition.Y = xevent.MotionEvent.y;
3059                                         }
3060                                         
3061                                         break;
3062                                 }
3063                                 
3064                         case XEventName.EnterNotify: {
3065                                         if (!hwnd.Enabled) {
3066                                                 goto ProcessNextMessage;
3067                                         }
3068                                         if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
3069                                                 goto ProcessNextMessage;
3070                                         }
3071                                         msg.message = Msg.WM_MOUSE_ENTER;
3072                                         HoverState.Timer.Enabled = true;
3073                                         HoverState.Window = xevent.CrossingEvent.window;
3074                                         break;
3075                                 }
3076                                 
3077                         case XEventName.LeaveNotify: {
3078                                         if (!hwnd.Enabled) {
3079                                                 goto ProcessNextMessage;
3080                                         }
3081                                         if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
3082                                                 goto ProcessNextMessage;
3083                                         }
3084                                         msg.message = Msg.WM_MOUSE_LEAVE;
3085                                         HoverState.Timer.Enabled = false;
3086                                         HoverState.Window = IntPtr.Zero;
3087                                         break;
3088                                 }
3089                                 
3090                                 #if later
3091                                 case XEventName.CreateNotify: {
3092                                         if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
3093                                                 msg.message = WM_CREATE;
3094                                                 // Set up CreateStruct
3095                                         } else {
3096                                                 goto ProcessNextMessage;
3097                                         }
3098                                         break;
3099                                 }
3100                                 #endif
3101                                 
3102                                 
3103                         case XEventName.ReparentNotify: {
3104                                         if (hwnd.parent == null) {      // Toplevel
3105                                                 if (xevent.ReparentEvent.parent != IntPtr.Zero) {
3106                                                         // We need to adjust x/y
3107                                                         int     dummy_int;
3108                                                         
3109                                                         hwnd.Reparented = true;
3110                                                         
3111                                                         gdk_window_get_geometry (gdk_window_lookup (hwnd.whole_window), out hwnd.x, out hwnd.y, out dummy_int, out dummy_int, out dummy_int);
3112                                                         msg.message = Msg.WM_WINDOWPOSCHANGED;
3113                                                         if (hwnd.opacity != 0xffffffff) {
3114                                                                 uint opacity;
3115                                                                 
3116                                                                 opacity = hwnd.opacity;
3117                                                                 XChangeProperty (DisplayHandle, XGetParent (hwnd.whole_window), NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY], Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
3118                                                         }
3119                                                 } else {
3120                                                         hwnd.Reparented = false;
3121                                                         goto ProcessNextMessage;
3122                                                 }
3123                                         }
3124                                         break;
3125                                 }
3126                                 
3127                         case XEventName.ConfigureNotify: {
3128                                         if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {        // Ignore events for children (SubstructureNotify) and client areas
3129                                                 XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
3130                                                 IntPtr                          ptr;
3131                                                 Rectangle                       rect;
3132                                                 
3133                                                 #if DriverDebugExtra
3134                                                         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);
3135                                                 #endif
3136                                                 msg.message = Msg.WM_WINDOWPOSCHANGED;
3137                                                 hwnd.configure_pending = false;
3138                                                 
3139                                                 // We need to adjust our client window to track the resize of whole_window
3140                                                 rect = hwnd.DefaultClientRect;
3141                                                 
3142                                                 ncp = new XplatUIWin32.NCCALCSIZE_PARAMS ();
3143                                                 ptr = Marshal.AllocHGlobal (Marshal.SizeOf (ncp));
3144                                                 
3145                                                 ncp.rgrc1.left = rect.Left;
3146                                                 ncp.rgrc1.top = rect.Top;
3147                                                 ncp.rgrc1.right = rect.Right;
3148                                                 ncp.rgrc1.bottom = rect.Bottom;
3149                                                 
3150                                                 Marshal.StructureToPtr (ncp, ptr, true);
3151                                                 NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
3152                                                 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
3153                                                 Marshal.FreeHGlobal (ptr);
3154                                                 
3155                                                 // FIXME - debug this with Menus, need to set hwnd.ClientRect
3156                                                 
3157                                                 rect = new Rectangle (ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
3158                                                 //Console.WriteLine("CreateOffscreenbuffer...");
3159 //                                              CreateOffscreenBuffer (ref hwnd.client_offscreen, rect.Width, rect.Height);
3160                                                 
3161                                                 XMoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
3162                                         } else {
3163                                                 goto ProcessNextMessage;
3164                                         }
3165                                         
3166                                         msg.lParam = IntPtr.Zero;               // FIXME - Generate LPWINDOWPOS structure and pass on
3167                                         break;
3168                                 }
3169                                 
3170                         case XEventName.FocusIn: {
3171                                         if (!hwnd.Enabled) {
3172                                                 goto ProcessNextMessage;
3173                                         }
3174                                         msg.message = Msg.WM_SETFOCUS;
3175                                         msg.wParam = IntPtr.Zero;
3176                                         break;
3177                                 }
3178                                 
3179                         case XEventName.FocusOut: {
3180                                         if (!hwnd.Enabled) {
3181                                                 goto ProcessNextMessage;
3182                                         }
3183                                         msg.message = Msg.WM_KILLFOCUS;
3184                                         msg.wParam = IntPtr.Zero;
3185                                         break;
3186                                 }
3187                                 
3188                         case XEventName.Expose: {
3189                                         if (PostQuitState) {
3190                                                 goto ProcessNextMessage;
3191                                         }
3192                                         
3193                                         
3194                                         if (client) {
3195                                                 if (!hwnd.expose_pending) {
3196                                                         goto ProcessNextMessage;
3197                                                 }
3198                                         } else {
3199                                                 if (!hwnd.nc_expose_pending) {
3200                                                         goto ProcessNextMessage;
3201                                                 }
3202                                                 
3203                                                 switch (hwnd.border_style) {
3204                                                 case FormBorderStyle.Fixed3D: {
3205                                                                 Graphics g;
3206                                                                 
3207                                                                 g = Graphics.FromHwnd (hwnd.whole_window);
3208                                                                 ControlPaint.DrawBorder3D (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
3209                                                                 g.Dispose ();
3210                                                                 break;
3211                                                         }
3212                                                         
3213                                                 case FormBorderStyle.FixedSingle: {
3214                                                                 Graphics g;
3215                                                                 
3216                                                                 g = Graphics.FromHwnd (hwnd.whole_window);
3217                                                                 ControlPaint.DrawBorder (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
3218                                                                 g.Dispose ();
3219                                                                 break;
3220                                                         }
3221                                                 }
3222                                                 #if DriverDebugExtra
3223                                                         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);
3224                                                 #endif
3225                                                 
3226                                                 Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
3227                                                 Region region = new Region (rect);
3228                                                 IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
3229                                                 msg.message = Msg.WM_NCPAINT;
3230                                                 msg.wParam = hrgn;
3231                                                 hwnd.nc_expose_pending = false;
3232                                                 break;
3233                                         }
3234                                         #if DriverDebugExtra
3235                                                 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);
3236                                         #endif
3237                                         if (Caret.Visible == 1) {
3238                                                 Caret.Paused = true;
3239                                                 HideCaret ();
3240                                         }
3241                                         
3242                                         if (Caret.Visible == 1) {
3243                                                 ShowCaret ();
3244                                                 Caret.Paused = false;
3245                                         }
3246                                         msg.message = Msg.WM_PAINT;
3247                                         break;
3248                                 }
3249                                 
3250                         case XEventName.DestroyNotify: {
3251                                         
3252                                         // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
3253                                         hwnd = Hwnd.ObjectFromHandle (xevent.DestroyWindowEvent.window);
3254                                         
3255                                         // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
3256                                         if (hwnd.client_window == xevent.DestroyWindowEvent.window) {
3257                                                 msg.hwnd = hwnd.client_window;
3258                                                 msg.message = Msg.WM_DESTROY;
3259                                                 hwnd.Dispose ();
3260                                                 
3261                                                 #if DriverDebug
3262                                                         Console.WriteLine("Got DestroyNotify on Window {0:X}", msg.hwnd.ToInt32());
3263                                                 #endif
3264                                         } else {
3265                                                 goto ProcessNextMessage;
3266                                         }
3267                                         
3268                                         break;
3269                                 }
3270                                 
3271                         case XEventName.ClientMessage: {
3272                                         if (Dnd.HandleClientMessage (ref xevent)) {
3273                                                 goto ProcessNextMessage;
3274                                         }
3275                                         
3276                                         if (xevent.ClientMessageEvent.message_type == (IntPtr)AsyncAtom) {
3277                                                 XplatUIDriverSupport.ExecuteClientMessage ((GCHandle)xevent.ClientMessageEvent.ptr1);
3278                                                 break;
3279                                         }
3280                                         
3281                                         if (xevent.ClientMessageEvent.message_type == (IntPtr)HoverState.Atom) {
3282                                                 msg.message = Msg.WM_MOUSEHOVER;
3283                                                 msg.wParam = GetMousewParam (0);
3284                                                 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
3285                                                 break;
3286                                         }
3287                                         
3288                                         if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
3289                                                 msg.hwnd = xevent.ClientMessageEvent.ptr1;
3290                                                 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
3291                                                 msg.wParam = xevent.ClientMessageEvent.ptr3;
3292                                                 msg.lParam = xevent.ClientMessageEvent.ptr4;
3293                                                 break;
3294                                         }
3295                                         
3296                                         #if dontcare
3297                                         if  (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms[(int)NA._XEMBED]) {
3298                                                 Console.WriteLine("GOT EMBED MESSAGE {0:X}", xevent.ClientMessageEvent.ptr2.ToInt32());
3299                                                 break;
3300                                         }
3301                                         #endif
3302                                         
3303                                         if  (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms [(int)NA.WM_PROTOCOLS]) {
3304                                                 if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_DELETE_WINDOW]) {
3305                                                         msg.message = Msg.WM_CLOSE;
3306                                                         Graphics.FromHdcInternal (IntPtr.Zero);
3307                                                         break;
3308                                                 }
3309                                                 
3310                                                 // We should not get this, but I'll leave the code in case we need it in the future
3311                                                 if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_TAKE_FOCUS]) {
3312                                                         goto ProcessNextMessage;
3313                                                 }
3314                                         }
3315                                         break;
3316                                 }
3317                                 
3318                         case XEventName.TimerNotify: {
3319                                         xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
3320                                         break;
3321                                 }
3322                                 
3323                         default: {
3324                                         goto ProcessNextMessage;
3325                                 }
3326                         }
3327                         
3328                         return true;
3329                 }
3330                 
3331                 internal override bool GetText (IntPtr handle, out string text)
3332                 {
3333                         IntPtr  textptr;
3334                         
3335                         textptr = IntPtr.Zero;
3336                         
3337                         lock (XlibLock) {
3338                                 // FIXME - use _NET properties
3339                                 XFetchName (DisplayHandle, Hwnd.ObjectFromHandle (handle).whole_window, ref textptr);
3340                         }
3341                         if (textptr != IntPtr.Zero) {
3342                                 text = Marshal.PtrToStringAnsi (textptr);
3343                                 XFree (textptr);
3344                                 return true;
3345                         } else {
3346                                 text = "";
3347                                 return false;
3348                         }
3349                 }
3350                 
3351                 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)
3352                 {
3353                         Hwnd            hwnd;
3354                         Rectangle       rect;
3355                         
3356                         hwnd = Hwnd.ObjectFromHandle (handle);
3357                         
3358                         if (hwnd != null) {
3359                                 x = hwnd.x;
3360                                 y = hwnd.y;
3361                                 width = hwnd.width;
3362                                 height = hwnd.height;
3363                                 
3364                                 rect = Hwnd.GetClientRectangle (hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
3365                                 
3366                                 client_width = rect.Width;
3367                                 client_height = rect.Height;
3368                                 
3369                                 return;
3370                         }
3371                         
3372                         // Should we throw an exception or fail silently?
3373                         // throw new ArgumentException("Called with an invalid window handle", "handle");
3374                         
3375                         x = 0;
3376                         y = 0;
3377                         width = 0;
3378                         height = 0;
3379                         client_width = 0;
3380                         client_height = 0;
3381                 }
3382                 
3383                 internal override FormWindowState GetWindowState (IntPtr handle)
3384                 {
3385                         Atom                    actual_atom;
3386                         int                     actual_format;
3387                         int                     nitems;
3388                         int                     bytes_after;
3389                         IntPtr                  prop = IntPtr.Zero;
3390                         IntPtr                  atom;
3391                         int                     maximized;
3392                         bool                    minimized;
3393                         XWindowAttributes       attributes;
3394                         Hwnd                    hwnd;
3395                         
3396                         hwnd = Hwnd.ObjectFromHandle (handle);
3397                         
3398                         maximized = 0;
3399                         minimized = false;
3400                         XGetWindowProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._NET_WM_STATE], 0, 256, false, Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
3401                         if ((nitems > 0) && (prop != IntPtr.Zero)) {
3402                                 for (int i = 0; i < nitems; i++) {
3403                                         atom = (IntPtr)Marshal.ReadInt32 (prop, i * 4);
3404                                         if ((atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ]) || (atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT])) {
3405                                                 maximized++;
3406                                         } else if (atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_HIDDEN]) {
3407                                                 minimized = true;
3408                                         }
3409                                 }
3410                                 XFree (prop);
3411                         }
3412                         
3413                         if (minimized) {
3414                                 return FormWindowState.Minimized;
3415                         } else if (maximized == 2) {
3416                                 return FormWindowState.Maximized;
3417                         }
3418                         
3419                         attributes = new XWindowAttributes ();
3420                         XGetWindowAttributes (DisplayHandle, handle, ref attributes);
3421                         if (attributes.map_state == MapState.IsUnmapped) {
3422                                 throw new NotSupportedException ("Cannot retrieve the state of an unmapped window");
3423                         }
3424                         
3425                         
3426                         return FormWindowState.Normal;
3427                 }
3428                 
3429                 internal override void GrabInfo (out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
3430                 {
3431                         handle = Grab.Hwnd;
3432                         GrabConfined = Grab.Confined;
3433                         GrabArea = Grab.Area;
3434                 }
3435                 
3436                 internal override void GrabWindow (IntPtr handle, IntPtr confine_to_handle)
3437                 {
3438                         Hwnd    hwnd;
3439                         IntPtr  confine_to_window;
3440                         
3441                         confine_to_window = IntPtr.Zero;
3442                         
3443                         if (confine_to_handle != IntPtr.Zero) {
3444                                 XWindowAttributes       attributes = new XWindowAttributes ();
3445                                 
3446                                 hwnd = Hwnd.ObjectFromHandle (confine_to_handle);
3447                                 
3448                                 lock (XlibLock) {
3449                                         XGetWindowAttributes (DisplayHandle, hwnd.client_window, ref attributes);
3450                                 }
3451                                 Grab.Area.X = attributes.x;
3452                                 Grab.Area.Y = attributes.y;
3453                                 Grab.Area.Width = attributes.width;
3454                                 Grab.Area.Height = attributes.height;
3455                                 Grab.Confined = true;
3456                                 confine_to_window = hwnd.client_window;
3457                         }
3458                         
3459                         Grab.Hwnd = handle;
3460                         
3461                         hwnd = Hwnd.ObjectFromHandle (handle);
3462                         
3463                         lock (XlibLock) {
3464                                 XGrabPointer (DisplayHandle, hwnd.client_window, false, 
3465                                               EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
3466                                               EventMask.ButtonReleaseMask | EventMask.PointerMotionMask,
3467                                               GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, 0, 0);
3468                         }
3469                 }
3470                 
3471                 internal override void UngrabWindow (IntPtr hwnd)
3472                 {
3473                         lock (XlibLock) {
3474                                 XUngrabPointer (DisplayHandle, 0);
3475                                 XFlush (DisplayHandle);
3476                         }
3477                         Grab.Hwnd = IntPtr.Zero;
3478                         Grab.Confined = false;
3479                 }
3480                 
3481                 internal override void HandleException (Exception e)
3482                 {
3483                         StackTrace st = new StackTrace (e, true);
3484                         Console.WriteLine ("Exception '{0}'", e.Message + st.ToString ());
3485                         Console.WriteLine ("{0}{1}", e.Message, st.ToString ());
3486                 }
3487                 
3488                 internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear)
3489                 {
3490                         Hwnd    hwnd;
3491                         XEvent  xevent;
3492                         
3493                         hwnd = Hwnd.ObjectFromHandle (handle);
3494                         
3495                         
3496                         xevent = new XEvent ();
3497                         xevent.type = XEventName.Expose;
3498                         xevent.ExposeEvent.display = DisplayHandle;
3499                         xevent.ExposeEvent.window = hwnd.client_window;
3500                         
3501                         if (clear) {
3502                                 xevent.ExposeEvent.x = hwnd.X;
3503                                 xevent.ExposeEvent.y = hwnd.Y;
3504                                 xevent.ExposeEvent.width = hwnd.Width;
3505                                 xevent.ExposeEvent.height = hwnd.Height;
3506                         } else {
3507                                 xevent.ExposeEvent.x = rc.X;
3508                                 xevent.ExposeEvent.y = rc.Y;
3509                                 xevent.ExposeEvent.width = rc.Width;
3510                                 xevent.ExposeEvent.height = rc.Height;
3511                         }
3512                         
3513                         AddExpose (xevent);
3514                 }
3515                 
3516                 internal override bool IsEnabled (IntPtr handle)
3517                 {
3518                         return Hwnd.ObjectFromHandle (handle).Enabled;
3519                 }
3520                 
3521                 internal override bool IsVisible (IntPtr handle)
3522                 {
3523                         return Hwnd.ObjectFromHandle (handle).visible;
3524                 }
3525                 
3526                 internal override void KillTimer (Timer timer)
3527                 {
3528                         lock (TimerList) {
3529                                 TimerList.Remove (timer);
3530                         }
3531                 }
3532                 
3533                 internal override void MenuToScreen (IntPtr handle, ref int x, ref int y)
3534                 {
3535                         int     dest_x_return;
3536                         int     dest_y_return;
3537                         IntPtr  child;
3538                         Hwnd    hwnd;
3539                         
3540                         hwnd = Hwnd.ObjectFromHandle (handle);
3541                         
3542                         lock (XlibLock) {
3543                                 XTranslateCoordinates (DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
3544                         }
3545                         
3546                         x = dest_x_return;
3547                         y = dest_y_return;
3548                 }
3549                 
3550                 internal override void OverrideCursor (IntPtr cursor)
3551                 {
3552                         OverrideCursorHandle = cursor;
3553                 }
3554                 
3555                 internal override PaintEventArgs PaintEventStart (IntPtr handle, bool client)
3556                 {
3557                         PaintEventArgs  paint_event;
3558                         Hwnd            hwnd;
3559                         
3560                         hwnd = Hwnd.ObjectFromHandle (handle);
3561                         
3562                         if (Caret.Visible == 1) {
3563                                 Caret.Paused = true;
3564                                 HideCaret ();
3565                         }
3566                         
3567                         if (client) {
3568                                 // handle backing store
3569                                 IntPtr gdk_window = gdk_window_lookup (hwnd.client_window);
3570                                 IntPtr gdk_pixmap = NewPixmap (gdk_window, hwnd.ClientRect.Width, hwnd.ClientRect.Height);
3571                                 
3572                                 backing_store [gdk_window] = gdk_pixmap;
3573                                 
3574                                 hwnd.client_dc = Graphics.FromHwnd (gdk_x11_drawable_get_xid (gdk_pixmap));
3575                                 hwnd.client_dc.SetClip (hwnd.invalid);
3576                                 paint_event = new PaintEventArgs (hwnd.client_dc, hwnd.invalid);
3577                                 hwnd.expose_pending = false;
3578                                 
3579                                 return paint_event;
3580                         } else {
3581                                 hwnd.client_dc = Graphics.FromHwnd (hwnd.whole_window);
3582                                 paint_event = new PaintEventArgs (hwnd.client_dc, new Rectangle (0, 0, hwnd.width, hwnd.height));
3583                                 hwnd.nc_expose_pending = false;
3584                                 
3585                                 return paint_event;
3586                         }
3587                 }
3588                 
3589                 internal override void PaintEventEnd (IntPtr handle, bool client)
3590                 {
3591                         Hwnd    hwnd;
3592                         
3593                         hwnd = Hwnd.ObjectFromHandle (handle);
3594                         
3595                         hwnd.client_dc.Flush ();
3596                         
3597                         if (client) {
3598                                 // clients are already drawn to a backing store pixmap
3599                                 IntPtr gdk_window = gdk_window_lookup (hwnd.client_window);
3600                                 IntPtr gdk_pixmap = (IntPtr)backing_store [gdk_window];
3601                                 
3602                                 BlitOffscreenPixmap (gdk_pixmap, gdk_window, hwnd.Invalid);
3603                                 
3604                                 g_object_unref (gdk_pixmap);
3605                                 backing_store.Remove (gdk_pixmap);
3606                                 
3607                                 hwnd.ClearInvalidArea ();
3608                         }
3609                         
3610                         hwnd.client_dc.Dispose ();
3611                         hwnd.client_dc = null;
3612                         
3613                         if (Caret.Visible == 1) {
3614                                 ShowCaret ();
3615                                 Caret.Paused = false;
3616                         }
3617                 }
3618                 
3619                 internal override bool PeekMessage (ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
3620                 {
3621                         bool    pending;
3622                         
3623                         // FIXME - imlement filtering
3624                         
3625                         if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
3626                                 throw new NotImplementedException ("PeekMessage PM_NOREMOVE is not implemented yet");   // FIXME - Implement PM_NOREMOVE flag
3627                         }
3628                         
3629                         pending = false;
3630                         if (MessageQueue.Count > 0) {
3631                                 pending = true;
3632                         } else {
3633                                 // Only call UpdateMessageQueue if real events are pending 
3634                                 // otherwise we go to sleep on the socket
3635                                 if (XPending (DisplayHandle) != 0) {
3636                                         UpdateMessageQueue ();
3637                                         pending = true;
3638                                 }
3639                         }
3640                         
3641                         CheckTimers (DateTime.Now);
3642                         
3643                         if (!pending) {
3644                                 return false;
3645                         }
3646                         return GetMessage (ref msg, hWnd, wFilterMin, wFilterMax);
3647                 }
3648                 
3649                 // FIXME - I think this should just enqueue directly
3650                 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
3651                 {
3652                         XEvent xevent = new XEvent ();
3653                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
3654                         
3655                         xevent.type = XEventName.ClientMessage;
3656                         xevent.ClientMessageEvent.display = DisplayHandle;
3657                         
3658                         if (hwnd != null) {
3659                                 xevent.ClientMessageEvent.window = hwnd.whole_window;
3660                         } else {
3661                                 xevent.ClientMessageEvent.window = IntPtr.Zero;
3662                         }
3663                         
3664                         xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
3665                         xevent.ClientMessageEvent.format = 32;
3666                         xevent.ClientMessageEvent.ptr1 = handle;
3667                         xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
3668                         xevent.ClientMessageEvent.ptr3 = wparam;
3669                         xevent.ClientMessageEvent.ptr4 = lparam;
3670                         
3671                         MessageQueue.Enqueue (xevent);
3672                         
3673                         return true;
3674                 }
3675                 
3676                 internal override void PostQuitMessage (int exitCode)
3677                 {
3678                         XFlush (DisplayHandle);
3679                         PostQuitState = true;
3680                         
3681                         // Remove our display handle from S.D
3682                         Graphics.FromHdcInternal (IntPtr.Zero);
3683                 }
3684                 
3685                 internal override void ScreenToClient (IntPtr handle, ref int x, ref int y)
3686                 {
3687                         int     dest_x_return;
3688                         int     dest_y_return;
3689                         IntPtr  child;
3690                         Hwnd    hwnd;
3691                         
3692                         hwnd = Hwnd.ObjectFromHandle (handle);
3693                         
3694                         lock (XlibLock) {
3695                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
3696                         }
3697                         
3698                         x = dest_x_return;
3699                         y = dest_y_return;
3700                 }
3701                 
3702                 internal override void ScreenToMenu (IntPtr handle, ref int x, ref int y)
3703                 {
3704                         int     dest_x_return;
3705                         int     dest_y_return;
3706                         IntPtr  child;
3707                         Hwnd    hwnd;
3708                         
3709                         hwnd = Hwnd.ObjectFromHandle (handle);
3710                         
3711                         lock (XlibLock) {
3712                                 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
3713                         }
3714                         
3715                         x = dest_x_return;
3716                         y = dest_y_return;
3717                 }
3718                 
3719                 internal override void ScrollWindow (IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
3720                 {
3721                         Hwnd            hwnd;
3722                         IntPtr          gc;
3723                         XGCValues       gc_values;
3724                         
3725                         hwnd = Hwnd.ObjectFromHandle (handle);
3726                         
3727                         if (hwnd.invalid != Rectangle.Empty) {
3728                                 // BIG FAT WARNING. This only works with how we use this function right now
3729                                 // where we basically still scroll the whole window, but work around areas
3730                                 // that are covered by our children
3731                                 
3732                                 hwnd.invalid.X += XAmount;
3733                                 hwnd.invalid.Y += YAmount;
3734                                 
3735                                 if (hwnd.invalid.X < 0) {
3736                                         hwnd.invalid.Width += hwnd.invalid.X;
3737                                         hwnd.invalid.X = 0;
3738                                 }
3739                                 
3740                                 if (hwnd.invalid.Y < 0) {
3741                                         hwnd.invalid.Height += hwnd.invalid.Y;
3742                                         hwnd.invalid.Y = 0;
3743                                 }
3744                         }
3745                         
3746                         gc_values = new XGCValues ();
3747                         
3748                         if (with_children) {
3749                                 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3750                         }
3751                         
3752                         gc = XCreateGC (DisplayHandle, hwnd.client_window, 0, ref gc_values);
3753                         
3754                         XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, area.X - XAmount, area.Y - YAmount, area.Width, area.Height, area.X, area.Y);
3755                         
3756                         // Generate an expose for the area exposed by the horizontal scroll
3757                         if (XAmount > 0) {
3758                                 hwnd.AddInvalidArea (area.X, area.Y, XAmount, area.Height);
3759                         } else if (XAmount < 0) {
3760                                 hwnd.AddInvalidArea (XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
3761                         }
3762                         
3763                         // Generate an expose for the area exposed by the vertical scroll
3764                         if (YAmount > 0) {
3765                                 hwnd.AddInvalidArea (area.X, area.Y, area.Width, YAmount);
3766                         } else if (YAmount < 0) {
3767                                 hwnd.AddInvalidArea (area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
3768                         }
3769                         XFreeGC (DisplayHandle, gc);
3770                         
3771                         UpdateWindow (handle);
3772                 }
3773                 
3774                 internal override void ScrollWindow (IntPtr handle, int XAmount, int YAmount, bool with_children)
3775                 {
3776                         Hwnd    hwnd;
3777                         
3778                         hwnd = Hwnd.GetObjectFromWindow (handle);
3779                         
3780                         ScrollWindow (handle, hwnd.ClientRect, XAmount, YAmount, with_children);
3781                 }
3782                 
3783                 internal override void SendAsyncMethod (AsyncMethodData method)
3784                 {
3785                         XEvent xevent = new XEvent ();
3786                         
3787                         xevent.type = XEventName.ClientMessage;
3788                         xevent.ClientMessageEvent.display = DisplayHandle;
3789                         xevent.ClientMessageEvent.window = FosterParent;
3790                         xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
3791                         xevent.ClientMessageEvent.format = 32;
3792                         xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
3793                         
3794                         MessageQueue.EnqueueLocked (xevent);
3795                         
3796                         WakeupMain ();
3797                 }
3798                 
3799                 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
3800                 {
3801                         return NativeWindow.WndProc (hwnd, message, wParam, lParam);
3802                 }
3803                 
3804                 internal override void SetAllowDrop (IntPtr handle, bool value)
3805                 {
3806                         // We allow drop on all windows
3807                 }
3808                 
3809                 internal override DragDropEffects StartDrag (IntPtr handle, object data,
3810                                                              DragDropEffects allowed_effects)
3811                 {
3812                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
3813                         
3814                         if (hwnd == null)
3815                                 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
3816                         
3817                         return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
3818                 }
3819                 
3820                 internal override void SetBorderStyle (IntPtr handle, FormBorderStyle border_style)
3821                 {
3822                         Hwnd    hwnd;
3823                         
3824                         hwnd = Hwnd.ObjectFromHandle (handle);
3825                         
3826                         hwnd.border_style = border_style;
3827                         
3828                         XMoveResizeWindow (DisplayHandle, hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y, hwnd.ClientRect.Width, hwnd.ClientRect.Height);
3829                         
3830                         InvalidateWholeWindow (handle);
3831                 }
3832                 
3833                 internal override void SetCaretPos (IntPtr handle, int x, int y)
3834                 {
3835                         if (Caret.Hwnd == handle) {
3836                                 Caret.Timer.Stop ();
3837                                 HideCaret ();
3838                                 
3839                                 Caret.X = x;
3840                                 Caret.Y = y;
3841                                 
3842                                 if (Caret.Visible == 1) {
3843                                         ShowCaret ();
3844                                         Caret.Timer.Start ();
3845                                 }
3846                         }
3847                 }
3848                 
3849                 internal override void SetCursor (IntPtr handle, IntPtr cursor)
3850                 {
3851                         Hwnd    hwnd;
3852                         
3853                         if (OverrideCursorHandle == IntPtr.Zero) {
3854                                 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
3855                                         return;
3856                                 }
3857                                 
3858                                 LastCursorHandle = cursor;
3859                                 LastCursorWindow = handle;
3860                                 
3861                                 hwnd = Hwnd.ObjectFromHandle (handle);
3862                                 lock (XlibLock) {
3863                                         if (cursor != IntPtr.Zero) {
3864                                                 XDefineCursor (DisplayHandle, hwnd.whole_window, cursor);
3865                                         } else {
3866                                                 XUndefineCursor (DisplayHandle, hwnd.whole_window);
3867                                         }
3868                                 }
3869                                 return;
3870                         }
3871                         
3872                         hwnd = Hwnd.ObjectFromHandle (handle);
3873                         lock (XlibLock) {
3874                                 XDefineCursor (DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
3875                         }
3876                 }
3877                 
3878                 internal override void SetCursorPos (IntPtr handle, int x, int y)
3879                 {
3880                         if (handle == IntPtr.Zero) {
3881                                 lock (XlibLock) {
3882                                         XWarpPointer (DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x, y);
3883                                 }
3884                                 return;
3885                         } else {
3886                                 Hwnd    hwnd;
3887                                 
3888                                 hwnd = Hwnd.ObjectFromHandle (handle);
3889                                 lock (XlibLock) {
3890                                         XWarpPointer (DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
3891                                 }
3892                                 return;
3893                         }
3894                 }
3895                 
3896                 internal override void SetFocus (IntPtr handle)
3897                 {
3898                         Hwnd    hwnd;
3899                         
3900                         hwnd = Hwnd.ObjectFromHandle (handle);
3901                         
3902                         if (FocusWindow != IntPtr.Zero) {
3903                                 PostMessage (FocusWindow, Msg.WM_KILLFOCUS, hwnd.client_window, IntPtr.Zero);
3904                         }
3905                         PostMessage (hwnd.client_window, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
3906                         FocusWindow = hwnd.client_window;
3907                         
3908                         //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
3909                 }
3910                 
3911                 internal override void SetIcon (IntPtr handle, Icon icon)
3912                 {
3913                         Hwnd    hwnd;
3914                         
3915                         hwnd = Hwnd.ObjectFromHandle (handle);
3916                         if (hwnd != null) {
3917                                 SetIcon (hwnd, icon);
3918                         }
3919                 }
3920                 
3921                 internal override void SetMenu (IntPtr handle, Menu menu)
3922                 {
3923                         Hwnd    hwnd;
3924                         
3925                         hwnd = Hwnd.ObjectFromHandle (handle);
3926                         hwnd.menu = menu;
3927                         
3928                         // FIXME - do we need to trigger some resize?
3929                 }
3930                 
3931                 internal override void SetModal (IntPtr handle, bool Modal)
3932                 {
3933                         if (Modal) {
3934                                 ModalWindows.Push (handle);
3935                         } else {
3936                                 if (ModalWindows.Contains (handle)) {
3937                                         ModalWindows.Pop ();
3938                                 }
3939                                 if (ModalWindows.Count > 0) {
3940                                         Activate ((IntPtr)ModalWindows.Peek ());
3941                                 }
3942                         }
3943                 }
3944                 
3945                 internal override IntPtr SetParent (IntPtr handle, IntPtr parent)
3946                 {
3947                         Hwnd    hwnd;
3948                         
3949                         hwnd = Hwnd.ObjectFromHandle (handle);
3950                         hwnd.parent = Hwnd.ObjectFromHandle (parent);
3951                         
3952                         lock (XlibLock) {
3953                                 #if DriverDebug
3954                                         Console.WriteLine("Parent for window {0:X} / {1:X} = {2:X} (Handle:{3:X})", hwnd.ClientWindow.ToInt32(), hwnd.WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, parent.ToInt32());
3955                                 #endif
3956                                 XReparentWindow (DisplayHandle, hwnd.whole_window, hwnd.parent.client_window, hwnd.x, hwnd.y);
3957                         }
3958                         
3959                         return IntPtr.Zero;
3960                 }
3961                 
3962                 internal override void SetTimer (Timer timer)
3963                 {
3964                         lock (TimerList) {
3965                                 TimerList.Add (timer);
3966                         }
3967                         WakeupMain ();
3968                 }
3969                 
3970                 internal override bool SetTopmost (IntPtr handle, IntPtr handle_owner, bool enabled)
3971                 {
3972                         Hwnd    hwnd;
3973                         Hwnd    hwnd_owner;
3974                         
3975                         hwnd = Hwnd.ObjectFromHandle (handle);
3976                         
3977                         if (handle_owner != IntPtr.Zero) {
3978                                 hwnd_owner = Hwnd.ObjectFromHandle (handle_owner);
3979                         } else {
3980                                 hwnd_owner = null;
3981                         }
3982                         
3983                         if (enabled) {
3984                                 lock (XlibLock) {
3985                                         if (hwnd_owner != null) {
3986                                                 XSetTransientForHint (DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
3987                                         } else {
3988                                                 XSetTransientForHint (DisplayHandle, hwnd.whole_window, FosterParent);
3989                                         }
3990                                 }
3991                         } else {
3992                                 lock (XlibLock) {
3993                                         XDeleteProperty (DisplayHandle, hwnd.whole_window, (int)Atom.XA_WM_TRANSIENT_FOR);
3994                                 }
3995                         }
3996                         return true;
3997                 }
3998                 
3999                 internal override bool SetVisible (IntPtr handle, bool visible)
4000                 {
4001                         Hwnd    hwnd;
4002                         
4003                         hwnd = Hwnd.ObjectFromHandle (handle);
4004                         hwnd.visible = visible;
4005                         
4006                         lock (XlibLock) {
4007                                 if (visible) {
4008                                         if (Control.FromHandle (handle) is Form) {
4009                                                 FormWindowState s;
4010                                                 
4011                                                 s = ((Form)Control.FromHandle (handle)).WindowState;
4012                                                 
4013                                                 XMapWindow (DisplayHandle, hwnd.whole_window);
4014                                                 XMapWindow (DisplayHandle, hwnd.client_window);
4015                                                 
4016                                                 switch (s) {
4017                                                 case FormWindowState.Minimized: SetWindowState (handle, FormWindowState.Minimized); break;
4018                                                 case FormWindowState.Maximized: SetWindowState (handle, FormWindowState.Maximized); break;
4019                                                 }
4020                                         } else {
4021                                                 XMapWindow (DisplayHandle, hwnd.whole_window);
4022                                                 XMapWindow (DisplayHandle, hwnd.client_window);
4023                                         }
4024                                 } else {
4025                                         XUnmapWindow (DisplayHandle, hwnd.whole_window);
4026                                 }
4027                         }
4028                         return true;
4029                 }
4030                 
4031                 internal override void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max)
4032                 {
4033                         Hwnd            hwnd;
4034                         XSizeHints      hints;
4035                         
4036                         hwnd = Hwnd.ObjectFromHandle (handle);
4037                         if (hwnd == null) {
4038                                 return;
4039                         }
4040                         
4041                         hints = new XSizeHints ();
4042                         
4043                         if (min != Size.Empty) {
4044                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
4045                                 hints.min_width = min.Width;
4046                                 hints.min_height = min.Height;
4047                         }
4048                         
4049                         if (max != Size.Empty) {
4050                                 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
4051                                 hints.max_width = max.Width;
4052                                 hints.max_height = max.Height;
4053                         }
4054                         
4055                         XSetWMNormalHints (DisplayHandle, hwnd.whole_window, ref hints);
4056                         
4057                         if (maximized != Rectangle.Empty) {
4058                                 hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
4059                                 hints.x = maximized.X;
4060                                 hints.y = maximized.Y;
4061                                 hints.width = maximized.Width;
4062                                 hints.height = maximized.Height;
4063                                 
4064                                 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
4065                                 XSetZoomHints (DisplayHandle, hwnd.whole_window, ref hints);
4066                         }
4067                 }
4068                 
4069                 
4070                 internal override void SetWindowPos (IntPtr handle, int x, int y, int width, int height)
4071                 {
4072                         Hwnd            hwnd;
4073                         Rectangle       client_rect;
4074                         
4075                         hwnd = Hwnd.ObjectFromHandle (handle);
4076                         
4077                         // X requires a sanity check for width & height; otherwise it dies
4078                         if (hwnd.zero_sized && width > 0 && height > 0) {
4079                                 if (hwnd.visible) {
4080                                         XMapWindow (DisplayHandle, hwnd.whole_window);
4081                                 }
4082                                 hwnd.zero_sized = false;
4083                         }
4084                         
4085                         if (width < 1) {
4086                                 hwnd.zero_sized = true;
4087                                 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4088                         }
4089                         
4090                         if (height < 1) {
4091                                 hwnd.zero_sized = true;
4092                                 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4093                         }
4094                         
4095                         client_rect = Hwnd.GetClientRectangle (hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
4096                         
4097                         // Save a server roundtrip (and prevent a feedback loop)
4098                         if ((hwnd.x == x) && (hwnd.y == y) && 
4099                             (hwnd.width == width) && (hwnd.height == height) &&
4100                             (hwnd.ClientRect == client_rect)) {
4101                                 return;
4102                         }
4103                         
4104                         if (!hwnd.zero_sized) {
4105                                 lock (XlibLock) {
4106                                         XMoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, width, height);
4107                                         XMoveResizeWindow (DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
4108                                 }
4109                         }
4110                         
4111                         // Prevent an old queued ConfigureNotify from setting our width with outdated data, set it now
4112                         hwnd.width = width;
4113                         hwnd.height = height;
4114                 }
4115                 
4116                 internal override void SetWindowState (IntPtr handle, FormWindowState state)
4117                 {
4118                         FormWindowState current_state;
4119                         Hwnd            hwnd;
4120                         
4121                         hwnd = Hwnd.ObjectFromHandle (handle);
4122                         
4123                         current_state = GetWindowState (handle);
4124                         
4125                         if (current_state == state) {
4126                                 return;
4127                         }
4128                         
4129                         switch (state) {
4130                         case FormWindowState.Normal: {
4131                                         lock (XlibLock) {
4132                                                 if (current_state == FormWindowState.Minimized) {
4133                                                         XMapWindow (DisplayHandle, hwnd.whole_window);
4134                                                         XMapWindow (DisplayHandle, hwnd.client_window);
4135                                                 } else if (current_state == FormWindowState.Maximized) {
4136                                                         SendNetWMMessage (hwnd.whole_window, (IntPtr)(uint)NetAtoms [(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
4137                                                 }
4138                                         }
4139                                         Activate (handle);
4140                                         return;
4141                                 }
4142                                 
4143                         case FormWindowState.Minimized: {
4144                                         lock (XlibLock) {
4145                                                 if (current_state == FormWindowState.Maximized) {
4146                                                         SendNetWMMessage (hwnd.whole_window, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
4147                                                 }
4148                                                 XIconifyWindow (DisplayHandle, hwnd.whole_window, ScreenNo);
4149                                         }
4150                                         return;
4151                                 }
4152                                 
4153                         case FormWindowState.Maximized: {
4154                                         lock (XlibLock) {
4155                                                 if (current_state == FormWindowState.Minimized) {
4156                                                         XMapWindow (DisplayHandle, hwnd.whole_window);
4157                                                         XMapWindow (DisplayHandle, hwnd.client_window);
4158                                                 }
4159                                                 
4160                                                 SendNetWMMessage (hwnd.whole_window, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE], (IntPtr)1 /* Add */, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
4161                                         }
4162                                         Activate (handle);
4163                                         return;
4164                                 }
4165                         }
4166                 }
4167                 
4168                 internal override void SetWindowStyle (IntPtr handle, CreateParams cp)
4169                 {
4170                         Hwnd    hwnd;
4171                         
4172                         hwnd = Hwnd.ObjectFromHandle (handle);
4173                         SetHwndStyles (hwnd, cp);
4174                         SetWMStyles (hwnd, cp);
4175                 }
4176                 
4177                 internal override void SetWindowTransparency (IntPtr handle, double transparency, Color key)
4178                 {
4179                         Hwnd    hwnd;
4180                         uint    opacity;
4181                         
4182                         hwnd = Hwnd.ObjectFromHandle (handle);
4183                         
4184                         if (hwnd == null) {
4185                                 return;
4186                         }
4187                         
4188                         hwnd.opacity = (uint)(0xffffffff * transparency);
4189                         opacity = hwnd.opacity;
4190                         
4191                         if (hwnd.reparented) {
4192                                 XChangeProperty (DisplayHandle, XGetParent (hwnd.whole_window), NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY], Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
4193                         }
4194                 }
4195                 
4196                 internal override bool SetZOrder (IntPtr handle, IntPtr after_handle, bool top, bool bottom)
4197                 {
4198                         Hwnd    hwnd = Hwnd.ObjectFromHandle (handle);
4199                         
4200                         if (top) {
4201                                 lock (XlibLock) {
4202                                         XRaiseWindow (DisplayHandle, hwnd.whole_window);
4203                                 }
4204                                 return true;
4205                         } else if (!bottom) {
4206                                 Hwnd    after_hwnd = null;
4207                                 
4208                                 if (after_handle != IntPtr.Zero) {
4209                                         after_hwnd = Hwnd.ObjectFromHandle (after_handle);
4210                                 }
4211                                 
4212                                 XWindowChanges  values = new XWindowChanges ();
4213                                 
4214                                 if (after_hwnd == null) {
4215                                         throw new ArgumentNullException ("after_handle", "Need sibling to adjust z-order");
4216                                 }
4217                                 values.sibling = after_hwnd.whole_window;
4218                                 values.stack_mode = StackMode.Below;
4219                                 
4220                                 lock (XlibLock) {
4221                                         XConfigureWindow (DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
4222                                 }
4223                         } else {
4224                                 // Bottom
4225                                 lock (XlibLock) {
4226                                         XLowerWindow (DisplayHandle, hwnd.whole_window);
4227                                 }
4228                                 return true;
4229                         }
4230                         return false;
4231                 }
4232                 
4233                 internal override void ShowCursor (bool show)
4234                 {
4235                         ;       // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
4236                 }
4237                 
4238                 internal override void StartLoop (Thread thread)
4239                 {
4240                         // Future place for prepping a new queue for this specific thread
4241                 }
4242                 
4243                 internal override bool SupportsTransparency ()
4244                 {
4245                         // We need to check if the x compositing manager is running
4246                         return true;
4247                 }
4248                 
4249                 internal override bool SystrayAdd (IntPtr handle, string tip, Icon icon, out ToolTip tt)
4250                 {
4251                         GetSystrayManagerWindow ();
4252                         
4253                         if (SystrayMgrWindow != IntPtr.Zero) {
4254                                 uint[]          atoms;
4255                                 XSizeHints      size_hints;
4256                                 Hwnd            hwnd;
4257                                 
4258                                 hwnd = Hwnd.ObjectFromHandle (handle);
4259                                 #if DriverDebug
4260                                         Console.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
4261                                 #endif
4262                                 
4263                                 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4264                                 XUnmapWindow (DisplayHandle, hwnd.client_window);
4265                                 
4266                                 // Oh boy.
4267                                 gdk_window_destroy (gdk_window_lookup (hwnd.client_window));
4268                                 hwnd.client_window = hwnd.whole_window;
4269                                 
4270                                 size_hints = new XSizeHints ();
4271                                 
4272                                 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
4273                                 size_hints.min_width = icon.Width;
4274                                 size_hints.min_height = icon.Height;
4275                                 
4276                                 size_hints.max_width = icon.Width;
4277                                 size_hints.max_height = icon.Height;
4278                                 
4279                                 size_hints.base_width = icon.Width;
4280                                 size_hints.base_height = icon.Height;
4281                                 XSetWMNormalHints (DisplayHandle, hwnd.whole_window, ref size_hints);
4282                                 
4283                                 atoms = new uint [2];
4284                                 atoms [0] = 1;  // Version 1
4285                                 atoms [1] = 0;  // We're not mapped
4286                                 
4287                                 // This line cost me 3 days...
4288                                 XChangeProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._XEMBED_INFO], NetAtoms [(int)NA._XEMBED_INFO], 32, PropertyMode.Replace, atoms, 2);
4289                                 
4290                                 // Need to pick some reasonable defaults
4291                                 tt = new ToolTip ();
4292                                 tt.AutomaticDelay = 100;
4293                                 tt.InitialDelay = 250;
4294                                 tt.ReshowDelay = 250;
4295                                 tt.ShowAlways = true;
4296                                 
4297                                 if ((tip != null) && (tip != string.Empty)) {
4298                                         tt.SetToolTip (Control.FromHandle (handle), tip);
4299                                         tt.Active = true;
4300                                 } else {
4301                                         tt.Active = false;
4302                                 }
4303                                 
4304                                 // Make sure the window exists
4305                                 XSync (DisplayHandle, hwnd.whole_window);
4306                                 
4307                                 SendNetClientMessage (SystrayMgrWindow, (IntPtr)NetAtoms [(int)NA._NET_SYSTEM_TRAY_OPCODE], IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
4308                                 return true;
4309                         }
4310                         
4311                         tt = null;
4312                         return false;
4313                 }
4314                 
4315                 internal override bool SystrayChange (IntPtr handle, string tip, Icon icon, ref ToolTip tt)
4316                 {
4317                         Control control;
4318                         
4319                         control = Control.FromHandle (handle);
4320                         if (control != null && tt != null) {
4321                                 tt.SetToolTip (control, tip);
4322                                 tt.Active = true;
4323                                 return true;
4324                         } else {
4325                                 return false;
4326                         }
4327                 }
4328                 
4329                 internal override void SystrayRemove (IntPtr handle, ref ToolTip tt)
4330                 {
4331                         Hwnd    hwnd;
4332                         
4333                         hwnd = Hwnd.ObjectFromHandle (handle);
4334                         
4335                         XUnmapWindow (DisplayHandle, hwnd.whole_window);
4336                         SetParent (hwnd.whole_window, FosterParent);
4337                         
4338                         // The caller can now re-dock it later...
4339                         if (tt != null) {
4340                                 tt.Dispose ();
4341                                 tt = null;
4342                         }
4343                 }
4344                 
4345                 internal override bool Text (IntPtr handle, string text)
4346                 {
4347                         lock (XlibLock) {
4348                                 gdk_window_set_title (gdk_window_lookup (Hwnd.ObjectFromHandle (handle).whole_window), text);
4349                         }
4350                         return true;
4351                 }
4352                 
4353                 internal override bool TranslateMessage (ref MSG msg)
4354                 {
4355                         return Keyboard.TranslateMessage (ref msg);
4356                 }
4357                 
4358                 internal override void UpdateWindow (IntPtr handle)
4359                 {
4360                         XEvent  xevent;
4361                         Hwnd    hwnd;
4362                         
4363                         hwnd = Hwnd.ObjectFromHandle (handle);
4364                         
4365                         if (!hwnd.visible || hwnd.expose_pending) {
4366                                 return;
4367                         }
4368                         
4369                         #if not
4370                         SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
4371                         #else
4372                         xevent = new XEvent ();
4373                         xevent.type = XEventName.Expose;
4374                         xevent.ExposeEvent.display = DisplayHandle;
4375                         xevent.ExposeEvent.window = hwnd.client_window;
4376                         
4377                         MessageQueue.Enqueue (xevent);
4378                         hwnd.expose_pending = true;
4379                         #endif
4380                 }
4381                 
4382                 internal static IntPtr NewPixmap (IntPtr gdk_window, int width, int height)
4383                 {
4384                         return gdk_pixmap_new (gdk_window, width, height, 24); // FIXME: instead of 24, get the correct display depth
4385                 }
4386                 
4387                 internal static void BlitOffscreenPixmap (IntPtr gdk_pixmap, IntPtr dest_drawable, Rectangle area)
4388                 {
4389                         IntPtr gdk_gc = gdk_gc_new (gdk_pixmap);
4390                         
4391                         gdk_draw_drawable (dest_drawable, gdk_gc, gdk_pixmap, area.X, area.Y, area.X, area.Y, area.Width, area.Height);
4392                         
4393                         g_object_unref (gdk_gc);
4394                 }
4395                 #endregion      // Public Static Methods
4396                 
4397                 #region Events
4398                 internal override event EventHandler Idle;
4399                 #endregion      // Events
4400                 
4401                 #region X11 Imports
4402                 [DllImport ("libX11", EntryPoint="XSynchronize")]
4403                 internal extern static IntPtr XSynchronize (IntPtr display, bool onoff);
4404                 
4405                 [DllImport ("libX11", EntryPoint="XCreateWindow")]
4406                 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, SetWindowValuemask valuemask, ref XSetWindowAttributes attributes);
4407                 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
4408                 internal extern static IntPtr XCreateSimpleWindow (IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int border, int background);
4409                 [DllImport ("libX11", EntryPoint="XMapWindow")]
4410                 internal extern static int XMapWindow (IntPtr display, IntPtr window);
4411                 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
4412                 internal extern static int XUnmapWindow (IntPtr display, IntPtr window);
4413                 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
4414                 internal extern static int XMapSubindows (IntPtr display, IntPtr window);
4415                 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
4416                 internal extern static int XUnmapSubwindows (IntPtr display, IntPtr window);
4417                 [DllImport ("libX11", EntryPoint="XRootWindow")]
4418                 internal extern static IntPtr XRootWindow (IntPtr display, int screen_number);
4419                 [DllImport ("libX11", EntryPoint="XNextEvent")]
4420                 internal extern static IntPtr XNextEvent (IntPtr display, ref XEvent xevent);
4421                 [DllImport ("libX11")]
4422                 internal extern static int XConnectionNumber (IntPtr diplay);
4423                 [DllImport ("libX11")]
4424                 internal extern static int XPending (IntPtr diplay);
4425                 [DllImport ("libX11")]
4426                 internal extern static bool XCheckWindowEvent (IntPtr display, IntPtr window, EventMask mask, ref XEvent xevent);
4427                 [DllImport ("libX11")]
4428                 internal extern static bool XCheckMaskEvent (IntPtr display, EventMask mask, ref XEvent xevent);
4429                 [DllImport ("libX11", EntryPoint="XSelectInput")]
4430                 internal extern static IntPtr XSelectInput (IntPtr display, IntPtr window, EventMask mask);
4431                 
4432                 [DllImport ("libX11", EntryPoint="XReparentWindow")]
4433                 internal extern static int XReparentWindow (IntPtr display, IntPtr window, IntPtr parent, int x, int y);
4434                 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
4435                 internal extern static int XMoveResizeWindow (IntPtr display, IntPtr window, int x, int y, int width, int height);
4436                 
4437                 [DllImport ("libX11", EntryPoint="XResizeWindow")]
4438                 internal extern static int XResizeWindow (IntPtr display, IntPtr window, int width, int height);
4439                 
4440                 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
4441                 internal extern static int XGetWindowAttributes (IntPtr display, IntPtr window, ref XWindowAttributes attributes);
4442                 
4443                 [DllImport ("libX11", EntryPoint="XFlush")]
4444                 internal extern static int XFlush (IntPtr display);
4445                 
4446                 [DllImport ("libX11", EntryPoint="XSetWMName")]
4447                 internal extern static int XSetWMName (IntPtr display, IntPtr window, ref XTextProperty text_prop);
4448                 
4449                 [DllImport ("libX11", EntryPoint="XStoreName")]
4450                 internal extern static int XStoreName (IntPtr display, IntPtr window, string window_name);
4451                 
4452                 [DllImport ("libX11", EntryPoint="XFetchName")]
4453                 internal extern static int XFetchName (IntPtr display, IntPtr window, ref IntPtr window_name);
4454                 
4455                 [DllImport ("libX11", EntryPoint="XSendEvent")]
4456                 internal extern static int XSendEvent (IntPtr display, IntPtr window, bool propagate, EventMask event_mask, ref XEvent send_event);
4457                 
4458                 [DllImport ("libX11", EntryPoint="XQueryTree")]
4459                 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);
4460                 
4461                 [DllImport ("libX11", EntryPoint="XFree")]
4462                 internal extern static int XFree (IntPtr data);
4463                 
4464                 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
4465                 internal extern static int XRaiseWindow (IntPtr display, IntPtr window);
4466                 
4467                 [DllImport ("libX11", EntryPoint="XLowerWindow")]
4468                 internal extern static uint XLowerWindow (IntPtr display, IntPtr window);
4469                 
4470                 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
4471                 internal extern static uint XConfigureWindow (IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
4472                 
4473                 [DllImport ("libX11", EntryPoint="XInternAtom")]
4474                 internal extern static int XInternAtom (IntPtr display, string atom_name, bool only_if_exists);
4475                 
4476                 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
4477                 internal extern static int XSetWMProtocols (IntPtr display, IntPtr window, uint[] protocols, int count);
4478                 
4479                 [DllImport ("libX11", EntryPoint="XGrabPointer")]
4480                 internal extern static int XGrabPointer (IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, uint cursor, uint timestamp);
4481                 
4482                 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
4483                 internal extern static int XUngrabPointer (IntPtr display, uint timestamp);
4484                 
4485                 [DllImport ("libX11", EntryPoint="XQueryPointer")]
4486                 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);
4487                 
4488                 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
4489                 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);
4490                 
4491                 [DllImport ("libX11", EntryPoint="XWarpPointer")]
4492                 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);
4493                 
4494                 [DllImport ("libX11", EntryPoint="XClearWindow")]
4495                 internal extern static int XClearWindow (IntPtr display, IntPtr window);
4496                 
4497                 [DllImport ("libX11", EntryPoint="XClearArea")]
4498                 internal extern static int XClearArea (IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
4499                 
4500                 // Colormaps
4501                 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
4502                 internal extern static IntPtr XDefaultScreenOfDisplay (IntPtr display);
4503                 
4504                 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
4505                 internal extern static int XScreenNumberOfScreen (IntPtr display, IntPtr Screen);
4506                 
4507                 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
4508                 internal extern static IntPtr XDefaultVisual (IntPtr display, int screen_number);
4509                 
4510                 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
4511                 internal extern static uint XDefaultDepth (IntPtr display, int screen_number);
4512                 
4513                 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
4514                 internal extern static IntPtr XDefaultColormap (IntPtr display, int screen_number);
4515                 
4516                 [DllImport ("libX11", EntryPoint="XLookupColor")]
4517                 internal extern static int XLookupColor (IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
4518                 
4519                 [DllImport ("libX11", EntryPoint="XAllocColor")]
4520                 internal extern static int XAllocColor (IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
4521                 
4522                 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
4523                 internal extern static int XSetTransientForHint (IntPtr display, IntPtr window, IntPtr prop_window);
4524                 
4525                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4526                 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int type, int format, PropertyMode  mode, ref MotifWmHints data, int nelements);
4527                 
4528                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4529                 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode  mode, uint[] atoms, int nelements);
4530                 
4531                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4532                 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode  mode, ref uint value, int nelements);
4533                 
4534                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4535                 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int format, int type, PropertyMode  mode, uint[] atoms, int nelements);
4536                 
4537                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4538                 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int format, int type, PropertyMode  mode, IntPtr atoms, int nelements);
4539                 
4540                 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4541                 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode  mode, IntPtr atoms, int nelements);
4542                 
4543                 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
4544                 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int type, int format, PropertyMode  mode, string text, int text_length);
4545                 
4546                 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
4547                 internal extern static int XDeleteProperty (IntPtr display, IntPtr window, int property);
4548                 
4549                 [DllImport ("gdiplus", EntryPoint="GetFontMetrics")]
4550                 internal extern static bool GetFontMetrics (IntPtr graphicsObject, IntPtr nativeObject, out int ascent, out int descent);
4551                 
4552                 // Drawing
4553                 [DllImport ("libX11", EntryPoint="XCreateGC")]
4554                 internal extern static IntPtr XCreateGC (IntPtr display, IntPtr window, GCFunction valuemask, ref XGCValues values);
4555                 
4556                 [DllImport ("libX11", EntryPoint="XFreeGC")]
4557                 internal extern static int XFreeGC (IntPtr display, IntPtr gc);
4558                 
4559                 [DllImport ("libX11", EntryPoint="XSetFunction")]
4560                 internal extern static int XSetFunction (IntPtr display, IntPtr gc, GXFunction function);
4561                 
4562                 [DllImport ("libX11", EntryPoint="XDrawLine")]
4563                 internal extern static int XDrawLine (IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
4564                 
4565                 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
4566                 internal extern static int XDrawRectangle (IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
4567                 
4568                 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
4569                 internal extern static int XSetWindowBackground (IntPtr display, IntPtr window, IntPtr background);
4570                 
4571                 [DllImport ("libX11", EntryPoint="XCopyArea")]
4572                 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);
4573                 
4574                 [DllImport ("libX11", EntryPoint="XGetAtomName")]
4575                 internal extern static string XGetAtomName (IntPtr display, int atom);
4576                 
4577                 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
4578                 internal extern static int XGetWindowProperty (IntPtr display, IntPtr window, int atom, int long_offset, int long_length, bool delete, Atom req_type, out Atom actual_type, out int actual_format, out int nitems, out int bytes_after, ref IntPtr prop);
4579                 
4580                 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
4581                 internal extern static int XSetInputFocus (IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
4582                 
4583                 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
4584                 internal extern static int XIconifyWindow (IntPtr display, IntPtr window, int screen_number);
4585                 
4586                 [DllImport ("libX11", EntryPoint="XDefineCursor")]
4587                 internal extern static int XDefineCursor (IntPtr display, IntPtr window, IntPtr cursor);
4588                 
4589                 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
4590                 internal extern static int XUndefineCursor (IntPtr display, IntPtr window);
4591                 
4592                 [DllImport ("libX11", EntryPoint="XFreeCursor")]
4593                 internal extern static int XFreeCursor (IntPtr display, IntPtr cursor);
4594                 
4595                 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
4596                 internal extern static IntPtr XCreateFontCursor (IntPtr display, CursorFontShape shape);
4597                 
4598                 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
4599                 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);
4600                 
4601                 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
4602                 internal extern static IntPtr XCreatePixmapFromBitmapData (IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
4603                 
4604                 [DllImport ("libX11", EntryPoint="XFreePixmap")]
4605                 internal extern static IntPtr XFreePixmap (IntPtr display, IntPtr pixmap);
4606                 
4607                 [DllImport ("libX11", EntryPoint="XWhitePixel")]
4608                 internal extern static IntPtr XWhitePixel (IntPtr display, int screen_no);
4609                 
4610                 [DllImport ("libX11", EntryPoint="XBlackPixel")]
4611                 internal extern static IntPtr XBlackPixel (IntPtr display, int screen_no);
4612                 
4613                 [DllImport ("libX11", EntryPoint="XGrabServer")]
4614                 internal extern static void XGrabServer (IntPtr display);
4615                 
4616                 [DllImport ("libX11", EntryPoint="XUngrabServer")]
4617                 internal extern static void XUngrabServer (IntPtr display);
4618                 
4619                 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
4620                 internal extern static void XSetWMNormalHints (IntPtr display, IntPtr window, ref XSizeHints hints);
4621                 
4622                 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
4623                 internal extern static void XSetZoomHints (IntPtr display, IntPtr window, ref XSizeHints hints);
4624                 
4625                 [DllImport ("libX11", EntryPoint="XSetWMHints")]
4626                 internal extern static void XSetWMHints (IntPtr display, IntPtr window, ref XWMHints wmhints);
4627                 
4628                 [DllImport ("libX11", EntryPoint="XSync")]
4629                 internal extern static void XSync (IntPtr display, IntPtr window);
4630                 
4631                 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
4632                 internal extern static int XGetIconSizes (IntPtr display, IntPtr window, out IntPtr size_list, out int count);
4633                 
4634                 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
4635                 internal extern static IntPtr XSetErrorHandler (XErrorHandler error_handler);
4636                 
4637                 [DllImport ("libX11", EntryPoint="XGetErrorText")]
4638                 internal extern static IntPtr XGetErrorText (IntPtr display, byte code, StringBuilder buffer, int length);
4639                 
4640                 [DllImport ("libX11", EntryPoint="XInitThreads")]
4641                 internal extern static int XInitThreads ();
4642                 
4643                 [DllImport ("libX11", EntryPoint="XConvertSelection")]
4644                 internal extern static int XConvertSelection (IntPtr display, int selection, int target, int property, IntPtr requestor, IntPtr time);
4645                 
4646                 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
4647                 internal extern static IntPtr XGetSelectionOwner (IntPtr display, int selection);
4648                 
4649                 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
4650                 internal extern static int XSetSelectionOwner (IntPtr display, int selection, IntPtr owner, IntPtr time);
4651                 
4652                 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
4653                 internal extern static int XSetPlaneMask (IntPtr display, IntPtr gc, uint mask);
4654                 
4655                 [DllImport ("libX11", EntryPoint="XSetForeground")]
4656                 internal extern static int XSetForeground (IntPtr display, IntPtr gc, uint foreground);
4657                 
4658                 [DllImport ("libX11", EntryPoint="XSetBackground")]
4659                 internal extern static int XSetBackground (IntPtr display, IntPtr gc, uint background);
4660                 
4661                 #endregion
4662                 
4663                 #region gdk imports
4664                 [DllImport("libgdk-x11-2.0.so")]
4665                 static extern bool gdk_init_check (out int argc, string argv);
4666                 
4667                 [DllImport("libgdk-x11-2.0.so")]
4668                 internal static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
4669                 
4670                 [DllImport("libgdk-x11-2.0.so")]
4671                 internal static extern IntPtr gdk_display_get_default ();
4672                 
4673                 [DllImport("libgdk-x11-2.0.so")]
4674                 static extern IntPtr gdk_pixmap_new (IntPtr drawable, int width, int height, int depth);
4675                 
4676                 [DllImport("libgdk-x11-2.0.so")]
4677                 static extern IntPtr gdk_x11_drawable_get_xid (IntPtr gdkdrawable);
4678                 
4679                 [DllImport("libgdk-x11-2.0.so")]
4680                 static extern void gdk_draw_drawable (IntPtr drawable_dest, IntPtr gdk_gc, IntPtr drawable_src, int xsrc, int ysrc, int xdest, int ydest, int width, int height);
4681                 
4682                 [DllImport("libgdk-x11-2.0.so")]
4683                 static extern IntPtr gdk_gc_new (IntPtr drawable);
4684                 
4685                 [DllImport("libgdk-x11-2.0.so")]
4686                 static extern IntPtr gdk_window_foreign_new (IntPtr anid);
4687                 
4688                 [DllImport("libgdk-x11-2.0.so")]
4689                 static extern IntPtr gdk_x11_lookup_xdisplay (IntPtr xdisplay);
4690                 
4691                 [DllImport("libgdk-x11-2.0.so")]
4692                 static extern void gdk_display_close (IntPtr display);
4693                 
4694                 [DllImport("libgdk-x11-2.0.so")]
4695                 static extern void gdk_display_beep (IntPtr display);
4696                 
4697                 [DllImport("libgdk-x11-2.0.so")]
4698                 static extern void gdk_display_sync (IntPtr display);
4699                 
4700                 [DllImport("libgdk-x11-2.0.so")]
4701                 static extern IntPtr gdk_get_default_root_window ();
4702                 
4703                 [DllImport("libgdk-x11-2.0.so")]
4704                 static extern IntPtr gdk_colormap_get_system ();
4705                 
4706                 [DllImport("libgdk-x11-2.0.so")]
4707                 static extern IntPtr gdk_x11_colormap_get_xcolormap  (IntPtr gdk_colormap);
4708                 
4709                 [DllImport("libgdk-x11-2.0.so")]
4710                 static extern void gdk_window_destroy (IntPtr gdk_window);
4711                 
4712                 [DllImport("libgdk-x11-2.0.so")]
4713                 static extern void gdk_x11_grab_server ();
4714                 
4715                 [DllImport("libgdk-x11-2.0.so")]
4716                 static extern void gdk_x11_ungrab_server ();
4717                 
4718                 [DllImport("libgdk-x11-2.0.so")]
4719                 static extern void gdk_display_flush (IntPtr gdk_display);
4720                 
4721                 [DllImport("libgdk-x11-2.0.so")]
4722                 static extern void gdk_window_iconify (IntPtr gdk_window);
4723                 
4724                 [DllImport("libgdk-x11-2.0.so")]
4725                 static extern void gdk_window_deiconify (IntPtr gdk_window);
4726                 
4727                 [DllImport("libgdk-x11-2.0.so")]
4728                 static extern void gdk_window_set_decorations (IntPtr gdk_window, int decorations);
4729                 
4730                 [DllImport("libgdk-x11-2.0.so")]
4731                 static extern IntPtr gdk_screen_get_default ();
4732                 
4733                 [DllImport("libgdk-x11-2.0.so")]
4734                 static extern int gdk_screen_get_number (IntPtr gdk_screen);
4735                 
4736                 [DllImport("libgdk-x11-2.0.so")]
4737                 static extern IntPtr gdk_window_lookup (IntPtr anid);
4738                 
4739                 [DllImport("libgdk-x11-2.0.so")]
4740                 static extern IntPtr gdk_window_new (IntPtr gdk_parent, ref GdkWindowAttr gdk_window_attributes, int attributes_mask);
4741                 
4742                 [DllImport("libgdk-x11-2.0.so")]
4743                 static extern void gdk_window_set_events (IntPtr gdk_window, int event_mask);
4744                 
4745                 [DllImport("libgdk-x11-2.0.so")]
4746                 static extern void gdk_window_show (IntPtr window);
4747                 
4748                 [DllImport("libgdk-x11-2.0.so")]
4749                 static extern void gdk_window_set_title (IntPtr gdk_window, string title);
4750                 
4751                 [DllImport("libgdk-x11-2.0.so")]
4752                 static extern int gdk_window_get_origin (IntPtr gdk_window, out int x, out int y);
4753                 
4754                 [DllImport("libgdk-x11-2.0.so")]
4755                 static extern void gdk_window_get_geometry (IntPtr gdk_window, out int x, out int y, out int width, out int height, out int depth);
4756                 
4757                 [DllImport("libgdk-x11-2.0.so")]
4758                 static extern void gdk_property_change (IntPtr gdk_window, /*GdkAtom*/IntPtr property, /*GdkAtom*/IntPtr type, int format, int gdk_prop_mode, /*const guchar **/ IntPtr data, int nelements);
4759                 
4760                 [DllImport("libgdk-x11-2.0.so")]
4761                 static extern IntPtr gdk_window_get_parent (IntPtr gdk_window);
4762                 
4763                 [DllImport("libgdk-x11-2.0.so")]
4764                 static extern void gdk_display_get_maximal_cursor_size (IntPtr gdk_display, out uint width, out uint height);
4765                 
4766                 [DllImport("libgdk-x11-2.0.so")]
4767                 static extern int gdk_visual_get_best_depth ();
4768                 #endregion
4769                 
4770                 #region gobject imports
4771                 [DllImport("libglib-2.0.so")]
4772                 static extern void g_free (IntPtr mem);
4773                 
4774                 [DllImport("libgobject-2.0.so")]
4775                 static extern void g_object_unref (IntPtr nativeObject);
4776                 #endregion
4777         }
4778 }