Merge branch 'scancodes'
Conflicts: Source/OpenTK/OpenTK.csproj Source/OpenTK/Platform/Windows/WinFactory.cs
This commit is contained in:
commit
73e3614338
7 changed files with 378 additions and 532 deletions
|
@ -261,6 +261,8 @@ namespace OpenTK.Input
|
||||||
KeypadPlus = KeypadAdd,
|
KeypadPlus = KeypadAdd,
|
||||||
/// <summary>The keypad decimal key.</summary>
|
/// <summary>The keypad decimal key.</summary>
|
||||||
KeypadDecimal,
|
KeypadDecimal,
|
||||||
|
/// <summary>The keypad period key (equivalent to KeypadDecimal).</summary>
|
||||||
|
KeypadPeriod = KeypadDecimal,
|
||||||
/// <summary>The keypad enter key.</summary>
|
/// <summary>The keypad enter key.</summary>
|
||||||
KeypadEnter,
|
KeypadEnter,
|
||||||
|
|
||||||
|
@ -343,6 +345,8 @@ namespace OpenTK.Input
|
||||||
// Symbols
|
// Symbols
|
||||||
/// <summary>The tilde key.</summary>
|
/// <summary>The tilde key.</summary>
|
||||||
Tilde,
|
Tilde,
|
||||||
|
/// <summary>The grave key (equivaent to Tilde).</summary>
|
||||||
|
Grave = Tilde,
|
||||||
/// <summary>The minus key.</summary>
|
/// <summary>The minus key.</summary>
|
||||||
Minus,
|
Minus,
|
||||||
//Equal,
|
//Equal,
|
||||||
|
@ -368,6 +372,8 @@ namespace OpenTK.Input
|
||||||
Slash,
|
Slash,
|
||||||
/// <summary>The backslash key.</summary>
|
/// <summary>The backslash key.</summary>
|
||||||
BackSlash,
|
BackSlash,
|
||||||
|
/// <summary>The secondary backslash key.</summary>
|
||||||
|
NonUSBackSlash,
|
||||||
/// <summary>Indicates the last available keyboard key.</summary>
|
/// <summary>Indicates the last available keyboard key.</summary>
|
||||||
LastKey
|
LastKey
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,9 +332,6 @@
|
||||||
<Compile Include="Platform\Windows\WinKeyMap.cs">
|
<Compile Include="Platform\Windows\WinKeyMap.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Platform\Windows\WMInput.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Platform\Windows\WinGLNative.cs">
|
<Compile Include="Platform\Windows\WinGLNative.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -809,4 +806,4 @@
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,209 +0,0 @@
|
||||||
#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;
|
|
||||||
using System.Diagnostics;
|
|
||||||
#if !MINIMAL
|
|
||||||
using System.Drawing;
|
|
||||||
#endif
|
|
||||||
using System.Threading;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using OpenTK.Input;
|
|
||||||
|
|
||||||
|
|
||||||
namespace OpenTK.Platform.Windows
|
|
||||||
{
|
|
||||||
// Input driver for legacy (pre XP) Windows platforms.
|
|
||||||
// Supports a single mouse and keyboard through async input.
|
|
||||||
// Supports multiple joysticks through WinMM.
|
|
||||||
sealed class WMInput : IInputDriver2, IMouseDriver2, IKeyboardDriver2/*, IGamePadDriver*/ //HACK uncomment and implement
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
readonly object MouseLock = new object();
|
|
||||||
readonly object KeyboardLock = new object();
|
|
||||||
readonly WinMMJoystick gamepad_driver = new WinMMJoystick();
|
|
||||||
readonly WinKeyMap KeyMap = new WinKeyMap();
|
|
||||||
|
|
||||||
KeyboardState keyboard = new KeyboardState();
|
|
||||||
MouseState mouse = new MouseState();
|
|
||||||
bool disposed;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructor
|
|
||||||
|
|
||||||
public WMInput()
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
Debug.WriteLine("Using WMInput.");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Private Members
|
|
||||||
|
|
||||||
void UpdateKeyboard()
|
|
||||||
{
|
|
||||||
for (byte i = 0; i < byte.MaxValue; i++)
|
|
||||||
{
|
|
||||||
bool pressed = (Functions.GetAsyncKeyState((VirtualKeys)i) >> 8) != 0;
|
|
||||||
Key key;
|
|
||||||
KeyMap.TryGetValue((VirtualKeys)i,out key);
|
|
||||||
keyboard.SetKeyState(key, i, pressed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateMouse()
|
|
||||||
{
|
|
||||||
POINT p = new POINT();
|
|
||||||
Functions.GetCursorPos(ref p);
|
|
||||||
mouse.X = p.X;
|
|
||||||
mouse.Y = p.Y;
|
|
||||||
// Note: we cannot poll the mouse wheel
|
|
||||||
mouse[MouseButton.Left] = (Functions.GetAsyncKeyState(VirtualKeys.LBUTTON) >> 8) != 0;
|
|
||||||
mouse[MouseButton.Middle] = (Functions.GetAsyncKeyState(VirtualKeys.RBUTTON) >> 8) != 0;
|
|
||||||
mouse[MouseButton.Right] = (Functions.GetAsyncKeyState(VirtualKeys.MBUTTON) >> 8) != 0;
|
|
||||||
mouse[MouseButton.Button1] = (Functions.GetAsyncKeyState(VirtualKeys.XBUTTON1) >> 8) != 0;
|
|
||||||
mouse[MouseButton.Button2] = (Functions.GetAsyncKeyState(VirtualKeys.XBUTTON2) >> 8) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IInputDriver2 Members
|
|
||||||
|
|
||||||
public IKeyboardDriver2 KeyboardDriver
|
|
||||||
{
|
|
||||||
get { return this; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMouseDriver2 MouseDriver
|
|
||||||
{
|
|
||||||
get { return this; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IGamePadDriver GamePadDriver
|
|
||||||
{
|
|
||||||
get { return null; } //HACK return this when implemented.
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IMouseDriver2 Members
|
|
||||||
|
|
||||||
public MouseState GetState()
|
|
||||||
{
|
|
||||||
lock (MouseLock)
|
|
||||||
{
|
|
||||||
UpdateMouse();
|
|
||||||
return mouse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MouseState GetState(int index)
|
|
||||||
{
|
|
||||||
lock (MouseLock)
|
|
||||||
{
|
|
||||||
UpdateMouse();
|
|
||||||
if (index == 0)
|
|
||||||
return mouse;
|
|
||||||
else
|
|
||||||
return new MouseState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetPosition(double x, double y)
|
|
||||||
{
|
|
||||||
Functions.SetCursorPos((int)x, (int)y);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IKeyboardDriver2 Members
|
|
||||||
|
|
||||||
KeyboardState IKeyboardDriver2.GetState()
|
|
||||||
{
|
|
||||||
lock (KeyboardLock)
|
|
||||||
{
|
|
||||||
UpdateKeyboard();
|
|
||||||
return keyboard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyboardState IKeyboardDriver2.GetState(int index)
|
|
||||||
{
|
|
||||||
lock (KeyboardLock)
|
|
||||||
{
|
|
||||||
UpdateKeyboard();
|
|
||||||
if (index == 0)
|
|
||||||
return keyboard;
|
|
||||||
else
|
|
||||||
return new KeyboardState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string IKeyboardDriver2.GetDeviceName(int index)
|
|
||||||
{
|
|
||||||
return "Default Windows Keyboard";
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IDisposable Members
|
|
||||||
|
|
||||||
void Dispose(bool manual)
|
|
||||||
{
|
|
||||||
if (!disposed)
|
|
||||||
{
|
|
||||||
if (manual)
|
|
||||||
{
|
|
||||||
// Todo: implement this
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
|
|
||||||
}
|
|
||||||
disposed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~WMInput()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,159 +1,158 @@
|
||||||
#region License
|
#region License
|
||||||
//
|
//
|
||||||
// The Open Toolkit Library License
|
// The Open Toolkit Library License
|
||||||
//
|
//
|
||||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// in the Software without restriction, including without limitation the rights to
|
// in the Software without restriction, including without limitation the rights to
|
||||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
// 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
|
// the Software, and to permit persons to whom the Software is furnished to do
|
||||||
// so, subject to the following conditions:
|
// so, subject to the following conditions:
|
||||||
//
|
//
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// copies or substantial portions of the Software.
|
// copies or substantial portions of the Software.
|
||||||
//
|
//
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
// OTHER DEALINGS IN THE SOFTWARE.
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace OpenTK.Platform.Windows
|
namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
using Graphics;
|
using Graphics;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
|
||||||
class WinFactory : IPlatformFactory
|
class WinFactory : IPlatformFactory
|
||||||
{
|
{
|
||||||
bool disposed;
|
bool disposed;
|
||||||
readonly object SyncRoot = new object();
|
readonly object SyncRoot = new object();
|
||||||
IInputDriver2 inputDriver;
|
IInputDriver2 inputDriver;
|
||||||
|
|
||||||
public WinFactory()
|
public WinFactory()
|
||||||
{
|
{
|
||||||
if (System.Environment.OSVersion.Version.Major >= 6)
|
if (System.Environment.OSVersion.Version.Major <= 4)
|
||||||
{
|
{
|
||||||
// Enable high-dpi support
|
throw new PlatformNotSupportedException("OpenTK requires Windows XP or higher");
|
||||||
// Only available on Windows Vista and higher
|
}
|
||||||
bool result = Functions.SetProcessDPIAware();
|
|
||||||
Debug.Print("SetProcessDPIAware() returned {0}", result);
|
if (System.Environment.OSVersion.Version.Major >= 6)
|
||||||
}
|
{
|
||||||
}
|
// Enable high-dpi support
|
||||||
|
// Only available on Windows Vista and higher
|
||||||
#region IPlatformFactory Members
|
bool result = Functions.SetProcessDPIAware();
|
||||||
|
Debug.Print("SetProcessDPIAware() returned {0}", result);
|
||||||
public virtual INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
}
|
||||||
{
|
}
|
||||||
return new WinGLNative(x, y, width, height, title, options, device);
|
|
||||||
}
|
#region IPlatformFactory Members
|
||||||
|
|
||||||
public virtual IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
public virtual INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
||||||
{
|
{
|
||||||
return new WinDisplayDeviceDriver();
|
return new WinGLNative(x, y, width, height, title, options, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
public virtual IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||||
{
|
{
|
||||||
return new WinGLContext(mode, (WinWindowInfo)window, shareContext, major, minor, flags);
|
return new WinDisplayDeviceDriver();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
public virtual IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||||
{
|
{
|
||||||
return new WinGLContext(handle, (WinWindowInfo)window, shareContext, major, minor, flags);
|
return new WinGLContext(mode, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
public virtual IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||||
{
|
{
|
||||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
return new WinGLContext(handle, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||||
{
|
}
|
||||||
return new ContextHandle(Wgl.GetCurrentContext());
|
|
||||||
};
|
public virtual GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||||
}
|
{
|
||||||
|
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||||
public virtual IGraphicsMode CreateGraphicsMode()
|
{
|
||||||
{
|
return new ContextHandle(Wgl.GetCurrentContext());
|
||||||
return new WinGraphicsMode();
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
public virtual IGraphicsMode CreateGraphicsMode()
|
||||||
{
|
{
|
||||||
return InputDriver.KeyboardDriver;
|
return new WinGraphicsMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||||
{
|
{
|
||||||
return InputDriver.MouseDriver;
|
return InputDriver.KeyboardDriver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual OpenTK.Input.IGamePadDriver CreateGamePadDriver()
|
public virtual OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||||
{
|
{
|
||||||
return InputDriver.GamePadDriver;
|
return InputDriver.MouseDriver;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
public virtual OpenTK.Input.IGamePadDriver CreateGamePadDriver()
|
||||||
|
{
|
||||||
IInputDriver2 InputDriver
|
return InputDriver.GamePadDriver;
|
||||||
{
|
}
|
||||||
get
|
|
||||||
{
|
#endregion
|
||||||
lock (SyncRoot)
|
|
||||||
{
|
IInputDriver2 InputDriver
|
||||||
if (inputDriver == null)
|
{
|
||||||
{
|
get
|
||||||
// If Windows version is NT5 or higher, we are able to use raw input.
|
{
|
||||||
if (System.Environment.OSVersion.Version.Major > 5 ||
|
lock (SyncRoot)
|
||||||
(System.Environment.OSVersion.Version.Major == 5 &&
|
{
|
||||||
System.Environment.OSVersion.Version.Minor > 0))
|
if (inputDriver == null)
|
||||||
inputDriver = new WinRawInput();
|
{
|
||||||
else
|
inputDriver = new WinRawInput();
|
||||||
inputDriver = new WMInput();
|
}
|
||||||
}
|
return inputDriver;
|
||||||
return inputDriver;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#region IDisposable Members
|
||||||
#region IDisposable Members
|
|
||||||
|
void Dispose(bool manual)
|
||||||
void Dispose(bool manual)
|
{
|
||||||
{
|
if (!disposed)
|
||||||
if (!disposed)
|
{
|
||||||
{
|
if (manual)
|
||||||
if (manual)
|
{
|
||||||
{
|
InputDriver.Dispose();
|
||||||
InputDriver.Dispose();
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
|
||||||
Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
|
}
|
||||||
}
|
disposed = true;
|
||||||
disposed = true;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void Dispose()
|
||||||
public void Dispose()
|
{
|
||||||
{
|
Dispose(true);
|
||||||
Dispose(true);
|
GC.SuppressFinalize(this);
|
||||||
GC.SuppressFinalize(this);
|
}
|
||||||
}
|
|
||||||
|
~WinFactory()
|
||||||
~WinFactory()
|
{
|
||||||
{
|
Dispose(false);
|
||||||
Dispose(false);
|
}
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
#endregion
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -375,64 +375,16 @@ namespace OpenTK.Platform.Windows
|
||||||
// In this case, both keys will be reported as pressed.
|
// In this case, both keys will be reported as pressed.
|
||||||
|
|
||||||
bool extended = (lParam.ToInt64() & ExtendedBit) != 0;
|
bool extended = (lParam.ToInt64() & ExtendedBit) != 0;
|
||||||
uint scancode = (uint)((lParam.ToInt64() >> 16) & 0xFF);
|
short scancode = (short)((lParam.ToInt64() >> 16) & 0xFF);
|
||||||
Key key = Key.Unknown;
|
VirtualKeys vkey = (VirtualKeys)wParam;
|
||||||
switch ((VirtualKeys)wParam)
|
bool is_valid;
|
||||||
|
Key key = KeyMap.TranslateKey(scancode, vkey, extended, false, out is_valid);
|
||||||
|
|
||||||
|
if (is_valid)
|
||||||
{
|
{
|
||||||
case VirtualKeys.SHIFT:
|
keyboard.SetKey(key, (byte)scancode, pressed);
|
||||||
// The behavior of this key is very strange. Unlike Control and Alt, there is no extended bit
|
|
||||||
// to distinguish between left and right keys. Moreover, pressing both keys and releasing one
|
|
||||||
// may result in both keys being held down (but not always).
|
|
||||||
// The only reliable way to solve this was reported by BlueMonkMN at the forums: we should
|
|
||||||
// check the scancodes. It looks like GLFW does the same thing, so it should be reliable.
|
|
||||||
|
|
||||||
// Note: we release both keys when either shift is released.
|
|
||||||
// Otherwise, the state of one key might be stuck to pressed.
|
|
||||||
if (ShiftRightScanCode != 0 && pressed)
|
|
||||||
{
|
|
||||||
if (scancode == ShiftRightScanCode)
|
|
||||||
key = Input.Key.ShiftRight;
|
|
||||||
else
|
|
||||||
key = Input.Key.ShiftLeft;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Windows 9x and NT4.0 or key release event.
|
|
||||||
keyboard.SetKey(Input.Key.ShiftLeft, ShiftLeftScanCode, pressed);
|
|
||||||
keyboard.SetKey(Input.Key.ShiftRight, ShiftRightScanCode, pressed);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VirtualKeys.CONTROL:
|
|
||||||
if (extended)
|
|
||||||
key = Input.Key.ControlRight;
|
|
||||||
else
|
|
||||||
key = Input.Key.ControlLeft;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VirtualKeys.MENU:
|
|
||||||
if (extended)
|
|
||||||
key = Input.Key.AltRight;
|
|
||||||
else
|
|
||||||
key = Input.Key.AltLeft;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VirtualKeys.RETURN:
|
|
||||||
if (extended)
|
|
||||||
key = Key.KeypadEnter;
|
|
||||||
else
|
|
||||||
key = Key.Enter;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (!KeyMap.ContainsKey((VirtualKeys)wParam))
|
|
||||||
Debug.Print("Virtual key {0} ({1}) not mapped.", (VirtualKeys)wParam, (long)lParam);
|
|
||||||
else
|
|
||||||
key = KeyMap[(VirtualKeys)wParam];
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboard.SetKey(key, scancode, pressed);
|
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
|
|
||||||
case WindowMessage.SYSCHAR:
|
case WindowMessage.SYSCHAR:
|
||||||
|
|
|
@ -27,96 +27,214 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace OpenTK.Platform.Windows
|
namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
class WinKeyMap : Dictionary<VirtualKeys, Input.Key>
|
class WinKeyMap
|
||||||
{
|
{
|
||||||
/// <summary>
|
readonly Dictionary<int, Key> ScanMap = new Dictionary<int, Key>();
|
||||||
/// Initializes the map between VirtualKeys and OpenTK.Key
|
|
||||||
/// </summary>
|
|
||||||
public WinKeyMap()
|
public WinKeyMap()
|
||||||
{
|
{
|
||||||
this.Add(VirtualKeys.ESCAPE, Key.Escape);
|
// 0 - 15
|
||||||
|
Append(Key.Unknown);
|
||||||
|
Append(Key.Escape);
|
||||||
|
|
||||||
// Function keys
|
for (int i = 0; i < 9; i++)
|
||||||
for (int i = 0; i < 24; i++)
|
Append(Key.Number1 + i);
|
||||||
|
Append(Key.Number0);
|
||||||
|
|
||||||
|
Append(Key.Minus);
|
||||||
|
Append(Key.Plus);
|
||||||
|
Append(Key.BackSpace);
|
||||||
|
Append(Key.Tab);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append(Key key)
|
||||||
|
{
|
||||||
|
ScanMap.Add(ScanMap.Count, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Key TranslateKey(short scancode, VirtualKeys vkey, bool extended0, bool extended1, out bool is_valid)
|
||||||
|
{
|
||||||
|
is_valid = true;
|
||||||
|
|
||||||
|
Key key;
|
||||||
|
ScanMap.TryGetValue(scancode, out key);
|
||||||
|
|
||||||
|
if (!extended0)
|
||||||
{
|
{
|
||||||
this.Add((VirtualKeys)((int)VirtualKeys.F1 + i), Key.F1 + i);
|
switch (key)
|
||||||
|
{
|
||||||
|
case Key.Insert: key = Key.Keypad0; break;
|
||||||
|
case Key.End: key = Key.Keypad1; break;
|
||||||
|
case Key.Down: key = Key.Keypad2; break;
|
||||||
|
case Key.PageDown: key = Key.Keypad3; break;
|
||||||
|
case Key.Left: key = Key.Keypad4; break;
|
||||||
|
case Key.Right: key = Key.Keypad6; break;
|
||||||
|
case Key.Home: key = Key.Keypad7; break;
|
||||||
|
case Key.Up: key = Key.Keypad8; break;
|
||||||
|
case Key.PageUp: key = Key.Keypad9; break;
|
||||||
|
case Key.PrintScreen: key = Key.KeypadMultiply; break;
|
||||||
|
case Key.Delete: key = Key.KeypadDecimal; break;
|
||||||
|
case Key.NumLock:
|
||||||
|
if (vkey == VirtualKeys.Last)
|
||||||
|
is_valid = false;
|
||||||
|
else if (vkey == VirtualKeys.PAUSE)
|
||||||
|
key = Key.Pause;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case Key.Enter: key = Key.KeypadEnter; break;
|
||||||
|
case Key.AltLeft: key = Key.AltRight; break;
|
||||||
|
case Key.AltRight: key = Key.AltLeft; break;
|
||||||
|
case Key.ControlLeft: key = Key.ControlRight; break;
|
||||||
|
case Key.ControlRight: key = Key.ControlLeft; break;
|
||||||
|
case Key.ShiftLeft: is_valid = false; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number keys (0-9)
|
if (extended1)
|
||||||
for (int i = 0; i <= 9; i++)
|
|
||||||
{
|
{
|
||||||
this.Add((VirtualKeys)(0x30 + i), Key.Number0 + i);
|
switch (key)
|
||||||
|
{
|
||||||
|
case Key.ControlLeft: key = Key.Pause; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Letters (A-Z)
|
return key;
|
||||||
for (int i = 0; i < 26; i++)
|
|
||||||
{
|
|
||||||
this.Add((VirtualKeys)(0x41 + i), Key.A + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Add(VirtualKeys.TAB, Key.Tab);
|
|
||||||
this.Add(VirtualKeys.CAPITAL, Key.CapsLock);
|
|
||||||
this.Add(VirtualKeys.LCONTROL, Key.ControlLeft);
|
|
||||||
this.Add(VirtualKeys.LSHIFT, Key.ShiftLeft);
|
|
||||||
this.Add(VirtualKeys.LWIN, Key.WinLeft);
|
|
||||||
this.Add(VirtualKeys.LMENU, Key.AltLeft);
|
|
||||||
this.Add(VirtualKeys.SPACE, Key.Space);
|
|
||||||
this.Add(VirtualKeys.RMENU, Key.AltRight);
|
|
||||||
this.Add(VirtualKeys.RWIN, Key.WinRight);
|
|
||||||
this.Add(VirtualKeys.APPS, Key.Menu);
|
|
||||||
this.Add(VirtualKeys.RCONTROL, Key.ControlRight);
|
|
||||||
this.Add(VirtualKeys.RSHIFT, Key.ShiftRight);
|
|
||||||
this.Add(VirtualKeys.RETURN, Key.Enter);
|
|
||||||
this.Add(VirtualKeys.BACK, Key.BackSpace);
|
|
||||||
|
|
||||||
this.Add(VirtualKeys.OEM_1, Key.Semicolon); // Varies by keyboard, ;: on Win2K/US
|
|
||||||
this.Add(VirtualKeys.OEM_2, Key.Slash); // Varies by keyboard, /? on Win2K/US
|
|
||||||
this.Add(VirtualKeys.OEM_3, Key.Tilde); // Varies by keyboard, `~ on Win2K/US
|
|
||||||
this.Add(VirtualKeys.OEM_4, Key.BracketLeft); // Varies by keyboard, [{ on Win2K/US
|
|
||||||
this.Add(VirtualKeys.OEM_5, Key.BackSlash); // Varies by keyboard, \| on Win2K/US
|
|
||||||
this.Add(VirtualKeys.OEM_6, Key.BracketRight); // Varies by keyboard, ]} on Win2K/US
|
|
||||||
this.Add(VirtualKeys.OEM_7, Key.Quote); // Varies by keyboard, '" on Win2K/US
|
|
||||||
this.Add(VirtualKeys.OEM_PLUS, Key.Plus); // Invariant: +
|
|
||||||
this.Add(VirtualKeys.OEM_COMMA, Key.Comma); // Invariant: ,
|
|
||||||
this.Add(VirtualKeys.OEM_MINUS, Key.Minus); // Invariant: -
|
|
||||||
this.Add(VirtualKeys.OEM_PERIOD, Key.Period); // Invariant: .
|
|
||||||
|
|
||||||
this.Add(VirtualKeys.HOME, Key.Home);
|
|
||||||
this.Add(VirtualKeys.END, Key.End);
|
|
||||||
this.Add(VirtualKeys.DELETE, Key.Delete);
|
|
||||||
this.Add(VirtualKeys.PRIOR, Key.PageUp);
|
|
||||||
this.Add(VirtualKeys.NEXT, Key.PageDown);
|
|
||||||
this.Add(VirtualKeys.PRINT, Key.PrintScreen);
|
|
||||||
this.Add(VirtualKeys.PAUSE, Key.Pause);
|
|
||||||
this.Add(VirtualKeys.NUMLOCK, Key.NumLock);
|
|
||||||
|
|
||||||
this.Add(VirtualKeys.SCROLL, Key.ScrollLock);
|
|
||||||
this.Add(VirtualKeys.SNAPSHOT, Key.PrintScreen);
|
|
||||||
this.Add(VirtualKeys.CLEAR, Key.Clear);
|
|
||||||
this.Add(VirtualKeys.INSERT, Key.Insert);
|
|
||||||
|
|
||||||
this.Add(VirtualKeys.SLEEP, Key.Sleep);
|
|
||||||
|
|
||||||
// Keypad
|
|
||||||
for (int i = 0; i <= 9; i++)
|
|
||||||
{
|
|
||||||
this.Add((VirtualKeys)((int)VirtualKeys.NUMPAD0 + i), Key.Keypad0 + i);
|
|
||||||
}
|
|
||||||
this.Add(VirtualKeys.DECIMAL, Key.KeypadDecimal);
|
|
||||||
this.Add(VirtualKeys.ADD, Key.KeypadAdd);
|
|
||||||
this.Add(VirtualKeys.SUBTRACT, Key.KeypadSubtract);
|
|
||||||
this.Add(VirtualKeys.DIVIDE, Key.KeypadDivide);
|
|
||||||
this.Add(VirtualKeys.MULTIPLY, Key.KeypadMultiply);
|
|
||||||
|
|
||||||
// Navigation
|
|
||||||
this.Add(VirtualKeys.UP, Key.Up);
|
|
||||||
this.Add(VirtualKeys.DOWN, Key.Down);
|
|
||||||
this.Add(VirtualKeys.LEFT, Key.Left);
|
|
||||||
this.Add(VirtualKeys.RIGHT, Key.Right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,13 @@ namespace OpenTK.Platform.Windows
|
||||||
bool pressed =
|
bool pressed =
|
||||||
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN ||
|
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN ||
|
||||||
rin.Data.Keyboard.Message == (int)WindowMessage.SYSKEYDOWN;
|
rin.Data.Keyboard.Message == (int)WindowMessage.SYSKEYDOWN;
|
||||||
|
var scancode = rin.Data.Keyboard.MakeCode;
|
||||||
|
var vkey = rin.Data.Keyboard.VKey;
|
||||||
|
|
||||||
|
bool extended0 = (int)(rin.Data.Keyboard.Flags & RawInputKeyboardDataFlags.E0) != 0;
|
||||||
|
bool extended1 = (int)(rin.Data.Keyboard.Flags & RawInputKeyboardDataFlags.E1) != 0;
|
||||||
|
|
||||||
|
bool is_valid = true;
|
||||||
|
|
||||||
ContextHandle handle = new ContextHandle(rin.Header.Device);
|
ContextHandle handle = new ContextHandle(rin.Header.Device);
|
||||||
KeyboardState keyboard;
|
KeyboardState keyboard;
|
||||||
|
@ -175,36 +182,12 @@ namespace OpenTK.Platform.Windows
|
||||||
int keyboard_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
int keyboard_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
||||||
keyboard = keyboards[keyboard_handle];
|
keyboard = keyboards[keyboard_handle];
|
||||||
|
|
||||||
// Generic control, shift, alt keys may be sent instead of left/right.
|
Key key = KeyMap.TranslateKey(scancode, vkey, extended0, extended1, out is_valid);
|
||||||
// It seems you have to explicitly register left/right events.
|
|
||||||
switch (rin.Data.Keyboard.VKey)
|
if (is_valid)
|
||||||
{
|
{
|
||||||
case VirtualKeys.SHIFT:
|
keyboard.SetKeyState(key, (byte)scancode, pressed);
|
||||||
keyboard.SetKeyState(Key.ShiftLeft, (byte)WinGLNative.ShiftLeftScanCode, pressed);
|
processed = true;
|
||||||
keyboard.SetKeyState(Key.ShiftRight, (byte)WinGLNative.ShiftRightScanCode, pressed);
|
|
||||||
processed = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VirtualKeys.CONTROL:
|
|
||||||
keyboard.SetKeyState(Key.ControlLeft, (byte)WinGLNative.ControlLeftScanCode, pressed);
|
|
||||||
keyboard.SetKeyState(Key.ControlRight, (byte)WinGLNative.ControlRightScanCode, pressed);
|
|
||||||
processed = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VirtualKeys.MENU:
|
|
||||||
keyboard.SetKeyState(Key.AltLeft, (byte)WinGLNative.AltLeftScanCode, pressed);
|
|
||||||
keyboard.SetKeyState(Key.AltRight, (byte)WinGLNative.AltRightScanCode, pressed);
|
|
||||||
processed = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Key key;
|
|
||||||
KeyMap.TryGetValue(rin.Data.Keyboard.VKey, out key);
|
|
||||||
if (key == Key.Unknown)
|
|
||||||
Debug.Print("Virtual key {0} ({1}) not mapped.", rin.Data.Keyboard.VKey, (int)rin.Data.Keyboard.VKey);
|
|
||||||
keyboard.SetKeyState(key, BitConverter.GetBytes(rin.Data.Keyboard.MakeCode)[0], pressed);
|
|
||||||
processed = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (UpdateLock)
|
lock (UpdateLock)
|
||||||
|
|
Loading…
Reference in a new issue