mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-12 22:45:29 +00:00
Can now distinguish between left and right control, shift, alt and enter keys.
This commit is contained in:
parent
b04606640f
commit
8386c20b6a
|
@ -521,7 +521,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetASsyncKeyState
|
#region GetAsyncKeyState
|
||||||
|
|
||||||
[System.Security.SuppressUnmanagedCodeSecurity]
|
[System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
@ -529,6 +529,26 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region GetKeyState
|
||||||
|
|
||||||
|
[System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
internal static extern SHORT GetKeyState(VirtualKeys vKey);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region MapVirtualKey
|
||||||
|
|
||||||
|
[System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
internal static extern UINT MapVirtualKey(UINT uCode, MapVirtualKeyType uMapType);
|
||||||
|
|
||||||
|
[System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
internal static extern UINT MapVirtualKey(VirtualKeys vkey, MapVirtualKeyType uMapType);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region ShowWindow
|
#region ShowWindow
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3506,6 +3526,23 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region MapVirtualKeyType
|
||||||
|
|
||||||
|
internal enum MapVirtualKeyType
|
||||||
|
{
|
||||||
|
/// <summary>uCode is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0.</summary>
|
||||||
|
VirtualKeyToScanCode = 0,
|
||||||
|
/// <summary>uCode is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. If there is no translation, the function returns 0.</summary>
|
||||||
|
ScanCodeToVirtualKey = 1,
|
||||||
|
/// <summary>uCode is a virtual-key code and is translated into an unshifted character value in the low-order word of the return value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function returns 0.</summary>
|
||||||
|
VirtualKeyToCharacter = 2,
|
||||||
|
/// <summary>Windows NT/2000/XP: uCode is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there is no translation, the function returns 0.</summary>
|
||||||
|
ScanCodeToVirtualKeyExtended = 3,
|
||||||
|
VirtualKeyToScanCodeExtended = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region --- Callbacks ---
|
#region --- Callbacks ---
|
||||||
|
|
|
@ -25,6 +25,10 @@ namespace OpenTK.Platform.Windows
|
||||||
IList<KeyboardDevice> keyboards = new List<KeyboardDevice>(1);
|
IList<KeyboardDevice> keyboards = new List<KeyboardDevice>(1);
|
||||||
IList<MouseDevice> mice = new List<MouseDevice>(1);
|
IList<MouseDevice> mice = new List<MouseDevice>(1);
|
||||||
internal static readonly WinKeyMap KeyMap = new WinKeyMap();
|
internal static readonly WinKeyMap KeyMap = new WinKeyMap();
|
||||||
|
// Used to distinguish left and right control, alt and enter keys.
|
||||||
|
const int ExtendedBit = 1 << 24;
|
||||||
|
// Used to distinguish left and right shift keys.
|
||||||
|
static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0);
|
||||||
|
|
||||||
#region --- Constructor ---
|
#region --- Constructor ---
|
||||||
|
|
||||||
|
@ -110,42 +114,58 @@ namespace OpenTK.Platform.Windows
|
||||||
case WindowMessage.SYSKEYUP:
|
case WindowMessage.SYSKEYUP:
|
||||||
bool pressed = (WindowMessage)msg.Msg == WindowMessage.KEYDOWN ||
|
bool pressed = (WindowMessage)msg.Msg == WindowMessage.KEYDOWN ||
|
||||||
(WindowMessage)msg.Msg == WindowMessage.SYSKEYDOWN;
|
(WindowMessage)msg.Msg == WindowMessage.SYSKEYDOWN;
|
||||||
//bool left = (((int)msg.LParam) & 0x100000) == 0; // valid for Shift, Control and Menu presses.
|
|
||||||
|
// Shift/Control/Alt behave strangely when e.g. ShiftRight is held down and ShiftLeft is pressed
|
||||||
|
// and released. It looks like neither key is released in this case, or that the wrong key is
|
||||||
|
// released in the case of Control and Alt.
|
||||||
|
// To combat this, we are going to release both keys when either is released. Hacky, but should work.
|
||||||
|
// Win95 does not distinguish left/right key constants (GetAsyncKeyState returns 0).
|
||||||
|
// In this case, both keys will be reported as pressed.
|
||||||
|
|
||||||
|
bool extended = (((int)msg.LParam) & ExtendedBit) != 0;
|
||||||
switch ((VirtualKeys)msg.WParam)
|
switch ((VirtualKeys)msg.WParam)
|
||||||
{
|
{
|
||||||
case VirtualKeys.SHIFT:
|
case VirtualKeys.SHIFT:
|
||||||
// Win95 does not distinguish left/right constants (GetAsyncKeyState returns 0).
|
// The behavior of this key is very strange. Unlike Control and Alt, there is no extended bit
|
||||||
// In this case, report both keys as down.
|
// to distinguish between left and right keys. Moreover, pressing both keys and releasing one
|
||||||
bool left = Functions.GetAsyncKeyState(VirtualKeys.LSHIFT) != 0;
|
// may result in both keys being held down (but not always).
|
||||||
bool right = Functions.GetAsyncKeyState(VirtualKeys.RSHIFT) != 0;
|
// The only reliably way to solve this was reported by BlueMonkMN at the forums: we should
|
||||||
if (left)
|
// check the scancodes. It looks like GLFW does the same thing, so it should be reliable.
|
||||||
|
|
||||||
|
// TODO: Not 100% reliable, when both keys are pressed at once.
|
||||||
|
if (ShiftRightScanCode != 0)
|
||||||
|
{
|
||||||
|
if ((((int)msg.LParam >> 16) & 0xFF) == ShiftRightScanCode)
|
||||||
|
keyboard[Input.Key.ShiftRight] = pressed;
|
||||||
|
else
|
||||||
|
keyboard[Input.Key.ShiftLeft] = pressed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Should only fall here on Windows 9x and NT4.0-
|
||||||
keyboard[Input.Key.ShiftLeft] = pressed;
|
keyboard[Input.Key.ShiftLeft] = pressed;
|
||||||
if (right)
|
}
|
||||||
keyboard[Input.Key.ShiftRight] = pressed;
|
|
||||||
if (!left && !right)
|
|
||||||
keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case VirtualKeys.CONTROL:
|
case VirtualKeys.CONTROL:
|
||||||
left = Functions.GetAsyncKeyState(VirtualKeys.LCONTROL) != 0;
|
if (extended)
|
||||||
right = Functions.GetAsyncKeyState(VirtualKeys.RCONTROL) != 0;
|
|
||||||
if (left)
|
|
||||||
keyboard[Input.Key.ControlLeft] = pressed;
|
|
||||||
if (right)
|
|
||||||
keyboard[Input.Key.ControlRight] = pressed;
|
keyboard[Input.Key.ControlRight] = pressed;
|
||||||
if (!left && !right)
|
else
|
||||||
keyboard[Input.Key.ControlLeft] = keyboard[Input.Key.ControlRight] = pressed;
|
keyboard[Input.Key.ControlLeft] = pressed;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case VirtualKeys.MENU:
|
case VirtualKeys.MENU:
|
||||||
left = Functions.GetAsyncKeyState(VirtualKeys.LMENU) != 0;
|
if (extended)
|
||||||
right = Functions.GetAsyncKeyState(VirtualKeys.RMENU) != 0;
|
|
||||||
if (left)
|
|
||||||
keyboard[Input.Key.AltLeft] = pressed;
|
|
||||||
if (right)
|
|
||||||
keyboard[Input.Key.AltRight] = pressed;
|
keyboard[Input.Key.AltRight] = pressed;
|
||||||
if (!left && !right)
|
else
|
||||||
keyboard[Input.Key.AltLeft] = keyboard[Input.Key.AltRight] = pressed;
|
keyboard[Input.Key.AltLeft] = pressed;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case VirtualKeys.RETURN:
|
||||||
|
if (extended)
|
||||||
|
keyboard[Key.KeypadEnter] = pressed;
|
||||||
|
else
|
||||||
|
keyboard[Key.Enter] = pressed;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -162,6 +182,10 @@ namespace OpenTK.Platform.Windows
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WindowMessage.KILLFOCUS:
|
||||||
|
keyboard.ClearKeys();
|
||||||
|
break;
|
||||||
|
|
||||||
case WindowMessage.DESTROY:
|
case WindowMessage.DESTROY:
|
||||||
Debug.Print("Input window detached from parent {0}.", Handle);
|
Debug.Print("Input window detached from parent {0}.", Handle);
|
||||||
ReleaseHandle();
|
ReleaseHandle();
|
||||||
|
|
|
@ -392,7 +392,7 @@ namespace OpenTK.Platform.Windows
|
||||||
if (!Wgl.Imports.DeleteContext(renderContext))
|
if (!Wgl.Imports.DeleteContext(renderContext))
|
||||||
{
|
{
|
||||||
//throw new ApplicationException("Could not destroy the OpenGL render context. Error: " + Marshal.GetLastWin32Error());
|
//throw new ApplicationException("Could not destroy the OpenGL render context. Error: " + Marshal.GetLastWin32Error());
|
||||||
//Debug.Print("Could not destroy the OpenGL render context. Error: {0}", Marshal.GetLastWin32Error());
|
Debug.Print("Could not destroy the OpenGL render context. Error: {0}", Marshal.GetLastWin32Error());
|
||||||
}
|
}
|
||||||
renderContext = null;
|
renderContext = null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue