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