From 8b60cc20180db652acd0b7d912ef97a0c7b31718 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Fri, 4 Sep 2009 21:11:25 +0000 Subject: [PATCH] Made GraphicsMode.Index public, as it is necessary when extending OpenTK. Removed OpenTK.Platform.Utilities.CreateWindowInfo and made the platform-specific CreateWindowInfo methods public (e.g. CreateX11WindowInfo). Moved Mono Windows.Forms-specific code into X11GLControl. Removed OpenTK.Platform.Utilities.IsIdle. Removed obsolete methods from OpenTK.Platform.Utilities. Marked OpenTK.Platform.Utilities.CreateGraphicsContext as obsolete (use GraphicsContext constructor instead). Made IWindowInfo implementations private. --- Source/GLControl/CarbonGLControl.cs | 2 +- Source/GLControl/DummyGLControl.cs | 2 +- Source/GLControl/WinGLControl.cs | 2 +- Source/GLControl/X11GLControl.cs | 80 ++++++- Source/OpenTK/Graphics/GraphicsMode.cs | 69 +++--- .../OpenTK/Platform/Dummy/DummyGLContext.cs | 17 -- .../OpenTK/Platform/MacOS/CarbonWindowInfo.cs | 2 +- Source/OpenTK/Platform/Utilities.cs | 196 +++++------------- .../OpenTK/Platform/Windows/WinWindowInfo.cs | 2 +- Source/OpenTK/Platform/X11/API.cs | 6 +- Source/OpenTK/Platform/X11/X11WindowInfo.cs | 2 +- 11 files changed, 164 insertions(+), 216 deletions(-) diff --git a/Source/GLControl/CarbonGLControl.cs b/Source/GLControl/CarbonGLControl.cs index 6925151c..c24b2a75 100644 --- a/Source/GLControl/CarbonGLControl.cs +++ b/Source/GLControl/CarbonGLControl.cs @@ -68,7 +68,7 @@ namespace OpenTK { get { - return Utilities.CreateWindowInfo(mode, control.Handle, true); + return Utilities.CreateDummyWindowInfo(); } } diff --git a/Source/GLControl/DummyGLControl.cs b/Source/GLControl/DummyGLControl.cs index 9531595a..05891b19 100644 --- a/Source/GLControl/DummyGLControl.cs +++ b/Source/GLControl/DummyGLControl.cs @@ -47,7 +47,7 @@ namespace OpenTK public IWindowInfo WindowInfo { - get { return Utilities.CreateWindowInfo(null, IntPtr.Zero, true); } + get { return Utilities.CreateDummyWindowInfo(); } } #endregion diff --git a/Source/GLControl/WinGLControl.cs b/Source/GLControl/WinGLControl.cs index 56f359df..e491632d 100644 --- a/Source/GLControl/WinGLControl.cs +++ b/Source/GLControl/WinGLControl.cs @@ -113,7 +113,7 @@ namespace OpenTK { this.mode = mode; - window_info = Utilities.CreateWindowInfo(mode, control.Handle, true); + window_info = Utilities.CreateWindowsWindowInfo(control.Handle); } #endregion diff --git a/Source/GLControl/X11GLControl.cs b/Source/GLControl/X11GLControl.cs index e0111930..f13e8b8d 100644 --- a/Source/GLControl/X11GLControl.cs +++ b/Source/GLControl/X11GLControl.cs @@ -22,7 +22,39 @@ namespace OpenTK #region P/Invokes [DllImport("libX11")] - public extern static int XPending(IntPtr diplay); + 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 @@ -30,6 +62,7 @@ namespace OpenTK GraphicsMode mode; IWindowInfo window_info; + IntPtr display; #endregion @@ -39,10 +72,33 @@ namespace OpenTK 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; - window_info = Utilities.CreateWindowInfo(mode, control.Handle, true); + // Use reflection to retrieve the necessary values from Mono's Windows.Forms implementation. + 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."); + + // get the required handles from the X11 API. + display = (IntPtr)GetStaticFieldValue(xplatui, "DisplayHandle"); + IntPtr rootWindow = (IntPtr)GetStaticFieldValue(xplatui, "RootWindow"); + int screen = (int)GetStaticFieldValue(xplatui, "ScreenNo"); + + // 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)); + + window_info = Utilities.CreateX11WindowInfo(display, screen, control.Handle, rootWindow, infoPtr); } #region IGLControl Members @@ -54,7 +110,7 @@ namespace OpenTK public bool IsIdle { - get { return XPending(((Platform.X11.X11WindowInfo)window_info).Display) == 0; } + get { return XPending(display) == 0; } } public IWindowInfo WindowInfo @@ -66,5 +122,21 @@ namespace OpenTK } #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 } } diff --git a/Source/OpenTK/Graphics/GraphicsMode.cs b/Source/OpenTK/Graphics/GraphicsMode.cs index febc0e65..2b7fb28b 100644 --- a/Source/OpenTK/Graphics/GraphicsMode.cs +++ b/Source/OpenTK/Graphics/GraphicsMode.cs @@ -168,6 +168,40 @@ namespace OpenTK.Graphics #region --- Public Methods --- + #region public IntPtr Index + + /// + /// Gets a nullable value, indicating the platform-specific index for this GraphicsMode. + /// + public IntPtr? Index + { + get + { + if (index == null) + { + GraphicsMode mode; + lock (mode_selection_lock) + { + mode = implementation.SelectGraphicsMode(ColorFormat, Depth, Stencil, Samples, AccumulatorFormat, Buffers, Stereo); + } + + Index = mode.Index; + ColorFormat = mode.ColorFormat; + Depth = mode.Depth; + Stencil = mode.Stencil; + Samples = mode.Samples; + AccumulatorFormat = mode.AccumulatorFormat; + Buffers = mode.Buffers; + Stereo = mode.Stereo; + } + + return index; + } + set { index = value; } + } + + #endregion + #region public int ColorFormat /// @@ -283,41 +317,6 @@ namespace OpenTK.Graphics #endregion - #region --- Internal Methods --- - - #region internal IntPtr Index - - internal IntPtr? Index - { - get - { - if (index == null) - { - GraphicsMode mode; - lock (mode_selection_lock) - { - mode = implementation.SelectGraphicsMode(ColorFormat, Depth, Stencil, Samples, AccumulatorFormat, Buffers, Stereo); - } - - Index = mode.Index; - ColorFormat = mode.ColorFormat; - Depth = mode.Depth; - Stencil = mode.Stencil; - Samples = mode.Samples; - AccumulatorFormat = mode.AccumulatorFormat; - Buffers = mode.Buffers; - Stereo = mode.Stereo; - } - - return index; - } - set { index = value; } - } - - #endregion - - #endregion - #region --- Overrides --- /// Returns a System.String describing the current GraphicsFormat. diff --git a/Source/OpenTK/Platform/Dummy/DummyGLContext.cs b/Source/OpenTK/Platform/Dummy/DummyGLContext.cs index 680d5cdb..a017b9b5 100644 --- a/Source/OpenTK/Platform/Dummy/DummyGLContext.cs +++ b/Source/OpenTK/Platform/Dummy/DummyGLContext.cs @@ -53,23 +53,6 @@ namespace OpenTK.Platform.Dummy public override void MakeCurrent(IWindowInfo info) { } public override bool IsCurrent { get { return true; } } - [Obsolete] - public event DestroyEvent Destroy; - [Obsolete] - void OnDestroy() { if (Destroy != null) Destroy(this, EventArgs.Empty); } - - [Obsolete] - public void RegisterForDisposal(IDisposable resource) - { - throw new NotImplementedException("Use the general GraphicsContext class instead."); - } - - [Obsolete] - public void DisposeResources() - { - throw new NotImplementedException("Use the general GraphicsContext class instead."); - } - public override IntPtr GetAddress(string function) { return IntPtr.Zero; } public override bool VSync { get { return vsync; } set { vsync = value; } } diff --git a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs index b20aaaa8..0b4377b0 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs @@ -35,7 +35,7 @@ namespace OpenTK.Platform.MacOS /// /// Describes a Carbon window. /// - public sealed class CarbonWindowInfo : IWindowInfo + sealed class CarbonWindowInfo : IWindowInfo { IntPtr windowRef; bool ownHandle = false; diff --git a/Source/OpenTK/Platform/Utilities.cs b/Source/OpenTK/Platform/Utilities.cs index ee25db84..ae44a2f4 100644 --- a/Source/OpenTK/Platform/Utilities.cs +++ b/Source/OpenTK/Platform/Utilities.cs @@ -169,50 +169,6 @@ namespace OpenTK.Platform return @new != null; } - #endregion - - - #region public bool IsIdle - - interface IIsIdle { bool IsIdle { get; } } - - class X11IsIdle : IIsIdle - { - public bool IsIdle - { - get - { - return X11.API.Pending(IntPtr.Zero) == 0; - } - } - } - - class WindowsIsIdle : IIsIdle - { - Windows.MSG msg; - - public bool IsIdle - { - get - { - return !Windows.Functions.PeekMessage(ref msg, IntPtr.Zero, 0, 0, 0); - } - } - } - - static IIsIdle isIdleImpl = - System.Environment.OSVersion.Platform == PlatformID.Unix ? - (IIsIdle)new X11IsIdle() : (IIsIdle)new WindowsIsIdle(); - - public static bool IsIdle - { - get - { - return isIdleImpl.IsIdle; - } - } - - #endregion #region --- Creating a Graphics Context --- @@ -226,6 +182,7 @@ namespace OpenTK.Platform /// The minor OpenGL version number for this IGraphicsContext. /// A bitwise collection of GraphicsContextFlags with specific options for this IGraphicsContext. /// A new IGraphicsContext instance. + [Obsolete("Call new OpenTK.Graphics.GraphicsContext() directly, instead.")] public static IGraphicsContext CreateGraphicsContext( GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags) @@ -238,135 +195,76 @@ namespace OpenTK.Platform return context; } - /// - /// Creates an IGraphicsContext instance for the specified System.Windows.Forms.Control. - /// - /// The GraphicsMode for the GraphicsContext. - /// A System.Windows.Forms.Control. - /// A new IGraphicsContext instance. - /// An IWindowInfo instance for the specified cntrl. - [Obsolete("Create the IWindowInfo object first by calling CreateWindowInfo, then use the CreateGraphicsContext overload which takes major, minor and flags parameters.")] - public static void CreateGraphicsContext(GraphicsMode mode, Control cntrl, - out IGraphicsContext context, out IWindowInfo info) - { - CreateGraphicsContext(mode, cntrl.Handle, out context, out info); - } + #region CreateX11WindowInfo /// - /// Creates an IGraphicsContext instance for the specified System.Windows.Forms.Control. + /// Constructs a new IWindowInfo instance for the X11 platform. /// - /// The GraphicsMode for the GraphicsContext. - /// A System.IntPtr that contains the handle for a System.Windows.Forms.Control. - /// A new IGraphicsContext instance. - /// An IWindowInfo instance for the specified ctrl. - [Obsolete("Create the IWindowInfo object first by calling CreateWindowInfo, then use the CreateGraphicsContext overload which takes major, minor and flags parameters.")] - public static void CreateGraphicsContext(GraphicsMode mode, IntPtr cntrlHandle, - out IGraphicsContext context, out IWindowInfo info) - { - info = CreateWindowInfo(mode, cntrlHandle, true); - - context = new GraphicsContext(mode, info); - context.MakeCurrent(info); - - (context as IGraphicsContextInternal).LoadAll(); - } - - #region --- CreateWindowInfo --- - - /// - /// Creates an object which implements the IWindowInfo interface for the platform - /// currently running on. - /// - /// The desired GraphicsMode for this window. - /// The handle to the control, obtained from Control.Handle. - /// Set to true if this is a Windows.Forms control. - /// - public static IWindowInfo CreateWindowInfo(GraphicsMode mode, IntPtr controlHandle, bool isControl) - { - if (Configuration.RunningOnWindows) return CreateWinWindowInfo(controlHandle); - else if (Configuration.RunningOnX11) return CreateX11WindowInfo(mode, controlHandle, isControl); - else if (Configuration.RunningOnMacOS) return CreateMacOSCarbonWindowInfo(controlHandle, isControl); - else - throw new PlatformNotSupportedException("Refer to http://www.opentk.com for more information."); - } - - #endregion - - #region --- X11 Platform-specific implementation --- - - private static IWindowInfo CreateX11WindowInfo(GraphicsMode mode, IntPtr controlHandle, bool isControl) + /// The display connection. + /// The screen. + /// The handle for the window. + /// The root window for screen. + /// A pointer to a XVisualInfo structure obtained through XGetVisualInfo. + /// A new IWindowInfo instance. + public static IWindowInfo CreateX11WindowInfo(IntPtr display, int screen, IntPtr windowHandle, IntPtr rootWindow, IntPtr visualInfo) { Platform.X11.X11WindowInfo window = new OpenTK.Platform.X11.X11WindowInfo(); - window.WindowHandle = controlHandle; - - if (isControl) - { - 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."); - - // get the required handles from the X11 API. - window.Display = (IntPtr)GetStaticFieldValue(xplatui, "DisplayHandle"); - window.RootWindow = (IntPtr)GetStaticFieldValue(xplatui, "RootWindow"); - window.Screen = (int)GetStaticFieldValue(xplatui, "ScreenNo"); - - // get the X11 Visual info for the display. - Platform.X11.XVisualInfo info = new Platform.X11.XVisualInfo(); - - if (!mode.Index.HasValue) - throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); - - info.VisualID = mode.Index.Value; - int dummy; - window.VisualInfo = (Platform.X11.XVisualInfo)Marshal.PtrToStructure( - Platform.X11.Functions.XGetVisualInfo(window.Display, Platform.X11.XVisualInfoMask.ID, - ref info, out dummy), typeof(Platform.X11.XVisualInfo)); - - // set the X11 colormap. - SetStaticFieldValue(xplatui, "CustomVisual", window.VisualInfo.Visual); - SetStaticFieldValue(xplatui, "CustomColormap", - Platform.X11.Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.Visual, 0)); - } - else - { - } + window.Display = display; + window.Screen = screen; + window.WindowHandle = windowHandle; + window.RootWindow = rootWindow; + window.VisualInfo = (X11.XVisualInfo)Marshal.PtrToStructure(visualInfo, typeof(X11.XVisualInfo)); return window; } #endregion - #region --- Windows Platform-specific implementation --- - private static IWindowInfo CreateWinWindowInfo(IntPtr controlHandle) + #region CreateWindowsWindowInfo + + /// + /// Creates an IWindowInfo instance for the windows platform. + /// + /// The handle of the window. + /// A new IWindowInfo instance. + public static IWindowInfo CreateWindowsWindowInfo(IntPtr windowHandle) { - return new OpenTK.Platform.Windows.WinWindowInfo(controlHandle, null); - } - - #endregion - #region --- Mac OS X Platform-specific implementation --- - - private static IWindowInfo CreateMacOSCarbonWindowInfo(IntPtr controlHandle, bool isControl) - { - return new OpenTK.Platform.MacOS.CarbonWindowInfo(controlHandle, false, isControl); + return new OpenTK.Platform.Windows.WinWindowInfo(windowHandle, null); } #endregion - #region --- Utility functions for reading/writing non-public static fields through reflection --- + #region CreateMacOSCarbonWindowInfo - private static object GetStaticFieldValue(Type type, string fieldName) + /// + /// Creates an IWindowInfo instance for the Mac OS X platform. + /// + /// The handle of the window. + /// Ignored. This is reserved for future use. + /// Set to true if windowHandle corresponds to a System.Windows.Forms control. + /// A new IWindowInfo instance. + public static IWindowInfo CreateMacOSCarbonWindowInfo(IntPtr windowHandle, bool ownHandle, bool isControl) { - return type.GetField(fieldName, - System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null); + return new OpenTK.Platform.MacOS.CarbonWindowInfo(windowHandle, false, isControl); } - private static void SetStaticFieldValue(Type type, string fieldName, object value) + + #endregion + + #region CreateDummyWindowInfo + + /// + /// Creates an IWindowInfo instance for the dummy platform. + /// + /// A new IWindowInfo instance. + public static IWindowInfo CreateDummyWindowInfo() { - type.GetField(fieldName, - System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, value); + return new Dummy.DummyWindowInfo(); } #endregion #endregion + + } } diff --git a/Source/OpenTK/Platform/Windows/WinWindowInfo.cs b/Source/OpenTK/Platform/Windows/WinWindowInfo.cs index 78cd5676..73239126 100644 --- a/Source/OpenTK/Platform/Windows/WinWindowInfo.cs +++ b/Source/OpenTK/Platform/Windows/WinWindowInfo.cs @@ -34,7 +34,7 @@ using System.Runtime.InteropServices; namespace OpenTK.Platform.Windows { /// Describes a win32 window. - public sealed class WinWindowInfo : IWindowInfo + sealed class WinWindowInfo : IWindowInfo { IntPtr handle, dc; WinWindowInfo parent; diff --git a/Source/OpenTK/Platform/X11/API.cs b/Source/OpenTK/Platform/X11/API.cs index 753943df..59831011 100644 --- a/Source/OpenTK/Platform/X11/API.cs +++ b/Source/OpenTK/Platform/X11/API.cs @@ -586,10 +586,8 @@ XF86VidModeGetGammaRampSize( #region internal class XVisualInfo -#pragma warning disable 1591 - [StructLayout(LayoutKind.Sequential)] - public struct XVisualInfo + struct XVisualInfo { public IntPtr Visual; public VisualID VisualID; @@ -609,8 +607,6 @@ XF86VidModeGetGammaRampSize( } } -#pragma warning restore 1591 - #endregion #region internal class SetWindowAttributes diff --git a/Source/OpenTK/Platform/X11/X11WindowInfo.cs b/Source/OpenTK/Platform/X11/X11WindowInfo.cs index 9d7d0fdc..9dcf1f93 100644 --- a/Source/OpenTK/Platform/X11/X11WindowInfo.cs +++ b/Source/OpenTK/Platform/X11/X11WindowInfo.cs @@ -32,7 +32,7 @@ using System.Text; namespace OpenTK.Platform.X11 { /// Describes an X11 window. - public sealed class X11WindowInfo : IWindowInfo + sealed class X11WindowInfo : IWindowInfo { IntPtr handle, rootWindow, display; X11WindowInfo parent;