Browse Source

[X11] Initial windowing and mouse events

Nikita Tsukanov 7 years ago
parent
commit
666efd311b

+ 1 - 1
samples/PlatformSanityChecks/Program.cs

@@ -20,7 +20,7 @@ namespace PlatformSanityChecks
             AppBuilder.Configure<App>().RuntimePlatformServicesInitializer();
             var app = new App();
             
-            new AvaloniaX11Platform().Initialize();
+            AvaloniaX11PlatformExtensions.InitializeX11Platform();
 
             CheckPlatformThreading();
 

+ 2 - 2
src/Avalonia.Input/MouseDevice.cs

@@ -18,7 +18,7 @@ namespace Avalonia.Input
     {
         private int _clickCount;
         private Rect _lastClickRect;
-        private uint _lastClickTime;
+        private ulong _lastClickTime;
         private IInputElement _captured;
         private IDisposable _capturedSubscription;
        
@@ -152,7 +152,7 @@ namespace Avalonia.Input
             ClearPointerOver(this, root);
         }
 
-        private bool MouseDown(IMouseDevice device, uint timestamp, IInputElement root, Point p, MouseButton button, InputModifiers inputModifiers)
+        private bool MouseDown(IMouseDevice device, ulong timestamp, IInputElement root, Point p, MouseButton button, InputModifiers inputModifiers)
         {
             Contract.Requires<ArgumentNullException>(device != null);
             Contract.Requires<ArgumentNullException>(root != null);

+ 2 - 2
src/Avalonia.Input/Raw/RawInputEventArgs.cs

@@ -21,7 +21,7 @@ namespace Avalonia.Input.Raw
         /// </summary>
         /// <param name="device">The associated device.</param>
         /// <param name="timestamp">The event timestamp.</param>
-        public RawInputEventArgs(IInputDevice device, uint timestamp)
+        public RawInputEventArgs(IInputDevice device, ulong timestamp)
         {
             Contract.Requires<ArgumentNullException>(device != null);
 
@@ -47,6 +47,6 @@ namespace Avalonia.Input.Raw
         /// <summary>
         /// Gets the timestamp associated with the event.
         /// </summary>
-        public uint Timestamp { get; private set; }
+        public ulong Timestamp { get; private set; }
     }
 }

+ 1 - 1
src/Avalonia.Input/Raw/RawKeyEventArgs.cs

@@ -13,7 +13,7 @@ namespace Avalonia.Input.Raw
     {
         public RawKeyEventArgs(
             IKeyboardDevice device,
-            uint timestamp,
+            ulong timestamp,
             RawKeyEventType type,
             Key key, InputModifiers modifiers)
             : base(device, timestamp)

+ 1 - 1
src/Avalonia.Input/Raw/RawMouseEventArgs.cs

@@ -35,7 +35,7 @@ namespace Avalonia.Input.Raw
         /// <param name="inputModifiers">The input modifiers.</param>
         public RawMouseEventArgs(
             IInputDevice device,
-            uint timestamp,
+            ulong timestamp,
             IInputRoot root,
             RawMouseEventType type,
             Point position, 

+ 1 - 1
src/Avalonia.Input/Raw/RawMouseWheelEventArgs.cs

@@ -8,7 +8,7 @@ namespace Avalonia.Input.Raw
     {
         public RawMouseWheelEventArgs(
             IInputDevice device,
-            uint timestamp,
+            ulong timestamp,
             IInputRoot root,
             Point position,
             Vector delta, InputModifiers inputModifiers)

+ 1 - 1
src/Avalonia.Input/Raw/RawTextInputEventArgs.cs

@@ -7,7 +7,7 @@ namespace Avalonia.Input.Raw
     {
         public string Text { get; set; }
 
-        public RawTextInputEventArgs(IKeyboardDevice device, uint timestamp, string text) : base(device, timestamp)
+        public RawTextInputEventArgs(IKeyboardDevice device, ulong timestamp, string text) : base(device, timestamp)
         {
             Text = text;
         }

+ 1 - 0
src/Avalonia.X11/Avalonia.X11.csproj

@@ -7,6 +7,7 @@
 
     <ItemGroup>
       <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" />
+      <ProjectReference Include="..\Avalonia.OpenGL\Avalonia.OpenGL.csproj" />
     </ItemGroup>
 
 </Project>

+ 103 - 0
src/Avalonia.X11/Stubs.cs

@@ -0,0 +1,103 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Avalonia.Controls;
+using Avalonia.Controls.Platform;
+using Avalonia.Input;
+using Avalonia.Input.Platform;
+using Avalonia.Platform;
+
+namespace Avalonia.X11
+{
+    class CursorFactoryStub : IStandardCursorFactory
+    {
+        public IPlatformHandle GetCursor(StandardCursorType cursorType)
+        {
+            return new PlatformHandle(IntPtr.Zero, "FAKE");
+        }
+    }
+
+    class ClipboardStub : IClipboard
+    {
+        private string _text;
+        public Task<string> GetTextAsync()
+        {
+            return Task.FromResult(_text);
+        }
+
+        public Task SetTextAsync(string text)
+        {
+            _text = text;
+            return Task.CompletedTask;
+        }
+
+        public Task ClearAsync()
+        {
+            _text = null;
+            return Task.CompletedTask;
+        }
+    }
+
+    class PlatformSettingsStub : IPlatformSettings
+    {
+        public Size DoubleClickSize { get; } = new Size(2, 2);
+        public TimeSpan DoubleClickTime { get; } = TimeSpan.FromMilliseconds(500);
+    }
+
+    class SystemDialogsStub : ISystemDialogImpl
+    {
+        public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent)
+        {
+            return Task.FromResult((string[])null);
+        }
+
+        public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent)
+        {
+            return Task.FromResult((string)null);
+        }
+    }
+
+    class IconLoaderStub : IPlatformIconLoader
+    {
+        class FakeIcon : IWindowIconImpl
+        {
+            private readonly byte[] _data;
+
+            public FakeIcon(byte[] data)
+            {
+                _data = data;
+            }
+            public void Save(Stream outputStream)
+            {
+                outputStream.Write(_data, 0, _data.Length);
+            }
+        }
+        
+        public IWindowIconImpl LoadIcon(string fileName)
+        {
+            return new FakeIcon(File.ReadAllBytes(fileName));
+        }
+
+        public IWindowIconImpl LoadIcon(Stream stream)
+        {
+            var ms = new MemoryStream();
+            stream.CopyTo(ms);
+            return new FakeIcon(ms.ToArray());
+        }
+
+        public IWindowIconImpl LoadIcon(IBitmapImpl bitmap)
+        {
+            var ms = new MemoryStream();
+            bitmap.Save(ms);
+            return new FakeIcon(ms.ToArray());
+        }
+    }
+
+    class ScreenStub : IScreenImpl
+    {
+        public int ScreenCount { get; } = 1;
+
+        public Screen[] AllScreens { get; } =
+            {new Screen(new Rect(0, 0, 1920, 1280), new Rect(0, 0, 1920, 1280), true)};
+    }
+}

+ 341 - 0
src/Avalonia.X11/X11Atoms.cs

@@ -0,0 +1,341 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2006 Novell, Inc. (http://www.novell.com)
+//
+//
+
+using System;
+using static Avalonia.X11.XLib;
+// ReSharper disable FieldCanBeMadeReadOnly.Global
+// ReSharper disable IdentifierTypo
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+// ReSharper disable CommentTypo
+// ReSharper disable ArrangeThisQualifier
+// ReSharper disable NotAccessedField.Global
+// ReSharper disable InconsistentNaming
+// ReSharper disable StringLiteralTypo
+#pragma warning disable 649
+
+namespace Avalonia.X11 {
+
+	internal class X11Atoms {
+
+		// Our atoms
+		public readonly IntPtr AnyPropertyType		= (IntPtr)0;
+		public readonly IntPtr XA_PRIMARY		= (IntPtr)1;
+		public readonly IntPtr XA_SECONDARY		= (IntPtr)2;
+		public readonly IntPtr XA_ARC			= (IntPtr)3;
+		public readonly IntPtr XA_ATOM			= (IntPtr)4;
+		public readonly IntPtr XA_BITMAP		= (IntPtr)5;
+		public readonly IntPtr XA_CARDINAL		= (IntPtr)6;
+		public readonly IntPtr XA_COLORMAP		= (IntPtr)7;
+		public readonly IntPtr XA_CURSOR		= (IntPtr)8;
+		public readonly IntPtr XA_CUT_BUFFER0		= (IntPtr)9;
+		public readonly IntPtr XA_CUT_BUFFER1		= (IntPtr)10;
+		public readonly IntPtr XA_CUT_BUFFER2		= (IntPtr)11;
+		public readonly IntPtr XA_CUT_BUFFER3		= (IntPtr)12;
+		public readonly IntPtr XA_CUT_BUFFER4		= (IntPtr)13;
+		public readonly IntPtr XA_CUT_BUFFER5		= (IntPtr)14;
+		public readonly IntPtr XA_CUT_BUFFER6		= (IntPtr)15;
+		public readonly IntPtr XA_CUT_BUFFER7		= (IntPtr)16;
+		public readonly IntPtr XA_DRAWABLE		= (IntPtr)17;
+		public readonly IntPtr XA_FONT			= (IntPtr)18;
+		public readonly IntPtr XA_INTEGER		= (IntPtr)19;
+		public readonly IntPtr XA_PIXMAP		= (IntPtr)20;
+		public readonly IntPtr XA_POINT			= (IntPtr)21;
+		public readonly IntPtr XA_RECTANGLE		= (IntPtr)22;
+		public readonly IntPtr XA_RESOURCE_MANAGER	= (IntPtr)23;
+		public readonly IntPtr XA_RGB_COLOR_MAP		= (IntPtr)24;
+		public readonly IntPtr XA_RGB_BEST_MAP		= (IntPtr)25;
+		public readonly IntPtr XA_RGB_BLUE_MAP		= (IntPtr)26;
+		public readonly IntPtr XA_RGB_DEFAULT_MAP	= (IntPtr)27;
+		public readonly IntPtr XA_RGB_GRAY_MAP		= (IntPtr)28;
+		public readonly IntPtr XA_RGB_GREEN_MAP		= (IntPtr)29;
+		public readonly IntPtr XA_RGB_RED_MAP		= (IntPtr)30;
+		public readonly IntPtr XA_STRING		= (IntPtr)31;
+		public readonly IntPtr XA_VISUALID		= (IntPtr)32;
+		public readonly IntPtr XA_WINDOW		= (IntPtr)33;
+		public readonly IntPtr XA_WM_COMMAND		= (IntPtr)34;
+		public readonly IntPtr XA_WM_HINTS		= (IntPtr)35;
+		public readonly IntPtr XA_WM_CLIENT_MACHINE	= (IntPtr)36;
+		public readonly IntPtr XA_WM_ICON_NAME		= (IntPtr)37;
+		public readonly IntPtr XA_WM_ICON_SIZE		= (IntPtr)38;
+		public readonly IntPtr XA_WM_NAME		= (IntPtr)39;
+		public readonly IntPtr XA_WM_NORMAL_HINTS	= (IntPtr)40;
+		public readonly IntPtr XA_WM_SIZE_HINTS		= (IntPtr)41;
+		public readonly IntPtr XA_WM_ZOOM_HINTS		= (IntPtr)42;
+		public readonly IntPtr XA_MIN_SPACE		= (IntPtr)43;
+		public readonly IntPtr XA_NORM_SPACE		= (IntPtr)44;
+		public readonly IntPtr XA_MAX_SPACE		= (IntPtr)45;
+		public readonly IntPtr XA_END_SPACE		= (IntPtr)46;
+		public readonly IntPtr XA_SUPERSCRIPT_X		= (IntPtr)47;
+		public readonly IntPtr XA_SUPERSCRIPT_Y		= (IntPtr)48;
+		public readonly IntPtr XA_SUBSCRIPT_X		= (IntPtr)49;
+		public readonly IntPtr XA_SUBSCRIPT_Y		= (IntPtr)50;
+		public readonly IntPtr XA_UNDERLINE_POSITION	= (IntPtr)51;
+		public readonly IntPtr XA_UNDERLINE_THICKNESS	= (IntPtr)52;
+		public readonly IntPtr XA_STRIKEOUT_ASCENT	= (IntPtr)53;
+		public readonly IntPtr XA_STRIKEOUT_DESCENT	= (IntPtr)54;
+		public readonly IntPtr XA_ITALIC_ANGLE		= (IntPtr)55;
+		public readonly IntPtr XA_X_HEIGHT		= (IntPtr)56;
+		public readonly IntPtr XA_QUAD_WIDTH		= (IntPtr)57;
+		public readonly IntPtr XA_WEIGHT		= (IntPtr)58;
+		public readonly IntPtr XA_POINT_SIZE		= (IntPtr)59;
+		public readonly IntPtr XA_RESOLUTION		= (IntPtr)60;
+		public readonly IntPtr XA_COPYRIGHT		= (IntPtr)61;
+		public readonly IntPtr XA_NOTICE		= (IntPtr)62;
+		public readonly IntPtr XA_FONT_NAME		= (IntPtr)63;
+		public readonly IntPtr XA_FAMILY_NAME		= (IntPtr)64;
+		public readonly IntPtr XA_FULL_NAME		= (IntPtr)65;
+		public readonly IntPtr XA_CAP_HEIGHT		= (IntPtr)66;
+		public readonly IntPtr XA_WM_CLASS		= (IntPtr)67;
+		public readonly IntPtr XA_WM_TRANSIENT_FOR	= (IntPtr)68;
+
+		public readonly IntPtr WM_PROTOCOLS;
+		public readonly IntPtr WM_DELETE_WINDOW;
+		public readonly IntPtr WM_TAKE_FOCUS;
+		public readonly IntPtr _NET_SUPPORTED;
+		public readonly IntPtr _NET_CLIENT_LIST;
+		public readonly IntPtr _NET_NUMBER_OF_DESKTOPS;
+		public readonly IntPtr _NET_DESKTOP_GEOMETRY;
+		public readonly IntPtr _NET_DESKTOP_VIEWPORT;
+		public readonly IntPtr _NET_CURRENT_DESKTOP;
+		public readonly IntPtr _NET_DESKTOP_NAMES;
+		public readonly IntPtr _NET_ACTIVE_WINDOW;
+		public readonly IntPtr _NET_WORKAREA;
+		public readonly IntPtr _NET_SUPPORTING_WM_CHECK;
+		public readonly IntPtr _NET_VIRTUAL_ROOTS;
+		public readonly IntPtr _NET_DESKTOP_LAYOUT;
+		public readonly IntPtr _NET_SHOWING_DESKTOP;
+		public readonly IntPtr _NET_CLOSE_WINDOW;
+		public readonly IntPtr _NET_MOVERESIZE_WINDOW;
+		public readonly IntPtr _NET_WM_MOVERESIZE;
+		public readonly IntPtr _NET_RESTACK_WINDOW;
+		public readonly IntPtr _NET_REQUEST_FRAME_EXTENTS;
+		public readonly IntPtr _NET_WM_NAME;
+		public readonly IntPtr _NET_WM_VISIBLE_NAME;
+		public readonly IntPtr _NET_WM_ICON_NAME;
+		public readonly IntPtr _NET_WM_VISIBLE_ICON_NAME;
+		public readonly IntPtr _NET_WM_DESKTOP;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE;
+		public readonly IntPtr _NET_WM_STATE;
+		public readonly IntPtr _NET_WM_ALLOWED_ACTIONS;
+		public readonly IntPtr _NET_WM_STRUT;
+		public readonly IntPtr _NET_WM_STRUT_PARTIAL;
+		public readonly IntPtr _NET_WM_ICON_GEOMETRY;
+		public readonly IntPtr _NET_WM_ICON;
+		public readonly IntPtr _NET_WM_PID;
+		public readonly IntPtr _NET_WM_HANDLED_ICONS;
+		public readonly IntPtr _NET_WM_USER_TIME;
+		public readonly IntPtr _NET_FRAME_EXTENTS;
+		public readonly IntPtr _NET_WM_PING;
+		public readonly IntPtr _NET_WM_SYNC_REQUEST;
+		public readonly IntPtr _NET_SYSTEM_TRAY_S;
+		public readonly IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
+		public readonly IntPtr _NET_SYSTEM_TRAY_OPCODE;
+		public readonly IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
+		public readonly IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
+		public readonly IntPtr _XEMBED;
+		public readonly IntPtr _XEMBED_INFO;
+		public readonly IntPtr _MOTIF_WM_HINTS;
+		public readonly IntPtr _NET_WM_STATE_SKIP_TASKBAR;
+		public readonly IntPtr _NET_WM_STATE_ABOVE;
+		public readonly IntPtr _NET_WM_STATE_MODAL;
+		public readonly IntPtr _NET_WM_STATE_HIDDEN;
+		public readonly IntPtr _NET_WM_CONTEXT_HELP;
+		public readonly IntPtr _NET_WM_WINDOW_OPACITY;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_DOCK;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_MENU;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
+		public readonly IntPtr CLIPBOARD;
+		public readonly IntPtr PRIMARY;
+		public readonly IntPtr DIB;
+		public readonly IntPtr OEMTEXT;
+		public readonly IntPtr UNICODETEXT;
+		public readonly IntPtr TARGETS;
+		public readonly IntPtr PostAtom;
+		public readonly IntPtr HoverState;
+		public readonly IntPtr AsyncAtom;
+
+
+		public X11Atoms (IntPtr display) {
+
+			// make sure this array stays in sync with the statements below
+			string [] atom_names = new string[] {
+				"WM_PROTOCOLS",
+				"WM_DELETE_WINDOW",
+				"WM_TAKE_FOCUS",
+				"_NET_SUPPORTED",
+				"_NET_CLIENT_LIST",
+				"_NET_NUMBER_OF_DESKTOPS",
+				"_NET_DESKTOP_GEOMETRY",
+				"_NET_DESKTOP_VIEWPORT",
+				"_NET_CURRENT_DESKTOP",
+				"_NET_DESKTOP_NAMES",
+				"_NET_ACTIVE_WINDOW",
+				"_NET_WORKAREA",
+				"_NET_SUPPORTING_WM_CHECK",
+				"_NET_VIRTUAL_ROOTS",
+				"_NET_DESKTOP_LAYOUT",
+				"_NET_SHOWING_DESKTOP",
+				"_NET_CLOSE_WINDOW",
+				"_NET_MOVERESIZE_WINDOW",
+				"_NET_WM_MOVERESIZE",
+				"_NET_RESTACK_WINDOW",
+				"_NET_REQUEST_FRAME_EXTENTS",
+				"_NET_WM_NAME",
+				"_NET_WM_VISIBLE_NAME",
+				"_NET_WM_ICON_NAME",
+				"_NET_WM_VISIBLE_ICON_NAME",
+				"_NET_WM_DESKTOP",
+				"_NET_WM_WINDOW_TYPE",
+				"_NET_WM_STATE",
+				"_NET_WM_ALLOWED_ACTIONS",
+				"_NET_WM_STRUT",
+				"_NET_WM_STRUT_PARTIAL",
+				"_NET_WM_ICON_GEOMETRY",
+				"_NET_WM_ICON",
+				"_NET_WM_PID",
+				"_NET_WM_HANDLED_ICONS",
+				"_NET_WM_USER_TIME",
+				"_NET_FRAME_EXTENTS",
+				"_NET_WM_PING",
+				"_NET_WM_SYNC_REQUEST",
+				"_NET_SYSTEM_TRAY_OPCODE",
+				"_NET_SYSTEM_TRAY_ORIENTATION",
+				"_NET_WM_STATE_MAXIMIZED_HORZ",
+				"_NET_WM_STATE_MAXIMIZED_VERT",
+				"_NET_WM_STATE_HIDDEN",
+				"_XEMBED",
+				"_XEMBED_INFO",
+				"_MOTIF_WM_HINTS",
+				"_NET_WM_STATE_SKIP_TASKBAR",
+				"_NET_WM_STATE_ABOVE",
+				"_NET_WM_STATE_MODAL",
+				"_NET_WM_CONTEXT_HELP",
+				"_NET_WM_WINDOW_OPACITY",
+				"_NET_WM_WINDOW_TYPE_DESKTOP",
+				"_NET_WM_WINDOW_TYPE_DOCK",
+				"_NET_WM_WINDOW_TYPE_TOOLBAR",
+				"_NET_WM_WINDOW_TYPE_MENU",
+				"_NET_WM_WINDOW_TYPE_UTILITY",
+				"_NET_WM_WINDOW_TYPE_DIALOG",
+				"_NET_WM_WINDOW_TYPE_SPLASH",
+				"_NET_WM_WINDOW_TYPE_NORMAL",
+				"CLIPBOARD",
+				"PRIMARY",
+				"COMPOUND_TEXT",
+				"UTF8_STRING",
+				"TARGETS",
+				"_SWF_AsyncAtom",
+				"_SWF_PostMessageAtom",
+				"_SWF_HoverAtom" };
+
+			IntPtr[] atoms = new IntPtr [atom_names.Length];;
+
+			XInternAtoms (display, atom_names, atom_names.Length, false, atoms);
+
+			int off = 0;
+			WM_PROTOCOLS = atoms [off++];
+			WM_DELETE_WINDOW = atoms [off++];
+			WM_TAKE_FOCUS = atoms [off++];
+			_NET_SUPPORTED = atoms [off++];
+			_NET_CLIENT_LIST = atoms [off++];
+			_NET_NUMBER_OF_DESKTOPS = atoms [off++];
+			_NET_DESKTOP_GEOMETRY = atoms [off++];
+			_NET_DESKTOP_VIEWPORT = atoms [off++];
+			_NET_CURRENT_DESKTOP = atoms [off++];
+			_NET_DESKTOP_NAMES = atoms [off++];
+			_NET_ACTIVE_WINDOW = atoms [off++];
+			_NET_WORKAREA = atoms [off++];
+			_NET_SUPPORTING_WM_CHECK = atoms [off++];
+			_NET_VIRTUAL_ROOTS = atoms [off++];
+			_NET_DESKTOP_LAYOUT = atoms [off++];
+			_NET_SHOWING_DESKTOP = atoms [off++];
+			_NET_CLOSE_WINDOW = atoms [off++];
+			_NET_MOVERESIZE_WINDOW = atoms [off++];
+			_NET_WM_MOVERESIZE = atoms [off++];
+			_NET_RESTACK_WINDOW = atoms [off++];
+			_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
+			_NET_WM_NAME = atoms [off++];
+			_NET_WM_VISIBLE_NAME = atoms [off++];
+			_NET_WM_ICON_NAME = atoms [off++];
+			_NET_WM_VISIBLE_ICON_NAME = atoms [off++];
+			_NET_WM_DESKTOP = atoms [off++];
+			_NET_WM_WINDOW_TYPE = atoms [off++];
+			_NET_WM_STATE = atoms [off++];
+			_NET_WM_ALLOWED_ACTIONS = atoms [off++];
+			_NET_WM_STRUT = atoms [off++];
+			_NET_WM_STRUT_PARTIAL = atoms [off++];
+			_NET_WM_ICON_GEOMETRY = atoms [off++];
+			_NET_WM_ICON = atoms [off++];
+			_NET_WM_PID = atoms [off++];
+			_NET_WM_HANDLED_ICONS = atoms [off++];
+			_NET_WM_USER_TIME = atoms [off++];
+			_NET_FRAME_EXTENTS = atoms [off++];
+			_NET_WM_PING = atoms [off++];
+			_NET_WM_SYNC_REQUEST = atoms [off++];
+			_NET_SYSTEM_TRAY_OPCODE = atoms [off++];
+			_NET_SYSTEM_TRAY_ORIENTATION = atoms [off++];
+			_NET_WM_STATE_MAXIMIZED_HORZ = atoms [off++];
+			_NET_WM_STATE_MAXIMIZED_VERT = atoms [off++];
+			_NET_WM_STATE_HIDDEN = atoms [off++];
+			_XEMBED = atoms [off++];
+			_XEMBED_INFO = atoms [off++];
+			_MOTIF_WM_HINTS = atoms [off++];
+			_NET_WM_STATE_SKIP_TASKBAR = atoms [off++];
+			_NET_WM_STATE_ABOVE = atoms [off++];
+			_NET_WM_STATE_MODAL = atoms [off++];
+			_NET_WM_CONTEXT_HELP = atoms [off++];
+			_NET_WM_WINDOW_OPACITY = atoms [off++];
+			_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
+			_NET_WM_WINDOW_TYPE_DOCK = atoms [off++];
+			_NET_WM_WINDOW_TYPE_TOOLBAR = atoms [off++];
+			_NET_WM_WINDOW_TYPE_MENU = atoms [off++];
+			_NET_WM_WINDOW_TYPE_UTILITY = atoms [off++];
+			_NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
+			_NET_WM_WINDOW_TYPE_SPLASH = atoms [off++];
+			_NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
+			CLIPBOARD = atoms [off++];
+			PRIMARY = atoms [off++];
+			OEMTEXT = atoms [off++];
+			UNICODETEXT = atoms [off++];
+			TARGETS = atoms [off++];
+			AsyncAtom = atoms [off++];
+			PostAtom = atoms [off++];
+			HoverState = atoms [off++];
+
+			DIB = XA_PIXMAP;
+
+		    var defScreen = XDefaultScreen(display);
+			// XXX multi screen stuff here
+			_NET_SYSTEM_TRAY_S = XInternAtom (display, "_NET_SYSTEM_TRAY_S" + defScreen.ToString(), false);
+		}
+
+	}
+
+}
+

+ 110 - 0
src/Avalonia.X11/X11Enums.cs

@@ -0,0 +1,110 @@
+using System;
+
+namespace Avalonia.X11
+{
+
+    public enum Status
+    {
+        Success = 0, /* everything's okay */
+        BadRequest = 1, /* bad request code */
+        BadValue = 2, /* int parameter out of range */
+        BadWindow = 3, /* parameter not a Window */
+        BadPixmap = 4, /* parameter not a Pixmap */
+        BadAtom = 5, /* parameter not an Atom */
+        BadCursor = 6, /* parameter not a Cursor */
+        BadFont = 7, /* parameter not a Font */
+        BadMatch = 8, /* parameter mismatch */
+        BadDrawable = 9, /* parameter not a Pixmap or Window */
+        BadAccess = 10, /* depending on context:
+                                 - key/button already grabbed
+                                 - attempt to free an illegal 
+                                   cmap entry 
+                                - attempt to store into a read-only 
+                                   color map entry.
+                                - attempt to modify the access control
+                                   list from other than the local host.
+                                */
+        BadAlloc = 11, /* insufficient resources */
+        BadColor = 12, /* no such colormap */
+        BadGC = 13, /* parameter not a GC */
+        BadIDChoice = 14, /* choice not in range or already used */
+        BadName = 15, /* font or color name doesn't exist */
+        BadLength = 16, /* Request length incorrect */
+        BadImplementation = 17, /* server is defective */
+
+        FirstExtensionError = 128,
+        LastExtensionError = 255,
+
+    }
+
+    [Flags]
+    public enum XEventMask : int
+    {
+        NoEventMask = 0,
+        KeyPressMask = (1 << 0),
+        KeyReleaseMask = (1 << 1),
+        ButtonPressMask = (1 << 2),
+        ButtonReleaseMask = (1 << 3),
+        EnterWindowMask = (1 << 4),
+        LeaveWindowMask = (1 << 5),
+        PointerMotionMask = (1 << 6),
+        PointerMotionHintMask = (1 << 7),
+        Button1MotionMask = (1 << 8),
+        Button2MotionMask = (1 << 9),
+        Button3MotionMask = (1 << 10),
+        Button4MotionMask = (1 << 11),
+        Button5MotionMask = (1 << 12),
+        ButtonMotionMask = (1 << 13),
+        KeymapStateMask = (1 << 14),
+        ExposureMask = (1 << 15),
+        VisibilityChangeMask = (1 << 16),
+        StructureNotifyMask = (1 << 17),
+        ResizeRedirectMask = (1 << 18),
+        SubstructureNotifyMask = (1 << 19),
+        SubstructureRedirectMask = (1 << 20),
+        FocusChangeMask = (1 << 21),
+        PropertyChangeMask = (1 << 22),
+        ColormapChangeMask = (1 << 23),
+        OwnerGrabButtonMask = (1 << 24)
+    }
+
+    [Flags]
+    public enum XModifierMask
+    {
+        ShiftMask = (1 << 0),
+        LockMask = (1 << 1),
+        ControlMask = (1 << 2),
+        Mod1Mask = (1 << 3),
+        Mod2Mask = (1 << 4),
+        Mod3Mask = (1 << 5),
+        Mod4Mask = (1 << 6),
+        Mod5Mask = (1 << 7),
+        Button1Mask = (1 << 8),
+        Button2Mask = (1 << 9),
+        Button3Mask = (1 << 10),
+        Button4Mask = (1 << 11),
+        Button5Mask = (1 << 12),
+        AnyModifier = (1 << 15)
+
+    }
+    
+    [Flags]
+    public enum XCreateWindowFlags
+    {
+        CWBackPixmap = (1 << 0),
+        CWBackPixel = (1 << 1),
+        CWBorderPixmap = (1 << 2),
+        CWBorderPixel = (1 << 3),
+        CWBitGravity = (1 << 4),
+        CWWinGravity = (1 << 5),
+        CWBackingStore = (1 << 6),
+        CWBackingPlanes = (1 << 7),
+        CWBackingPixel = (1 << 8),
+        CWOverrideRedirect = (1 << 9),
+        CWSaveUnder = (1 << 10),
+        CWEventMask = (1 << 11),
+        CWDontPropagate = (1 << 12),
+        CWColormap = (1 << 13),
+        CWCursor = (1 << 14),
+    }
+}

+ 57 - 0
src/Avalonia.X11/X11Framebuffer.cs

@@ -0,0 +1,57 @@
+using System;
+using Avalonia.Platform;
+using static Avalonia.X11.XLib;
+namespace Avalonia.X11
+{
+    class X11Framebuffer : ILockedFramebuffer
+    {
+        private readonly IntPtr _display;
+        private readonly IntPtr _xid;
+        private IUnmanagedBlob _blob;
+
+        public X11Framebuffer(IntPtr display, IntPtr xid, int width, int height, int factor)
+        {
+            _display = display;
+            _xid = xid;
+            Width = width*factor;
+            Height = height*factor;
+            RowBytes = Width * 4;
+            Dpi = new Vector(96, 96) * factor;
+            Format = PixelFormat.Bgra8888;
+            _blob = AvaloniaLocator.Current.GetService<IRuntimePlatform>().AllocBlob(RowBytes * Height);
+            Address = _blob.Address;
+        }
+        
+        public void Dispose()
+        {
+            var image = new XImage();
+            int bitsPerPixel = 32;
+            image.width = Width;
+            image.height = Height;
+            image.format = 2; //ZPixmap;
+            image.data = Address;
+            image.byte_order = 0;// LSBFirst;
+            image.bitmap_unit = bitsPerPixel;
+            image.bitmap_bit_order = 0;// LSBFirst;
+            image.bitmap_pad = bitsPerPixel;
+            image.depth = 32;
+            image.bytes_per_line = RowBytes - Width * 4;
+            image.bits_per_pixel = bitsPerPixel;
+            XLockDisplay(_display);
+            XInitImage(ref image);
+            var gc = XCreateGC(_display, _xid, 0, IntPtr.Zero);
+            XPutImage(_display, _xid, gc, ref image, 0, 0, 0, 0, (uint) Width, (uint) Height);
+            XFreeGC(_display, gc);
+            XSync(_display, true);
+            XUnlockDisplay(_display);
+            _blob.Dispose();
+        }
+
+        public IntPtr Address { get; }
+        public int Width { get; }
+        public int Height { get; }
+        public int RowBytes { get; }
+        public Vector Dpi { get; }
+        public PixelFormat Format { get; }
+    }
+}

+ 27 - 0
src/Avalonia.X11/X11FramebufferSurface.cs

@@ -0,0 +1,27 @@
+using System;
+using Avalonia.Controls.Platform.Surfaces;
+using Avalonia.Platform;
+using static Avalonia.X11.XLib;
+namespace Avalonia.X11
+{
+    public class X11FramebufferSurface : IFramebufferPlatformSurface
+    {
+        private readonly IntPtr _display;
+        private readonly IntPtr _xid;
+
+        public X11FramebufferSurface(IntPtr display, IntPtr xid)
+        {
+            _display = display;
+            _xid = xid;
+        }
+        
+        public ILockedFramebuffer Lock()
+        {
+            XLockDisplay(_display);
+            XGetGeometry(_display, _xid, out var root, out var x, out var y, out var width, out var height,
+                out var bw, out var d);
+            XUnlockDisplay(_display);
+            return new X11Framebuffer(_display, _xid, width, height, 1);
+        }
+    }
+}

+ 35 - 0
src/Avalonia.X11/X11Info.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using static Avalonia.X11.XLib;
+// ReSharper disable UnusedAutoPropertyAccessor.Local
+namespace Avalonia.X11
+{
+    class X11Info
+    {
+        public IntPtr Display { get; }
+        public IntPtr DeferredDisplay { get; }
+        public int DefaultScreen { get; }
+        public IntPtr BlackPixel { get; }
+        public IntPtr RootWindow { get; }
+        public IntPtr DefaultRootWindow { get; }
+        public XVisualInfo MatchedVisual { get; }
+        public X11Atoms Atoms { get; }
+
+        public IntPtr LastActivityTimestamp { get; set; }
+        
+        public unsafe X11Info(IntPtr display, IntPtr deferredDisplay)
+        {
+            Display = display;
+            DeferredDisplay = deferredDisplay;
+            DefaultScreen = XDefaultScreen(display);
+            BlackPixel = XBlackPixel(display, DefaultScreen);
+            RootWindow = XRootWindow(display, DefaultScreen);
+            DefaultRootWindow = XDefaultRootWindow(display);
+            Atoms = new X11Atoms(display);
+            XMatchVisualInfo(display, DefaultScreen, 32, 4, out var info);
+            MatchedVisual = info;
+        }
+    }
+}

+ 44 - 3
src/Avalonia.X11/X11Platform.cs

@@ -1,27 +1,66 @@
 using System;
+using System.Collections.Generic;
 using Avalonia.Controls;
+using Avalonia.Controls.Platform;
+using Avalonia.Input;
+using Avalonia.Input.Platform;
+using Avalonia.OpenGL;
 using Avalonia.Platform;
+using Avalonia.Rendering;
 using Avalonia.X11;
 using static Avalonia.X11.XLib;
 namespace Avalonia.X11
 {
-    public class AvaloniaX11Platform
+    class AvaloniaX11Platform : IWindowingPlatform
     {
+        private Lazy<KeyboardDevice> _keyboardDevice = new Lazy<KeyboardDevice>(() => new KeyboardDevice());
+        private Lazy<MouseDevice> _mouseDevice = new Lazy<MouseDevice>(() => new MouseDevice());
+        public KeyboardDevice KeyboardDevice => _keyboardDevice.Value;
+        public MouseDevice MouseDevice => _mouseDevice.Value;
+        public Dictionary<IntPtr, Action<XEvent>> Windows = new Dictionary<IntPtr, Action<XEvent>>();
+        public X11Info Info { get; private set; }
         public void Initialize()
         {
+            XInitThreads();
             Display = XOpenDisplay(IntPtr.Zero);
             DeferredDisplay = XOpenDisplay(IntPtr.Zero);
             if (Display == IntPtr.Zero)
                 throw new Exception("XOpenDisplay failed");
-
+            XError.Init();
+            Info = new X11Info(Display, DeferredDisplay);
 
             AvaloniaLocator.CurrentMutable.BindToSelf(this)
-                .Bind<IPlatformThreadingInterface>().ToConstant(new X11PlatformThreading(Display));
+                .Bind<IWindowingPlatform>().ToConstant(this)
+                .Bind<IPlatformThreadingInterface>().ToConstant(new X11PlatformThreading(Display, Windows))
+                .Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
+                .Bind<IRenderLoop>().ToConstant(new RenderLoop())
+                .Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Control))
+                .Bind<IKeyboardDevice>().ToFunc(() => KeyboardDevice)
+                .Bind<IStandardCursorFactory>().ToConstant(new CursorFactoryStub())
+                .Bind<IClipboard>().ToSingleton<ClipboardStub>()
+                .Bind<IPlatformSettings>().ToConstant(new PlatformSettingsStub())
+                .Bind<ISystemDialogImpl>().ToConstant(new SystemDialogsStub())
+                .Bind<IPlatformIconLoader>().ToConstant(new IconLoaderStub());
+            EglGlPlatformFeature.TryInitialize();
 
         }
 
         public IntPtr DeferredDisplay { get; set; }
         public IntPtr Display { get; set; }
+        public IWindowImpl CreateWindow()
+        {
+            return new X11Window(this, false);
+        }
+
+        public IEmbeddableWindowImpl CreateEmbeddableWindow()
+        {
+            throw new NotSupportedException();
+        }
+
+        public IPopupImpl CreatePopup()
+        {
+            return new X11Window(this, true);
+        }
     }
 }
 
@@ -34,6 +73,8 @@ namespace Avalonia
             builder.UseWindowingSubsystem(() => new AvaloniaX11Platform().Initialize());
             return builder;
         }
+
+        public static void InitializeX11Platform() => new AvaloniaX11Platform().Initialize();
     }
 
 }

+ 18 - 6
src/Avalonia.X11/X11PlatformThreading.cs

@@ -9,9 +9,10 @@ using static Avalonia.X11.XLib;
 
 namespace Avalonia.X11
 {
-    public unsafe class X11PlatformThreading : IPlatformThreadingInterface
+    unsafe class X11PlatformThreading : IPlatformThreadingInterface
     {
         private readonly IntPtr _display;
+        private readonly Dictionary<IntPtr, Action<XEvent>> _eventHandlers;
         private Thread _mainThread;
 
         [StructLayout(LayoutKind.Explicit)]
@@ -102,9 +103,10 @@ namespace Avalonia.X11
 
         List<X11Timer> _timers = new List<X11Timer>();
         
-        public X11PlatformThreading(IntPtr display)
+        public X11PlatformThreading(IntPtr display, Dictionary<IntPtr, Action<XEvent>> eventHandlers)
         {
             _display = display;
+            _eventHandlers = eventHandlers;
             _mainThread = Thread.CurrentThread;
             var fd = XLib.XConnectionNumber(display);
             var ev = new epoll_event()
@@ -202,12 +204,22 @@ namespace Avalonia.X11
                     }
                     else
                     {
-                        while (XPending(_display))
+                        while (true)
                         {
-                            if (cancellationToken.IsCancellationRequested)
-                                return;
-                            XNextEvent(_display, out var xev);
+                            var pending = XPending(_display);
+                            if (pending == 0)
+                                break;
+                            while (pending > 0)
+                            {
+                                if (cancellationToken.IsCancellationRequested)
+                                    return;
+                                XNextEvent(_display, out var xev);
+                                pending--;
+                                if (_eventHandlers.TryGetValue(xev.AnyEvent.window, out var handler))
+                                    handler(xev);
+                            }
                         }
+                        Dispatcher.UIThread.RunJobs();
                     }
                 }
             }

+ 1815 - 0
src/Avalonia.X11/X11Structs.cs

@@ -0,0 +1,1815 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software",, to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004 Novell, Inc.
+//
+// Authors:
+//	Peter Bartok	[email protected]
+//
+
+
+// NOT COMPLETE
+
+using System;
+using System.ComponentModel;
+using System.Collections;
+using System.Drawing;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+// ReSharper disable FieldCanBeMadeReadOnly.Global
+// ReSharper disable IdentifierTypo
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+// ReSharper disable CommentTypo
+// ReSharper disable ArrangeThisQualifier
+// ReSharper disable NotAccessedField.Global
+#pragma warning disable 649
+
+namespace Avalonia.X11 {
+	//
+	// In the structures below, fields of type long are mapped to IntPtr.
+	// This will work on all platforms where sizeof(long)==sizeof(void*), which
+	// is almost all platforms except WIN64.
+	//
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XAnyEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XKeyEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		root;
+		internal IntPtr		subwindow;
+		internal IntPtr		time;
+		internal int		x;
+		internal int		y;
+		internal int		x_root;
+		internal int		y_root;
+		internal int		state;
+		internal int		keycode;
+		internal bool		same_screen;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XButtonEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		root;
+		internal IntPtr		subwindow;
+		internal IntPtr		time;
+		internal int		x;
+		internal int		y;
+		internal int		x_root;
+		internal int		y_root;
+		internal XModifierMask		state;
+		internal int		button;
+		internal bool		same_screen;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XMotionEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		root;
+		internal IntPtr		subwindow;
+		internal IntPtr		time;
+		internal int		x;
+		internal int		y;
+		internal int		x_root;
+		internal int		y_root;
+		internal XModifierMask		state;
+		internal byte		is_hint;
+		internal bool		same_screen;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XCrossingEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		root;
+		internal IntPtr		subwindow;
+		internal IntPtr		time;
+		internal int		x;
+		internal int		y;
+		internal int		x_root;
+		internal int		y_root;
+		internal NotifyMode	mode;
+		internal NotifyDetail	detail;
+		internal bool		same_screen;
+		internal bool		focus;
+		internal int		state;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XFocusChangeEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal int		mode;
+		internal NotifyDetail	detail;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XKeymapEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal byte		key_vector0;
+		internal byte		key_vector1;
+		internal byte		key_vector2;
+		internal byte		key_vector3;
+		internal byte		key_vector4;
+		internal byte		key_vector5;
+		internal byte		key_vector6;
+		internal byte		key_vector7;
+		internal byte		key_vector8;
+		internal byte		key_vector9;
+		internal byte		key_vector10;
+		internal byte		key_vector11;
+		internal byte		key_vector12;
+		internal byte		key_vector13;
+		internal byte		key_vector14;
+		internal byte		key_vector15;
+		internal byte		key_vector16;
+		internal byte		key_vector17;
+		internal byte		key_vector18;
+		internal byte		key_vector19;
+		internal byte		key_vector20;
+		internal byte		key_vector21;
+		internal byte		key_vector22;
+		internal byte		key_vector23;
+		internal byte		key_vector24;
+		internal byte		key_vector25;
+		internal byte		key_vector26;
+		internal byte		key_vector27;
+		internal byte		key_vector28;
+		internal byte		key_vector29;
+		internal byte		key_vector30;
+		internal byte		key_vector31;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XExposeEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal int		x;
+		internal int		y;
+		internal int		width;
+		internal int		height;
+		internal int		count;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XGraphicsExposeEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		drawable;
+		internal int		x;
+		internal int		y;
+		internal int		width;
+		internal int		height;
+		internal int		count;
+		internal int		major_code;
+		internal int		minor_code;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XNoExposeEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		drawable;
+		internal int		major_code;
+		internal int		minor_code;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XVisibilityEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal int		state;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XCreateWindowEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		parent;
+		internal IntPtr		window;
+		internal int		x;
+		internal int		y;
+		internal int		width;
+		internal int		height;
+		internal int		border_width;
+		internal bool		override_redirect;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XDestroyWindowEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		xevent;
+		internal IntPtr		window;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XUnmapEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		xevent;
+		internal IntPtr		window;
+		internal bool		from_configure;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XMapEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		xevent;
+		internal IntPtr		window;
+		internal bool		override_redirect;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XMapRequestEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		parent;
+		internal IntPtr		window;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XReparentEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		xevent;
+		internal IntPtr		window;
+		internal IntPtr		parent;
+		internal int		x;
+		internal int		y;
+		internal bool		override_redirect;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XConfigureEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		xevent;
+		internal IntPtr		window;
+		internal int		x;
+		internal int		y;
+		internal int		width;
+		internal int		height;
+		internal int		border_width;
+		internal IntPtr		above;
+		internal bool		override_redirect;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XGravityEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		xevent;
+		internal IntPtr		window;
+		internal int		x;
+		internal int		y;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XResizeRequestEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal int		width;
+		internal int		height;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XConfigureRequestEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		parent;
+		internal IntPtr		window;
+		internal int		x;
+		internal int		y;
+		internal int		width;
+		internal int		height;
+		internal int		border_width;
+		internal IntPtr		above;
+		internal int		detail;
+		internal IntPtr		value_mask;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XCirculateEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		xevent;
+		internal IntPtr		window;
+		internal int		place;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XCirculateRequestEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		parent;
+		internal IntPtr		window;
+		internal int		place;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XPropertyEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		atom;
+		internal IntPtr		time;
+		internal int		state;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XSelectionClearEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		selection;
+		internal IntPtr		time;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XSelectionRequestEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		owner;
+		internal IntPtr		requestor;
+		internal IntPtr		selection;
+		internal IntPtr		target;
+		internal IntPtr		property;
+		internal IntPtr		time;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XSelectionEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		requestor;
+		internal IntPtr		selection;
+		internal IntPtr		target;
+		internal IntPtr		property;
+		internal IntPtr		time;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XColormapEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		colormap;
+		internal bool		c_new;
+		internal int		state;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XClientMessageEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal IntPtr		message_type;
+		internal int		format;
+		internal IntPtr		ptr1;
+		internal IntPtr		ptr2;
+		internal IntPtr		ptr3;
+		internal IntPtr		ptr4;
+		internal IntPtr		ptr5;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XMappingEvent {
+		internal XEventName	type;
+		internal IntPtr		serial;
+		internal bool		send_event;
+		internal IntPtr		display;
+		internal IntPtr		window;
+		internal int		request;
+		internal int		first_keycode;
+		internal int		count;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XErrorEvent {
+		internal XEventName	type;
+		internal IntPtr		display;
+		internal IntPtr		resourceid;
+		internal IntPtr		serial;
+		internal byte		error_code;
+		internal XRequest	request_code;
+		internal byte		minor_code;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XEventPad {
+		internal IntPtr pad0;
+		internal IntPtr pad1;
+		internal IntPtr pad2;
+		internal IntPtr pad3;
+		internal IntPtr pad4;
+		internal IntPtr pad5;
+		internal IntPtr pad6;
+		internal IntPtr pad7;
+		internal IntPtr pad8;
+		internal IntPtr pad9;
+		internal IntPtr pad10;
+		internal IntPtr pad11;
+		internal IntPtr pad12;
+		internal IntPtr pad13;
+		internal IntPtr pad14;
+		internal IntPtr pad15;
+		internal IntPtr pad16;
+		internal IntPtr pad17;
+		internal IntPtr pad18;
+		internal IntPtr pad19;
+		internal IntPtr pad20;
+		internal IntPtr pad21;
+		internal IntPtr pad22;
+		internal IntPtr pad23;
+	}
+
+	[StructLayout(LayoutKind.Explicit)]
+	internal struct XEvent {
+		[ FieldOffset(0) ] internal XEventName type;
+		[ FieldOffset(0) ] internal XAnyEvent AnyEvent;
+		[ FieldOffset(0) ] internal XKeyEvent KeyEvent;
+		[ FieldOffset(0) ] internal XButtonEvent ButtonEvent;
+		[ FieldOffset(0) ] internal XMotionEvent MotionEvent;
+		[ FieldOffset(0) ] internal XCrossingEvent CrossingEvent;
+		[ FieldOffset(0) ] internal XFocusChangeEvent FocusChangeEvent;
+		[ FieldOffset(0) ] internal XExposeEvent ExposeEvent;
+		[ FieldOffset(0) ] internal XGraphicsExposeEvent GraphicsExposeEvent;
+		[ FieldOffset(0) ] internal XNoExposeEvent NoExposeEvent;
+		[ FieldOffset(0) ] internal XVisibilityEvent VisibilityEvent;
+		[ FieldOffset(0) ] internal XCreateWindowEvent CreateWindowEvent;
+		[ FieldOffset(0) ] internal XDestroyWindowEvent DestroyWindowEvent;
+		[ FieldOffset(0) ] internal XUnmapEvent UnmapEvent;
+		[ FieldOffset(0) ] internal XMapEvent MapEvent;
+		[ FieldOffset(0) ] internal XMapRequestEvent MapRequestEvent;
+		[ FieldOffset(0) ] internal XReparentEvent ReparentEvent;
+		[ FieldOffset(0) ] internal XConfigureEvent ConfigureEvent;
+		[ FieldOffset(0) ] internal XGravityEvent GravityEvent;
+		[ FieldOffset(0) ] internal XResizeRequestEvent ResizeRequestEvent;
+		[ FieldOffset(0) ] internal XConfigureRequestEvent ConfigureRequestEvent;
+		[ FieldOffset(0) ] internal XCirculateEvent CirculateEvent;
+		[ FieldOffset(0) ] internal XCirculateRequestEvent CirculateRequestEvent;
+		[ FieldOffset(0) ] internal XPropertyEvent PropertyEvent;
+		[ FieldOffset(0) ] internal XSelectionClearEvent SelectionClearEvent;
+		[ FieldOffset(0) ] internal XSelectionRequestEvent SelectionRequestEvent;
+		[ FieldOffset(0) ] internal XSelectionEvent SelectionEvent;
+		[ FieldOffset(0) ] internal XColormapEvent ColormapEvent;
+		[ FieldOffset(0) ] internal XClientMessageEvent ClientMessageEvent;
+		[ FieldOffset(0) ] internal XMappingEvent MappingEvent;
+		[ FieldOffset(0) ] internal XErrorEvent ErrorEvent;
+		[ FieldOffset(0) ] internal XKeymapEvent KeymapEvent;
+
+		//[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=24)]
+		//[ FieldOffset(0) ] internal int[] pad;
+		[ FieldOffset(0) ] internal XEventPad Pad;
+		public override string ToString() {
+			switch (type)
+			{
+				case XEventName.ButtonPress:
+				case XEventName.ButtonRelease:
+					return ToString (ButtonEvent);
+				case XEventName.CirculateNotify:
+				case XEventName.CirculateRequest:
+					return ToString (CirculateEvent);
+				case XEventName.ClientMessage:
+					return ToString (ClientMessageEvent);
+				case XEventName.ColormapNotify:
+					return ToString (ColormapEvent);
+				case XEventName.ConfigureNotify:
+					return ToString (ConfigureEvent);
+				case XEventName.ConfigureRequest:
+					return ToString (ConfigureRequestEvent);
+				case XEventName.CreateNotify:
+					return ToString (CreateWindowEvent);
+				case XEventName.DestroyNotify:
+					return ToString (DestroyWindowEvent);
+				case XEventName.Expose:
+					return ToString (ExposeEvent);
+				case XEventName.FocusIn:
+				case XEventName.FocusOut:
+					return ToString (FocusChangeEvent);
+				case XEventName.GraphicsExpose:
+					return ToString (GraphicsExposeEvent);
+				case XEventName.GravityNotify:
+					return ToString (GravityEvent);
+				case XEventName.KeymapNotify:
+					return ToString (KeymapEvent);
+				case XEventName.MapNotify:
+					return ToString (MapEvent);
+				case XEventName.MappingNotify:
+					return ToString (MappingEvent);
+				case XEventName.MapRequest:
+					return ToString (MapRequestEvent);
+				case XEventName.MotionNotify:
+					return ToString (MotionEvent);
+				case XEventName.NoExpose:
+					return ToString (NoExposeEvent);
+				case XEventName.PropertyNotify:
+					return ToString (PropertyEvent);
+				case XEventName.ReparentNotify:
+					return ToString (ReparentEvent);
+				case XEventName.ResizeRequest:
+					return ToString (ResizeRequestEvent);
+				case XEventName.SelectionClear:
+					return ToString (SelectionClearEvent);
+				case XEventName.SelectionNotify:
+					return ToString (SelectionEvent);
+				case XEventName.SelectionRequest:
+					return ToString (SelectionRequestEvent);
+				case XEventName.UnmapNotify:
+					return ToString (UnmapEvent);
+				case XEventName.VisibilityNotify:
+					return ToString (VisibilityEvent);
+				case XEventName.EnterNotify:
+				case XEventName.LeaveNotify:
+					return ToString (CrossingEvent);
+				default:
+					return type.ToString ();
+			}
+		}
+		
+		public static string ToString (object ev)
+		{
+			string result = string.Empty;
+			Type type = ev.GetType ();
+			FieldInfo [] fields = type.GetFields (System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance);
+			for (int i = 0; i < fields.Length; i++) {
+				if (result != string.Empty) {
+					result += ", ";
+				}
+				object value = fields [i].GetValue (ev);
+				result += fields [i].Name + "=" + (value == null ? "<null>" : value.ToString ());
+			}
+			return type.Name + " (" + result + ")";
+		}
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XSetWindowAttributes {
+		internal IntPtr		background_pixmap;
+		internal IntPtr		background_pixel;
+		internal IntPtr		border_pixmap;
+		internal IntPtr		border_pixel;
+		internal Gravity	bit_gravity;
+		internal Gravity	win_gravity;
+		internal int		backing_store;
+		internal IntPtr		backing_planes;
+		internal IntPtr		backing_pixel;
+		internal bool		save_under;
+		internal IntPtr		event_mask;
+		internal IntPtr		do_not_propagate_mask;
+		internal bool		override_redirect;
+		internal IntPtr		colormap;
+		internal IntPtr		cursor;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XWindowAttributes {
+		internal int		x;
+		internal int		y;
+		internal int		width;
+		internal int		height;
+		internal int		border_width;
+		internal int		depth;
+		internal IntPtr		visual;
+		internal IntPtr		root;
+		internal int		c_class;
+		internal Gravity	bit_gravity;
+		internal Gravity	win_gravity;
+		internal int		backing_store;
+		internal IntPtr		backing_planes;
+		internal IntPtr		backing_pixel;
+		internal bool		save_under;
+		internal IntPtr		colormap;
+		internal bool		map_installed;
+		internal MapState	map_state;
+		internal IntPtr		all_event_masks;
+		internal IntPtr		your_event_mask;
+		internal IntPtr		do_not_propagate_mask;
+		internal bool		override_direct;
+		internal IntPtr		screen;
+
+		public override string ToString ()
+		{
+			return XEvent.ToString (this);
+		}
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XTextProperty {
+		internal string		value;
+		internal IntPtr		encoding;
+		internal int		format;
+		internal IntPtr		nitems;
+	}
+
+	internal enum XWindowClass {
+		InputOutput	= 1,
+		InputOnly	= 2
+	}
+
+	internal enum XEventName {
+		KeyPress                = 2,
+		KeyRelease              = 3,
+		ButtonPress             = 4,
+		ButtonRelease           = 5,
+		MotionNotify            = 6,
+		EnterNotify             = 7,
+		LeaveNotify             = 8,
+		FocusIn                 = 9,
+		FocusOut                = 10,
+		KeymapNotify            = 11,
+		Expose                  = 12,
+		GraphicsExpose          = 13,
+		NoExpose                = 14,
+		VisibilityNotify        = 15,
+		CreateNotify            = 16,
+		DestroyNotify           = 17,
+		UnmapNotify             = 18,
+		MapNotify               = 19,
+		MapRequest              = 20,
+		ReparentNotify          = 21,
+		ConfigureNotify         = 22,
+		ConfigureRequest        = 23,
+		GravityNotify           = 24,
+		ResizeRequest           = 25,
+		CirculateNotify         = 26,
+		CirculateRequest        = 27,
+		PropertyNotify          = 28,
+		SelectionClear          = 29,
+		SelectionRequest        = 30,
+		SelectionNotify         = 31,
+		ColormapNotify          = 32,
+		ClientMessage		= 33,
+		MappingNotify		= 34,
+
+		LASTEvent
+	}
+
+	[Flags]
+	internal enum SetWindowValuemask {
+		Nothing		= 0,
+		BackPixmap	= 1,
+		BackPixel	= 2,
+		BorderPixmap	= 4,
+		BorderPixel	= 8,
+		BitGravity	= 16,
+		WinGravity	= 32,
+		BackingStore	= 64,
+		BackingPlanes	= 128,
+		BackingPixel	= 256,
+		OverrideRedirect = 512,
+		SaveUnder	= 1024,
+		EventMask	= 2048,
+		DontPropagate	= 4096,
+		ColorMap	= 8192,
+		Cursor		= 16384
+	}
+	
+	internal enum SendEventValues {
+		PointerWindow = 0,
+		InputFocus = 1
+	}
+
+	internal enum CreateWindowArgs {
+		CopyFromParent	= 0,
+		ParentRelative	= 1,
+		InputOutput	= 1,
+		InputOnly	= 2
+	}
+
+	internal enum Gravity {
+		ForgetGravity	= 0,
+		NorthWestGravity= 1,
+		NorthGravity	= 2,
+		NorthEastGravity= 3,
+		WestGravity	= 4,
+		CenterGravity	= 5,
+		EastGravity	= 6,
+		SouthWestGravity= 7,
+		SouthGravity	= 8,
+		SouthEastGravity= 9,
+		StaticGravity	= 10
+	}
+
+	internal enum XKeySym : uint {
+		XK_BackSpace	= 0xFF08,
+		XK_Tab		= 0xFF09,
+		XK_Clear	= 0xFF0B,
+		XK_Return	= 0xFF0D,
+		XK_Home		= 0xFF50,
+		XK_Left		= 0xFF51,
+		XK_Up		= 0xFF52,
+		XK_Right	= 0xFF53,
+		XK_Down		= 0xFF54,
+		XK_Page_Up	= 0xFF55,
+		XK_Page_Down	= 0xFF56,
+		XK_End		= 0xFF57,
+		XK_Begin	= 0xFF58,
+		XK_Menu		= 0xFF67,
+		XK_Shift_L	= 0xFFE1,
+		XK_Shift_R	= 0xFFE2,
+		XK_Control_L	= 0xFFE3,
+		XK_Control_R	= 0xFFE4,
+		XK_Caps_Lock	= 0xFFE5,
+		XK_Shift_Lock	= 0xFFE6,	
+		XK_Meta_L	= 0xFFE7,
+		XK_Meta_R	= 0xFFE8,
+		XK_Alt_L	= 0xFFE9,
+		XK_Alt_R	= 0xFFEA,
+		XK_Super_L	= 0xFFEB,
+		XK_Super_R	= 0xFFEC,
+		XK_Hyper_L	= 0xFFED,
+		XK_Hyper_R	= 0xFFEE,
+	}
+
+	[Flags]
+	internal enum EventMask {
+		NoEventMask		= 0,
+		KeyPressMask		= 1<<0,
+		KeyReleaseMask		= 1<<1,
+		ButtonPressMask		= 1<<2,
+		ButtonReleaseMask	= 1<<3,
+		EnterWindowMask		= 1<<4,
+		LeaveWindowMask		= 1<<5,
+		PointerMotionMask	= 1<<6,
+		PointerMotionHintMask	= 1<<7,
+		Button1MotionMask	= 1<<8,
+		Button2MotionMask	= 1<<9,
+		Button3MotionMask	= 1<<10,
+		Button4MotionMask	= 1<<11,
+		Button5MotionMask	= 1<<12,
+		ButtonMotionMask	= 1<<13,
+		KeymapStateMask		= 1<<14,
+		ExposureMask		= 1<<15,
+		VisibilityChangeMask	= 1<<16,
+		StructureNotifyMask	= 1<<17,
+		ResizeRedirectMask	= 1<<18,
+		SubstructureNotifyMask	= 1<<19,
+		SubstructureRedirectMask= 1<<20,
+		FocusChangeMask		= 1<<21,
+		PropertyChangeMask	= 1<<22,
+		ColormapChangeMask	= 1<<23,
+		OwnerGrabButtonMask	= 1<<24
+	}
+
+	internal enum GrabMode {
+		GrabModeSync		= 0,
+		GrabModeAsync		= 1
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XStandardColormap {
+		internal IntPtr		colormap;
+		internal IntPtr		red_max;
+		internal IntPtr		red_mult;
+		internal IntPtr		green_max;
+		internal IntPtr		green_mult;
+		internal IntPtr		blue_max;
+		internal IntPtr		blue_mult;
+		internal IntPtr		base_pixel;
+		internal IntPtr		visualid;
+		internal IntPtr		killid;
+	}
+
+	[StructLayout(LayoutKind.Sequential, Pack=2)]
+	internal struct XColor {
+		internal IntPtr		pixel;
+		internal ushort		red;
+		internal ushort		green;
+		internal ushort		blue;
+		internal byte		flags;
+		internal byte		pad;
+	}
+
+	internal enum Atom {
+		AnyPropertyType		= 0,
+		XA_PRIMARY		= 1,
+		XA_SECONDARY		= 2,
+		XA_ARC			= 3,
+		XA_ATOM			= 4,
+		XA_BITMAP		= 5,
+		XA_CARDINAL		= 6,
+		XA_COLORMAP		= 7,
+		XA_CURSOR		= 8,
+		XA_CUT_BUFFER0		= 9,
+		XA_CUT_BUFFER1		= 10,
+		XA_CUT_BUFFER2		= 11,
+		XA_CUT_BUFFER3		= 12,
+		XA_CUT_BUFFER4		= 13,
+		XA_CUT_BUFFER5		= 14,
+		XA_CUT_BUFFER6		= 15,
+		XA_CUT_BUFFER7		= 16,
+		XA_DRAWABLE		= 17,
+		XA_FONT			= 18,
+		XA_INTEGER		= 19,
+		XA_PIXMAP		= 20,
+		XA_POINT		= 21,
+		XA_RECTANGLE		= 22,
+		XA_RESOURCE_MANAGER	= 23,
+		XA_RGB_COLOR_MAP	= 24,
+		XA_RGB_BEST_MAP		= 25,
+		XA_RGB_BLUE_MAP		= 26,
+		XA_RGB_DEFAULT_MAP	= 27,
+		XA_RGB_GRAY_MAP		= 28,
+		XA_RGB_GREEN_MAP	= 29,
+		XA_RGB_RED_MAP		= 30,
+		XA_STRING		= 31,
+		XA_VISUALID		= 32,
+		XA_WINDOW		= 33,
+		XA_WM_COMMAND		= 34,
+		XA_WM_HINTS		= 35,
+		XA_WM_CLIENT_MACHINE	= 36,
+		XA_WM_ICON_NAME		= 37,
+		XA_WM_ICON_SIZE		= 38,
+		XA_WM_NAME		= 39,
+		XA_WM_NORMAL_HINTS	= 40,
+		XA_WM_SIZE_HINTS	= 41,
+		XA_WM_ZOOM_HINTS	= 42,
+		XA_MIN_SPACE		= 43,
+		XA_NORM_SPACE		= 44,
+		XA_MAX_SPACE		= 45,
+		XA_END_SPACE		= 46,
+		XA_SUPERSCRIPT_X	= 47,
+		XA_SUPERSCRIPT_Y	= 48,
+		XA_SUBSCRIPT_X		= 49,
+		XA_SUBSCRIPT_Y		= 50,
+		XA_UNDERLINE_POSITION	= 51,
+		XA_UNDERLINE_THICKNESS	= 52,
+		XA_STRIKEOUT_ASCENT	= 53,
+		XA_STRIKEOUT_DESCENT	= 54,
+		XA_ITALIC_ANGLE		= 55,
+		XA_X_HEIGHT		= 56,
+		XA_QUAD_WIDTH		= 57,
+		XA_WEIGHT		= 58,
+		XA_POINT_SIZE		= 59,
+		XA_RESOLUTION		= 60,
+		XA_COPYRIGHT		= 61,
+		XA_NOTICE		= 62,
+		XA_FONT_NAME		= 63,
+		XA_FAMILY_NAME		= 64,
+		XA_FULL_NAME		= 65,
+		XA_CAP_HEIGHT		= 66,
+		XA_WM_CLASS		= 67,
+		XA_WM_TRANSIENT_FOR	= 68,
+
+		XA_LAST_PREDEFINED	= 68
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XScreen {
+		internal IntPtr		ext_data;
+		internal IntPtr		display;
+		internal IntPtr		root;
+		internal int		width;
+		internal int		height;
+		internal int		mwidth;
+		internal int		mheight;
+		internal int		ndepths;
+		internal IntPtr		depths;
+		internal int		root_depth;
+		internal IntPtr		root_visual;
+		internal IntPtr		default_gc;
+		internal IntPtr		cmap;
+		internal IntPtr		white_pixel;
+		internal IntPtr		black_pixel;
+		internal int		max_maps;
+		internal int		min_maps;
+		internal int		backing_store;
+		internal bool		save_unders;
+		internal IntPtr	    root_input_mask;
+	}
+
+	[Flags]
+	internal enum ChangeWindowFlags {
+		CWX			= 1<<0,
+		CWY			= 1<<1,
+		CWWidth			= 1<<2,
+		CWHeight		= 1<<3,
+		CWBorderWidth		= 1<<4,
+		CWSibling		= 1<<5,
+		CWStackMode		= 1<<6
+	}
+
+	internal enum StackMode {
+		Above			= 0,
+		Below			= 1,
+		TopIf			= 2,
+		BottomIf		= 3,
+		Opposite		= 4
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XWindowChanges {
+		internal int		x;
+		internal int		y;
+		internal int		width;
+		internal int		height;
+		internal int		border_width;
+		internal IntPtr		sibling;
+		internal StackMode	stack_mode;
+	}	
+
+	[Flags]
+	internal enum ColorFlags {
+		DoRed			= 1<<0,
+		DoGreen			= 1<<1,
+		DoBlue			= 1<<2
+	}
+
+	internal enum NotifyMode {
+		NotifyNormal		= 0,
+		NotifyGrab		= 1,
+		NotifyUngrab		= 2
+	}
+
+	internal enum NotifyDetail {
+		NotifyAncestor		= 0,
+		NotifyVirtual		= 1,
+		NotifyInferior		= 2,
+		NotifyNonlinear		= 3,
+		NotifyNonlinearVirtual	= 4,
+		NotifyPointer		= 5,
+		NotifyPointerRoot	= 6,
+		NotifyDetailNone	= 7
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct MotifWmHints {
+		internal IntPtr		flags;
+		internal IntPtr		functions;
+		internal IntPtr	    decorations;
+		internal IntPtr		input_mode;
+		internal IntPtr		status;
+
+		public override string ToString ()
+		{
+			return string.Format("MotifWmHints <flags={0}, functions={1}, decorations={2}, input_mode={3}, status={4}", (MotifFlags) flags.ToInt32 (), (MotifFunctions) functions.ToInt32 (), (MotifDecorations) decorations.ToInt32 (), (MotifInputMode) input_mode.ToInt32 (), status.ToInt32 ());
+		}
+	}
+
+	[Flags]
+	internal enum MotifFlags {
+		Functions		= 1,
+		Decorations		= 2,
+		InputMode		= 4,
+		Status			= 8
+	}
+
+	[Flags]
+	internal enum MotifFunctions {
+		All			= 0x01,
+		Resize			= 0x02,
+		Move			= 0x04,
+		Minimize		= 0x08,
+		Maximize		= 0x10,
+		Close			= 0x20
+	}
+
+	[Flags]
+	internal enum MotifDecorations {
+		All			= 0x01,
+		Border			= 0x02,
+		ResizeH			= 0x04,
+		Title			= 0x08,
+		Menu			= 0x10,
+		Minimize		= 0x20,
+		Maximize		= 0x40,
+		
+	}
+
+	[Flags]
+	internal enum MotifInputMode {
+		Modeless		= 0,
+		ApplicationModal	= 1,
+		SystemModal		= 2,
+		FullApplicationModal	= 3
+	}
+
+	[Flags]
+	internal enum KeyMasks {
+		ShiftMask		= (1 << 0),
+		LockMask		= (1 << 1),
+		ControlMask		= (1 << 2),
+		Mod1Mask		= (1 << 3),
+		Mod2Mask		= (1 << 4),
+		Mod3Mask		= (1 << 5),
+		Mod4Mask		= (1 << 6),
+		Mod5Mask		= (1 << 7),
+
+		ModMasks		= Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask
+	}
+
+	[Flags]
+	internal enum MouseKeyMasks {
+		Button1Mask		= (1 << 8),
+		Button2Mask		= (1 << 9),
+		Button3Mask		= (1 << 10),
+		Button4Mask		= (1 << 11),
+		Button5Mask		= (1 << 12),
+	}
+
+	[StructLayout (LayoutKind.Sequential)]
+	internal struct XModifierKeymap {
+		public int max_keypermod;
+		public IntPtr modifiermap;
+	} 
+
+	internal enum PropertyMode {
+		Replace			= 0,
+		Prepend			= 1,
+		Append			= 2
+	}
+
+	[StructLayout (LayoutKind.Sequential)]
+	internal struct XKeyBoardState {
+		public int key_click_percent;
+		public int bell_percent;
+		public uint bell_pitch, bell_duration;
+		public IntPtr led_mask;
+		public int global_auto_repeat;
+		public AutoRepeats auto_repeats;
+
+		[StructLayout (LayoutKind.Explicit)]
+			public struct AutoRepeats {
+			[FieldOffset (0)]
+			public byte first;
+				
+			[FieldOffset (31)]
+			public byte last;
+		}
+	}
+
+	[Flags]
+	internal enum GCFunction {
+		GCFunction              = 1<<0,
+		GCPlaneMask             = 1<<1,
+		GCForeground            = 1<<2,
+		GCBackground            = 1<<3,
+		GCLineWidth             = 1<<4,
+		GCLineStyle             = 1<<5,
+		GCCapStyle              = 1<<6,
+		GCJoinStyle             = 1<<7,
+		GCFillStyle             = 1<<8,
+		GCFillRule              = 1<<9, 
+		GCTile                  = 1<<10,
+		GCStipple               = 1<<11,
+		GCTileStipXOrigin       = 1<<12,
+		GCTileStipYOrigin       = 1<<13,
+		GCFont                  = 1<<14,
+		GCSubwindowMode         = 1<<15,
+		GCGraphicsExposures     = 1<<16,
+		GCClipXOrigin           = 1<<17,
+		GCClipYOrigin           = 1<<18,
+		GCClipMask              = 1<<19,
+		GCDashOffset            = 1<<20,
+		GCDashList              = 1<<21,
+		GCArcMode               = 1<<22
+	}
+
+	internal enum GCJoinStyle {
+		JoinMiter		= 0,
+		JoinRound		= 1,
+		JoinBevel		= 2
+	}
+
+	internal enum GCLineStyle {
+		LineSolid		= 0,
+		LineOnOffDash		= 1,
+		LineDoubleDash		= 2
+	}
+
+	internal enum GCCapStyle {
+		CapNotLast		= 0,
+		CapButt			= 1,
+		CapRound		= 2,
+		CapProjecting		= 3
+	}
+
+	internal enum GCFillStyle {
+		FillSolid		= 0,
+		FillTiled		= 1,
+		FillStippled		= 2,
+		FillOpaqueStppled	= 3
+	}
+
+	internal enum GCFillRule {
+		EvenOddRule		= 0,
+		WindingRule		= 1
+	}
+
+	internal enum GCArcMode {
+		ArcChord		= 0,
+		ArcPieSlice		= 1
+	}
+
+	internal enum GCSubwindowMode {
+		ClipByChildren		= 0,
+		IncludeInferiors	= 1
+	}
+
+	[StructLayout (LayoutKind.Sequential)]
+	internal struct XGCValues {
+		internal GXFunction		function;
+		internal IntPtr			plane_mask;
+		internal IntPtr			foreground;
+		internal IntPtr			background;
+		internal int			line_width;
+		internal GCLineStyle		line_style;
+		internal GCCapStyle		cap_style;
+		internal GCJoinStyle		join_style;
+		internal GCFillStyle		fill_style;
+		internal GCFillRule		fill_rule;
+		internal GCArcMode		arc_mode;
+		internal IntPtr			tile;
+		internal IntPtr			stipple;
+		internal int			ts_x_origin;
+		internal int			ts_y_origin;
+		internal IntPtr			font;
+		internal GCSubwindowMode	subwindow_mode;
+		internal bool			graphics_exposures;
+		internal int			clip_x_origin;
+		internal int			clib_y_origin;
+		internal IntPtr			clip_mask;
+		internal int			dash_offset;
+		internal byte			dashes;
+	}
+
+	internal enum GXFunction {
+		GXclear				= 0x0,		/* 0 */
+		GXand                   	= 0x1,		/* src AND dst */
+		GXandReverse            	= 0x2,		/* src AND NOT dst */
+		GXcopy                  	= 0x3,		/* src */
+		GXandInverted           	= 0x4,		/* NOT src AND dst */
+		GXnoop                  	= 0x5,		/* dst */
+		GXxor                   	= 0x6,		/* src XOR dst */
+		GXor                    	= 0x7,		/* src OR dst */
+		GXnor                   	= 0x8,		/* NOT src AND NOT dst */
+		GXequiv                 	= 0x9,		/* NOT src XOR dst */
+		GXinvert                	= 0xa,		/* NOT dst */
+		GXorReverse             	= 0xb,		/* src OR NOT dst */
+		GXcopyInverted          	= 0xc,		/* NOT src */
+		GXorInverted            	= 0xd,		/* NOT src OR dst */
+		GXnand                  	= 0xe,		/* NOT src OR NOT dst */
+		GXset                   	= 0xf		/* 1 */
+	}
+
+	internal enum NetWindowManagerState {
+		Remove				= 0,
+		Add				= 1,
+		Toggle				= 2
+	}
+
+	internal enum RevertTo {
+		None				= 0,
+		PointerRoot			= 1,
+		Parent				= 2
+	}
+
+	internal enum MapState {
+		IsUnmapped			= 0,
+		IsUnviewable			= 1,
+		IsViewable			= 2
+	}
+
+	internal enum CursorFontShape {
+		XC_X_cursor			= 0,
+		XC_arrow			= 2,
+		XC_based_arrow_down		= 4,
+		XC_based_arrow_up		= 6,
+		XC_boat				= 8,
+		XC_bogosity			= 10,
+		XC_bottom_left_corner		= 12,
+		XC_bottom_right_corner		= 14,
+		XC_bottom_side			= 16,
+		XC_bottom_tee			= 18,
+		XC_box_spiral			= 20,
+		XC_center_ptr			= 22,
+
+		XC_circle			= 24,
+		XC_clock			= 26,
+		XC_coffee_mug			= 28,
+		XC_cross			= 30,
+		XC_cross_reverse		= 32,
+		XC_crosshair			= 34,
+		XC_diamond_cross		= 36,
+		XC_dot				= 38,
+		XC_dotbox			= 40,
+		XC_double_arrow			= 42,
+		XC_draft_large			= 44,
+		XC_draft_small			= 46,
+
+		XC_draped_box			= 48,
+		XC_exchange			= 50,
+		XC_fleur			= 52,
+		XC_gobbler			= 54,
+		XC_gumby			= 56,
+		XC_hand1			= 58,
+		XC_hand2			= 60,
+		XC_heart			= 62,
+		XC_icon				= 64,
+		XC_iron_cross			= 66,
+		XC_left_ptr			= 68,
+		XC_left_side			= 70,
+
+		XC_left_tee			= 72,
+		XC_left_button			= 74,
+		XC_ll_angle			= 76,
+		XC_lr_angle			= 78,
+		XC_man				= 80,
+		XC_middlebutton			= 82,
+		XC_mouse			= 84,
+		XC_pencil			= 86,
+		XC_pirate			= 88,
+		XC_plus				= 90,
+		XC_question_arrow		= 92,
+		XC_right_ptr			= 94,
+
+		XC_right_side			= 96,
+		XC_right_tee			= 98,
+		XC_rightbutton			= 100,
+		XC_rtl_logo			= 102,
+		XC_sailboat			= 104,
+		XC_sb_down_arrow		= 106,
+		XC_sb_h_double_arrow		= 108,
+		XC_sb_left_arrow		= 110,
+		XC_sb_right_arrow		= 112,
+		XC_sb_up_arrow			= 114,
+		XC_sb_v_double_arrow		= 116,
+		XC_sb_shuttle			= 118,
+
+		XC_sizing			= 120,
+		XC_spider			= 122,
+		XC_spraycan			= 124,
+		XC_star				= 126,
+		XC_target			= 128,
+		XC_tcross			= 130,
+		XC_top_left_arrow		= 132,
+		XC_top_left_corner		= 134,
+		XC_top_right_corner		= 136,
+		XC_top_side			= 138,
+		XC_top_tee			= 140,
+		XC_trek				= 142,
+
+		XC_ul_angle			= 144,
+		XC_umbrella			= 146,
+		XC_ur_angle			= 148,
+		XC_watch			= 150,
+		XC_xterm			= 152,
+		XC_num_glyphs			= 154
+	}
+
+	internal enum SystrayRequest {
+		SYSTEM_TRAY_REQUEST_DOCK	= 0,
+		SYSTEM_TRAY_BEGIN_MESSAGE	= 1,
+		SYSTEM_TRAY_CANCEL_MESSAGE	= 2
+	}
+
+	internal enum NetWmStateRequest {
+		_NET_WM_STATE_REMOVE 		= 0,
+		_NET_WM_STATE_ADD		= 1,
+		_NET_WM_STATE_TOGGLE		= 2
+	}
+
+	internal enum NetWmMoveResize {
+		_NET_WM_MOVERESIZE_SIZE_TOPLEFT = 	0,
+		_NET_WM_MOVERESIZE_SIZE_TOP = 		1,
+		_NET_WM_MOVERESIZE_SIZE_TOPRIGHT = 	2,
+		_NET_WM_MOVERESIZE_SIZE_RIGHT = 	3,
+		_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT = 	4,
+		_NET_WM_MOVERESIZE_SIZE_BOTTOM = 	5,
+		_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT =	6,
+		_NET_WM_MOVERESIZE_SIZE_LEFT = 		7,
+		_NET_WM_MOVERESIZE_MOVE = 		8,
+		_NET_WM_MOVERESIZE_SIZE_KEYBOARD = 	9,
+		_NET_WM_MOVERESIZE_MOVE_KEYBOARD = 	10,
+		_NET_WM_MOVERESIZE_CANCEL = 		11
+	}
+
+	[Flags]
+	internal enum XSizeHintsFlags  {
+		USPosition			= (1 << 0),
+		USSize				= (1 << 1),
+		PPosition			= (1 << 2),
+		PSize				= (1 << 3),
+		PMinSize			= (1 << 4),
+		PMaxSize			= (1 << 5),
+		PResizeInc			= (1 << 6),
+		PAspect				= (1 << 7),
+		PAllHints			= (PPosition | PSize | PMinSize | PMaxSize | PResizeInc | PAspect),
+		PBaseSize			= (1 << 8),
+		PWinGravity			= (1 << 9),
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XSizeHints {
+		internal IntPtr			flags;
+		internal int			x;
+		internal int			y;
+		internal int			width;
+		internal int			height;
+		internal int			min_width;
+		internal int			min_height;
+		internal int			max_width;
+		internal int			max_height;
+		internal int			width_inc;
+		internal int			height_inc;
+		internal int			min_aspect_x;
+		internal int			min_aspect_y;
+		internal int			max_aspect_x;
+		internal int			max_aspect_y;
+		internal int			base_width;
+		internal int			base_height;
+		internal int			win_gravity;
+	}
+
+	[Flags]
+	internal enum XWMHintsFlags {
+		InputHint			= (1 << 0),
+		StateHint			= (1 << 1),
+		IconPixmapHint			= (1 << 2),
+		IconWindowHint			= (1 << 3),
+		IconPositionHint		= (1 << 4),
+		IconMaskHint			= (1 << 5),
+		WindowGroupHint			= (1 << 6),
+		AllHints			= (InputHint | StateHint | IconPixmapHint | IconWindowHint | IconPositionHint | IconMaskHint | WindowGroupHint)
+	}
+
+	internal enum XInitialState {
+		DontCareState			= 0,
+		NormalState			= 1,
+		ZoomState			= 2,
+		IconicState			= 3,
+		InactiveState			= 4
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XWMHints {
+		internal IntPtr			flags;
+		internal bool			input;
+		internal XInitialState		initial_state;
+		internal IntPtr			icon_pixmap;
+		internal IntPtr			icon_window;
+		internal int			icon_x;
+		internal int			icon_y;
+		internal IntPtr			icon_mask;
+		internal IntPtr			window_group;
+	}
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct XIconSize {
+		internal int			min_width;
+		internal int			min_height;
+		internal int			max_width;
+		internal int			max_height;
+		internal int			width_inc;
+		internal int			height_inc;
+	}
+
+	internal delegate int  XErrorHandler(IntPtr DisplayHandle, ref XErrorEvent error_event);
+
+	internal enum XRequest : byte {
+		X_CreateWindow			= 1,
+		X_ChangeWindowAttributes	= 2,
+		X_GetWindowAttributes           = 3,
+		X_DestroyWindow                 = 4,
+		X_DestroySubwindows             = 5,
+		X_ChangeSaveSet                 = 6,
+		X_ReparentWindow                = 7,
+		X_MapWindow                     = 8,
+		X_MapSubwindows                 = 9,
+		X_UnmapWindow			= 10,
+		X_UnmapSubwindows		= 11,
+		X_ConfigureWindow		= 12,
+		X_CirculateWindow		= 13,
+		X_GetGeometry			= 14,
+		X_QueryTree			= 15,
+		X_InternAtom			= 16,
+		X_GetAtomName			= 17,
+		X_ChangeProperty		= 18,
+		X_DeleteProperty		= 19,
+		X_GetProperty			= 20,
+		X_ListProperties		= 21,
+		X_SetSelectionOwner		= 22,
+		X_GetSelectionOwner		= 23,
+		X_ConvertSelection		= 24,
+		X_SendEvent			= 25,
+		X_GrabPointer			= 26,
+		X_UngrabPointer			= 27,
+		X_GrabButton			= 28,
+		X_UngrabButton			= 29,
+		X_ChangeActivePointerGrab	= 30,
+		X_GrabKeyboard			= 31,
+		X_UngrabKeyboard		= 32,
+		X_GrabKey			= 33,
+		X_UngrabKey			= 34,
+		X_AllowEvents			= 35,
+		X_GrabServer			= 36,
+		X_UngrabServer			= 37,
+		X_QueryPointer			= 38,
+		X_GetMotionEvents		= 39,
+		X_TranslateCoords		= 40,
+		X_WarpPointer			= 41,
+		X_SetInputFocus			= 42,
+		X_GetInputFocus			= 43,
+		X_QueryKeymap			= 44,
+		X_OpenFont			= 45,
+		X_CloseFont			= 46,
+		X_QueryFont			= 47,
+		X_QueryTextExtents		= 48,
+		X_ListFonts			= 49,
+		X_ListFontsWithInfo		= 50,
+		X_SetFontPath			= 51,
+		X_GetFontPath			= 52,
+		X_CreatePixmap			= 53,
+		X_FreePixmap			= 54,
+		X_CreateGC			= 55,
+		X_ChangeGC			= 56,
+		X_CopyGC			= 57,
+		X_SetDashes			= 58,
+		X_SetClipRectangles		= 59,
+		X_FreeGC			= 60,
+		X_ClearArea			= 61,
+		X_CopyArea			= 62,
+		X_CopyPlane			= 63,
+		X_PolyPoint			= 64,
+		X_PolyLine			= 65,
+		X_PolySegment			= 66,
+		X_PolyRectangle			= 67,
+		X_PolyArc			= 68,
+		X_FillPoly			= 69,
+		X_PolyFillRectangle		= 70,
+		X_PolyFillArc			= 71,
+		X_PutImage			= 72,
+		X_GetImage			= 73,
+		X_PolyText8			= 74,
+		X_PolyText16			= 75,
+		X_ImageText8			= 76,
+		X_ImageText16			= 77,
+		X_CreateColormap		= 78,
+		X_FreeColormap			= 79,
+		X_CopyColormapAndFree		= 80,
+		X_InstallColormap		= 81,
+		X_UninstallColormap		= 82,
+		X_ListInstalledColormaps	= 83,
+		X_AllocColor			= 84,
+		X_AllocNamedColor		= 85,
+		X_AllocColorCells		= 86,
+		X_AllocColorPlanes		= 87,
+		X_FreeColors			= 88,
+		X_StoreColors			= 89,
+		X_StoreNamedColor		= 90,
+		X_QueryColors			= 91,
+		X_LookupColor			= 92,
+		X_CreateCursor			= 93,
+		X_CreateGlyphCursor		= 94,
+		X_FreeCursor			= 95,
+		X_RecolorCursor			= 96,
+		X_QueryBestSize			= 97,
+		X_QueryExtension		= 98,
+		X_ListExtensions		= 99,
+		X_ChangeKeyboardMapping		= 100,
+		X_GetKeyboardMapping		= 101,
+		X_ChangeKeyboardControl		= 102,
+		X_GetKeyboardControl		= 103,
+		X_Bell				= 104,
+		X_ChangePointerControl		= 105,
+		X_GetPointerControl		= 106,
+		X_SetScreenSaver		= 107,
+		X_GetScreenSaver		= 108,
+		X_ChangeHosts			= 109,
+		X_ListHosts			= 110,
+		X_SetAccessControl		= 111,
+		X_SetCloseDownMode		= 112,
+		X_KillClient			= 113,
+		X_RotateProperties		= 114,
+		X_ForceScreenSaver		= 115,
+		X_SetPointerMapping		= 116,
+		X_GetPointerMapping		= 117,
+		X_SetModifierMapping		= 118,
+		X_GetModifierMapping		= 119,
+		X_NoOperation			= 127
+	}
+
+	[Flags]
+	internal enum XIMProperties {
+		XIMPreeditArea		= 0x0001,
+		XIMPreeditCallbacks	= 0x0002,
+		XIMPreeditPosition	= 0x0004,
+		XIMPreeditNothing	= 0x0008,
+		XIMPreeditNone		= 0x0010,
+		XIMStatusArea		= 0x0100,
+		XIMStatusCallbacks	= 0x0200,
+		XIMStatusNothing	= 0x0400,
+		XIMStatusNone		= 0x0800,
+	}
+
+	[Flags]
+	internal enum WindowType {
+		Client			= 1,
+		Whole			= 2,
+		Both			= 3
+	}
+
+	internal enum XEmbedMessage {
+		EmbeddedNotify = 0,
+		WindowActivate = 1,
+		WindowDeactivate = 2,
+		RequestFocus = 3,
+		FocusIn = 4,
+		FocusOut = 5,
+		FocusNext = 6,
+		FocusPrev = 7,
+		/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
+		ModalityOn = 10,
+		ModalityOff = 11,
+		RegisterAccelerator = 12,
+		UnregisterAccelerator = 13,
+		ActivateAccelerator = 14
+	}
+
+	[StructLayout (LayoutKind.Sequential)]
+	internal struct XcursorImage
+	{
+		private int version;
+		public int size;       /* nominal size for matching */
+		public int width;      /* actual width */
+		public int height;     /* actual height */
+		public int xhot;       /* hot spot x (must be inside image) */
+		public int yhot;       /* hot spot y (must be inside image) */
+		public int delay;       /* hot spot y (must be inside image) */
+		public IntPtr pixels;    /* pointer to pixels */
+
+		public override string ToString ()
+		{
+			return string.Format ("XCursorImage (version: {0}, size: {1}, width: {2}, height: {3}, xhot: {4}, yhot: {5}, delay: {6}, pixels: {7}", 
+				version, size, width, height, xhot, yhot, delay, pixels);
+		}
+	} ;
+
+	[StructLayout (LayoutKind.Sequential)]
+	internal struct XcursorImages
+	{
+		public int nimage;     /* number of images */
+		public IntPtr images;   /* array of XcursorImage pointers */
+	}
+
+	[StructLayout (LayoutKind.Sequential)]
+	internal struct XIMStyles
+	{
+		public ushort count_styles;
+		public IntPtr supported_styles;
+	}
+
+	[StructLayout (LayoutKind.Sequential)]
+	[Serializable]
+	internal class XPoint
+	{
+		public short X;
+		public short Y;
+	}
+
+	[StructLayout (LayoutKind.Sequential)]
+	[Serializable]
+	internal class XIMCallback
+	{
+		public IntPtr client_data;
+		public XIMProc callback;
+		[NonSerialized]
+		GCHandle gch;
+
+		public XIMCallback (IntPtr clientData, XIMProc proc)
+		{
+			this.client_data = clientData;
+			this.gch = GCHandle.Alloc (proc);
+			this.callback = proc;
+		}
+
+		~XIMCallback ()
+		{
+			gch.Free ();
+		}
+	}
+    
+    [StructLayout(LayoutKind.Sequential)]
+    public unsafe struct XImage
+    {
+        public int width, height; /* size of image */
+        public int xoffset; /* number of pixels offset in X direction */
+        public int format; /* XYBitmap, XYPixmap, ZPixmap */
+        public IntPtr data; /* pointer to image data */
+        public int byte_order; /* data byte order, LSBFirst, MSBFirst */
+        public int bitmap_unit; /* quant. of scanline 8, 16, 32 */
+        public int bitmap_bit_order; /* LSBFirst, MSBFirst */
+        public int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
+        public int depth; /* depth of image */
+        public int bytes_per_line; /* accelerator to next scanline */
+        public int bits_per_pixel; /* bits per pixel (ZPixmap) */
+        public ulong red_mask; /* bits in z arrangement */
+        public ulong green_mask;
+        public ulong blue_mask;
+        private fixed byte funcs[128];
+    }
+    
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct XVisualInfo
+    {
+        internal IntPtr visual;
+        internal IntPtr visualid;
+        internal int screen;
+        internal uint depth;
+        internal int klass;
+        internal IntPtr red_mask;
+        internal IntPtr green_mask;
+        internal IntPtr blue_mask;
+        internal int colormap_size;
+        internal int bits_per_rgb;		
+    }
+	
+	internal enum XIMFeedback
+	{
+		Reverse = 1,
+		Underline = 2,
+		Highlight = 4,
+		Primary = 32,
+		Secondary = 64,
+		Tertiary = 128,
+	}
+
+	internal struct XIMFeedbackStruct
+	{
+		public byte FeedbackMask; // one or more of XIMFeedback enum
+	}
+	
+	internal struct XIMText
+	{
+		public ushort Length;
+		public IntPtr Feedback; // to XIMFeedbackStruct
+		public bool EncodingIsWChar;
+		public IntPtr String; // it could be either char* or wchar_t*
+	}
+
+	internal struct XIMPreeditDrawCallbackStruct
+	{
+		public int Caret;
+		public int ChangeFirst;
+		public int ChangeLength;
+		public IntPtr Text; // to XIMText
+	}
+
+	internal enum XIMCaretDirection
+	{
+		XIMForwardChar,
+		XIMBackwardChar,
+		XIMForwardWord,
+		XIMBackwardWord,
+		XIMCaretUp,
+		XIMCaretDown,
+		XIMNextLine,
+		XIMPreviousLine,
+		XIMLineStart,
+		XIMLineEnd,
+		XIMAbsolutePosition,
+		XIMDontChange
+	}
+
+	internal enum XIMCaretStyle
+	{
+		IsInvisible,
+		IsPrimary,
+		IsSecondary
+	}
+
+	internal struct XIMPreeditCaretCallbackStruct
+	{
+		public int Position;
+		public XIMCaretDirection Direction;
+		public XIMCaretStyle Style;
+	}
+
+	// only PreeditStartCallback requires return value though.
+	internal delegate int XIMProc (IntPtr xim, IntPtr clientData, IntPtr callData);
+
+	internal static class XNames
+	{
+		public const string XNVaNestedList = "XNVaNestedList";
+		public const string XNQueryInputStyle = "queryInputStyle";
+		public const string XNClientWindow = "clientWindow";
+		public const string XNInputStyle = "inputStyle";
+		public const string XNFocusWindow = "focusWindow";
+
+		// XIMPreeditCallbacks delegate names.
+		public const string XNPreeditStartCallback = "preeditStartCallback";
+		public const string XNPreeditDoneCallback = "preeditDoneCallback";
+		public const string XNPreeditDrawCallback = "preeditDrawCallback";
+		public const string XNPreeditCaretCallback = "preeditCaretCallback";
+		public const string XNPreeditStateNotifyCallback = "preeditStateNotifyCallback";
+		public const string XNPreeditAttributes = "preeditAttributes";
+		// XIMStatusCallbacks delegate names.
+		public const string XNStatusStartCallback = "statusStartCallback";
+		public const string XNStatusDoneCallback = "statusDoneCallback";
+		public const string XNStatusDrawCallback = "statusDrawCallback";
+		public const string XNStatusAttributes = "statusAttributes";
+
+		public const string XNArea = "area";
+		public const string XNAreaNeeded = "areaNeeded";
+		public const string XNSpotLocation = "spotLocation";
+		public const string XNFontSet = "fontSet";
+	}
+}

+ 492 - 0
src/Avalonia.X11/X11Window.cs

@@ -0,0 +1,492 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Diagnostics;
+using System.Reactive.Disposables;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Input.Raw;
+using Avalonia.OpenGL;
+using Avalonia.Platform;
+using Avalonia.Rendering;
+using Avalonia.Threading;
+using static Avalonia.X11.XLib;
+namespace Avalonia.X11
+{
+    class X11Window : IWindowImpl, IPopupImpl
+    {
+        private readonly AvaloniaX11Platform _platform;
+        private readonly bool _popup;
+        private readonly X11Info _x11;
+        private readonly Action<XEvent> _eventHandler;
+        private bool _invalidated;
+        private XConfigureEvent? _configure;
+        private IInputRoot _inputRoot;
+        private IMouseDevice _mouse;
+        private Point _position;
+        private IntPtr _handle;
+        private bool _mapped;
+
+        class InputEventContainer
+        {
+            public RawInputEventArgs Event;
+        }
+        private Queue<InputEventContainer> _inputQueue = new Queue<InputEventContainer>();
+        private InputEventContainer _lastEvent;
+
+        public X11Window(AvaloniaX11Platform platform, bool popup)
+        {
+            _platform = platform;
+            _popup = popup;
+            _x11 = platform.Info;
+            _mouse = platform.MouseDevice;
+            
+            
+            XSetWindowAttributes attr = new XSetWindowAttributes();
+            var valueMask = default(SetWindowValuemask);
+            /*
+            _handle = XCreateSimpleWindow(_x11.Display, _x11.DefaultRootWindow, 10, 10, 100, 100, 0, IntPtr.Zero,
+                IntPtr.Zero);*/
+            var vinfo = _x11.MatchedVisual;
+            attr.colormap = XCreateColormap(_x11.Display, _x11.RootWindow, vinfo.visual, 0);
+            attr.backing_store = 2;
+            attr.bit_gravity = Gravity.NorthWestGravity;
+            attr.win_gravity = Gravity.NorthWestGravity;
+            valueMask |= SetWindowValuemask.ColorMap | SetWindowValuemask.BackPixel | SetWindowValuemask.BorderPixel
+                         | SetWindowValuemask.BackPixmap | SetWindowValuemask.BackingStore
+                         | SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
+
+            if (popup)
+            {
+                attr.override_redirect = true;
+                valueMask |= SetWindowValuemask.OverrideRedirect;
+            }
+            
+            _handle = XCreateWindow(_x11.Display, _x11.RootWindow, 10, 10, 300, 200, 0,
+                (int)vinfo.depth,
+                (int)CreateWindowArgs.InputOutput, vinfo.visual,
+                new UIntPtr((uint)valueMask), ref attr);
+
+
+            Handle = new PlatformHandle(_handle, "XID");
+            ClientSize = new Size(400, 400);
+            _eventHandler = OnEvent;
+            platform.Windows[_handle] = _eventHandler;
+            XSelectInput(_x11.Display, _handle,
+                new IntPtr(0xffffff 
+                           ^ (int)XEventMask.SubstructureRedirectMask 
+                           ^ (int)XEventMask.ResizeRedirectMask
+                           ^ (int)XEventMask.PointerMotionHintMask));
+            var protocols = new[]
+            {
+                _x11.Atoms.WM_DELETE_WINDOW
+            };
+            XSetWMProtocols(_x11.Display, _handle, protocols, protocols.Length);
+            var feature = (EglGlPlatformFeature)AvaloniaLocator.Current.GetService<IWindowingPlatformGlFeature>();
+            var surfaces = new List<object>
+            {
+                new X11FramebufferSurface(_x11.DeferredDisplay, _handle)
+            };
+            if (feature != null)
+                surfaces.Insert(0,
+                    new EglGlPlatformSurface((EglDisplay)feature.Display, feature.DeferredContext,
+                        new SurfaceInfo(_x11.DeferredDisplay, _handle)));
+            Surfaces = surfaces.ToArray();
+            UpdateWmHits();
+            XFlush(_x11.Display);
+        }
+
+        class SurfaceInfo  : EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo
+        {
+            private readonly IntPtr _display;
+
+            public SurfaceInfo(IntPtr display, IntPtr xid)
+            {
+                _display = display;
+                Handle = xid;
+            }
+            public IntPtr Handle { get; }
+
+            public System.Drawing.Size PixelSize
+            {
+                get
+                {
+                    XLockDisplay(_display);
+                    
+                    XGetGeometry(_display, Handle, out var geo);
+                    XUnlockDisplay(_display);
+                    return new System.Drawing.Size(geo.width, geo.height);
+                }
+            }
+
+            public double Scaling { get; } = 1;
+        }
+
+        void UpdateWmHits()
+        {
+            var functions = MotifFunctions.All;
+            var decorations = MotifDecorations.All;
+
+            if (_popup || !_systemDecorations)
+            {
+                functions = 0;
+                decorations = 0;
+            }
+
+            if (!_canResize)
+            {
+                functions ^= MotifFunctions.Resize | MotifFunctions.Maximize;
+                decorations ^= MotifDecorations.Maximize | MotifDecorations.ResizeH;
+            }
+
+            var hints = new MotifWmHints();
+            hints.flags = new IntPtr((int)(MotifFlags.Decorations | MotifFlags.Functions));
+
+            hints.decorations = new IntPtr((int)decorations);
+            hints.functions = new IntPtr((int)functions);
+            
+            XChangeProperty(_x11.Display, _handle,
+                _x11.Atoms._MOTIF_WM_HINTS, _x11.Atoms._MOTIF_WM_HINTS, 32,
+                PropertyMode.Replace, ref hints, 5);
+        }
+        
+        public Size ClientSize { get; private set; }
+        public double Scaling { get; } = 1;
+        public IEnumerable<object> Surfaces { get; }
+        public Action<RawInputEventArgs> Input { get; set; }
+        public Action<Rect> Paint { get; set; }
+        public Action<Size> Resized { get; set; }
+        public Action<double> ScalingChanged { get; set; }
+        public Action Deactivated { get; set; }
+        public Action Activated { get; set; }
+        public Func<bool> Closing { get; set; }
+        public WindowState WindowState { get; set; }
+        public Action<WindowState> WindowStateChanged { get; set; }
+        public Action Closed { get; set; }
+        public Action<Point> PositionChanged { get; set; }
+
+        public IRenderer CreateRenderer(IRenderRoot root) =>
+            new DeferredRenderer(root, AvaloniaLocator.Current.GetService<IRenderLoop>());
+
+        unsafe void OnEvent(XEvent ev)
+        {
+            if (ev.type == XEventName.MapNotify)
+                _mapped = true;
+            else if (ev.type == XEventName.UnmapNotify)
+                _mapped = false;
+            else if (ev.type == XEventName.Expose)
+                DoPaint();
+            else if (ev.type == XEventName.FocusIn)
+                Activated?.Invoke();
+            else if (ev.type == XEventName.FocusOut)
+                Deactivated?.Invoke();
+            else if (ev.type == XEventName.MotionNotify)
+                MouseEvent(RawMouseEventType.Move, ev, ev.MotionEvent.state);
+
+            else if (ev.type == XEventName.ButtonPress)
+            {
+                if (ev.ButtonEvent.button < 4)
+                    MouseEvent(ev.ButtonEvent.button == 1 ? RawMouseEventType.LeftButtonDown
+                        : ev.ButtonEvent.button == 2 ? RawMouseEventType.MiddleButtonDown
+                        : RawMouseEventType.RightButtonDown, ev, ev.ButtonEvent.state);
+                else
+                {
+                    var delta = ev.ButtonEvent.button == 4
+                        ? new Vector(0, 1)
+                        : ev.ButtonEvent.button == 5
+                            ? new Vector(0, -1)
+                            : ev.ButtonEvent.button == 6
+                                ? new Vector(1, 0)
+                                : new Vector(-1, 0);
+                    ScheduleInput(new RawMouseWheelEventArgs(_mouse, (ulong)ev.ButtonEvent.time.ToInt64(),
+                        _inputRoot, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), delta,
+                        TranslateModifiers(ev.ButtonEvent.state)));
+                }
+                
+            }
+            else if (ev.type == XEventName.ButtonRelease)
+            {
+                if (ev.ButtonEvent.button < 4)
+                    MouseEvent(ev.ButtonEvent.button == 1 ? RawMouseEventType.LeftButtonUp
+                        : ev.ButtonEvent.button == 2 ? RawMouseEventType.MiddleButtonUp
+                        : RawMouseEventType.RightButtonUp, ev, ev.ButtonEvent.state);
+            }
+            else if (ev.type == XEventName.ConfigureNotify)
+            {
+                var needEnqueue = (_configure == null);
+                _configure = ev.ConfigureEvent;
+                if (needEnqueue)
+                    Dispatcher.UIThread.Post(() =>
+                    {
+                        if (_configure == null)
+                            return;
+                        var cev = _configure.Value;
+                        _configure = null;
+                        var nsize = new Size(cev.width, cev.height);
+                        var npos = new Point(cev.x, cev.y);
+                        var changedSize = ClientSize != nsize;
+                        var changedPos = npos != _position;
+                        ClientSize = nsize;
+                        _position = npos;
+                        if (changedSize)
+                            Resized?.Invoke(nsize);
+                        if (changedPos)
+                            PositionChanged?.Invoke(npos);
+                    });
+            }
+            else if (ev.type == XEventName.DestroyNotify)
+            {
+                if (_handle != IntPtr.Zero)
+                {
+                    _platform.Windows.Remove(_handle);
+                    _handle = IntPtr.Zero;
+                    Closed?.Invoke();
+                }
+            }
+            else if (ev.type == XEventName.ClientMessage)
+            {
+                if (ev.ClientMessageEvent.message_type == _x11.Atoms.WM_PROTOCOLS)
+                {
+                    if (ev.ClientMessageEvent.ptr1 == _x11.Atoms.WM_DELETE_WINDOW)
+                    {
+                        if (Closing?.Invoke() != true)
+                            Dispose();
+                    }
+
+                }
+            }
+        }
+        
+        
+
+        InputModifiers TranslateModifiers(XModifierMask state)
+        {
+            var rv = default(InputModifiers);
+            if (state.HasFlag(XModifierMask.Button1Mask))
+                rv |= InputModifiers.LeftMouseButton;
+            if (state.HasFlag(XModifierMask.Button2Mask))
+                rv |= InputModifiers.RightMouseButton;
+            if (state.HasFlag(XModifierMask.Button2Mask))
+                rv |= InputModifiers.MiddleMouseButton;
+            if (state.HasFlag(XModifierMask.ShiftMask))
+                rv |= InputModifiers.Shift;
+            if (state.HasFlag(XModifierMask.ControlMask))
+                rv |= InputModifiers.Control;
+            if (state.HasFlag(XModifierMask.Mod1Mask))
+                rv |= InputModifiers.Alt;
+            if (state.HasFlag(XModifierMask.Mod4Mask))
+                rv |= InputModifiers.Windows;
+            return rv;
+        }
+        static Stopwatch St = Stopwatch.StartNew();
+        private bool _systemDecorations = true;
+        private bool _canResize = true;
+
+        void ScheduleInput(RawInputEventArgs args)
+        {
+            _lastEvent = new InputEventContainer() {Event = args};
+            _inputQueue.Enqueue(_lastEvent);
+            if (_inputQueue.Count == 1)
+            {
+                Dispatcher.UIThread.Post(() =>
+                {
+                    while (_inputQueue.Count > 0)
+                    {
+                        Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
+                        var ev = _inputQueue.Dequeue();
+                        Input?.Invoke(ev.Event);
+                    }
+                }, DispatcherPriority.Input);
+            }
+        }
+        
+        void MouseEvent(RawMouseEventType type, XEvent ev, XModifierMask mods)
+        {
+            _x11.LastActivityTimestamp = ev.ButtonEvent.time;
+            var mev = new RawMouseEventArgs(
+                _mouse, (ulong)ev.ButtonEvent.time.ToInt64(), _inputRoot,
+                type, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), TranslateModifiers(mods)); 
+            if(type == RawMouseEventType.Move && _inputQueue.Count>0 && _lastEvent.Event is RawMouseEventArgs ma)
+                if (ma.Type == RawMouseEventType.Move)
+                {
+                    _lastEvent.Event = mev;
+                    return;
+                }
+            ScheduleInput(mev);
+        }
+
+        void DoPaint()
+        {
+            _invalidated = false;
+            Paint?.Invoke(new Rect());
+        }
+        
+        public void Invalidate(Rect rect)
+        {
+            if(_invalidated)
+                return;
+            _invalidated = true;
+            Dispatcher.UIThread.InvokeAsync(() =>
+            {
+                if (_mapped)
+                    DoPaint();
+            });
+        }
+
+        public void SetInputRoot(IInputRoot inputRoot)
+        {
+            _inputRoot = inputRoot;
+        }
+
+        public void Dispose()
+        {
+            if (_handle != IntPtr.Zero)
+            {
+                XDestroyWindow(_x11.Display, _handle);
+                _platform.Windows.Remove(_handle);
+                _handle = IntPtr.Zero;
+                Closed?.Invoke();
+                
+            }
+        }
+        
+        public void Show() => XMapWindow(_x11.Display, _handle);
+
+        public void Hide() => XUnmapWindow(_x11.Display, _handle);
+        
+        
+        public Point PointToClient(Point point) => new Point(point.X - _position.X, point.Y - _position.Y);
+
+        public Point PointToScreen(Point point) => new Point(point.X + _position.X, point.Y + _position.Y);
+        
+        public void SetSystemDecorations(bool enabled)
+        {
+            _systemDecorations = enabled;
+            UpdateWmHits();
+        }
+        
+                
+        public void Resize(Size clientSize)
+        {
+            if (clientSize == ClientSize)
+                return;
+            var changes = new XWindowChanges();
+            changes.width = (int)clientSize.Width;
+            changes.height = (int)clientSize.Height;
+            var needResize = clientSize != ClientSize;
+            XConfigureWindow(_x11.Display, _handle, ChangeWindowFlags.CWHeight | ChangeWindowFlags.CWWidth,
+                ref changes);
+            XFlush(_x11.Display);
+
+            if (_popup && needResize)
+            {
+                ClientSize = clientSize;
+                Resized?.Invoke(clientSize);
+            }
+        }
+        
+        public void CanResize(bool value)
+        {
+            _canResize = value;
+            UpdateWmHits();
+        }
+
+        public void SetCursor(IPlatformHandle cursor)
+        {
+        }
+
+        public IPlatformHandle Handle { get; }
+        
+        public Point Position
+        {
+            get => _position;
+            set
+            {
+                var changes = new XWindowChanges();
+                changes.x = (int)value.X;
+                changes.y = (int)value.Y;
+                XConfigureWindow(_x11.Display, _handle, ChangeWindowFlags.CWX | ChangeWindowFlags.CWY,
+                    ref changes);
+                XFlush(_x11.Display);
+
+            }
+        }
+
+        public IMouseDevice MouseDevice => _mouse;
+       
+        public unsafe void Activate()
+        {
+            if (_x11.Atoms._NET_ACTIVE_WINDOW != IntPtr.Zero)
+            {
+
+                var ev = new XEvent
+                {
+                    AnyEvent = 
+                    {
+                        type = XEventName.ClientMessage,
+                        window = _handle,
+                    },
+                    ClientMessageEvent = {
+                    message_type = _x11.Atoms._NET_ACTIVE_WINDOW,
+                    format = 32,
+                        ptr1 = new IntPtr(1),
+                        ptr2 = _x11.LastActivityTimestamp
+                        
+                    }
+                };
+
+                XSendEvent(_x11.Display, _x11.RootWindow, false,
+                    new IntPtr((int)(XEventMask.SubstructureRedirectMask | XEventMask.StructureNotifyMask)), ref ev);
+            }
+            else
+            {
+                XRaiseWindow(_x11.Display, _handle);
+                XSetInputFocus(_x11.Display, _handle, 0, IntPtr.Zero);
+            }
+        }
+
+        
+        public IScreenImpl Screen { get; } = new ScreenStub();
+        public Size MaxClientSize { get; } = new Size(1920, 1280);
+        
+       
+        public void BeginMoveDrag()
+        {
+        }
+
+        public void BeginResizeDrag(WindowEdge edge)
+        {
+        }
+        
+        public void SetTitle(string title)
+        {
+        }
+
+        public void SetMinMaxSize(Size minSize, Size maxSize)
+        {
+            
+        }
+
+        public void SetTopmost(bool value)
+        {
+            
+        }
+
+        public IDisposable ShowDialog()
+        {
+            return Disposable.Empty;
+        }
+
+        public void SetIcon(IWindowIconImpl icon)
+        {
+        }
+
+        public void ShowTaskbarIcon(bool value)
+        {
+        }
+
+
+
+        
+    }
+}

+ 30 - 0
src/Avalonia.X11/XError.cs

@@ -0,0 +1,30 @@
+using System;
+
+namespace Avalonia.X11
+{
+    static class XError
+    {
+        private static readonly XErrorHandler s_errorHandlerDelegate = Handler;
+        public static XErrorEvent LastError;
+        static int Handler(IntPtr display, ref XErrorEvent error)
+        {
+            LastError = error;
+            return 0;
+        }
+
+        public static void ThrowLastError(string desc)
+        {
+            var err = LastError;
+            LastError = new XErrorEvent();
+            if (err.error_code == 0)
+                throw new X11Exception(desc);
+            throw new X11Exception(desc + ": " + err.error_code);
+
+        }
+
+        public static void Init()
+        {
+            XLib.XSetErrorHandler(s_errorHandlerDelegate);
+        }
+    }
+}

+ 392 - 76
src/Avalonia.X11/XLib.cs

@@ -1,105 +1,421 @@
 using System;
 using System.Runtime.InteropServices;
+using System.Text;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable FieldCanBeMadeReadOnly.Global
+// ReSharper disable CommentTypo
+// ReSharper disable UnusedMember.Global
+// ReSharper disable IdentifierTypo
+// ReSharper disable NotAccessedField.Global
+// ReSharper disable UnusedMethodReturnValue.Global
 
 namespace Avalonia.X11
 {
-    public static class XLib
+    internal static class XLib
     {
+        const string libX11 = "X11";
+
+        [DllImport(libX11)]
+        public static extern IntPtr XOpenDisplay(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern int XCloseDisplay(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XSynchronize(IntPtr display, bool onoff);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height,
+            int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask,
+            ref XSetWindowAttributes attributes);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width,
+            int height, int border_width, IntPtr border, IntPtr background);
+
+        [DllImport(libX11)]
+        public static extern int XMapWindow(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern int XUnmapWindow(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern int XMapSubindows(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern int XUnmapSubwindows(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XRootWindow(IntPtr display, int screen_number);
+        [DllImport(libX11)]
+        public static extern IntPtr XDefaultRootWindow(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XNextEvent(IntPtr display, out XEvent xevent);
+
+        [DllImport(libX11)]
+        public static extern int XConnectionNumber(IntPtr diplay);
+
+        [DllImport(libX11)]
+        public static extern int XPending(IntPtr diplay);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
+
+        [DllImport(libX11)]
+        public static extern int XDestroyWindow(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
+
+        [DllImport(libX11)]
+        public static extern int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
+
+        [DllImport(libX11)]
+        public static extern int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
+
+        [DllImport(libX11)]
+        public static extern int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
+
+        [DllImport(libX11)]
+        public static extern int XFlush(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
+
+        [DllImport(libX11)]
+        public static extern int XStoreName(IntPtr display, IntPtr window, string window_name);
+
+        [DllImport(libX11)]
+        public static extern int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
+
+        [DllImport(libX11)]
+        public static extern int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask,
+            ref XEvent send_event);
+
+        [DllImport(libX11)]
+        public static extern int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return,
+            out IntPtr parent_return, out IntPtr children_return, out int nchildren_return);
+
+        [DllImport(libX11)]
+        public static extern int XFree(IntPtr data);
+
+        [DllImport(libX11)]
+        public static extern int XRaiseWindow(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern uint XLowerWindow(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask,
+            ref XWindowChanges values);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
+
+        [DllImport(libX11)]
+        public static extern int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists,
+            IntPtr[] atoms);
+
+        [DllImport(libX11)]
+        public static extern int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
+
+        [DllImport(libX11)]
+        public static extern int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask,
+            GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
+
+        [DllImport(libX11)]
+        public static extern int XUngrabPointer(IntPtr display, IntPtr timestamp);
+
+        [DllImport(libX11)]
+        public static extern 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);
+
+        [DllImport(libX11)]
+        public static extern 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);
+
+        [DllImport(libX11)]
+        public static extern 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);
+
+        [DllImport(libX11)]
+        public static extern 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);
+
+        [DllImport(libX11)]
+        public static extern bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y,
+            IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
+
+        [DllImport(libX11)]
+        public static extern bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y,
+            out int width, out int height, IntPtr border_width, IntPtr depth);
+
+        [DllImport(libX11)]
+        public static extern 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);
+
+        [DllImport(libX11)]
+        public static extern int XClearWindow(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height,
+            bool exposures);
+
+        // Colormaps
+        [DllImport(libX11)]
+        public static extern IntPtr XDefaultScreenOfDisplay(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XDefaultVisual(IntPtr display, int screen_number);
+
+        [DllImport(libX11)]
+        public static extern uint XDefaultDepth(IntPtr display, int screen_number);
+
+        [DllImport(libX11)]
+        public static extern int XDefaultScreen(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XDefaultColormap(IntPtr display, int screen_number);
+
+        [DllImport(libX11)]
+        public static extern int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem,
+            ref XColor exact_def_color, ref XColor screen_def_color);
+
+        [DllImport(libX11)]
+        public static extern int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
+
+        [DllImport(libX11)]
+        public static extern int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
+
+        [DllImport(libX11)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, ref MotifWmHints data, int nelements);
+
+        [DllImport(libX11)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, ref uint value, int nelements);
+
+        [DllImport(libX11)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, ref IntPtr value, int nelements);
+
+        [DllImport(libX11)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, uint[] data, int nelements);
+
+        [DllImport(libX11)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, int[] data, int nelements);
+
+        [DllImport(libX11)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, IntPtr[] data, int nelements);
+
+        [DllImport(libX11)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, IntPtr atoms, int nelements);
+
+        [DllImport(libX11, CharSet = CharSet.Ansi)]
+        public static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type,
+            int format, PropertyMode mode, string text, int text_length);
+
+        [DllImport(libX11)]
+        public static extern int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
+
+        // Drawing
+        [DllImport(libX11)]
+        public static extern IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
+
+        [DllImport(libX11)]
+        public static extern int XFreeGC(IntPtr display, IntPtr gc);
+
+        [DllImport(libX11)]
+        public static extern int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
+
+        [DllImport(libX11)]
+        internal static extern int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style,
+            GCCapStyle cap_style, GCJoinStyle join_style);
+
+        [DllImport(libX11)]
+        public static extern int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
+
+        [DllImport(libX11)]
+        public static extern int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width,
+            int height);
+
+        [DllImport(libX11)]
+        public static extern int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width,
+            int height);
+
+        [DllImport(libX11)]
+        public static extern int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
+
+        [DllImport(libX11)]
+        public static extern 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);
+
+        [DllImport(libX11)]
+        public static extern int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset,
+            IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format,
+            out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
+
+        [DllImport(libX11)]
+        public static extern int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
+
+        [DllImport(libX11)]
+        public static extern int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
+
+        [DllImport(libX11)]
+        public static extern int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
+
+        [DllImport(libX11)]
+        public static extern int XUndefineCursor(IntPtr display, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern int XFreeCursor(IntPtr display, IntPtr cursor);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask,
+            ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width,
+            int height, IntPtr fg, IntPtr bg, int depth);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
+
+        [DllImport(libX11)]
+        public static extern int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height,
+            out int best_width, out int best_height);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XWhitePixel(IntPtr display, int screen_no);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XBlackPixel(IntPtr display, int screen_no);
+
+        [DllImport(libX11)]
+        public static extern void XGrabServer(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern void XUngrabServer(IntPtr display);
+
+        [DllImport(libX11)]
+        public static extern void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints,
+            out IntPtr supplied_return);
+
+        [DllImport(libX11)]
+        public static extern void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
+
+        [DllImport(libX11)]
+        public static extern void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
+
+        [DllImport(libX11)]
+        public static extern void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
+
+        [DllImport(libX11)]
+        public static extern int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XSetErrorHandler(XErrorHandler error_handler);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
+
+        [DllImport(libX11)]
+        public static extern int XInitThreads();
+
+        [DllImport(libX11)]
+        public static extern int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property,
+            IntPtr requestor, IntPtr time);
+
+        [DllImport(libX11)]
+        public static extern IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
+
+        [DllImport(libX11)]
+        public static extern int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
+
+        [DllImport(libX11)]
+        public static extern int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
+
+        [DllImport(libX11)]
+        public static extern int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
+
+        [DllImport(libX11)]
+        public static extern int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
+
+        [DllImport(libX11)]
+        public static extern int XBell(IntPtr display, int percent);
+
+        [DllImport(libX11)]
+        public static extern int XChangeActivePointerGrab(IntPtr display, EventMask event_mask, IntPtr cursor,
+            IntPtr time);
+
+        [DllImport(libX11)]
+        public static extern bool XFilterEvent(ref XEvent xevent, IntPtr window);
+
+        [DllImport(libX11)]
+        public static extern void XkbSetDetectableAutoRepeat(IntPtr display, bool detectable, IntPtr supported);
+
+        [DllImport(libX11)]
+        public static extern void XPeekEvent(IntPtr display, out XEvent xevent);
         
-        [DllImport("libX11.so.6")]
-        public static extern IntPtr XInitThreads();
-        
-        [DllImport("libX11.so.6")]
-        public static extern IntPtr XOpenDisplay(IntPtr name);
-        
-        [DllImport("libX11.so.6")]
-        public static extern int XConnectionNumber(IntPtr display);
+        [DllImport(libX11)]
+        public static extern void XMatchVisualInfo(IntPtr display, int screen, int depth, int klass, out XVisualInfo info);
         
-        [DllImport("libX11.so.6")]
+        [DllImport(libX11)]
         public static extern IntPtr XLockDisplay(IntPtr display);
         
-        [DllImport("libX11.so.6")]
+        [DllImport(libX11)]
         public static extern IntPtr XUnlockDisplay(IntPtr display);
         
-        [DllImport("libX11.so.6")]
-        public static extern IntPtr XFreeGC(IntPtr display, IntPtr gc);
-        
-        [DllImport("libX11.so.6")]
+        [DllImport(libX11)]
         public static extern IntPtr XCreateGC(IntPtr display, IntPtr drawable, ulong valuemask, IntPtr values);
         
-        [DllImport("libX11.so.6")]
+        [DllImport(libX11)]
         public static extern int XInitImage(ref XImage image);
         
-        [DllImport("libX11.so.6")]
+        [DllImport(libX11)]
         public static extern int XDestroyImage(ref XImage image);
-        
-        [DllImport("libX11.so.6")]
-        public static extern IntPtr XSetErrorHandler(XErrorHandler handler);
 
-        [DllImport("libX11.so.6")]
+        [DllImport(libX11)]
+        public static extern int XPutImage(IntPtr display, IntPtr drawable, IntPtr gc, ref XImage image,
+            int srcx, int srcy, int destx, int desty, uint width, uint height);
+        [DllImport(libX11)]
         public static extern int XSync(IntPtr display, bool discard);
         
-        [DllImport("libX11.so.6")]
-        public static extern int XNextEvent(IntPtr display, out XEvent ev);
+        [DllImport(libX11)]
+        public static extern IntPtr XCreateColormap(IntPtr display, IntPtr window, IntPtr visual, int create);
         
-        [DllImport("libX11.so.6")]
-        public static extern bool XPending(IntPtr display);
-
-        [StructLayout(LayoutKind.Sequential)]
-        public struct XAnyEvent
+        public struct XGeometry
         {
-
-            public int Type;
-            public ulong Serial; /* # of last request processed by server */
-            public bool send_event; /* true if this came from a SendEvent request */
-            public IntPtr display; /* Display the event was read from */
-            public IntPtr window; /* window on which event was requested in event mask */
+            public IntPtr root;
+            public int x;
+            public int y;
+            public int width;
+            public int height;
+            public int bw;
+            public int d;
         }
 
-        [StructLayout(LayoutKind.Explicit)]
-        public unsafe struct XEvent
+        public static bool XGetGeometry(IntPtr display, IntPtr window, out XGeometry geo)
         {
-            [FieldOffset(0)] public int Type;
-            [FieldOffset(0)] public XAnyEvent XAny;
-            [FieldOffset(0)] private fixed int pad[40];
+            geo = new XGeometry();
+            return XGetGeometry(display, window, out geo.root, out geo.x, out geo.y, out geo.width, out geo.height,
+                out geo.bw, out geo.d);
         }
 
-        public delegate int XErrorHandler(IntPtr display, ref XErrorEvent error);
-
-        [DllImport("libX11.so.6")]
-        public static extern int XPutImage(IntPtr display, IntPtr drawable, IntPtr gc, ref XImage image,
-            int srcx, int srcy, int destx, int desty, uint width, uint height);
-
-        [StructLayout(LayoutKind.Sequential)]
-        public unsafe struct XErrorEvent
-        {
-            public int type;
-            public IntPtr* display; /* Display the event was read from */
-            public ulong serial; /* serial number of failed request */
-            public byte error_code; /* error code of failed request */
-            public byte request_code; /* Major op-code of failed request */
-            public byte minor_code; /* Minor op-code of failed request */
-            public IntPtr resourceid; /* resource id */
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        public unsafe struct XImage
-        {
-            public int width, height; /* size of image */
-            public int xoffset; /* number of pixels offset in X direction */
-            public int format; /* XYBitmap, XYPixmap, ZPixmap */
-            public IntPtr data; /* pointer to image data */
-            public int byte_order; /* data byte order, LSBFirst, MSBFirst */
-            public int bitmap_unit; /* quant. of scanline 8, 16, 32 */
-            public int bitmap_bit_order; /* LSBFirst, MSBFirst */
-            public int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
-            public int depth; /* depth of image */
-            public int bytes_per_line; /* accelerator to next scanline */
-            public int bits_per_pixel; /* bits per pixel (ZPixmap) */
-            public ulong red_mask; /* bits in z arrangement */
-            public ulong green_mask;
-            public ulong blue_mask;
-            private fixed byte funcs[128];
-        }
     }
 }