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,
|
||||
/// <summary>The keypad decimal key.</summary>
|
||||
KeypadDecimal,
|
||||
/// <summary>The keypad period key (equivalent to KeypadDecimal).</summary>
|
||||
KeypadPeriod = KeypadDecimal,
|
||||
/// <summary>The keypad enter key.</summary>
|
||||
KeypadEnter,
|
||||
|
||||
|
@ -343,6 +345,8 @@ namespace OpenTK.Input
|
|||
// Symbols
|
||||
/// <summary>The tilde key.</summary>
|
||||
Tilde,
|
||||
/// <summary>The grave key (equivaent to Tilde).</summary>
|
||||
Grave = Tilde,
|
||||
/// <summary>The minus key.</summary>
|
||||
Minus,
|
||||
//Equal,
|
||||
|
@ -368,6 +372,8 @@ namespace OpenTK.Input
|
|||
Slash,
|
||||
/// <summary>The backslash key.</summary>
|
||||
BackSlash,
|
||||
/// <summary>The secondary backslash key.</summary>
|
||||
NonUSBackSlash,
|
||||
/// <summary>Indicates the last available keyboard key.</summary>
|
||||
LastKey
|
||||
}
|
||||
|
|
|
@ -332,9 +332,6 @@
|
|||
<Compile Include="Platform\Windows\WinKeyMap.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Platform\Windows\WMInput.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Platform\Windows\WinGLNative.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
@ -809,4 +806,4 @@
|
|||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<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
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 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;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
using Graphics;
|
||||
using OpenTK.Input;
|
||||
|
||||
class WinFactory : IPlatformFactory
|
||||
{
|
||||
bool disposed;
|
||||
readonly object SyncRoot = new object();
|
||||
IInputDriver2 inputDriver;
|
||||
|
||||
public WinFactory()
|
||||
{
|
||||
if (System.Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
// Enable high-dpi support
|
||||
// Only available on Windows Vista and higher
|
||||
bool result = Functions.SetProcessDPIAware();
|
||||
Debug.Print("SetProcessDPIAware() returned {0}", result);
|
||||
}
|
||||
}
|
||||
|
||||
#region IPlatformFactory Members
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public virtual IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
return new WinDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
public virtual IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new WinGLContext(mode, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public virtual IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new WinGLContext(handle, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public virtual GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Wgl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
|
||||
public virtual IGraphicsMode CreateGraphicsMode()
|
||||
{
|
||||
return new WinGraphicsMode();
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
return InputDriver.KeyboardDriver;
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
return InputDriver.MouseDriver;
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IGamePadDriver CreateGamePadDriver()
|
||||
{
|
||||
return InputDriver.GamePadDriver;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
IInputDriver2 InputDriver
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (inputDriver == null)
|
||||
{
|
||||
// If Windows version is NT5 or higher, we are able to use raw input.
|
||||
if (System.Environment.OSVersion.Version.Major > 5 ||
|
||||
(System.Environment.OSVersion.Version.Major == 5 &&
|
||||
System.Environment.OSVersion.Version.Minor > 0))
|
||||
inputDriver = new WinRawInput();
|
||||
else
|
||||
inputDriver = new WMInput();
|
||||
}
|
||||
return inputDriver;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
void Dispose(bool manual)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
InputDriver.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
|
||||
}
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~WinFactory()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 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;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
using Graphics;
|
||||
using OpenTK.Input;
|
||||
|
||||
class WinFactory : IPlatformFactory
|
||||
{
|
||||
bool disposed;
|
||||
readonly object SyncRoot = new object();
|
||||
IInputDriver2 inputDriver;
|
||||
|
||||
public WinFactory()
|
||||
{
|
||||
if (System.Environment.OSVersion.Version.Major <= 4)
|
||||
{
|
||||
throw new PlatformNotSupportedException("OpenTK requires Windows XP or higher");
|
||||
}
|
||||
|
||||
if (System.Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
// Enable high-dpi support
|
||||
// Only available on Windows Vista and higher
|
||||
bool result = Functions.SetProcessDPIAware();
|
||||
Debug.Print("SetProcessDPIAware() returned {0}", result);
|
||||
}
|
||||
}
|
||||
|
||||
#region IPlatformFactory Members
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public virtual IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
return new WinDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
public virtual IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new WinGLContext(mode, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public virtual IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new WinGLContext(handle, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public virtual GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Wgl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
|
||||
public virtual IGraphicsMode CreateGraphicsMode()
|
||||
{
|
||||
return new WinGraphicsMode();
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
return InputDriver.KeyboardDriver;
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
return InputDriver.MouseDriver;
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IGamePadDriver CreateGamePadDriver()
|
||||
{
|
||||
return InputDriver.GamePadDriver;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
IInputDriver2 InputDriver
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (inputDriver == null)
|
||||
{
|
||||
inputDriver = new WinRawInput();
|
||||
}
|
||||
return inputDriver;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
void Dispose(bool manual)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
InputDriver.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
|
||||
}
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~WinFactory()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -375,64 +375,16 @@ namespace OpenTK.Platform.Windows
|
|||
// In this case, both keys will be reported as pressed.
|
||||
|
||||
bool extended = (lParam.ToInt64() & ExtendedBit) != 0;
|
||||
uint scancode = (uint)((lParam.ToInt64() >> 16) & 0xFF);
|
||||
Key key = Key.Unknown;
|
||||
switch ((VirtualKeys)wParam)
|
||||
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);
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
case VirtualKeys.SHIFT:
|
||||
// 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, (byte)scancode, pressed);
|
||||
}
|
||||
|
||||
keyboard.SetKey(key, scancode, pressed);
|
||||
return IntPtr.Zero;
|
||||
|
||||
case WindowMessage.SYSCHAR:
|
||||
|
|
|
@ -27,96 +27,214 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
class WinKeyMap : Dictionary<VirtualKeys, Input.Key>
|
||||
class WinKeyMap
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the map between VirtualKeys and OpenTK.Key
|
||||
/// </summary>
|
||||
readonly Dictionary<int, Key> ScanMap = new Dictionary<int, Key>();
|
||||
|
||||
public WinKeyMap()
|
||||
{
|
||||
this.Add(VirtualKeys.ESCAPE, Key.Escape);
|
||||
// 0 - 15
|
||||
Append(Key.Unknown);
|
||||
Append(Key.Escape);
|
||||
|
||||
// Function keys
|
||||
for (int i = 0; i < 24; i++)
|
||||
for (int i = 0; i < 9; 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)
|
||||
for (int i = 0; i <= 9; i++)
|
||||
if (extended1)
|
||||
{
|
||||
this.Add((VirtualKeys)(0x30 + i), Key.Number0 + i);
|
||||
switch (key)
|
||||
{
|
||||
case Key.ControlLeft: key = Key.Pause; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Letters (A-Z)
|
||||
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);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,6 +157,13 @@ namespace OpenTK.Platform.Windows
|
|||
bool pressed =
|
||||
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN ||
|
||||
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);
|
||||
KeyboardState keyboard;
|
||||
|
@ -175,36 +182,12 @@ namespace OpenTK.Platform.Windows
|
|||
int keyboard_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
||||
keyboard = keyboards[keyboard_handle];
|
||||
|
||||
// Generic control, shift, alt keys may be sent instead of left/right.
|
||||
// It seems you have to explicitly register left/right events.
|
||||
switch (rin.Data.Keyboard.VKey)
|
||||
Key key = KeyMap.TranslateKey(scancode, vkey, extended0, extended1, out is_valid);
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
case VirtualKeys.SHIFT:
|
||||
keyboard.SetKeyState(Key.ShiftLeft, (byte)WinGLNative.ShiftLeftScanCode, pressed);
|
||||
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;
|
||||
keyboard.SetKeyState(key, (byte)scancode, pressed);
|
||||
processed = true;
|
||||
}
|
||||
|
||||
lock (UpdateLock)
|
||||
|
|
Loading…
Reference in a new issue