#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
#region --- Using Directives ---
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
#endregion
namespace OpenTK.Platform
{
///
/// Provides cross-platform utilities to help interact with the underlying platform.
///
public static class Utilities
{
#region --- LoadAddress ---
internal interface ILoadAddress
{
IntPtr LoadAddress(string function);
}
internal class LoadAddressWindows : ILoadAddress
{
public IntPtr LoadAddress(string function)
{
return OpenTK.Platform.Windows.Wgl.Imports.GetProcAddress(function);
}
}
internal class LoadAddressX11 : ILoadAddress
{
public IntPtr LoadAddress(string function)
{
return X11.Glx.GetProcAddress(function);
}
}
internal class LoadAddressOSX : ILoadAddress
{
public IntPtr LoadAddress(string function)
{
string fname = "_" + function;
if (!OSX.Functions.NSIsSymbolNameDefined(fname))
return IntPtr.Zero;
IntPtr symbol = OSX.Functions.NSLookupAndBindSymbol(fname);
if (symbol != IntPtr.Zero)
symbol = OSX.Functions.NSAddressOfSymbol(symbol);
return symbol;
}
}
#endregion
#region --- Fields ---
///
/// Enumerates the platforms OpenTK can run on.
///
private enum Platform
{
Unknown,
Windows,
X11,
X11_ARB,
OSX
};
private static ILoadAddress loadAddress;
#endregion
private static Platform platform = Platform.Unknown;
public static IWindowInfo GetWindowInfo(Form form)
{
throw new NotImplementedException();
}
#region public static IntPtr GetAddress(string function)
///
/// Retrieves the entry point for a dynamically exported OpenGL function.
///
/// The function string for the OpenGL function (eg. "glNewList")
///
/// An IntPtr contaning the address for the entry point, or IntPtr.Zero if the specified
/// OpenGL function is not dynamically exported.
///
///
///
/// The Marshal.GetDelegateForFunctionPointer method can be used to turn the return value
/// into a call-able delegate.
///
///
/// This function is cross-platform. It determines the underlying platform and uses the
/// correct wgl, glx or agl GetAddress function to retrieve the function pointer.
///
///
///
///
public static IntPtr GetAddress(string function)
{
if (platform == Platform.Unknown)
{
if (System.Environment.OSVersion.Platform == PlatformID.Win32NT ||
System.Environment.OSVersion.Platform == PlatformID.Win32S ||
System.Environment.OSVersion.Platform == PlatformID.Win32Windows ||
System.Environment.OSVersion.Platform == PlatformID.WinCE)
{
platform = Platform.Windows;
loadAddress = new LoadAddressWindows();
}
else if (System.Environment.OSVersion.Platform == PlatformID.Unix)
{
platform = Platform.X11;
loadAddress = new LoadAddressX11();
}
else
{
throw new PlatformNotSupportedException(
"Extension loading is only supported under X11 and Windows. We are sorry for the inconvience.");
}
}
return loadAddress.LoadAddress(function);
}
#endregion
#region private static Delegate GetExtensionDelegate(string name, Type signature)
///
/// Creates a System.Delegate that can be used to call a dynamically exported OpenGL function.
///
/// The name of the OpenGL function (eg. "glNewList")
/// The signature of the OpenGL function.
///
/// A System.Delegate that can be used to call this OpenGL function or null
/// if the function is not available in the current OpenGL context.
///
internal static Delegate GetExtensionDelegate(string name, Type signature)
{
IntPtr address = GetAddress(name);
if (address == IntPtr.Zero ||
address == new IntPtr(1) || // Workaround for buggy nvidia drivers which return
address == new IntPtr(2)) // 1 or 2 instead of IntPtr.Zero for some extensions.
{
return null;
}
else
{
return Marshal.GetDelegateForFunctionPointer(address, signature);
}
}
#endregion
static bool throw_on_error;
internal static bool ThrowOnX11Error
{
get { return throw_on_error; }
set
{
if (value && !throw_on_error)
{
Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms")
.GetField("ErrorExceptions", System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic)
.SetValue(null, true);
}
else if (!value && throw_on_error)
{
Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms")
.GetField("ErrorExceptions", System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic)
.SetValue(null, false);
}
}
}
}
}