Opentk/Source/GLControl/X11GLControl.cs

148 lines
4.8 KiB
C#
Raw Normal View History

#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;
using OpenTK.Platform;
namespace OpenTK
{
class X11GLControl : IGLControl
{
#region P/Invokes
[DllImport("libX11")]
static extern IntPtr XCreateColormap(IntPtr display, IntPtr window, IntPtr visual, int alloc);
[DllImport("libX11", EntryPoint = "XGetVisualInfo")]
static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, out int nitems);
static IntPtr XGetVisualInfo(IntPtr display, int vinfo_mask, ref XVisualInfo template, out int nitems)
{
return XGetVisualInfoInternal(display, (IntPtr)vinfo_mask, ref template, out nitems);
}
[DllImport("libX11")]
extern static int XPending(IntPtr diplay);
[StructLayout(LayoutKind.Sequential)]
struct XVisualInfo
{
public IntPtr Visual;
public IntPtr VisualID;
public int Screen;
public int Depth;
public int Class;
public long RedMask;
public long GreenMask;
public long blueMask;
public int ColormapSize;
public int BitsPerRgb;
public override string ToString()
{
return String.Format("id ({0}), screen ({1}), depth ({2}), class ({3})",
VisualID, Screen, Depth, Class);
}
}
#endregion
#region Fields
GraphicsMode mode;
IWindowInfo window_info;
IntPtr display;
IntPtr rootWindow;
// Use reflection to retrieve the necessary values from Mono's Windows.Forms implementation.
Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
#endregion
internal X11GLControl(GraphicsMode mode, Control control)
{
if (mode == null)
throw new ArgumentNullException("mode");
if (control == null)
throw new ArgumentNullException("control");
if (!mode.Index.HasValue)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
this.mode = mode;
if (xplatui == null) throw new PlatformNotSupportedException(
"System.Windows.Forms.XplatUIX11 missing. Unsupported platform or Mono runtime version, aborting.");
// get the required handles from the X11 API.
display = (IntPtr)GetStaticFieldValue(xplatui, "DisplayHandle");
rootWindow = (IntPtr)GetStaticFieldValue(xplatui, "RootWindow");
int screen = (int)GetStaticFieldValue(xplatui, "ScreenNo");
window_info = Utilities.CreateX11WindowInfo(display, screen, control.Handle, rootWindow, IntPtr.Zero);
}
#region IGLControl Members
public IGraphicsContext CreateContext(int major, int minor, GraphicsContextFlags flags)
{
GraphicsContext context = new GraphicsContext(mode, this.WindowInfo, major, minor, flags);
mode = context.GraphicsMode;
// get the XVisualInfo for this GraphicsMode
XVisualInfo info = new XVisualInfo();
info.VisualID = mode.Index.Value;
int dummy;
IntPtr infoPtr = XGetVisualInfo(display, 1 /* VisualInfoMask.ID */, ref info, out dummy);
info = (XVisualInfo)Marshal.PtrToStructure(infoPtr, typeof(XVisualInfo));
// set the X11 colormap.
SetStaticFieldValue(xplatui, "CustomVisual", info.Visual);
SetStaticFieldValue(xplatui, "CustomColormap", XCreateColormap(display, rootWindow, info.Visual, 0));
return context;
}
public bool IsIdle
{
get { return XPending(display) == 0; }
}
public IWindowInfo WindowInfo
{
get
{
return window_info;
}
}
#endregion
#region Private Members
static object GetStaticFieldValue(Type type, string fieldName)
{
return type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
}
static void SetStaticFieldValue(Type type, string fieldName, object value)
{
type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, value);
}
#endregion
}
}