Merge pull request #103 from thefiddler/memopt
Memory optimizations. Memory consumption reduced by up to 80% and memory allocations reduced by up to 70%, depending on the platform.
This commit is contained in:
commit
47ffbe3501
52 changed files with 90017 additions and 141738 deletions
|
@ -168,19 +168,42 @@ namespace Bind
|
|||
sw.WriteLine("static {0}()", Settings.OutputClass);
|
||||
sw.WriteLine("{");
|
||||
sw.Indent();
|
||||
sw.WriteLine("EntryPointNames = new string[]", delegates.Count);
|
||||
// Write entry point names.
|
||||
// Instead of strings, which are costly to construct,
|
||||
// we use a 1d array of ASCII bytes. Names are laid out
|
||||
// sequentially, with a nul-terminator between them.
|
||||
sw.WriteLine("EntryPointNames = new byte[]", delegates.Count);
|
||||
sw.WriteLine("{");
|
||||
sw.Indent();
|
||||
foreach (var d in delegates.Values.Select(d => d.First()))
|
||||
{
|
||||
if (!Settings.IsEnabled(Settings.Legacy.UseDllImports) || d.Extension != "Core")
|
||||
if (d.RequiresSlot(Settings))
|
||||
{
|
||||
sw.WriteLine("\"{0}{1}\",", Settings.FunctionPrefix, d.Name);
|
||||
var name = Settings.FunctionPrefix + d.Name;
|
||||
sw.WriteLine("{0}, 0,", String.Join(", ",
|
||||
System.Text.Encoding.ASCII.GetBytes(name).Select(b => b.ToString()).ToArray()));
|
||||
}
|
||||
}
|
||||
sw.Unindent();
|
||||
sw.WriteLine("};");
|
||||
sw.WriteLine("EntryPoints = new IntPtr[EntryPointNames.Length];");
|
||||
// Write entry point name offsets.
|
||||
// This is an array of offsets into the EntryPointNames[] array above.
|
||||
sw.WriteLine("EntryPointNameOffsets = new int[]", delegates.Count);
|
||||
sw.WriteLine("{");
|
||||
sw.Indent();
|
||||
int offset = 0;
|
||||
foreach (var d in delegates.Values.Select(d => d.First()))
|
||||
{
|
||||
if (d.RequiresSlot(Settings))
|
||||
{
|
||||
sw.WriteLine("{0},", offset);
|
||||
var name = Settings.FunctionPrefix + d.Name;
|
||||
offset += name.Length + 1;
|
||||
}
|
||||
}
|
||||
sw.Unindent();
|
||||
sw.WriteLine("};");
|
||||
sw.WriteLine("EntryPoints = new IntPtr[EntryPointNameOffsets.Length];");
|
||||
sw.Unindent();
|
||||
sw.WriteLine("}");
|
||||
sw.WriteLine();
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Bind.ES
|
|||
// overloads using the "All" enum in addition to strongly-typed enums.
|
||||
// This can be disabled by passing "-o:-keep_untyped_enums" as a cmdline parameter.
|
||||
Settings.DefaultCompatibility |= Settings.Legacy.KeepUntypedEnums;
|
||||
Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports;
|
||||
//Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Bind.ES
|
|||
// overloads using the "All" enum in addition to strongly-typed enums.
|
||||
// This can be disabled by passing "-o:-keep_untyped_enums" as a cmdline parameter.
|
||||
Settings.DefaultCompatibility |= Settings.Legacy.KeepUntypedEnums;
|
||||
Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports;
|
||||
//Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace Bind.ES
|
|||
// overloads using the "All" enum in addition to strongly-typed enums.
|
||||
// This can be disabled by passing "-o:-keep_untyped_enums" as a cmdline parameter.
|
||||
Settings.DefaultCompatibility |= Settings.Legacy.KeepUntypedEnums;
|
||||
Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports;
|
||||
//Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,10 +154,20 @@ namespace Bind
|
|||
|
||||
void GenerateAddressTable(DelegateCollection delegates)
|
||||
{
|
||||
// We allocate one slot per entry point. Rules:
|
||||
// - All extensions get a slot
|
||||
// - Core functions get a slot, unless UseDllImports is enabled
|
||||
// - On Windows, core functions with version > 1.1 must be treated as extensions.
|
||||
// This is controlled via the UseWindowsCompatibleGL setting.
|
||||
// Entry points without a slot are assigned the magic slot index -1.
|
||||
// Generator.Rewrite detects this and generates a static DllImport call
|
||||
// instead of a calli instruction for these functions.
|
||||
|
||||
int slot = -1;
|
||||
foreach (var list in delegates.Values)
|
||||
{
|
||||
if (!Settings.IsEnabled(Settings.Legacy.UseDllImports) || list.First().Extension != "Core")
|
||||
var func = list.First();
|
||||
if (func.RequiresSlot(Settings))
|
||||
{
|
||||
slot++;
|
||||
foreach (var d in list)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#region License
|
||||
#region License
|
||||
//
|
||||
// GL2Generator.cs
|
||||
//
|
||||
|
@ -55,6 +55,9 @@ namespace Bind.GL2
|
|||
Settings.DefaultWrappersFile = "GL.cs";
|
||||
Settings.DefaultDocPath = Path.Combine(
|
||||
Settings.DefaultDocPath, "GL");
|
||||
|
||||
//Settings.DefaultCompatibility |=
|
||||
// Settings.Legacy.UseDllImports | Settings.Legacy.UseWindowsCompatibleGL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#region License
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
|
@ -49,6 +49,9 @@ namespace Bind.GL2
|
|||
Settings.DefaultDocPath, "GL");
|
||||
|
||||
Profile = "glcore";
|
||||
|
||||
//Settings.DefaultCompatibility |=
|
||||
// Settings.Legacy.UseDllImports | Settings.Legacy.UseWindowsCompatibleGL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,13 @@ namespace Bind
|
|||
AddDeprecationWarnings = 0x2000,
|
||||
/// <summary>Use DllImport declaration for core functions (do not generate entry point slots)</summary>
|
||||
UseDllImports = 0x4000,
|
||||
/// <summary>
|
||||
/// Use in conjuction with UseDllImports, to create
|
||||
/// bindings that are compatible with opengl32.dll on Windows.
|
||||
/// This uses DllImports up to GL 1.1 and function pointers
|
||||
/// for higher versions.
|
||||
/// </summary>
|
||||
UseWindowsCompatibleGL = 0x8000,
|
||||
Tao = ConstIntEnums |
|
||||
NoAdvancedEnumProcessing |
|
||||
NoPublicUnsafeFunctions |
|
||||
|
|
|
@ -302,5 +302,19 @@ namespace Bind
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static bool RequiresSlot(this Delegate d, Settings settings)
|
||||
{
|
||||
double version;
|
||||
Double.TryParse(
|
||||
d.Version,
|
||||
System.Globalization.NumberStyles.Float,
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
out version);
|
||||
return
|
||||
!settings.IsEnabled(Settings.Legacy.UseDllImports) ||
|
||||
(settings.IsEnabled(Settings.Legacy.UseWindowsCompatibleGL) && version > 1.1) ||
|
||||
d.Extension != "Core";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,22 +17,49 @@ namespace Examples.Tests
|
|||
{
|
||||
using (Toolkit.Init(new ToolkitOptions { Backend = PlatformBackend.PreferNative }))
|
||||
{
|
||||
var window = Sdl2.CreateWindow("Test", 0, 0, 640, 480, WindowFlags.AllowHighDpi | WindowFlags.OpenGL);
|
||||
var context = Sdl2.CreateContext(window);
|
||||
Sdl2.MakeCurrent(window, context);
|
||||
// Create a window and context using a third-party toolkit
|
||||
// (in this case SDL2)
|
||||
var window = SDL.CreateWindow("Test", 0, 0, 640, 480,
|
||||
WindowFlags.AllowHighDpi | WindowFlags.OpenGL);
|
||||
var context = SDL.GL.CreateContext(window);
|
||||
|
||||
using (var dummy = new GraphicsContext(new ContextHandle(context), OpenTK.Platform.Utilities.CreateDummyWindowInfo()))
|
||||
// The external context must be made current,
|
||||
// in order to correctly initialize OpenTK.Graphics
|
||||
SDL.GL.MakeCurrent(window, context);
|
||||
|
||||
// Now we need to initialize OpenTK.Graphics using
|
||||
// the external context. This can be achieved in
|
||||
// two ways:
|
||||
//
|
||||
// var dummy = new GraphicsContext(ContextHandle.Zero, null);
|
||||
// -- or --
|
||||
// var dummy = new GraphicsContext(
|
||||
// new ContextHandle(context),
|
||||
// (name) => SDL.GL.GetAddress(name),
|
||||
// () => new ContextHandle(SDL.GL.GetCurrentContext()));
|
||||
//
|
||||
// The first approach works only on Windows, Mac and Linux/X11.
|
||||
//
|
||||
// The second approach will work on all platforms supported
|
||||
// by the external toolkit. This means that you can use
|
||||
// OpenTK.Graphics everywhere, even on platforms not directly
|
||||
// supported by OpenTK.
|
||||
|
||||
using (var dummy = new GraphicsContext(
|
||||
new ContextHandle(context),
|
||||
SDL.GL.GetAddress,
|
||||
() => new ContextHandle(SDL.GL.GetCurrentContext())))
|
||||
{
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
Sdl2.PumpEvents();
|
||||
SDL.PumpEvents();
|
||||
GL.ClearColor(i / 100.0f, i / 100.0f, i / 100.0f, i / 100.0f);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
|
||||
Sdl2.SwapWindow(window);
|
||||
SDL.GL.SwapWindow(window);
|
||||
}
|
||||
|
||||
Sdl2.DestroyWindow(window);
|
||||
SDL.DestroyWindow(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,33 +74,36 @@ namespace Examples.Tests
|
|||
AllowHighDpi = 0x00002000,
|
||||
}
|
||||
|
||||
static class Sdl2
|
||||
static class SDL
|
||||
{
|
||||
const string lib = "SDL2.dll";
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_CreateWindow", ExactSpelling = true)]
|
||||
public static extern IntPtr CreateWindow(string title, int x, int y, int w, int h, WindowFlags flags);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_CreateContext", ExactSpelling = true)]
|
||||
public static extern IntPtr CreateContext(IntPtr window);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_DestroyWindow", ExactSpelling = true)]
|
||||
public static extern void DestroyWindow(IntPtr window);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_GetCurrentContext", ExactSpelling = true)]
|
||||
public static extern IntPtr GetCurrentContext();
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_GetProcAddress", ExactSpelling = true)]
|
||||
public static extern IntPtr GetAddress(string name);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_MakeCurrent", ExactSpelling = true)]
|
||||
public static extern int MakeCurrent(IntPtr window, IntPtr context);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_PumpEvents", ExactSpelling = true)]
|
||||
public static extern void PumpEvents();
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_SwapWindow", ExactSpelling = true)]
|
||||
public static extern void SwapWindow(IntPtr window);
|
||||
public static class GL
|
||||
{
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_CreateContext", ExactSpelling = true)]
|
||||
public static extern IntPtr CreateContext(IntPtr window);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_GetCurrentContext", ExactSpelling = true)]
|
||||
public static extern IntPtr GetCurrentContext();
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_GetProcAddress", ExactSpelling = true)]
|
||||
public static extern IntPtr GetAddress(string name);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_MakeCurrent", ExactSpelling = true)]
|
||||
public static extern int MakeCurrent(IntPtr window, IntPtr context);
|
||||
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_SwapWindow", ExactSpelling = true)]
|
||||
public static extern void SwapWindow(IntPtr window);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -44,17 +44,20 @@ namespace OpenTK
|
|||
/// <summary>
|
||||
/// A reflection handle to the nested type that contains the function delegates.
|
||||
/// </summary>
|
||||
[Obsolete("Not used")]
|
||||
readonly protected Type DelegatesClass;
|
||||
|
||||
/// <summary>
|
||||
/// A refection handle to the nested type that contains core functions (i.e. not extensions).
|
||||
/// </summary>
|
||||
[Obsolete("Not used")]
|
||||
readonly protected Type CoreClass;
|
||||
|
||||
/// <summary>
|
||||
/// A mapping of core function names to MethodInfo handles.
|
||||
/// </summary>
|
||||
readonly protected SortedList<string, MethodInfo> CoreFunctionMap = new SortedList<string, MethodInfo>();
|
||||
[Obsolete("Not used")]
|
||||
readonly protected SortedList<string, MethodInfo> CoreFunctionMap;
|
||||
|
||||
bool rebuildExtensionList = true;
|
||||
|
||||
|
@ -67,18 +70,6 @@ namespace OpenTK
|
|||
/// </summary>
|
||||
public BindingsBase()
|
||||
{
|
||||
DelegatesClass = this.GetType().GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
CoreClass = this.GetType().GetNestedType("Core", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
if (CoreClass != null)
|
||||
{
|
||||
MethodInfo[] methods = CoreClass.GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
|
||||
CoreFunctionMap = new SortedList<string, MethodInfo>(methods.Length); // Avoid resizing
|
||||
foreach (MethodInfo m in methods)
|
||||
{
|
||||
CoreFunctionMap.Add(m.Name, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -122,7 +113,7 @@ namespace OpenTK
|
|||
/// <summary>
|
||||
/// Marshals a pointer to a null-terminated byte array to the specified <c>StringBuilder</c>.
|
||||
/// This method supports OpenTK and is not intended to be called by user code.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
/// <param name="ptr">A pointer to a null-terminated byte array.</param>
|
||||
/// <param name="sb">The StringBuilder to receive the contents of the pointer.</param>
|
||||
protected static void MarshalPtrToStringBuilder(IntPtr ptr, StringBuilder sb)
|
||||
|
@ -238,107 +229,7 @@ namespace OpenTK
|
|||
|
||||
#region Internal Members
|
||||
|
||||
#region LoadEntryPoints
|
||||
|
||||
internal virtual void LoadEntryPoints()
|
||||
{
|
||||
// Using reflection is more than 3 times faster than directly loading delegates on the first
|
||||
// run, probably due to code generation overhead. Subsequent runs are faster with direct loading
|
||||
// than with reflection, but the first time is more significant.
|
||||
|
||||
int supported = 0;
|
||||
|
||||
FieldInfo[] delegates = DelegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (delegates == null)
|
||||
throw new InvalidOperationException("The specified type does not have any loadable extensions.");
|
||||
|
||||
Debug.Write("Loading extensions for " + this.GetType().FullName + "... ");
|
||||
|
||||
Stopwatch time = new Stopwatch();
|
||||
time.Reset();
|
||||
time.Start();
|
||||
|
||||
foreach (FieldInfo f in delegates)
|
||||
{
|
||||
Delegate d = LoadDelegate(f.Name, f.FieldType);
|
||||
if (d != null)
|
||||
++supported;
|
||||
|
||||
lock (SyncRoot)
|
||||
{
|
||||
f.SetValue(null, d);
|
||||
}
|
||||
}
|
||||
|
||||
rebuildExtensionList = true;
|
||||
|
||||
time.Stop();
|
||||
Debug.Print("{0} extensions loaded in {1} ms.", supported, time.Elapsed.TotalMilliseconds);
|
||||
time.Reset();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LoadEntryPoint
|
||||
|
||||
internal virtual bool LoadEntryPoint(string function)
|
||||
{
|
||||
FieldInfo f = DelegatesClass.GetField(function, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
if (f == null)
|
||||
return false;
|
||||
|
||||
Delegate old = f.GetValue(null) as Delegate;
|
||||
Delegate @new = LoadDelegate(f.Name, f.FieldType);
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (old.Target != @new.Target)
|
||||
{
|
||||
f.SetValue(null, @new);
|
||||
}
|
||||
}
|
||||
return @new != null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetExtensionDelegate
|
||||
|
||||
// Creates a System.Delegate that can be used to call a dynamically exported OpenGL function.
|
||||
internal virtual 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
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Members
|
||||
|
||||
#region LoadDelegate
|
||||
|
||||
// Tries to load the specified core or extension function.
|
||||
Delegate LoadDelegate(string name, Type signature)
|
||||
{
|
||||
MethodInfo m;
|
||||
return
|
||||
GetExtensionDelegate(name, signature) ??
|
||||
(CoreFunctionMap.TryGetValue((name.Substring(2)), out m) ?
|
||||
Delegate.CreateDelegate(signature, m) : null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
internal abstract void LoadEntryPoints();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -7,31 +7,8 @@ namespace OpenTK.Graphics.ES10
|
|||
/// <summary>
|
||||
/// Provides access to OpenGL ES 1.0 methods.
|
||||
/// </summary>
|
||||
public sealed partial class GL : GraphicsBindingsBase
|
||||
public sealed partial class GL
|
||||
{
|
||||
const string Library = "libGLES.dll";
|
||||
static readonly object sync_root = new object();
|
||||
|
||||
#region --- Protected Members ---
|
||||
|
||||
/// <summary>
|
||||
/// Returns a synchronization token unique for the GL class.
|
||||
/// </summary>
|
||||
protected override object SyncRoot
|
||||
{
|
||||
get { return sync_root; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal override void LoadEntryPoints()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
internal override bool LoadEntryPoint(string function)
|
||||
{
|
||||
return true; // nothing to do
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,8 @@ namespace OpenTK.Graphics.ES11
|
|||
static readonly object sync_root = new object();
|
||||
|
||||
static IntPtr[] EntryPoints;
|
||||
static string[] EntryPointNames;
|
||||
static byte[] EntryPointNames;
|
||||
static int[] EntryPointNameOffsets;
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
@ -25,8 +26,9 @@ namespace OpenTK.Graphics.ES11
|
|||
/// </summary>
|
||||
public GL()
|
||||
{
|
||||
EntryPointsInstance = EntryPoints;
|
||||
EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointsInstance = EntryPoints;
|
||||
_EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointNameOffsetsInstance = EntryPointNameOffsets;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,7 +44,8 @@ namespace OpenTK.Graphics.ES20
|
|||
static readonly object sync_root = new object();
|
||||
|
||||
static IntPtr[] EntryPoints;
|
||||
static string[] EntryPointNames;
|
||||
static byte[] EntryPointNames;
|
||||
static int[] EntryPointNameOffsets;
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
@ -53,8 +54,9 @@ namespace OpenTK.Graphics.ES20
|
|||
/// </summary>
|
||||
public GL()
|
||||
{
|
||||
EntryPointsInstance = EntryPoints;
|
||||
EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointsInstance = EntryPoints;
|
||||
_EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointNameOffsetsInstance = EntryPointNameOffsets;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,7 +44,8 @@ namespace OpenTK.Graphics.ES30
|
|||
static readonly object sync_root = new object();
|
||||
|
||||
static IntPtr[] EntryPoints;
|
||||
static string[] EntryPointNames;
|
||||
static byte[] EntryPointNames;
|
||||
static int[] EntryPointNameOffsets;
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
@ -53,8 +54,9 @@ namespace OpenTK.Graphics.ES30
|
|||
/// </summary>
|
||||
public GL()
|
||||
{
|
||||
EntryPointsInstance = EntryPoints;
|
||||
EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointsInstance = EntryPoints;
|
||||
_EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointNameOffsetsInstance = EntryPointNameOffsets;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -39,14 +39,22 @@ namespace OpenTK.Graphics
|
|||
/// Contains the list of API entry points (function pointers).
|
||||
/// This field must be set by an inheriting class.
|
||||
/// </summary>
|
||||
[Obsolete("Not used - this field remains for 1.1 API compatibility")]
|
||||
protected IntPtr[] EntryPointsInstance;
|
||||
|
||||
/// <summary>
|
||||
/// with the 1.1 API.
|
||||
/// Contains the list of API entry point names.
|
||||
/// This field must be set by an inheriting class.
|
||||
/// </summary>
|
||||
[Obsolete("Not used - this field remains for 1.1 API compatibility")]
|
||||
protected string[] EntryPointNamesInstance;
|
||||
|
||||
|
||||
internal protected IntPtr[] _EntryPointsInstance;
|
||||
internal protected byte[] _EntryPointNamesInstance;
|
||||
internal protected int[] _EntryPointNameOffsetsInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an unmanaged function pointer to the specified function.
|
||||
/// </summary>
|
||||
|
@ -81,9 +89,16 @@ namespace OpenTK.Graphics
|
|||
throw new GraphicsContextMissingException();
|
||||
|
||||
IGraphicsContextInternal context_internal = context as IGraphicsContextInternal;
|
||||
for (int i = 0; i < EntryPointsInstance.Length; i++)
|
||||
unsafe
|
||||
{
|
||||
EntryPointsInstance[i] = context_internal.GetAddress(EntryPointNamesInstance[i]);
|
||||
fixed (byte* name = _EntryPointNamesInstance)
|
||||
{
|
||||
for (int i = 0; i < _EntryPointsInstance.Length; i++)
|
||||
{
|
||||
_EntryPointsInstance[i] = context_internal.GetAddress(
|
||||
new IntPtr(name + _EntryPointNameOffsetsInstance[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -601,7 +601,10 @@ namespace OpenTK.Graphics
|
|||
/// </returns>
|
||||
IntPtr IGraphicsContextInternal.GetAddress(string function)
|
||||
{
|
||||
return (implementation as IGraphicsContextInternal).GetAddress(function);
|
||||
IntPtr name = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(function);
|
||||
IntPtr address = (implementation as IGraphicsContextInternal).GetAddress(name);
|
||||
System.Runtime.InteropServices.Marshal.FreeHGlobal(name);
|
||||
return address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -92,7 +92,13 @@ namespace OpenTK.Graphics
|
|||
|
||||
public ContextHandle Context { get { return Handle; } }
|
||||
|
||||
public abstract IntPtr GetAddress(string function);
|
||||
// This function is no longer used.
|
||||
// The GraphicsContext facade will
|
||||
// always call the IntPtr overload.
|
||||
public IntPtr GetAddress(string function)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public abstract IntPtr GetAddress(IntPtr function);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -75,11 +75,11 @@ namespace OpenTK.Graphics.OpenGL
|
|||
|
||||
internal const string Library = "opengl32.dll";
|
||||
|
||||
static SortedList<string, bool> AvailableExtensions = new SortedList<string, bool>();
|
||||
static readonly object sync_root = new object();
|
||||
|
||||
static IntPtr[] EntryPoints;
|
||||
static string[] EntryPointNames;
|
||||
static byte[] EntryPointNames;
|
||||
static int[] EntryPointNameOffsets;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -90,8 +90,9 @@ namespace OpenTK.Graphics.OpenGL
|
|||
/// </summary>
|
||||
public GL()
|
||||
{
|
||||
EntryPointsInstance = EntryPoints;
|
||||
EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointsInstance = EntryPoints;
|
||||
_EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointNameOffsetsInstance = EntryPointNameOffsets;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,7 +44,8 @@ namespace OpenTK.Graphics.OpenGL4
|
|||
static readonly object sync_root = new object();
|
||||
|
||||
static IntPtr[] EntryPoints;
|
||||
static string[] EntryPointNames;
|
||||
static byte[] EntryPointNames;
|
||||
static int[] EntryPointNameOffsets;
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
@ -53,8 +54,9 @@ namespace OpenTK.Graphics.OpenGL4
|
|||
/// </summary>
|
||||
public GL()
|
||||
{
|
||||
EntryPointsInstance = EntryPoints;
|
||||
EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointsInstance = EntryPoints;
|
||||
_EntryPointNamesInstance = EntryPointNames;
|
||||
_EntryPointNameOffsetsInstance = EntryPointNameOffsets;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace OpenTK.Input
|
|||
public sealed class KeyboardDevice : IInputDevice
|
||||
{
|
||||
//private IKeyboard keyboard;
|
||||
private bool[] keys = new bool[Enum.GetValues(typeof(Key)).Length];
|
||||
private bool[] keys = new bool[(int)Key.LastKey];
|
||||
private bool[] scancodes = new bool[256];
|
||||
private string description;
|
||||
private int numKeys, numFKeys, numLeds;
|
||||
|
|
|
@ -345,9 +345,6 @@
|
|||
<Compile Include="Platform\X11\Functions.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Platform\X11\GlxHelper.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Platform\X11\API.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
|
||||
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
|
||||
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
|
||||
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
|
||||
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
|
|
|
@ -40,12 +40,11 @@ namespace OpenTK.Platform
|
|||
|
||||
new OpenTK.Graphics.OpenGL.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.OpenGL4.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES10.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES11.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES20.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES30.GL().LoadEntryPoints();
|
||||
|
||||
Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
|
||||
Debug.WriteLine(String.Format("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,14 +79,10 @@ namespace OpenTK.Platform.Dummy
|
|||
get { return current_thread != null && current_thread == Thread.CurrentThread; }
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(string function)
|
||||
{
|
||||
return Loader(function);
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
string str = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(function);
|
||||
return Loader(str);
|
||||
}
|
||||
|
||||
public override int SwapInterval
|
||||
|
@ -108,7 +104,6 @@ namespace OpenTK.Platform.Dummy
|
|||
{
|
||||
new OpenTK.Graphics.OpenGL.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.OpenGL4.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES10.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES11.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES20.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES30.GL().LoadEntryPoints();
|
||||
|
|
|
@ -136,11 +136,6 @@ namespace OpenTK.Platform.Egl
|
|||
|
||||
#region IGraphicsContextInternal Members
|
||||
|
||||
public override IntPtr GetAddress(string function)
|
||||
{
|
||||
return Egl.GetProcAddress(function);
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
return Egl.GetProcAddress(function);
|
||||
|
|
|
@ -38,7 +38,6 @@ namespace OpenTK.Platform
|
|||
{
|
||||
Stopwatch time = Stopwatch.StartNew();
|
||||
|
||||
new OpenTK.Graphics.ES10.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES11.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES20.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES30.GL().LoadEntryPoints();
|
||||
|
|
1143
Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
Normal file
1143
Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -47,6 +47,12 @@ namespace OpenTK
|
|||
static readonly IntPtr selFlushBuffer = Selector.Get("flushBuffer");
|
||||
static readonly IntPtr selMakeCurrentContext = Selector.Get("makeCurrentContext");
|
||||
static readonly IntPtr selUpdate = Selector.Get("update");
|
||||
static readonly IntPtr opengl = NS.AddImage(
|
||||
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
|
||||
AddImageFlags.ReturnOnError);
|
||||
static readonly IntPtr opengles = NS.AddImage(
|
||||
"/System/Library/Frameworks/OpenGL.framework/OpenGLES",
|
||||
AddImageFlags.ReturnOnError);
|
||||
|
||||
static CocoaContext()
|
||||
{
|
||||
|
@ -292,14 +298,49 @@ namespace OpenTK
|
|||
|
||||
#region IGraphicsContextInternal Members
|
||||
|
||||
public override IntPtr GetAddress(string function)
|
||||
{
|
||||
return NS.GetAddress(function);
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
return NS.GetAddress(function);
|
||||
unsafe
|
||||
{
|
||||
// Add a leading underscore to the function name
|
||||
// As of OpenGL 4.4, all functions are < 64 bytes
|
||||
// in length. Double that just to be sure.
|
||||
const int max = 128;
|
||||
byte* fun = stackalloc byte[max];
|
||||
byte* ptr = fun;
|
||||
byte* cur = (byte*)function.ToPointer();
|
||||
int i = 0;
|
||||
|
||||
*ptr++ = (byte)'_';
|
||||
while (*cur != 0 && ++i < max)
|
||||
{
|
||||
*ptr++ = *cur++;
|
||||
}
|
||||
|
||||
if (i >= max - 1)
|
||||
{
|
||||
Debug.Print("Function {0} too long. Loading will fail.",
|
||||
Marshal.PtrToStringAnsi(function));
|
||||
}
|
||||
|
||||
IntPtr address = IntPtr.Zero;
|
||||
IntPtr symbol = IntPtr.Zero;
|
||||
if (opengl != IntPtr.Zero)
|
||||
{
|
||||
symbol = NS.LookupSymbolInImage(opengl, new IntPtr(fun),
|
||||
SymbolLookupFlags.Bind | SymbolLookupFlags.ReturnOnError);
|
||||
}
|
||||
if (symbol == IntPtr.Zero && opengles != IntPtr.Zero)
|
||||
{
|
||||
symbol = NS.LookupSymbolInImage(opengles, new IntPtr(fun),
|
||||
SymbolLookupFlags.Bind | SymbolLookupFlags.ReturnOnError);
|
||||
}
|
||||
if (symbol != IntPtr.Zero)
|
||||
{
|
||||
address = NS.AddressOfSymbol(symbol);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -135,7 +135,6 @@ namespace OpenTK.Platform.MacOS
|
|||
private Nullable<WindowBorder> deferredWindowBorder;
|
||||
private Nullable<WindowBorder> previousWindowBorder;
|
||||
private WindowState windowState = WindowState.Normal;
|
||||
private MacOSKeyMap keyMap = new MacOSKeyMap();
|
||||
private OpenTK.Input.KeyboardKeyEventArgs keyArgs = new OpenTK.Input.KeyboardKeyEventArgs();
|
||||
private KeyPressEventArgs keyPressArgs = new KeyPressEventArgs((char)0);
|
||||
private string title;
|
||||
|
@ -337,13 +336,7 @@ namespace OpenTK.Platform.MacOS
|
|||
|
||||
private void GetKey(ushort keyCode, NSEventModifierMask modifierFlags, OpenTK.Input.KeyboardKeyEventArgs args)
|
||||
{
|
||||
OpenTK.Input.Key key;
|
||||
if (!keyMap.TryGetValue((OpenTK.Platform.MacOS.Carbon.MacOSKeyCode)keyCode, out key))
|
||||
{
|
||||
key = OpenTK.Input.Key.Unknown;
|
||||
}
|
||||
|
||||
args.Key = key;
|
||||
args.Key = MacOSKeyMap.GetKey((Carbon.MacOSKeyCode)keyCode);
|
||||
args.Modifiers = GetModifiers(modifierFlags);
|
||||
args.ScanCode = (uint)keyCode;
|
||||
}
|
||||
|
|
|
@ -36,127 +36,229 @@ namespace OpenTK.Platform.MacOS
|
|||
using Carbon;
|
||||
using Input;
|
||||
|
||||
class MacOSKeyMap : Dictionary<MacOSKeyCode, Key>
|
||||
static class MacOSKeyMap
|
||||
{
|
||||
public MacOSKeyMap()
|
||||
public static Key GetKey(MacOSKeyCode code)
|
||||
{
|
||||
// comments indicate members of the Key enum that are missing
|
||||
|
||||
Add(MacOSKeyCode.A, Key.A);
|
||||
Add(MacOSKeyCode.OptionAlt, Key.AltLeft);
|
||||
// AltRight
|
||||
Add(MacOSKeyCode.B, Key.B);
|
||||
|
||||
Add(MacOSKeyCode.Backslash, Key.BackSlash);
|
||||
Add(MacOSKeyCode.Backspace, Key.BackSpace);
|
||||
Add(MacOSKeyCode.BracketLeft, Key.BracketLeft);
|
||||
Add(MacOSKeyCode.BracketRight, Key.BracketRight);
|
||||
Add(MacOSKeyCode.C, Key.C);
|
||||
// Capslock
|
||||
// Clear
|
||||
Add(MacOSKeyCode.Comma, Key.Comma);
|
||||
Add(MacOSKeyCode.Control, Key.ControlLeft);
|
||||
// ControlRight
|
||||
Add(MacOSKeyCode.D, Key.D);
|
||||
Add(MacOSKeyCode.Del, Key.Delete);
|
||||
Add(MacOSKeyCode.Down, Key.Down);
|
||||
Add(MacOSKeyCode.E, Key.E);
|
||||
Add(MacOSKeyCode.End, Key.End);
|
||||
Add(MacOSKeyCode.Enter, Key.Enter);
|
||||
Add(MacOSKeyCode.Return, Key.Enter);
|
||||
Add(MacOSKeyCode.Esc, Key.Escape);
|
||||
Add(MacOSKeyCode.F, Key.F);
|
||||
Add(MacOSKeyCode.F1, Key.F1);
|
||||
Add(MacOSKeyCode.F2, Key.F2);
|
||||
Add(MacOSKeyCode.F3, Key.F3);
|
||||
Add(MacOSKeyCode.F4, Key.F4);
|
||||
Add(MacOSKeyCode.F5, Key.F5);
|
||||
Add(MacOSKeyCode.F6, Key.F6);
|
||||
Add(MacOSKeyCode.F7, Key.F7);
|
||||
Add(MacOSKeyCode.F8, Key.F8);
|
||||
Add(MacOSKeyCode.F9, Key.F9);
|
||||
Add(MacOSKeyCode.F10, Key.F10);
|
||||
Add(MacOSKeyCode.F11, Key.F11);
|
||||
Add(MacOSKeyCode.F12, Key.F12);
|
||||
Add(MacOSKeyCode.F13, Key.F13);
|
||||
Add(MacOSKeyCode.F14, Key.F14);
|
||||
Add(MacOSKeyCode.F15, Key.F15);
|
||||
// F16-F35
|
||||
Add(MacOSKeyCode.G, Key.G);
|
||||
Add(MacOSKeyCode.H, Key.H);
|
||||
Add(MacOSKeyCode.Home, Key.Home);
|
||||
Add(MacOSKeyCode.I, Key.I);
|
||||
Add(MacOSKeyCode.Insert, Key.Insert);
|
||||
Add(MacOSKeyCode.J, Key.J);
|
||||
Add(MacOSKeyCode.K, Key.K);
|
||||
Add(MacOSKeyCode.KeyPad_0, Key.Keypad0);
|
||||
Add(MacOSKeyCode.KeyPad_1, Key.Keypad1);
|
||||
Add(MacOSKeyCode.KeyPad_2, Key.Keypad2);
|
||||
Add(MacOSKeyCode.KeyPad_3, Key.Keypad3);
|
||||
Add(MacOSKeyCode.KeyPad_4, Key.Keypad4);
|
||||
Add(MacOSKeyCode.KeyPad_5, Key.Keypad5);
|
||||
Add(MacOSKeyCode.KeyPad_6, Key.Keypad6);
|
||||
Add(MacOSKeyCode.KeyPad_7, Key.Keypad7);
|
||||
Add(MacOSKeyCode.KeyPad_8, Key.Keypad8);
|
||||
Add(MacOSKeyCode.KeyPad_9, Key.Keypad9);
|
||||
Add(MacOSKeyCode.KeyPad_Add, Key.KeypadAdd);
|
||||
Add(MacOSKeyCode.KeyPad_Decimal, Key.KeypadDecimal);
|
||||
Add(MacOSKeyCode.KeyPad_Divide, Key.KeypadDivide);
|
||||
Add(MacOSKeyCode.KeyPad_Enter, Key.KeypadEnter);
|
||||
Add(MacOSKeyCode.KeyPad_Multiply, Key.KeypadMultiply);
|
||||
Add(MacOSKeyCode.KeyPad_Subtract, Key.KeypadSubtract);
|
||||
//Add(MacOSKeyCode.KeyPad_Equal);
|
||||
Add(MacOSKeyCode.L, Key.L);
|
||||
Add(MacOSKeyCode.Left, Key.Left);
|
||||
Add(MacOSKeyCode.M, Key.M);
|
||||
//Key.MaxKeys
|
||||
Add(MacOSKeyCode.Menu, Key.Menu);
|
||||
Add(MacOSKeyCode.Minus, Key.Minus);
|
||||
Add(MacOSKeyCode.N, Key.N);
|
||||
Add(MacOSKeyCode.Key_0, Key.Number0);
|
||||
Add(MacOSKeyCode.Key_1, Key.Number1);
|
||||
Add(MacOSKeyCode.Key_2, Key.Number2);
|
||||
Add(MacOSKeyCode.Key_3, Key.Number3);
|
||||
Add(MacOSKeyCode.Key_4, Key.Number4);
|
||||
Add(MacOSKeyCode.Key_5, Key.Number5);
|
||||
Add(MacOSKeyCode.Key_6, Key.Number6);
|
||||
Add(MacOSKeyCode.Key_7, Key.Number7);
|
||||
Add(MacOSKeyCode.Key_8, Key.Number8);
|
||||
Add(MacOSKeyCode.Key_9, Key.Number9);
|
||||
// Numlock
|
||||
Add(MacOSKeyCode.O, Key.O);
|
||||
Add(MacOSKeyCode.P, Key.P);
|
||||
Add(MacOSKeyCode.Pagedown, Key.PageDown);
|
||||
Add(MacOSKeyCode.Pageup, Key.PageUp);
|
||||
// Pause
|
||||
Add(MacOSKeyCode.Period, Key.Period);
|
||||
Add(MacOSKeyCode.Equals, Key.Plus);
|
||||
// PrintScreen
|
||||
Add(MacOSKeyCode.Q, Key.Q);
|
||||
Add(MacOSKeyCode.Quote, Key.Quote);
|
||||
Add(MacOSKeyCode.R, Key.R);
|
||||
Add(MacOSKeyCode.Right, Key.Right);
|
||||
Add(MacOSKeyCode.S, Key.S);
|
||||
// ScrollLock
|
||||
Add(MacOSKeyCode.Semicolon, Key.Semicolon);
|
||||
Add(MacOSKeyCode.Shift, Key.ShiftLeft);
|
||||
//Key.ShiftRight
|
||||
Add(MacOSKeyCode.Slash, Key.Slash);
|
||||
// Key.Sleep
|
||||
Add(MacOSKeyCode.Space, Key.Space);
|
||||
Add(MacOSKeyCode.T, Key.T);
|
||||
Add(MacOSKeyCode.Tab, Key.Tab);
|
||||
Add(MacOSKeyCode.Tilde, Key.Tilde);
|
||||
Add(MacOSKeyCode.U, Key.U);
|
||||
Add(MacOSKeyCode.Up, Key.Up);
|
||||
Add(MacOSKeyCode.V, Key.V);
|
||||
Add(MacOSKeyCode.W, Key.W);
|
||||
Add(MacOSKeyCode.Command, Key.WinLeft);
|
||||
// WinKeyRight
|
||||
Add(MacOSKeyCode.X, Key.X);
|
||||
Add(MacOSKeyCode.Y, Key.Y);
|
||||
Add(MacOSKeyCode.Z, Key.Z);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case MacOSKeyCode.A:
|
||||
return Key.A;
|
||||
case MacOSKeyCode.OptionAlt:
|
||||
return Key.AltLeft;
|
||||
// AltRight
|
||||
case MacOSKeyCode.B:
|
||||
return Key.B;
|
||||
case MacOSKeyCode.Backslash:
|
||||
return Key.BackSlash;
|
||||
case MacOSKeyCode.Backspace:
|
||||
return Key.BackSpace;
|
||||
case MacOSKeyCode.BracketLeft:
|
||||
return Key.BracketLeft;
|
||||
case MacOSKeyCode.BracketRight:
|
||||
return Key.BracketRight;
|
||||
case MacOSKeyCode.C:
|
||||
return Key.C;
|
||||
// Capslock
|
||||
// Clear
|
||||
case MacOSKeyCode.Comma:
|
||||
return Key.Comma;
|
||||
case MacOSKeyCode.Control:
|
||||
return Key.ControlLeft;
|
||||
// ControlRight
|
||||
case MacOSKeyCode.D:
|
||||
return Key.D;
|
||||
case MacOSKeyCode.Del:
|
||||
return Key.Delete;
|
||||
case MacOSKeyCode.Down:
|
||||
return Key.Down;
|
||||
case MacOSKeyCode.E:
|
||||
return Key.E;
|
||||
case MacOSKeyCode.End:
|
||||
return Key.End;
|
||||
case MacOSKeyCode.Enter:
|
||||
return Key.Enter;
|
||||
case MacOSKeyCode.Return:
|
||||
return Key.Enter;
|
||||
case MacOSKeyCode.Esc:
|
||||
return Key.Escape;
|
||||
case MacOSKeyCode.F:
|
||||
return Key.F;
|
||||
case MacOSKeyCode.F1:
|
||||
return Key.F1;
|
||||
case MacOSKeyCode.F2:
|
||||
return Key.F2;
|
||||
case MacOSKeyCode.F3:
|
||||
return Key.F3;
|
||||
case MacOSKeyCode.F4:
|
||||
return Key.F4;
|
||||
case MacOSKeyCode.F5:
|
||||
return Key.F5;
|
||||
case MacOSKeyCode.F6:
|
||||
return Key.F6;
|
||||
case MacOSKeyCode.F7:
|
||||
return Key.F7;
|
||||
case MacOSKeyCode.F8:
|
||||
return Key.F8;
|
||||
case MacOSKeyCode.F9:
|
||||
return Key.F9;
|
||||
case MacOSKeyCode.F10:
|
||||
return Key.F10;
|
||||
case MacOSKeyCode.F11:
|
||||
return Key.F11;
|
||||
case MacOSKeyCode.F12:
|
||||
return Key.F12;
|
||||
case MacOSKeyCode.F13:
|
||||
return Key.F13;
|
||||
case MacOSKeyCode.F14:
|
||||
return Key.F14;
|
||||
case MacOSKeyCode.F15:
|
||||
return Key.F15;
|
||||
// F16-F35
|
||||
case MacOSKeyCode.G:
|
||||
return Key.G;
|
||||
case MacOSKeyCode.H:
|
||||
return Key.H;
|
||||
case MacOSKeyCode.Home:
|
||||
return Key.Home;
|
||||
case MacOSKeyCode.I:
|
||||
return Key.I;
|
||||
case MacOSKeyCode.Insert:
|
||||
return Key.Insert;
|
||||
case MacOSKeyCode.J:
|
||||
return Key.J;
|
||||
case MacOSKeyCode.K:
|
||||
return Key.K;
|
||||
case MacOSKeyCode.KeyPad_0:
|
||||
return Key.Keypad0;
|
||||
case MacOSKeyCode.KeyPad_1:
|
||||
return Key.Keypad1;
|
||||
case MacOSKeyCode.KeyPad_2:
|
||||
return Key.Keypad2;
|
||||
case MacOSKeyCode.KeyPad_3:
|
||||
return Key.Keypad3;
|
||||
case MacOSKeyCode.KeyPad_4:
|
||||
return Key.Keypad4;
|
||||
case MacOSKeyCode.KeyPad_5:
|
||||
return Key.Keypad5;
|
||||
case MacOSKeyCode.KeyPad_6:
|
||||
return Key.Keypad6;
|
||||
case MacOSKeyCode.KeyPad_7:
|
||||
return Key.Keypad7;
|
||||
case MacOSKeyCode.KeyPad_8:
|
||||
return Key.Keypad8;
|
||||
case MacOSKeyCode.KeyPad_9:
|
||||
return Key.Keypad9;
|
||||
case MacOSKeyCode.KeyPad_Add:
|
||||
return Key.KeypadAdd;
|
||||
case MacOSKeyCode.KeyPad_Decimal:
|
||||
return Key.KeypadDecimal;
|
||||
case MacOSKeyCode.KeyPad_Divide:
|
||||
return Key.KeypadDivide;
|
||||
case MacOSKeyCode.KeyPad_Enter:
|
||||
return Key.KeypadEnter;
|
||||
case MacOSKeyCode.KeyPad_Multiply:
|
||||
return Key.KeypadMultiply;
|
||||
case MacOSKeyCode.KeyPad_Subtract:
|
||||
return Key.KeypadSubtract;
|
||||
//case MacOSKeyCode.KeyPad_Equal;
|
||||
case MacOSKeyCode.L:
|
||||
return Key.L;
|
||||
case MacOSKeyCode.Left:
|
||||
return Key.Left;
|
||||
case MacOSKeyCode.M:
|
||||
return Key.M;
|
||||
//Key.MaxKeys
|
||||
case MacOSKeyCode.Menu:
|
||||
return Key.Menu;
|
||||
case MacOSKeyCode.Minus:
|
||||
return Key.Minus;
|
||||
case MacOSKeyCode.N:
|
||||
return Key.N;
|
||||
case MacOSKeyCode.Key_0:
|
||||
return Key.Number0;
|
||||
case MacOSKeyCode.Key_1:
|
||||
return Key.Number1;
|
||||
case MacOSKeyCode.Key_2:
|
||||
return Key.Number2;
|
||||
case MacOSKeyCode.Key_3:
|
||||
return Key.Number3;
|
||||
case MacOSKeyCode.Key_4:
|
||||
return Key.Number4;
|
||||
case MacOSKeyCode.Key_5:
|
||||
return Key.Number5;
|
||||
case MacOSKeyCode.Key_6:
|
||||
return Key.Number6;
|
||||
case MacOSKeyCode.Key_7:
|
||||
return Key.Number7;
|
||||
case MacOSKeyCode.Key_8:
|
||||
return Key.Number8;
|
||||
case MacOSKeyCode.Key_9:
|
||||
return Key.Number9;
|
||||
// Numlock
|
||||
case MacOSKeyCode.O:
|
||||
return Key.O;
|
||||
case MacOSKeyCode.P:
|
||||
return Key.P;
|
||||
case MacOSKeyCode.Pagedown:
|
||||
return Key.PageDown;
|
||||
case MacOSKeyCode.Pageup:
|
||||
return Key.PageUp;
|
||||
// Pause
|
||||
case MacOSKeyCode.Period:
|
||||
return Key.Period;
|
||||
case MacOSKeyCode.Equals:
|
||||
return Key.Plus;
|
||||
// PrintScreen
|
||||
case MacOSKeyCode.Q:
|
||||
return Key.Q;
|
||||
case MacOSKeyCode.Quote:
|
||||
return Key.Quote;
|
||||
case MacOSKeyCode.R:
|
||||
return Key.R;
|
||||
case MacOSKeyCode.Right:
|
||||
return Key.Right;
|
||||
case MacOSKeyCode.S:
|
||||
return Key.S;
|
||||
// ScrollLock
|
||||
case MacOSKeyCode.Semicolon:
|
||||
return Key.Semicolon;
|
||||
case MacOSKeyCode.Shift:
|
||||
return Key.ShiftLeft;
|
||||
//Key.ShiftRight
|
||||
case MacOSKeyCode.Slash:
|
||||
return Key.Slash;
|
||||
// Key.Sleep
|
||||
case MacOSKeyCode.Space:
|
||||
return Key.Space;
|
||||
case MacOSKeyCode.T:
|
||||
return Key.T;
|
||||
case MacOSKeyCode.Tab:
|
||||
return Key.Tab;
|
||||
case MacOSKeyCode.Tilde:
|
||||
return Key.Tilde;
|
||||
case MacOSKeyCode.U:
|
||||
return Key.U;
|
||||
case MacOSKeyCode.Up:
|
||||
return Key.Up;
|
||||
case MacOSKeyCode.V:
|
||||
return Key.V;
|
||||
case MacOSKeyCode.W:
|
||||
return Key.W;
|
||||
case MacOSKeyCode.Command:
|
||||
return Key.WinLeft;
|
||||
// WinKeyRight
|
||||
case MacOSKeyCode.X:
|
||||
return Key.X;
|
||||
case MacOSKeyCode.Y:
|
||||
return Key.Y;
|
||||
case MacOSKeyCode.Z:
|
||||
return Key.Z;
|
||||
|
||||
default:
|
||||
return Key.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,27 +33,52 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
[Flags]
|
||||
enum AddImageFlags
|
||||
{
|
||||
ReturnOnError = 1,
|
||||
WithSearching = 2,
|
||||
ReturnOnlyIfLoaded = 4
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum SymbolLookupFlags
|
||||
{
|
||||
Bind = 0,
|
||||
BindNow = 1,
|
||||
BindFully = 2,
|
||||
ReturnOnError = 4
|
||||
}
|
||||
|
||||
internal class NS
|
||||
{
|
||||
const string Library = "libdl.dylib";
|
||||
|
||||
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
|
||||
static extern bool NSIsSymbolNameDefined(string s);
|
||||
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
|
||||
static extern bool NSIsSymbolNameDefined(IntPtr s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
|
||||
static extern IntPtr NSLookupAndBindSymbol(string s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
|
||||
static extern IntPtr NSLookupAndBindSymbol(IntPtr s);
|
||||
[DllImport(Library, EntryPoint = "NSAddImage")]
|
||||
internal static extern IntPtr AddImage(string s, AddImageFlags flags);
|
||||
[DllImport(Library, EntryPoint = "NSAddressOfSymbol")]
|
||||
static extern IntPtr NSAddressOfSymbol(IntPtr symbol);
|
||||
internal static extern IntPtr AddressOfSymbol(IntPtr symbol);
|
||||
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
|
||||
internal static extern bool IsSymbolNameDefined(string s);
|
||||
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
|
||||
internal static extern bool IsSymbolNameDefined(IntPtr s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
|
||||
internal static extern IntPtr LookupAndBindSymbol(string s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
|
||||
internal static extern IntPtr LookupAndBindSymbol(IntPtr s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupSymbolInImage")]
|
||||
internal static extern IntPtr LookupSymbolInImage(IntPtr image, IntPtr symbolName, SymbolLookupFlags options);
|
||||
|
||||
// Unfortunately, these are slower even if they are more
|
||||
// portable and simpler to use.
|
||||
[DllImport(Library)]
|
||||
private static extern IntPtr dlopen(String fileName, int flags);
|
||||
internal static extern IntPtr dlopen(String fileName, int flags);
|
||||
[DllImport(Library)]
|
||||
private static extern int dlclose(IntPtr handle);
|
||||
internal static extern int dlclose(IntPtr handle);
|
||||
[DllImport (Library)]
|
||||
private static extern IntPtr dlsym (IntPtr handle, string symbol);
|
||||
internal static extern IntPtr dlsym (IntPtr handle, string symbol);
|
||||
[DllImport (Library)]
|
||||
internal static extern IntPtr dlsym (IntPtr handle, IntPtr symbol);
|
||||
|
||||
public static IntPtr GetAddress(string function)
|
||||
{
|
||||
|
@ -73,7 +98,7 @@ namespace OpenTK.Platform.MacOS
|
|||
}
|
||||
Marshal.WriteByte(ptr, function.Length + 1, 0); // null-terminate
|
||||
|
||||
IntPtr symbol = GetAddress(ptr);
|
||||
IntPtr symbol = GetAddressInternal(ptr);
|
||||
return symbol;
|
||||
}
|
||||
finally
|
||||
|
@ -84,12 +109,39 @@ namespace OpenTK.Platform.MacOS
|
|||
|
||||
public static IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
IntPtr symbol = IntPtr.Zero;
|
||||
if (NSIsSymbolNameDefined(function))
|
||||
unsafe
|
||||
{
|
||||
symbol = NSLookupAndBindSymbol(function);
|
||||
const int max = 64;
|
||||
byte* symbol = stackalloc byte[max];
|
||||
byte* ptr = symbol;
|
||||
byte* cur = (byte*)function.ToPointer();
|
||||
int i = 0;
|
||||
|
||||
*ptr++ = (byte)'_';
|
||||
while (*cur != 0 && ++i < max)
|
||||
{
|
||||
*ptr++ = *cur++;
|
||||
}
|
||||
|
||||
if (i >= max - 1)
|
||||
{
|
||||
throw new NotSupportedException(String.Format(
|
||||
"Function {0} is too long. Please report a bug at https://github.com/opentk/issues/issues",
|
||||
Marshal.PtrToStringAnsi(function)));
|
||||
}
|
||||
|
||||
return GetAddressInternal(new IntPtr(symbol));
|
||||
}
|
||||
}
|
||||
|
||||
static IntPtr GetAddressInternal(IntPtr function)
|
||||
{
|
||||
IntPtr symbol = IntPtr.Zero;
|
||||
if (IsSymbolNameDefined(function))
|
||||
{
|
||||
symbol = LookupAndBindSymbol(function);
|
||||
if (symbol != IntPtr.Zero)
|
||||
symbol = NSAddressOfSymbol(symbol);
|
||||
symbol = AddressOfSymbol(symbol);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
@ -99,6 +151,11 @@ namespace OpenTK.Platform.MacOS
|
|||
return dlsym(handle, symbol);
|
||||
}
|
||||
|
||||
public static IntPtr GetSymbol(IntPtr handle, IntPtr symbol)
|
||||
{
|
||||
return dlsym(handle, symbol);
|
||||
}
|
||||
|
||||
public static IntPtr LoadLibrary(string fileName)
|
||||
{
|
||||
const int RTLD_NOW = 2;
|
||||
|
|
|
@ -344,11 +344,6 @@ namespace OpenTK.Platform.SDL2
|
|||
}
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(string function)
|
||||
{
|
||||
return SDL.GL.GetProcAddress(function);
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
return SDL.GL.GetProcAddress(function);
|
||||
|
|
|
@ -33,91 +33,270 @@ namespace OpenTK.Platform.SDL2
|
|||
{
|
||||
using Code = Scancode;
|
||||
|
||||
class Sdl2KeyMap : Dictionary<Scancode, Key>
|
||||
class Sdl2KeyMap
|
||||
{
|
||||
public Sdl2KeyMap()
|
||||
public static Key GetKey(Code code)
|
||||
{
|
||||
Add(Code.ESCAPE, Key.Escape);
|
||||
|
||||
// Function keys
|
||||
for (int i = 0; i < 12; i++)
|
||||
switch (code)
|
||||
{
|
||||
Add(Code.F1 + i, Key.F1 + i);
|
||||
case Code.ESCAPE:
|
||||
return Key.Escape;
|
||||
|
||||
// Function keys
|
||||
case Code.F1:
|
||||
return Key.F1;
|
||||
case Code.F2:
|
||||
return Key.F2;
|
||||
case Code.F3:
|
||||
return Key.F3;
|
||||
case Code.F4:
|
||||
return Key.F4;
|
||||
case Code.F5:
|
||||
return Key.F5;
|
||||
case Code.F6:
|
||||
return Key.F6;
|
||||
case Code.F7:
|
||||
return Key.F7;
|
||||
case Code.F8:
|
||||
return Key.F8;
|
||||
case Code.F9:
|
||||
return Key.F9;
|
||||
case Code.F10:
|
||||
return Key.F10;
|
||||
case Code.F11:
|
||||
return Key.F11;
|
||||
case Code.F12:
|
||||
return Key.F12;
|
||||
case Code.F13:
|
||||
return Key.F13;
|
||||
case Code.F14:
|
||||
return Key.F14;
|
||||
case Code.F15:
|
||||
return Key.F15;
|
||||
case Code.F16:
|
||||
return Key.F16;
|
||||
case Code.F17:
|
||||
return Key.F17;
|
||||
case Code.F18:
|
||||
return Key.F18;
|
||||
case Code.F19:
|
||||
return Key.F19;
|
||||
case Code.F20:
|
||||
return Key.F20;
|
||||
case Code.F21:
|
||||
return Key.F21;
|
||||
case Code.F22:
|
||||
return Key.F22;
|
||||
case Code.F23:
|
||||
return Key.F23;
|
||||
case Code.F24:
|
||||
return Key.F24;
|
||||
|
||||
// Number keys (0-9)
|
||||
case Code.Num0:
|
||||
return Key.Number0;
|
||||
case Code.Num1:
|
||||
return Key.Number1;
|
||||
case Code.Num2:
|
||||
return Key.Number2;
|
||||
case Code.Num3:
|
||||
return Key.Number3;
|
||||
case Code.Num4:
|
||||
return Key.Number4;
|
||||
case Code.Num5:
|
||||
return Key.Number5;
|
||||
case Code.Num6:
|
||||
return Key.Number6;
|
||||
case Code.Num7:
|
||||
return Key.Number7;
|
||||
case Code.Num8:
|
||||
return Key.Number8;
|
||||
case Code.Num9:
|
||||
return Key.Number9;
|
||||
|
||||
// Letters (A-Z)
|
||||
case Code.A:
|
||||
return Key.A;
|
||||
case Code.B:
|
||||
return Key.B;
|
||||
case Code.C:
|
||||
return Key.C;
|
||||
case Code.D:
|
||||
return Key.D;
|
||||
case Code.E:
|
||||
return Key.E;
|
||||
case Code.F:
|
||||
return Key.F;
|
||||
case Code.G:
|
||||
return Key.G;
|
||||
case Code.H:
|
||||
return Key.H;
|
||||
case Code.I:
|
||||
return Key.I;
|
||||
case Code.J:
|
||||
return Key.J;
|
||||
case Code.K:
|
||||
return Key.K;
|
||||
case Code.L:
|
||||
return Key.L;
|
||||
case Code.M:
|
||||
return Key.M;
|
||||
case Code.N:
|
||||
return Key.N;
|
||||
case Code.O:
|
||||
return Key.O;
|
||||
case Code.P:
|
||||
return Key.P;
|
||||
case Code.Q:
|
||||
return Key.Q;
|
||||
case Code.R:
|
||||
return Key.R;
|
||||
case Code.S:
|
||||
return Key.S;
|
||||
case Code.T:
|
||||
return Key.T;
|
||||
case Code.U:
|
||||
return Key.U;
|
||||
case Code.V:
|
||||
return Key.V;
|
||||
case Code.W:
|
||||
return Key.W;
|
||||
case Code.X:
|
||||
return Key.X;
|
||||
case Code.Y:
|
||||
return Key.Y;
|
||||
case Code.Z:
|
||||
return Key.Z;
|
||||
|
||||
case Code.TAB:
|
||||
return Key.Tab;
|
||||
case Code.CAPSLOCK:
|
||||
return Key.CapsLock;
|
||||
case Code.LCTRL:
|
||||
return Key.ControlLeft;
|
||||
case Code.LSHIFT:
|
||||
return Key.ShiftLeft;
|
||||
case Code.LALT:
|
||||
return Key.AltLeft;
|
||||
case Code.MENU:
|
||||
return Key.Menu;
|
||||
case Code.LGUI:
|
||||
return Key.WinLeft;
|
||||
case Code.RGUI:
|
||||
return Key.WinRight;
|
||||
case Code.SPACE:
|
||||
return Key.Space;
|
||||
case Code.RALT:
|
||||
return Key.AltRight;
|
||||
//case Code.:
|
||||
// return Key.WinRight;
|
||||
case Code.APPLICATION:
|
||||
return Key.Menu;
|
||||
case Code.RCTRL:
|
||||
return Key.ControlRight;
|
||||
case Code.RSHIFT:
|
||||
return Key.ShiftRight;
|
||||
case Code.RETURN:
|
||||
return Key.Enter;
|
||||
case Code.BACKSPACE:
|
||||
return Key.BackSpace;
|
||||
|
||||
case Code.SEMICOLON:
|
||||
return Key.Semicolon; // Varies by keyboard: return ;: on Win2K/US
|
||||
case Code.SLASH:
|
||||
return Key.Slash; // Varies by keyboard: return /? on Win2K/US
|
||||
case Code.GRAVE:
|
||||
return Key.Tilde; // Varies by keyboard: return `~ on Win2K/US
|
||||
case Code.LEFTBRACKET:
|
||||
return Key.BracketLeft; // Varies by keyboard: return [{ on Win2K/US
|
||||
case Code.BACKSLASH:
|
||||
return Key.BackSlash; // Varies by keyboard: return \| on Win2K/US
|
||||
case Code.RIGHTBRACKET:
|
||||
return Key.BracketRight; // Varies by keyboard: return ]} on Win2K/US
|
||||
case Code.APOSTROPHE:
|
||||
return Key.Quote; // Varies by keyboard: return '" on Win2K/US
|
||||
case Code.EQUALS:
|
||||
return Key.Plus;
|
||||
case Code.COMMA:
|
||||
return Key.Comma; // Invariant: : return
|
||||
case Code.MINUS:
|
||||
return Key.Minus; // Invariant: -
|
||||
case Code.PERIOD:
|
||||
return Key.Period; // Invariant: .
|
||||
|
||||
case Code.HOME:
|
||||
return Key.Home;
|
||||
case Code.END:
|
||||
return Key.End;
|
||||
case Code.DELETE:
|
||||
return Key.Delete;
|
||||
case Code.PAGEUP:
|
||||
return Key.PageUp;
|
||||
case Code.PAGEDOWN:
|
||||
return Key.PageDown;
|
||||
case Code.PAUSE:
|
||||
return Key.Pause;
|
||||
case Code.NUMLOCKCLEAR:
|
||||
return Key.NumLock;
|
||||
|
||||
case Code.SCROLLLOCK:
|
||||
return Key.ScrollLock;
|
||||
case Code.PRINTSCREEN:
|
||||
return Key.PrintScreen;
|
||||
case Code.CLEAR:
|
||||
return Key.Clear;
|
||||
case Code.INSERT:
|
||||
return Key.Insert;
|
||||
|
||||
case Code.SLEEP:
|
||||
return Key.Sleep;
|
||||
|
||||
// Keypad
|
||||
case Code.KP_0:
|
||||
return Key.Keypad0;
|
||||
case Code.KP_1:
|
||||
return Key.Keypad1;
|
||||
case Code.KP_2:
|
||||
return Key.Keypad2;
|
||||
case Code.KP_3:
|
||||
return Key.Keypad3;
|
||||
case Code.KP_4:
|
||||
return Key.Keypad4;
|
||||
case Code.KP_5:
|
||||
return Key.Keypad5;
|
||||
case Code.KP_6:
|
||||
return Key.Keypad6;
|
||||
case Code.KP_7:
|
||||
return Key.Keypad7;
|
||||
case Code.KP_8:
|
||||
return Key.Keypad8;
|
||||
case Code.KP_9:
|
||||
return Key.Keypad9;
|
||||
|
||||
case Code.KP_DECIMAL:
|
||||
return Key.KeypadDecimal;
|
||||
case Code.KP_PLUS:
|
||||
return Key.KeypadAdd;
|
||||
case Code.KP_MINUS:
|
||||
return Key.KeypadSubtract;
|
||||
case Code.KP_DIVIDE:
|
||||
return Key.KeypadDivide;
|
||||
case Code.KP_MULTIPLY:
|
||||
return Key.KeypadMultiply;
|
||||
|
||||
// Navigation
|
||||
case Code.UP:
|
||||
return Key.Up;
|
||||
case Code.DOWN:
|
||||
return Key.Down;
|
||||
case Code.LEFT:
|
||||
return Key.Left;
|
||||
case Code.RIGHT:
|
||||
return Key.Right;
|
||||
|
||||
default:
|
||||
return Key.Unknown;
|
||||
}
|
||||
|
||||
// Number keys (0-9)
|
||||
Add(Code.Num0, Key.Number0);
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
Add(Code.Num1 + i, Key.Number1 + i);
|
||||
}
|
||||
|
||||
// Letters (A-Z)
|
||||
for (int i = 0; i < 26; i++)
|
||||
{
|
||||
Add(Code.A + i, Key.A + i);
|
||||
}
|
||||
|
||||
Add(Code.TAB, Key.Tab);
|
||||
Add(Code.CAPSLOCK, Key.CapsLock);
|
||||
Add(Code.LCTRL, Key.ControlLeft);
|
||||
Add(Code.LSHIFT, Key.ShiftLeft);
|
||||
Add(Code.LALT, Key.AltLeft);
|
||||
Add(Code.MENU, Key.WinLeft);
|
||||
Add(Code.SPACE, Key.Space);
|
||||
Add(Code.RALT, Key.AltRight);
|
||||
//Add(Code., Key.WinRight);
|
||||
Add(Code.APPLICATION, Key.Menu);
|
||||
Add(Code.RCTRL, Key.ControlRight);
|
||||
Add(Code.RSHIFT, Key.ShiftRight);
|
||||
Add(Code.RETURN, Key.Enter);
|
||||
Add(Code.BACKSPACE, Key.BackSpace);
|
||||
|
||||
Add(Code.SEMICOLON, Key.Semicolon); // Varies by keyboard, ;: on Win2K/US
|
||||
Add(Code.SLASH, Key.Slash); // Varies by keyboard, /? on Win2K/US
|
||||
Add(Code.GRAVE, Key.Tilde); // Varies by keyboard, `~ on Win2K/US
|
||||
Add(Code.LEFTBRACKET, Key.BracketLeft); // Varies by keyboard, [{ on Win2K/US
|
||||
Add(Code.BACKSLASH, Key.BackSlash); // Varies by keyboard, \| on Win2K/US
|
||||
Add(Code.RIGHTBRACKET, Key.BracketRight); // Varies by keyboard, ]} on Win2K/US
|
||||
Add(Code.APOSTROPHE, Key.Quote); // Varies by keyboard, '" on Win2K/US
|
||||
Add(Code.EQUALS, Key.Plus);
|
||||
Add(Code.COMMA, Key.Comma); // Invariant: ,
|
||||
Add(Code.MINUS, Key.Minus); // Invariant: -
|
||||
Add(Code.PERIOD, Key.Period); // Invariant: .
|
||||
|
||||
Add(Code.HOME, Key.Home);
|
||||
Add(Code.END, Key.End);
|
||||
Add(Code.DELETE, Key.Delete);
|
||||
Add(Code.PAGEUP, Key.PageUp);
|
||||
Add(Code.PAGEDOWN, Key.PageDown);
|
||||
Add(Code.PAUSE, Key.Pause);
|
||||
Add(Code.NUMLOCKCLEAR, Key.NumLock);
|
||||
|
||||
Add(Code.SCROLLLOCK, Key.ScrollLock);
|
||||
Add(Code.PRINTSCREEN, Key.PrintScreen);
|
||||
Add(Code.CLEAR, Key.Clear);
|
||||
Add(Code.INSERT, Key.Insert);
|
||||
|
||||
Add(Code.SLEEP, Key.Sleep);
|
||||
|
||||
// Keypad
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
Add(Code.KP_1 + i, Key.Keypad1 + i);
|
||||
}
|
||||
Add(Code.KP_0, Key.Keypad0); // Note: SDL2 goes KP_1..KP_9, then KP_0
|
||||
|
||||
Add(Code.KP_DECIMAL, Key.KeypadDecimal);
|
||||
Add(Code.KP_PLUS, Key.KeypadAdd);
|
||||
Add(Code.KP_MINUS, Key.KeypadSubtract);
|
||||
Add(Code.KP_DIVIDE, Key.KeypadDivide);
|
||||
Add(Code.KP_MULTIPLY, Key.KeypadMultiply);
|
||||
|
||||
// Navigation
|
||||
Add(Code.UP, Key.Up);
|
||||
Add(Code.DOWN, Key.Down);
|
||||
Add(Code.LEFT, Key.Left);
|
||||
Add(Code.RIGHT, Key.Right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ namespace OpenTK.Platform.SDL2
|
|||
{
|
||||
class Sdl2Keyboard : IKeyboardDriver2, IKeyboardDriver
|
||||
{
|
||||
static readonly Sdl2KeyMap KeyMap = new Sdl2KeyMap();
|
||||
KeyboardState state;
|
||||
|
||||
readonly List<KeyboardDevice> keyboards =
|
||||
|
@ -84,10 +83,10 @@ namespace OpenTK.Platform.SDL2
|
|||
|
||||
internal void ProcessKeyboardEvent(KeyboardEvent e)
|
||||
{
|
||||
Key key;
|
||||
bool pressed = e.State != 0;
|
||||
var scancode = e.Keysym.Scancode;
|
||||
if (KeyMap.TryGetValue(scancode, out key))
|
||||
Key key = Sdl2KeyMap.GetKey(scancode);
|
||||
if (key != Key.Unknown)
|
||||
{
|
||||
state.SetKeyState(key, (byte)scancode, pressed);
|
||||
keyboards[0].SetKey(key, (byte)scancode, pressed);
|
||||
|
|
|
@ -75,8 +75,6 @@ namespace OpenTK.Platform.SDL2
|
|||
static readonly Dictionary<uint, Sdl2NativeWindow> windows =
|
||||
new Dictionary<uint, Sdl2NativeWindow>();
|
||||
|
||||
static readonly Sdl2KeyMap map = new Sdl2KeyMap();
|
||||
|
||||
public Sdl2NativeWindow(int x, int y, int width, int height,
|
||||
string title, GameWindowFlags options, DisplayDevice device,
|
||||
IInputDriver input_driver)
|
||||
|
@ -132,12 +130,7 @@ namespace OpenTK.Platform.SDL2
|
|||
|
||||
static Key TranslateKey(Scancode scan)
|
||||
{
|
||||
Key result = Key.Unknown;
|
||||
if (map.ContainsKey(scan))
|
||||
{
|
||||
result = map[scan];
|
||||
}
|
||||
return result;
|
||||
return Sdl2KeyMap.GetKey(scan);
|
||||
}
|
||||
|
||||
static Key TranslateKey(Keycode key)
|
||||
|
|
|
@ -15,7 +15,7 @@ using OpenTK.Graphics;
|
|||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
internal partial class Wgl : GraphicsBindingsBase
|
||||
internal partial class Wgl
|
||||
{
|
||||
static IntPtr[] EntryPoints;
|
||||
static string[] EntryPointNames;
|
||||
|
@ -29,8 +29,6 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
public Wgl()
|
||||
{
|
||||
EntryPointsInstance = EntryPoints;
|
||||
EntryPointNamesInstance = EntryPointNames;
|
||||
}
|
||||
|
||||
#region Public Members
|
||||
|
@ -43,8 +41,8 @@ namespace OpenTK.Platform.Windows
|
|||
/// <summary>
|
||||
/// Checks if a Wgl extension is supported by the given context.
|
||||
/// </summary>
|
||||
/// <param name="context">The device context.</param>
|
||||
/// <param name="ext">The extension to check.</param>
|
||||
/// <param name="dc">The device context.</param>
|
||||
/// <param name="name">The extension to check.</param>
|
||||
/// <returns>True if the extension is supported by the given context, false otherwise</returns>
|
||||
public static bool SupportsExtension(IntPtr dc, string name)
|
||||
{
|
||||
|
@ -102,12 +100,12 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#region Protected Members
|
||||
|
||||
protected override object SyncRoot
|
||||
object SyncRoot
|
||||
{
|
||||
get { return sync; }
|
||||
}
|
||||
|
||||
protected override IntPtr GetAddress(string function_string)
|
||||
IntPtr GetAddress(string function_string)
|
||||
{
|
||||
IntPtr address = Wgl.GetProcAddress(function_string);
|
||||
if (!IsValid(address))
|
||||
|
@ -133,15 +131,15 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#region Internal Members
|
||||
|
||||
internal override void LoadEntryPoints()
|
||||
internal void LoadEntryPoints()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (Wgl.GetCurrentContext() != IntPtr.Zero)
|
||||
{
|
||||
for (int i = 0; i < EntryPointsInstance.Length; i++)
|
||||
for (int i = 0; i < EntryPointNames.Length; i++)
|
||||
{
|
||||
EntryPointsInstance[i] = GetAddress(EntryPointNamesInstance[i]);
|
||||
EntryPoints[i] = GetAddress(EntryPointNames[i]);
|
||||
}
|
||||
extensions.Clear();
|
||||
}
|
||||
|
|
|
@ -374,16 +374,6 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#region GetAddress
|
||||
|
||||
public override IntPtr GetAddress(string function_string)
|
||||
{
|
||||
IntPtr address = Wgl.GetProcAddress(function_string);
|
||||
if (!IsValid(address))
|
||||
{
|
||||
address = Functions.GetProcAddress(WinFactory.OpenGLHandle, function_string);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function_string)
|
||||
{
|
||||
IntPtr address = Wgl.GetProcAddress(function_string);
|
||||
|
|
|
@ -51,7 +51,6 @@ namespace OpenTK.Platform.Windows
|
|||
const ExtendedWindowStyle ParentStyleEx = ExtendedWindowStyle.WindowEdge | ExtendedWindowStyle.ApplicationWindow;
|
||||
const ExtendedWindowStyle ChildStyleEx = 0;
|
||||
|
||||
static readonly WinKeyMap KeyMap = new WinKeyMap();
|
||||
readonly IntPtr Instance = Marshal.GetHINSTANCE(typeof(WinGLNative).Module);
|
||||
readonly IntPtr ClassName = Marshal.StringToHGlobalAuto(Guid.NewGuid().ToString());
|
||||
readonly WindowProcedure WindowProcedureDelegate;
|
||||
|
@ -578,7 +577,7 @@ namespace OpenTK.Platform.Windows
|
|||
short scancode = (short)((lParam.ToInt64() >> 16) & 0xFF);
|
||||
VirtualKeys vkey = (VirtualKeys)wParam;
|
||||
bool is_valid;
|
||||
Key key = KeyMap.TranslateKey(scancode, vkey, extended, false, out is_valid);
|
||||
Key key = WinKeyMap.TranslateKey(scancode, vkey, extended, false, out is_valid);
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
|
|
|
@ -32,163 +32,142 @@ using OpenTK.Input;
|
|||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
class WinKeyMap
|
||||
static class WinKeyMap
|
||||
{
|
||||
readonly Dictionary<int, Key> ScanMap = new Dictionary<int, Key>();
|
||||
|
||||
public WinKeyMap()
|
||||
public static Key GetKey(int code)
|
||||
{
|
||||
// 0 - 15
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Escape);
|
||||
switch (code)
|
||||
{
|
||||
// 0 - 15
|
||||
case 0: return Key.Unknown;
|
||||
case 1: return Key.Escape;
|
||||
case 2: return Key.Number1;
|
||||
case 3: return Key.Number2;
|
||||
case 4: return Key.Number3;
|
||||
case 5: return Key.Number4;
|
||||
case 6: return Key.Number5;
|
||||
case 7: return Key.Number6;
|
||||
case 8: return Key.Number7;
|
||||
case 9: return Key.Number8;
|
||||
case 10: return Key.Number9;
|
||||
case 11: return Key.Number0;
|
||||
case 12: return Key.Minus;
|
||||
case 13: return Key.Plus;
|
||||
case 14: return Key.BackSpace;
|
||||
case 15: return Key.Tab;
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
Append(Key.Number1 + i);
|
||||
Append(Key.Number0);
|
||||
// 16-31
|
||||
case 16: return Key.Q;
|
||||
case 17: return Key.W;
|
||||
case 18: return Key.E;
|
||||
case 19: return Key.R;
|
||||
case 20: return Key.T;
|
||||
case 21: return Key.Y;
|
||||
case 22: return Key.U;
|
||||
case 23: return Key.I;
|
||||
case 24: return Key.O;
|
||||
case 25: return Key.P;
|
||||
case 26: return Key.BracketLeft;
|
||||
case 27: return Key.BracketRight;
|
||||
case 28: return Key.Enter;
|
||||
case 29: return Key.ControlLeft;
|
||||
case 30: return Key.A;
|
||||
case 31: return Key.S;
|
||||
|
||||
Append(Key.Minus);
|
||||
Append(Key.Plus);
|
||||
Append(Key.BackSpace);
|
||||
Append(Key.Tab);
|
||||
// 32 - 47
|
||||
case 32: return Key.D;
|
||||
case 33: return Key.F;
|
||||
case 34: return Key.G;
|
||||
case 35: return Key.H;
|
||||
case 36: return Key.J;
|
||||
case 37: return Key.K;
|
||||
case 38: return Key.L;
|
||||
case 39: return Key.Semicolon;
|
||||
case 40: return Key.Quote;
|
||||
case 41: return Key.Grave;
|
||||
case 42: return Key.ShiftLeft;
|
||||
case 43: return Key.BackSlash;
|
||||
case 44: return Key.Z;
|
||||
case 45: return Key.X;
|
||||
case 46: return Key.C;
|
||||
case 47: return Key.V;
|
||||
|
||||
// 16-31
|
||||
Append(Key.Q);
|
||||
Append(Key.W);
|
||||
Append(Key.E);
|
||||
Append(Key.R);
|
||||
Append(Key.T);
|
||||
Append(Key.Y);
|
||||
Append(Key.U);
|
||||
Append(Key.I);
|
||||
Append(Key.O);
|
||||
Append(Key.P);
|
||||
Append(Key.BracketLeft);
|
||||
Append(Key.BracketRight);
|
||||
Append(Key.Enter);
|
||||
Append(Key.ControlLeft);
|
||||
Append(Key.A);
|
||||
Append(Key.S);
|
||||
// 48 - 63
|
||||
case 48: return Key.B;
|
||||
case 49: return Key.N;
|
||||
case 50: return Key.M;
|
||||
case 51: return Key.Comma;
|
||||
case 52: return Key.Period;
|
||||
case 53: return Key.Slash;
|
||||
case 54: return Key.ShiftRight;
|
||||
case 55: return Key.PrintScreen;
|
||||
case 56: return Key.AltLeft;
|
||||
case 57: return Key.Space;
|
||||
case 58: return Key.CapsLock;
|
||||
case 59: return Key.F1;
|
||||
case 60: return Key.F2;
|
||||
case 61: return Key.F3;
|
||||
case 62: return Key.F4;
|
||||
case 63: return Key.F5;
|
||||
|
||||
// 32 - 47
|
||||
Append(Key.D);
|
||||
Append(Key.F);
|
||||
Append(Key.G);
|
||||
Append(Key.H);
|
||||
Append(Key.J);
|
||||
Append(Key.K);
|
||||
Append(Key.L);
|
||||
Append(Key.Semicolon);
|
||||
Append(Key.Quote);
|
||||
Append(Key.Grave);
|
||||
Append(Key.ShiftLeft);
|
||||
Append(Key.BackSlash);
|
||||
Append(Key.Z);
|
||||
Append(Key.X);
|
||||
Append(Key.C);
|
||||
Append(Key.V);
|
||||
// 64 - 79
|
||||
case 64: return Key.F6;
|
||||
case 65: return Key.F7;
|
||||
case 66: return Key.F8;
|
||||
case 67: return Key.F9;
|
||||
case 68: return Key.F10;
|
||||
case 69: return Key.NumLock;
|
||||
case 70: return Key.ScrollLock;
|
||||
case 71: return Key.Home;
|
||||
case 72: return Key.Up;
|
||||
case 73: return Key.PageUp;
|
||||
case 74: return Key.KeypadMinus;
|
||||
case 75: return Key.Left;
|
||||
case 76: return Key.Keypad5;
|
||||
case 77: return Key.Right;
|
||||
case 78: return Key.KeypadPlus;
|
||||
case 79: return Key.End;
|
||||
|
||||
// 48 - 63
|
||||
Append(Key.B);
|
||||
Append(Key.N);
|
||||
Append(Key.M);
|
||||
Append(Key.Comma);
|
||||
Append(Key.Period);
|
||||
Append(Key.Slash);
|
||||
Append(Key.ShiftRight);
|
||||
Append(Key.PrintScreen);
|
||||
Append(Key.AltLeft);
|
||||
Append(Key.Space);
|
||||
Append(Key.CapsLock);
|
||||
Append(Key.F1);
|
||||
Append(Key.F2);
|
||||
Append(Key.F3);
|
||||
Append(Key.F4);
|
||||
Append(Key.F5);
|
||||
// 80 - 95
|
||||
case 80: return Key.Down;
|
||||
case 81: return Key.PageDown;
|
||||
case 82: return Key.Insert;
|
||||
case 83: return Key.Delete;
|
||||
case 84: return Key.Unknown;
|
||||
case 85: return Key.Unknown;
|
||||
case 86: return Key.NonUSBackSlash;
|
||||
case 87: return Key.F11;
|
||||
case 88: return Key.F12;
|
||||
case 89: return Key.Pause;
|
||||
case 90: return Key.Unknown;
|
||||
case 91: return Key.WinLeft;
|
||||
case 92: return Key.WinRight;
|
||||
case 93: return Key.Menu;
|
||||
case 94: return Key.Unknown;
|
||||
case 95: return Key.Unknown;
|
||||
|
||||
// 64 - 79
|
||||
Append(Key.F6);
|
||||
Append(Key.F7);
|
||||
Append(Key.F8);
|
||||
Append(Key.F9);
|
||||
Append(Key.F10);
|
||||
Append(Key.NumLock);
|
||||
Append(Key.ScrollLock);
|
||||
Append(Key.Home);
|
||||
Append(Key.Up);
|
||||
Append(Key.PageUp);
|
||||
Append(Key.KeypadMinus);
|
||||
Append(Key.Left);
|
||||
Append(Key.Keypad5);
|
||||
Append(Key.Right);
|
||||
Append(Key.KeypadPlus);
|
||||
Append(Key.End);
|
||||
// 96 - 106
|
||||
case 96: return Key.Unknown;
|
||||
case 97: return Key.Unknown;
|
||||
case 98: return Key.Unknown;
|
||||
case 99: return Key.Unknown;
|
||||
case 100: return Key.F13;
|
||||
case 101: return Key.F14;
|
||||
case 102: return Key.F15;
|
||||
case 103: return Key.F16;
|
||||
case 104: return Key.F17;
|
||||
case 105: return Key.F18;
|
||||
case 106: return Key.F19;
|
||||
|
||||
// 80 - 95
|
||||
Append(Key.Down);
|
||||
Append(Key.PageDown);
|
||||
Append(Key.Insert);
|
||||
Append(Key.Delete);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.NonUSBackSlash);
|
||||
Append(Key.F11);
|
||||
Append(Key.F12);
|
||||
Append(Key.Pause);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.WinLeft);
|
||||
Append(Key.WinRight);
|
||||
Append(Key.Menu);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
|
||||
// 96 - 111
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.F13);
|
||||
Append(Key.F14);
|
||||
Append(Key.F15);
|
||||
Append(Key.F16);
|
||||
Append(Key.F17);
|
||||
Append(Key.F18);
|
||||
Append(Key.F19);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
|
||||
// 112 - 127
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Unknown);
|
||||
default: return Key.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
void Append(Key key)
|
||||
{
|
||||
ScanMap.Add(ScanMap.Count, key);
|
||||
}
|
||||
|
||||
public Key TranslateKey(short scancode, VirtualKeys vkey, bool extended0, bool extended1, out bool is_valid)
|
||||
public static Key TranslateKey(short scancode, VirtualKeys vkey, bool extended0, bool extended1, out bool is_valid)
|
||||
{
|
||||
is_valid = true;
|
||||
|
||||
Key key;
|
||||
ScanMap.TryGetValue(scancode, out key);
|
||||
Key key = GetKey(scancode);
|
||||
|
||||
if (!extended0)
|
||||
{
|
||||
|
|
|
@ -38,7 +38,6 @@ namespace OpenTK.Platform.Windows
|
|||
{
|
||||
sealed class WinRawKeyboard : IKeyboardDriver2
|
||||
{
|
||||
static readonly WinKeyMap KeyMap = new WinKeyMap();
|
||||
readonly List<KeyboardState> keyboards = new List<KeyboardState>();
|
||||
readonly List<string> names = new List<string>();
|
||||
readonly Dictionary<ContextHandle, int> rawids = new Dictionary<ContextHandle, int>();
|
||||
|
@ -185,7 +184,7 @@ namespace OpenTK.Platform.Windows
|
|||
int keyboard_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
||||
keyboard = keyboards[keyboard_handle];
|
||||
|
||||
Key key = KeyMap.TranslateKey(scancode, vkey, extended0, extended1, out is_valid);
|
||||
Key key = WinKeyMap.TranslateKey(scancode, vkey, extended0, extended1, out is_valid);
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
|
|
|
@ -259,8 +259,38 @@ namespace OpenTK.Platform.X11
|
|||
/// <summary>
|
||||
/// Provides access to GLX functions.
|
||||
/// </summary>
|
||||
partial class Glx
|
||||
class Glx
|
||||
{
|
||||
const string Library = "libGL.so.1";
|
||||
|
||||
static string[] EntryPointNames = new string[]
|
||||
{
|
||||
"glXCreateContextAttribs",
|
||||
"glXSwapIntervalSGI",
|
||||
};
|
||||
static IntPtr[] EntryPoints = new IntPtr[EntryPointNames.Length];
|
||||
|
||||
static Glx()
|
||||
{
|
||||
// GLX entry points are not bound to a context.
|
||||
// This means we can load them without creating
|
||||
// a context first! (unlike WGL)
|
||||
for (int i = 0; i < EntryPointNames.Length; i++)
|
||||
{
|
||||
EntryPoints[i] = Arb.GetProcAddress(EntryPointNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool SupportsFunction(string name)
|
||||
{
|
||||
int index = Array.IndexOf(EntryPointNames, name);
|
||||
if (index >= 0)
|
||||
{
|
||||
return EntryPoints[index] != IntPtr.Zero;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#region GLX functions
|
||||
|
||||
[DllImport(Library, EntryPoint = "glXIsDirect")]
|
||||
|
@ -343,40 +373,26 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
#endregion
|
||||
|
||||
#region Extensions
|
||||
|
||||
public partial class Sgi
|
||||
{
|
||||
public static ErrorCode SwapInterval(int interval)
|
||||
{
|
||||
return (ErrorCode)Delegates.glXSwapIntervalSGI(interval);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Arb
|
||||
{
|
||||
#region CreateContextAttri
|
||||
#region CreateContextAttribs
|
||||
|
||||
[AutoGenerated(EntryPoint = "glXCreateContextAttribsARB")]
|
||||
unsafe public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs)
|
||||
{
|
||||
return Delegates.glXCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[AutoGenerated(EntryPoint = "glXCreateContextAttribsARB")]
|
||||
public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int[] attribs)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (int* attribs_ptr = attribs)
|
||||
{
|
||||
return Delegates.glXCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs_ptr);
|
||||
}
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region GetProcAddress
|
||||
|
||||
|
||||
// The linux OpenGL ABI 3.6 (1999) requires
|
||||
// that glXGetProcAddressARB be available as
|
||||
// a static export. The same is *not* true
|
||||
|
@ -385,22 +401,25 @@ namespace OpenTK.Platform.X11
|
|||
// See http://www.opengl.org/registry/ABI/
|
||||
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
|
||||
public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
internal static partial class Delegates
|
||||
public partial class Sgi
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
public delegate int SwapIntervalSGI(int interval);
|
||||
public static SwapIntervalSGI glXSwapIntervalSGI = null;
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
unsafe public delegate IntPtr CreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
|
||||
unsafe public static CreateContextAttribsARB glXCreateContextAttribsARB = null;
|
||||
[AutoGenerated(EntryPoint = "glXSwapIntervalSGI")]
|
||||
public static ErrorCode SwapInterval(int interval)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
[Slot(0)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern IntPtr glXCreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
|
||||
[Slot(1)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern IntPtr glXSwapIntervalSGI(int interval);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
#region --- License ---
|
||||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||
* See license.txt for license info
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
partial class Glx : BindingsBase
|
||||
{
|
||||
const string Library = "libGL.so.1";
|
||||
static readonly object sync_root = new object();
|
||||
|
||||
static Glx()
|
||||
{
|
||||
// GLX entry points are not bound to a context.
|
||||
// This means we can load them without creating
|
||||
// a context first! (unlike WGL)
|
||||
// See
|
||||
// for more details.
|
||||
Debug.WriteLine("Loading GLX entry points.");
|
||||
new Glx().LoadEntryPoints();
|
||||
}
|
||||
|
||||
protected override object SyncRoot
|
||||
{
|
||||
get { return sync_root; }
|
||||
}
|
||||
|
||||
protected override IntPtr GetAddress(string funcname)
|
||||
{
|
||||
// We must use glXGetProcAddressARB, *not*
|
||||
// glXGetProcAddress. See comment on function
|
||||
// signature.
|
||||
return Glx.Arb.GetProcAddress(funcname);
|
||||
}
|
||||
|
||||
#if false
|
||||
#region static Delegate LoadDelegate(string name, Type signature)
|
||||
|
||||
/// <summary>
|
||||
/// Creates a System.Delegate that can be used to call an OpenGL function, core or extension.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the Wgl function (eg. "wglNewList")</param>
|
||||
/// <param name="signature">The signature of the OpenGL function.</param>
|
||||
/// <returns>
|
||||
/// A System.Delegate that can be used to call this OpenGL function, or null if the specified
|
||||
/// function name did not correspond to an OpenGL function.
|
||||
/// </returns>
|
||||
static Delegate LoadDelegate(string name, Type signature)
|
||||
{
|
||||
Delegate d;
|
||||
string realName = name.ToLower().StartsWith("glx") ? name.Substring(3) : name;
|
||||
|
||||
if (typeof(Glx).GetMethod(realName,
|
||||
BindingFlags.NonPublic | BindingFlags.Static) != null)
|
||||
d = GetExtensionDelegate(name, signature) ??
|
||||
Delegate.CreateDelegate(signature, typeof(Glx), realName);
|
||||
else
|
||||
d = GetExtensionDelegate(name, signature);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private static Delegate GetExtensionDelegate(string name, Type signature)
|
||||
|
||||
/// <summary>
|
||||
/// Creates a System.Delegate that can be used to call a dynamically exported OpenGL function.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the OpenGL function (eg. "glNewList")</param>
|
||||
/// <param name="signature">The signature of the OpenGL function.</param>
|
||||
/// <returns>
|
||||
/// 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.
|
||||
/// </returns>
|
||||
private static Delegate GetExtensionDelegate(string name, Type signature)
|
||||
{
|
||||
IntPtr address = Glx.GetProcAddress(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
|
||||
|
||||
#region internal static void LoadAll
|
||||
|
||||
public static void LoadAll()
|
||||
{
|
||||
OpenTK.Platform.Utilities.LoadExtensions(typeof(Glx));
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -253,7 +253,7 @@ namespace OpenTK.Platform.X11
|
|||
return
|
||||
SupportsExtension(display, window, "GLX_ARB_create_context") &&
|
||||
SupportsExtension(display, window, "GLX_ARB_create_context_profile") &&
|
||||
Glx.Delegates.glXCreateContextAttribsARB != null;
|
||||
Glx.SupportsFunction("glXCreateContextAttribsARB");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -380,8 +380,7 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
public override void LoadAll()
|
||||
{
|
||||
new Glx().LoadEntryPoints();
|
||||
vsync_supported = this.GetAddress("glXSwapIntervalSGI") != IntPtr.Zero;
|
||||
vsync_supported = Glx.SupportsFunction("glXSwapIntervalSGI");
|
||||
Debug.Print("Context supports vsync: {0}.", vsync_supported);
|
||||
|
||||
base.LoadAll();
|
||||
|
@ -395,14 +394,6 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
#region GetAddress
|
||||
|
||||
public override IntPtr GetAddress(string function)
|
||||
{
|
||||
using (new XLock(Display))
|
||||
{
|
||||
return Glx.GetProcAddress(function);
|
||||
}
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
using (new XLock(Display))
|
||||
|
|
|
@ -29,7 +29,6 @@ namespace OpenTK.Platform.X11
|
|||
List<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1);
|
||||
List<MouseDevice> dummy_mice_list = new List<MouseDevice>(1);
|
||||
|
||||
X11KeyMap keymap = new X11KeyMap();
|
||||
int firstKeyCode, lastKeyCode; // The smallest and largest KeyCode supported by the X server.
|
||||
int keysyms_per_keycode; // The number of KeySyms for each KeyCode.
|
||||
IntPtr[] keysyms;
|
||||
|
@ -100,17 +99,12 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
XKey keysym = (XKey)API.LookupKeysym(ref e, 0);
|
||||
XKey keysym2 = (XKey)API.LookupKeysym(ref e, 1);
|
||||
key = Key.Unknown;
|
||||
|
||||
if (keymap.ContainsKey(keysym))
|
||||
key = X11KeyMap.GetKey(keysym);
|
||||
if (key == Key.Unknown)
|
||||
{
|
||||
key = keymap[keysym];
|
||||
key = X11KeyMap.GetKey(keysym2);
|
||||
}
|
||||
else if (keymap.ContainsKey(keysym2))
|
||||
{
|
||||
key = keymap[keysym2];
|
||||
}
|
||||
else
|
||||
if (key == Key.Unknown)
|
||||
{
|
||||
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
|
||||
}
|
||||
|
|
|
@ -10,129 +10,364 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
internal class X11KeyMap : Dictionary<XKey, Key>
|
||||
static class X11KeyMap
|
||||
{
|
||||
internal X11KeyMap()
|
||||
public static Key GetKey(XKey key)
|
||||
{
|
||||
try
|
||||
switch (key)
|
||||
{
|
||||
this.Add(XKey.Escape, Key.Escape);
|
||||
this.Add(XKey.Return, Key.Enter);
|
||||
this.Add(XKey.space, Key.Space);
|
||||
this.Add(XKey.BackSpace, Key.BackSpace);
|
||||
case XKey.Escape:
|
||||
return Key.Escape;
|
||||
case XKey.Return:
|
||||
return Key.Enter;
|
||||
case XKey.space:
|
||||
return Key.Space;
|
||||
case XKey.BackSpace:
|
||||
return Key.BackSpace;
|
||||
|
||||
this.Add(XKey.Shift_L, Key.ShiftLeft);
|
||||
this.Add(XKey.Shift_R, Key.ShiftRight);
|
||||
this.Add(XKey.Alt_L, Key.AltLeft);
|
||||
this.Add(XKey.Alt_R, Key.AltRight);
|
||||
this.Add(XKey.Control_L, Key.ControlLeft);
|
||||
this.Add(XKey.Control_R, Key.ControlRight);
|
||||
this.Add(XKey.Super_L, Key.WinLeft);
|
||||
this.Add(XKey.Super_R, Key.WinRight);
|
||||
this.Add(XKey.Meta_L, Key.WinLeft);
|
||||
this.Add(XKey.Meta_R, Key.WinRight);
|
||||
this.Add(XKey.ISO_Level3_Shift, Key.AltRight); // Normally AltGr
|
||||
case XKey.Shift_L:
|
||||
return Key.ShiftLeft;
|
||||
case XKey.Shift_R:
|
||||
return Key.ShiftRight;
|
||||
case XKey.Alt_L:
|
||||
return Key.AltLeft;
|
||||
case XKey.Alt_R:
|
||||
return Key.AltRight;
|
||||
case XKey.Control_L:
|
||||
return Key.ControlLeft;
|
||||
case XKey.Control_R:
|
||||
return Key.ControlRight;
|
||||
case XKey.Super_L:
|
||||
return Key.WinLeft;
|
||||
case XKey.Super_R:
|
||||
return Key.WinRight;
|
||||
case XKey.Meta_L:
|
||||
return Key.WinLeft;
|
||||
case XKey.Meta_R:
|
||||
return Key.WinRight;
|
||||
case XKey.ISO_Level3_Shift:
|
||||
return Key.AltRight; // Normally AltGr
|
||||
|
||||
this.Add(XKey.Menu, Key.Menu);
|
||||
this.Add(XKey.Tab, Key.Tab);
|
||||
this.Add(XKey.minus, Key.Minus);
|
||||
this.Add(XKey.plus, Key.Plus);
|
||||
this.Add(XKey.equal, Key.Plus);
|
||||
case XKey.Menu:
|
||||
return Key.Menu;
|
||||
case XKey.Tab:
|
||||
return Key.Tab;
|
||||
case XKey.minus:
|
||||
return Key.Minus;
|
||||
case XKey.plus:
|
||||
return Key.Plus;
|
||||
case XKey.equal:
|
||||
return Key.Plus;
|
||||
|
||||
this.Add(XKey.Caps_Lock, Key.CapsLock);
|
||||
this.Add(XKey.Num_Lock, Key.NumLock);
|
||||
case XKey.Caps_Lock:
|
||||
return Key.CapsLock;
|
||||
case XKey.Num_Lock:
|
||||
return Key.NumLock;
|
||||
|
||||
for (int i = (int)XKey.F1; i <= (int)XKey.F35; i++)
|
||||
{
|
||||
this.Add((XKey)i, (Key)((int)Key.F1 + (i - (int)XKey.F1)));
|
||||
}
|
||||
case XKey.F1:
|
||||
return Key.F1;
|
||||
case XKey.F2:
|
||||
return Key.F2;
|
||||
case XKey.F3:
|
||||
return Key.F3;
|
||||
case XKey.F4:
|
||||
return Key.F4;
|
||||
case XKey.F5:
|
||||
return Key.F5;
|
||||
case XKey.F6:
|
||||
return Key.F6;
|
||||
case XKey.F7:
|
||||
return Key.F7;
|
||||
case XKey.F8:
|
||||
return Key.F8;
|
||||
case XKey.F9:
|
||||
return Key.F9;
|
||||
case XKey.F10:
|
||||
return Key.F10;
|
||||
case XKey.F11:
|
||||
return Key.F11;
|
||||
case XKey.F12:
|
||||
return Key.F12;
|
||||
case XKey.F13:
|
||||
return Key.F13;
|
||||
case XKey.F14:
|
||||
return Key.F14;
|
||||
case XKey.F15:
|
||||
return Key.F15;
|
||||
case XKey.F16:
|
||||
return Key.F16;
|
||||
case XKey.F17:
|
||||
return Key.F17;
|
||||
case XKey.F18:
|
||||
return Key.F18;
|
||||
case XKey.F19:
|
||||
return Key.F19;
|
||||
case XKey.F20:
|
||||
return Key.F20;
|
||||
case XKey.F21:
|
||||
return Key.F21;
|
||||
case XKey.F22:
|
||||
return Key.F22;
|
||||
case XKey.F23:
|
||||
return Key.F23;
|
||||
case XKey.F24:
|
||||
return Key.F24;
|
||||
case XKey.F25:
|
||||
return Key.F25;
|
||||
case XKey.F26:
|
||||
return Key.F26;
|
||||
case XKey.F27:
|
||||
return Key.F27;
|
||||
case XKey.F28:
|
||||
return Key.F28;
|
||||
case XKey.F29:
|
||||
return Key.F29;
|
||||
case XKey.F30:
|
||||
return Key.F30;
|
||||
case XKey.F31:
|
||||
return Key.F31;
|
||||
case XKey.F32:
|
||||
return Key.F32;
|
||||
case XKey.F33:
|
||||
return Key.F33;
|
||||
case XKey.F34:
|
||||
return Key.F34;
|
||||
case XKey.F35:
|
||||
return Key.F35;
|
||||
|
||||
for (int i = (int)XKey.a; i <= (int)XKey.z; i++)
|
||||
{
|
||||
this.Add((XKey)i, (Key)((int)Key.A + (i - (int)XKey.a)));
|
||||
}
|
||||
case XKey.a:
|
||||
case XKey.A:
|
||||
return Key.A;
|
||||
case XKey.b:
|
||||
case XKey.B:
|
||||
return Key.B;
|
||||
case XKey.c:
|
||||
case XKey.C:
|
||||
return Key.C;
|
||||
case XKey.d:
|
||||
case XKey.D:
|
||||
return Key.D;
|
||||
case XKey.e:
|
||||
case XKey.E:
|
||||
return Key.E;
|
||||
case XKey.f:
|
||||
case XKey.F:
|
||||
return Key.F;
|
||||
case XKey.g:
|
||||
case XKey.G:
|
||||
return Key.G;
|
||||
case XKey.h:
|
||||
case XKey.H:
|
||||
return Key.H;
|
||||
case XKey.i:
|
||||
case XKey.I:
|
||||
return Key.I;
|
||||
case XKey.j:
|
||||
case XKey.J:
|
||||
return Key.J;
|
||||
case XKey.k:
|
||||
case XKey.K:
|
||||
return Key.K;
|
||||
case XKey.l:
|
||||
case XKey.L:
|
||||
return Key.L;
|
||||
case XKey.m:
|
||||
case XKey.M:
|
||||
return Key.M;
|
||||
case XKey.n:
|
||||
case XKey.N:
|
||||
return Key.N;
|
||||
case XKey.o:
|
||||
case XKey.O:
|
||||
return Key.O;
|
||||
case XKey.p:
|
||||
case XKey.P:
|
||||
return Key.P;
|
||||
case XKey.q:
|
||||
case XKey.Q:
|
||||
return Key.Q;
|
||||
case XKey.r:
|
||||
case XKey.R:
|
||||
return Key.R;
|
||||
case XKey.s:
|
||||
case XKey.S:
|
||||
return Key.S;
|
||||
case XKey.t:
|
||||
case XKey.T:
|
||||
return Key.T;
|
||||
case XKey.u:
|
||||
case XKey.U:
|
||||
return Key.U;
|
||||
case XKey.v:
|
||||
case XKey.V:
|
||||
return Key.V;
|
||||
case XKey.w:
|
||||
case XKey.W:
|
||||
return Key.W;
|
||||
case XKey.x:
|
||||
case XKey.X:
|
||||
return Key.X;
|
||||
case XKey.y:
|
||||
case XKey.Y:
|
||||
return Key.Y;
|
||||
case XKey.z:
|
||||
case XKey.Z:
|
||||
return Key.Z;
|
||||
|
||||
for (int i = (int)XKey.A; i <= (int)XKey.Z; i++)
|
||||
{
|
||||
this.Add((XKey)i, (Key)((int)Key.A + (i - (int)XKey.A)));
|
||||
}
|
||||
case XKey.Number0:
|
||||
return Key.Number0;
|
||||
case XKey.Number1:
|
||||
return Key.Number1;
|
||||
case XKey.Number2:
|
||||
return Key.Number2;
|
||||
case XKey.Number3:
|
||||
return Key.Number3;
|
||||
case XKey.Number4:
|
||||
return Key.Number4;
|
||||
case XKey.Number5:
|
||||
return Key.Number5;
|
||||
case XKey.Number6:
|
||||
return Key.Number6;
|
||||
case XKey.Number7:
|
||||
return Key.Number7;
|
||||
case XKey.Number8:
|
||||
return Key.Number8;
|
||||
case XKey.Number9:
|
||||
return Key.Number9;
|
||||
|
||||
for (int i = (int)XKey.Number0; i <= (int)XKey.Number9; i++)
|
||||
{
|
||||
this.Add((XKey)i, (Key)((int)Key.Number0 + (i - (int)XKey.Number0)));
|
||||
}
|
||||
case XKey.KP_0:
|
||||
return Key.Keypad0;
|
||||
case XKey.KP_1:
|
||||
return Key.Keypad1;
|
||||
case XKey.KP_2:
|
||||
return Key.Keypad2;
|
||||
case XKey.KP_3:
|
||||
return Key.Keypad3;
|
||||
case XKey.KP_4:
|
||||
return Key.Keypad4;
|
||||
case XKey.KP_5:
|
||||
return Key.Keypad5;
|
||||
case XKey.KP_6:
|
||||
return Key.Keypad6;
|
||||
case XKey.KP_7:
|
||||
return Key.Keypad7;
|
||||
case XKey.KP_8:
|
||||
return Key.Keypad8;
|
||||
case XKey.KP_9:
|
||||
return Key.Keypad9;
|
||||
|
||||
for (int i = (int)XKey.KP_0; i <= (int)XKey.KP_9; i++)
|
||||
{
|
||||
this.Add((XKey)i, (Key)((int)Key.Keypad0 + (i - (int)XKey.KP_0)));
|
||||
}
|
||||
case XKey.Pause:
|
||||
return Key.Pause;
|
||||
case XKey.Break:
|
||||
return Key.Pause;
|
||||
case XKey.Scroll_Lock:
|
||||
return Key.Pause;
|
||||
case XKey.Insert:
|
||||
return Key.PrintScreen;
|
||||
case XKey.Print:
|
||||
return Key.PrintScreen;
|
||||
case XKey.Sys_Req:
|
||||
return Key.PrintScreen;
|
||||
|
||||
this.Add(XKey.Pause, Key.Pause);
|
||||
this.Add(XKey.Break, Key.Pause);
|
||||
this.Add(XKey.Scroll_Lock, Key.Pause);
|
||||
this.Add(XKey.Insert, Key.PrintScreen);
|
||||
this.Add(XKey.Print, Key.PrintScreen);
|
||||
this.Add(XKey.Sys_Req, Key.PrintScreen);
|
||||
case XKey.backslash:
|
||||
return Key.BackSlash;
|
||||
case XKey.bar:
|
||||
return Key.BackSlash;
|
||||
case XKey.braceleft:
|
||||
return Key.BracketLeft;
|
||||
case XKey.bracketleft:
|
||||
return Key.BracketLeft;
|
||||
case XKey.braceright:
|
||||
return Key.BracketRight;
|
||||
case XKey.bracketright:
|
||||
return Key.BracketRight;
|
||||
case XKey.colon:
|
||||
return Key.Semicolon;
|
||||
case XKey.semicolon:
|
||||
return Key.Semicolon;
|
||||
case XKey.quoteright:
|
||||
return Key.Quote;
|
||||
case XKey.quotedbl:
|
||||
return Key.Quote;
|
||||
case XKey.quoteleft:
|
||||
return Key.Tilde;
|
||||
case XKey.asciitilde:
|
||||
return Key.Tilde;
|
||||
|
||||
this.Add(XKey.backslash, Key.BackSlash);
|
||||
this.Add(XKey.bar, Key.BackSlash);
|
||||
this.Add(XKey.braceleft, Key.BracketLeft);
|
||||
this.Add(XKey.bracketleft, Key.BracketLeft);
|
||||
this.Add(XKey.braceright, Key.BracketRight);
|
||||
this.Add(XKey.bracketright, Key.BracketRight);
|
||||
this.Add(XKey.colon, Key.Semicolon);
|
||||
this.Add(XKey.semicolon, Key.Semicolon);
|
||||
this.Add(XKey.quoteright, Key.Quote);
|
||||
this.Add(XKey.quotedbl, Key.Quote);
|
||||
this.Add(XKey.quoteleft, Key.Tilde);
|
||||
this.Add(XKey.asciitilde, Key.Tilde);
|
||||
case XKey.comma:
|
||||
return Key.Comma;
|
||||
case XKey.less:
|
||||
return Key.Comma;
|
||||
case XKey.period:
|
||||
return Key.Period;
|
||||
case XKey.greater:
|
||||
return Key.Period;
|
||||
case XKey.slash:
|
||||
return Key.Slash;
|
||||
case XKey.question:
|
||||
return Key.Slash;
|
||||
|
||||
this.Add(XKey.comma, Key.Comma);
|
||||
this.Add(XKey.less, Key.Comma);
|
||||
this.Add(XKey.period, Key.Period);
|
||||
this.Add(XKey.greater, Key.Period);
|
||||
this.Add(XKey.slash, Key.Slash);
|
||||
this.Add(XKey.question, Key.Slash);
|
||||
case XKey.Left:
|
||||
return Key.Left;
|
||||
case XKey.Down:
|
||||
return Key.Down;
|
||||
case XKey.Right:
|
||||
return Key.Right;
|
||||
case XKey.Up:
|
||||
return Key.Up;
|
||||
|
||||
this.Add(XKey.Left, Key.Left);
|
||||
this.Add(XKey.Down, Key.Down);
|
||||
this.Add(XKey.Right, Key.Right);
|
||||
this.Add(XKey.Up, Key.Up);
|
||||
case XKey.Delete:
|
||||
return Key.Delete;
|
||||
case XKey.Home:
|
||||
return Key.Home;
|
||||
case XKey.End:
|
||||
return Key.End;
|
||||
//case XKey.Prior: return Key.PageUp; // XKey.Prior == XKey.Page_Up
|
||||
case XKey.Page_Up:
|
||||
return Key.PageUp;
|
||||
case XKey.Page_Down:
|
||||
return Key.PageDown;
|
||||
//case XKey.Next: return Key.PageDown; // XKey.Next == XKey.Page_Down
|
||||
|
||||
this.Add(XKey.Delete, Key.Delete);
|
||||
this.Add(XKey.Home, Key.Home);
|
||||
this.Add(XKey.End, Key.End);
|
||||
//this.Add(XKey.Prior, Key.PageUp); // XKey.Prior == XKey.Page_Up
|
||||
this.Add(XKey.Page_Up, Key.PageUp);
|
||||
this.Add(XKey.Page_Down, Key.PageDown);
|
||||
//this.Add(XKey.Next, Key.PageDown); // XKey.Next == XKey.Page_Down
|
||||
case XKey.KP_Add:
|
||||
return Key.KeypadAdd;
|
||||
case XKey.KP_Subtract:
|
||||
return Key.KeypadSubtract;
|
||||
case XKey.KP_Multiply:
|
||||
return Key.KeypadMultiply;
|
||||
case XKey.KP_Divide:
|
||||
return Key.KeypadDivide;
|
||||
case XKey.KP_Decimal:
|
||||
return Key.KeypadDecimal;
|
||||
case XKey.KP_Insert:
|
||||
return Key.Keypad0;
|
||||
case XKey.KP_End:
|
||||
return Key.Keypad1;
|
||||
case XKey.KP_Down:
|
||||
return Key.Keypad2;
|
||||
case XKey.KP_Page_Down:
|
||||
return Key.Keypad3;
|
||||
case XKey.KP_Left:
|
||||
return Key.Keypad4;
|
||||
case XKey.KP_Right:
|
||||
return Key.Keypad6;
|
||||
case XKey.KP_Home:
|
||||
return Key.Keypad7;
|
||||
case XKey.KP_Up:
|
||||
return Key.Keypad8;
|
||||
case XKey.KP_Page_Up:
|
||||
return Key.Keypad9;
|
||||
case XKey.KP_Delete:
|
||||
return Key.KeypadDecimal;
|
||||
case XKey.KP_Enter:
|
||||
return Key.KeypadEnter;
|
||||
|
||||
this.Add(XKey.KP_Add, Key.KeypadAdd);
|
||||
this.Add(XKey.KP_Subtract, Key.KeypadSubtract);
|
||||
this.Add(XKey.KP_Multiply, Key.KeypadMultiply);
|
||||
this.Add(XKey.KP_Divide, Key.KeypadDivide);
|
||||
this.Add(XKey.KP_Decimal, Key.KeypadDecimal);
|
||||
this.Add(XKey.KP_Insert, Key.Keypad0);
|
||||
this.Add(XKey.KP_End, Key.Keypad1);
|
||||
this.Add(XKey.KP_Down, Key.Keypad2);
|
||||
this.Add(XKey.KP_Page_Down, Key.Keypad3);
|
||||
this.Add(XKey.KP_Left, Key.Keypad4);
|
||||
this.Add(XKey.KP_Right, Key.Keypad6);
|
||||
this.Add(XKey.KP_Home, Key.Keypad7);
|
||||
this.Add(XKey.KP_Up, Key.Keypad8);
|
||||
this.Add(XKey.KP_Page_Up, Key.Keypad9);
|
||||
this.Add(XKey.KP_Delete, Key.KeypadDecimal);
|
||||
this.Add(XKey.KP_Enter, Key.KeypadEnter);
|
||||
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
Debug.Print("Exception while creating keymap: '{0}'.", e.ToString());
|
||||
default:
|
||||
return Key.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -36,7 +36,6 @@ namespace OpenTK.Platform.X11
|
|||
// Only one keyboard supported.
|
||||
sealed class X11Keyboard : IKeyboardDriver2
|
||||
{
|
||||
readonly static X11KeyMap keymap = new X11KeyMap();
|
||||
readonly static string name = "Core X11 keyboard";
|
||||
readonly byte[] keys = new byte[32];
|
||||
readonly int KeysymsPerKeycode;
|
||||
|
@ -53,8 +52,11 @@ namespace OpenTK.Platform.X11
|
|||
// Find the number of keysyms per keycode.
|
||||
int first = 0, last = 0;
|
||||
API.DisplayKeycodes(display, ref first, ref last);
|
||||
IntPtr keysym_ptr = API.GetKeyboardMapping(display, (byte)first, last - first + 1,
|
||||
ref KeysymsPerKeycode);
|
||||
IntPtr keysym_ptr =
|
||||
API.GetKeyboardMapping(display,
|
||||
(byte)first,
|
||||
last - first + 1,
|
||||
ref KeysymsPerKeycode);
|
||||
Functions.XFree(keysym_ptr);
|
||||
|
||||
try
|
||||
|
@ -66,7 +68,9 @@ namespace OpenTK.Platform.X11
|
|||
bool supported;
|
||||
Functions.XkbSetDetectableAutoRepeat(display, true, out supported);
|
||||
}
|
||||
catch { }
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,8 +112,9 @@ namespace OpenTK.Platform.X11
|
|||
for (int mod = 0; mod < KeysymsPerKeycode; mod++)
|
||||
{
|
||||
IntPtr keysym = Functions.XKeycodeToKeysym(display, (byte)keycode, mod);
|
||||
if (keysym != IntPtr.Zero && keymap.TryGetValue((XKey)keysym, out key))
|
||||
if (keysym != IntPtr.Zero)
|
||||
{
|
||||
key = X11KeyMap.GetKey((XKey)keysym);
|
||||
if (pressed)
|
||||
state.EnableBit((int)key);
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue