Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1452 | chris | 1 | #region --- License --- |
| 2 | /* Licensed under the MIT/X11 license. |
||
| 3 | * Copyright (c) 2006-2008 the OpenTK Team. |
||
| 4 | * This notice may not be removed from any source distribution. |
||
| 5 | * See license.txt for licensing detailed licensing details. |
||
| 6 | */ |
||
| 7 | #endregion |
||
| 8 | |||
| 9 | using System; |
||
| 10 | using System.Collections.Generic; |
||
| 11 | using System.Text; |
||
| 12 | using System.Windows.Forms; |
||
| 13 | using System.Runtime.InteropServices; |
||
| 14 | |||
| 15 | using OpenTK.Graphics; |
||
| 16 | using OpenTK.Platform; |
||
| 17 | |||
| 18 | namespace OpenTK |
||
| 19 | { |
||
| 20 | class X11GLControl : IGLControl |
||
| 21 | { |
||
| 22 | #region P/Invokes |
||
| 23 | |||
| 24 | [DllImport("libX11")] |
||
| 25 | static extern IntPtr XCreateColormap(IntPtr display, IntPtr window, IntPtr visual, int alloc); |
||
| 26 | |||
| 27 | [DllImport("libX11", EntryPoint = "XGetVisualInfo")] |
||
| 28 | static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, out int nitems); |
||
| 29 | |||
| 30 | static IntPtr XGetVisualInfo(IntPtr display, int vinfo_mask, ref XVisualInfo template, out int nitems) |
||
| 31 | { |
||
| 32 | return XGetVisualInfoInternal(display, (IntPtr)vinfo_mask, ref template, out nitems); |
||
| 33 | } |
||
| 34 | |||
| 35 | [DllImport("libX11")] |
||
| 36 | extern static int XPending(IntPtr diplay); |
||
| 37 | |||
| 38 | [StructLayout(LayoutKind.Sequential)] |
||
| 39 | struct XVisualInfo |
||
| 40 | { |
||
| 41 | public IntPtr Visual; |
||
| 42 | public IntPtr VisualID; |
||
| 43 | public int Screen; |
||
| 44 | public int Depth; |
||
| 45 | public int Class; |
||
| 46 | public long RedMask; |
||
| 47 | public long GreenMask; |
||
| 48 | public long blueMask; |
||
| 49 | public int ColormapSize; |
||
| 50 | public int BitsPerRgb; |
||
| 51 | |||
| 52 | public override string ToString() |
||
| 53 | { |
||
| 54 | return String.Format("id ({0}), screen ({1}), depth ({2}), class ({3})", |
||
| 55 | VisualID, Screen, Depth, Class); |
||
| 56 | } |
||
| 57 | } |
||
| 58 | |||
| 59 | #endregion |
||
| 60 | |||
| 61 | #region Fields |
||
| 62 | |||
| 63 | GraphicsMode mode; |
||
| 64 | IWindowInfo window_info; |
||
| 65 | IntPtr display; |
||
| 66 | |||
| 67 | #endregion |
||
| 68 | |||
| 69 | internal X11GLControl(GraphicsMode mode, Control control) |
||
| 70 | { |
||
| 71 | if (mode == null) |
||
| 72 | throw new ArgumentNullException("mode"); |
||
| 73 | if (control == null) |
||
| 74 | throw new ArgumentNullException("control"); |
||
| 75 | if (!mode.Index.HasValue) |
||
| 76 | throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); |
||
| 77 | |||
| 78 | this.mode = mode; |
||
| 79 | |||
| 80 | // Use reflection to retrieve the necessary values from Mono's Windows.Forms implementation. |
||
| 81 | Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms"); |
||
| 82 | if (xplatui == null) throw new PlatformNotSupportedException( |
||
| 83 | "System.Windows.Forms.XplatUIX11 missing. Unsupported platform or Mono runtime version, aborting."); |
||
| 84 | |||
| 85 | // get the required handles from the X11 API. |
||
| 86 | display = (IntPtr)GetStaticFieldValue(xplatui, "DisplayHandle"); |
||
| 87 | IntPtr rootWindow = (IntPtr)GetStaticFieldValue(xplatui, "RootWindow"); |
||
| 88 | int screen = (int)GetStaticFieldValue(xplatui, "ScreenNo"); |
||
| 89 | |||
| 90 | // get the XVisualInfo for this GraphicsMode |
||
| 91 | XVisualInfo info = new XVisualInfo(); |
||
| 92 | info.VisualID = mode.Index.Value; |
||
| 93 | int dummy; |
||
| 94 | IntPtr infoPtr = XGetVisualInfo(display, 1 /* VisualInfoMask.ID */, ref info, out dummy); |
||
| 95 | info = (XVisualInfo)Marshal.PtrToStructure(infoPtr, typeof(XVisualInfo)); |
||
| 96 | |||
| 97 | // set the X11 colormap. |
||
| 98 | SetStaticFieldValue(xplatui, "CustomVisual", info.Visual); |
||
| 99 | SetStaticFieldValue(xplatui, "CustomColormap", XCreateColormap(display, rootWindow, info.Visual, 0)); |
||
| 100 | |||
| 101 | window_info = Utilities.CreateX11WindowInfo(display, screen, control.Handle, rootWindow, infoPtr); |
||
| 102 | } |
||
| 103 | |||
| 104 | #region IGLControl Members |
||
| 105 | |||
| 106 | public IGraphicsContext CreateContext(int major, int minor, GraphicsContextFlags flags) |
||
| 107 | { |
||
| 108 | return new GraphicsContext(mode, this.WindowInfo, major, minor, flags); |
||
| 109 | } |
||
| 110 | |||
| 111 | public bool IsIdle |
||
| 112 | { |
||
| 113 | get { return XPending(display) == 0; } |
||
| 114 | } |
||
| 115 | |||
| 116 | public IWindowInfo WindowInfo |
||
| 117 | { |
||
| 118 | get |
||
| 119 | { |
||
| 120 | return window_info; |
||
| 121 | } |
||
| 122 | } |
||
| 123 | |||
| 124 | #endregion |
||
| 125 | |||
| 126 | #region Private Members |
||
| 127 | |||
| 128 | static object GetStaticFieldValue(Type type, string fieldName) |
||
| 129 | { |
||
| 130 | return type.GetField(fieldName, |
||
| 131 | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null); |
||
| 132 | } |
||
| 133 | |||
| 134 | static void SetStaticFieldValue(Type type, string fieldName, object value) |
||
| 135 | { |
||
| 136 | type.GetField(fieldName, |
||
| 137 | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, value); |
||
| 138 | } |
||
| 139 | |||
| 140 | #endregion |
||
| 141 | } |
||
| 142 | } |