00001 #region --- License ---
00002
00003
00004
00005
00006
00007 #endregion
00008
00009 using System;
00010 using System.Collections.Generic;
00011 using System.Text;
00012 using System.Windows.Forms;
00013 using System.Runtime.InteropServices;
00014
00015 using OpenTK.Graphics;
00016 using OpenTK.Platform;
00017
00018 namespace OpenTK
00019 {
00020 class X11GLControl : IGLControl
00021 {
00022 #region P/Invokes
00023
00024 [DllImport("libX11")]
00025 static extern IntPtr XCreateColormap(IntPtr display, IntPtr window, IntPtr visual, int alloc);
00026
00027 [DllImport("libX11", EntryPoint = "XGetVisualInfo")]
00028 static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, out int nitems);
00029
00030 static IntPtr XGetVisualInfo(IntPtr display, int vinfo_mask, ref XVisualInfo template, out int nitems)
00031 {
00032 return XGetVisualInfoInternal(display, (IntPtr)vinfo_mask, ref template, out nitems);
00033 }
00034
00035 [DllImport("libX11")]
00036 extern static int XPending(IntPtr diplay);
00037
00038 [StructLayout(LayoutKind.Sequential)]
00039 struct XVisualInfo
00040 {
00041 public IntPtr Visual;
00042 public IntPtr VisualID;
00043 public int Screen;
00044 public int Depth;
00045 public int Class;
00046 public long RedMask;
00047 public long GreenMask;
00048 public long blueMask;
00049 public int ColormapSize;
00050 public int BitsPerRgb;
00051
00052 public override string ToString()
00053 {
00054 return String.Format("id ({0}), screen ({1}), depth ({2}), class ({3})",
00055 VisualID, Screen, Depth, Class);
00056 }
00057 }
00058
00059 #endregion
00060
00061 #region Fields
00062
00063 GraphicsMode mode;
00064 IWindowInfo window_info;
00065 IntPtr display;
00066
00067 #endregion
00068
00069 internal X11GLControl(GraphicsMode mode, Control control)
00070 {
00071 if (mode == null)
00072 throw new ArgumentNullException("mode");
00073 if (control == null)
00074 throw new ArgumentNullException("control");
00075 if (!mode.Index.HasValue)
00076 throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
00077
00078 this.mode = mode;
00079
00080
00081 Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
00082 if (xplatui == null) throw new PlatformNotSupportedException(
00083 "System.Windows.Forms.XplatUIX11 missing. Unsupported platform or Mono runtime version, aborting.");
00084
00085
00086 display = (IntPtr)GetStaticFieldValue(xplatui, "DisplayHandle");
00087 IntPtr rootWindow = (IntPtr)GetStaticFieldValue(xplatui, "RootWindow");
00088 int screen = (int)GetStaticFieldValue(xplatui, "ScreenNo");
00089
00090
00091 XVisualInfo info = new XVisualInfo();
00092 info.VisualID = mode.Index.Value;
00093 int dummy;
00094 IntPtr infoPtr = XGetVisualInfo(display, 1 , ref info, out dummy);
00095 info = (XVisualInfo)Marshal.PtrToStructure(infoPtr, typeof(XVisualInfo));
00096
00097
00098 SetStaticFieldValue(xplatui, "CustomVisual", info.Visual);
00099 SetStaticFieldValue(xplatui, "CustomColormap", XCreateColormap(display, rootWindow, info.Visual, 0));
00100
00101 window_info = Utilities.CreateX11WindowInfo(display, screen, control.Handle, rootWindow, infoPtr);
00102 }
00103
00104 #region IGLControl Members
00105
00106 public IGraphicsContext CreateContext(int major, int minor, GraphicsContextFlags flags)
00107 {
00108 return new GraphicsContext(mode, this.WindowInfo, major, minor, flags);
00109 }
00110
00111 public bool IsIdle
00112 {
00113 get { return XPending(display) == 0; }
00114 }
00115
00116 public IWindowInfo WindowInfo
00117 {
00118 get
00119 {
00120 return window_info;
00121 }
00122 }
00123
00124 #endregion
00125
00126 #region Private Members
00127
00128 static object GetStaticFieldValue(Type type, string fieldName)
00129 {
00130 return type.GetField(fieldName,
00131 System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
00132 }
00133
00134 static void SetStaticFieldValue(Type type, string fieldName, object value)
00135 {
00136 type.GetField(fieldName,
00137 System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, value);
00138 }
00139
00140 #endregion
00141 }
00142 }