diff --git a/Source/OpenTK/Platform/X11/X11GLControl.cs b/Source/OpenTK/Platform/X11/X11GLControl.cs
new file mode 100644
index 00000000..c0317db3
--- /dev/null
+++ b/Source/OpenTK/Platform/X11/X11GLControl.cs
@@ -0,0 +1,84 @@
+#region --- License ---
+/* Licensed under the MIT/X11 license.
+ * Copyright (c) 2006-2008 the OpenTK Team.
+ * This notice may not be removed from any source distribution.
+ * See license.txt for licensing detailed licensing details.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using System.Runtime.InteropServices;
+
+using OpenTK.Graphics;
+
+namespace OpenTK.Platform.X11
+{
+ class X11GLControl : IGLControl
+ {
+ GraphicsMode mode;
+ Control control;
+ IntPtr display;
+
+ internal X11GLControl(GraphicsMode mode, Control control)
+ {
+ this.mode = mode;
+ this.control = control;
+
+ X11WindowInfo window = (X11WindowInfo)this.WindowInfo;
+
+ XVisualInfo info = new XVisualInfo();
+ info.visualid = mode.Index;
+ int dummy;
+ window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure(
+ Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo));
+
+ Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
+ xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
+ .SetValue(null, window.VisualInfo.visual);
+ xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
+ .SetValue(null, API.CreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0));
+ }
+
+ #region --- IGLControl Members ---
+
+ public GraphicsContext CreateContext()
+ {
+ return new GraphicsContext(mode, this.WindowInfo);
+ }
+
+ public bool IsIdle
+ {
+ get { return Functions.XPending(display) == 0; }
+ }
+
+ public IWindowInfo WindowInfo
+ {
+ get
+ {
+ Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
+ if (xplatui == null) throw new PlatformNotSupportedException(
+ "System.Windows.Forms.XplatUIX11 missing. Unsupported platform or Mono runtime version, aborting.");
+
+ X11WindowInfo window = new X11WindowInfo(control.Handle, null);
+
+ display =
+ window.Display = (IntPtr)xplatui.GetField("DisplayHandle",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ window.RootWindow = (IntPtr)xplatui.GetField("RootWindow",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ window.Screen = (int)xplatui.GetField("ScreenNo",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+
+ if (control.IsHandleCreated)
+ window.WindowHandle = control.Handle;
+
+ return window;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Platform/X11/X11GLControlHelper.cs b/Source/OpenTK/Platform/X11/X11GLControlHelper.cs
new file mode 100644
index 00000000..24f975fb
--- /dev/null
+++ b/Source/OpenTK/Platform/X11/X11GLControlHelper.cs
@@ -0,0 +1,63 @@
+#region --- License ---
+/* Licensed under the MIT/X11 license.
+ * Copyright (c) 2006-2008 the OpenTK Team.
+ * This notice may not be removed from any source distribution.
+ * See license.txt for licensing detailed licensing details.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+
+namespace OpenTK.Platform.X11
+{
+ ///
+ /// Utility to obtain IWindowInfo from a System.Windows.Forms.Control on Mono/X11.
+ internal sealed class X11GLControlHelper : IGLControlHelper
+ {
+ Control control;
+ IntPtr display;
+
+ public X11GLControlHelper(Control c)
+ {
+ }
+
+ #region IGLControlHelper Members
+
+ public IWindowInfo WindowInfo
+ {
+ get
+ {
+ X11WindowInfo window = new X11WindowInfo();
+ Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
+ if (xplatui == null)
+ throw new ApplicationException("Could not get System.Windows.Forms.XplatUIX11 through reflection. Unsupported platform or Mono runtime version, aborting.");
+
+ display =
+ window.Display = (IntPtr)xplatui.GetField("DisplayHandle",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ window.RootWindow = (IntPtr)xplatui.GetField("RootWindow",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ window.Screen = (int)xplatui.GetField("ScreenNo",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+
+ return (IWindowInfo)window;
+ }
+ }
+
+ public bool IsIdle
+ {
+ get
+ {
+ lock (Functions.Lock)
+ {
+ return Functions.XPending(display) == 0;
+ }
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Platform/X11/X11GraphicsMode.cs b/Source/OpenTK/Platform/X11/X11GraphicsMode.cs
new file mode 100644
index 00000000..66c40d31
--- /dev/null
+++ b/Source/OpenTK/Platform/X11/X11GraphicsMode.cs
@@ -0,0 +1,127 @@
+#region --- License ---
+/* Licensed under the MIT/X11 license.
+ * Copyright (c) 2006-2008 the OpenTK Team.
+ * This notice may not be removed from any source distribution.
+ * See license.txt for licensing detailed licensing details.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+
+using OpenTK.Graphics;
+
+namespace OpenTK.Platform.X11
+{
+ class X11GraphicsMode : IGraphicsMode
+ {
+ internal X11GraphicsMode()
+ {
+ }
+
+ public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
+ int buffers, bool stereo)
+ {
+ List visualAttributes = new List();
+
+ if (color.BitsPerPixel > 0)
+ {
+ if (!color.IsIndexed)
+ visualAttributes.Add((int)GLXAttribute.RGBA);
+ visualAttributes.Add((int)GLXAttribute.RED_SIZE);
+ visualAttributes.Add(color.Red);
+ visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
+ visualAttributes.Add(color.Green);
+ visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
+ visualAttributes.Add(color.Blue);
+ visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
+ visualAttributes.Add(color.Alpha);
+ }
+
+ if (depth > 0)
+ {
+ visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
+ visualAttributes.Add(depth);
+ }
+
+ if (buffers > 1)
+ visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER);
+
+ if (stencil > 1)
+ {
+ visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE);
+ visualAttributes.Add(stencil);
+ }
+
+ if (accum.BitsPerPixel > 0)
+ {
+ visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE);
+ visualAttributes.Add(accum.Alpha);
+ visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE);
+ visualAttributes.Add(accum.Blue);
+ visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE);
+ visualAttributes.Add(accum.Green);
+ visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE);
+ visualAttributes.Add(accum.Red);
+ }
+
+ if (stereo)
+ visualAttributes.Add((int)GLXAttribute.STEREO);
+
+ visualAttributes.Add((int)0);
+
+ // Prepare Windows.Forms for creating OpenGL drawables.
+ // We reuse the display connection.
+ // TODO: Multiple screens.
+ Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
+ IntPtr display = (IntPtr)xplatui.GetField("DisplayHandle",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ IntPtr root = (IntPtr)xplatui.GetField("RootWindow",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ int screen = (int)xplatui.GetField("ScreenNo",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+
+ Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
+
+ IntPtr visual = Glx.ChooseVisual(display, screen, visualAttributes.ToArray());
+
+ if (visual == IntPtr.Zero)
+ throw new GraphicsContextException("Requested GraphicsMode not available.");
+
+ XVisualInfo info = (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo));
+
+ // See what we *really* got:
+ int r, g, b, a;
+ Glx.GetConfig(display, ref info, GLXAttribute.ALPHA_SIZE, out a);
+ Glx.GetConfig(display, ref info, GLXAttribute.RED_SIZE, out r);
+ Glx.GetConfig(display, ref info, GLXAttribute.GREEN_SIZE, out g);
+ Glx.GetConfig(display, ref info, GLXAttribute.BLUE_SIZE, out b);
+ int ar, ag, ab, aa;
+ Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_ALPHA_SIZE, out aa);
+ Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_RED_SIZE, out ar);
+ Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_GREEN_SIZE, out ag);
+ Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_BLUE_SIZE, out ab);
+ Glx.GetConfig(display, ref info, GLXAttribute.DEPTH_SIZE, out depth);
+ Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil);
+ Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples);
+ Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers);
+ ++buffers; // the above lines returns 0 - false and 1 - true.
+ int st;
+ Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
+ stereo = st != 0;
+
+ GraphicsMode gfx = new GraphicsMode(info.visualid, new ColorFormat(r, g, b, a), depth, stencil, samples,
+ new ColorFormat(ar, ag, ab, aa), buffers, stereo);
+
+ xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
+ .SetValue(null, visual);
+ xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
+ .SetValue(null, API.CreateColormap(display, root, visual, 0));
+
+ return gfx;
+ }
+ }
+}