From 0f64af130a1c132ae66b1d6e82f7eded92b34827 Mon Sep 17 00:00:00 2001 From: Andy Korth Date: Thu, 24 Jan 2013 15:48:01 -0600 Subject: [PATCH] Committing artfunkel patch for scan codes --- Source/Examples/Main.cs | 1 + .../Examples/OpenTK/Test/BasicMouseInput.cs | 9 +- Source/OpenTK/Input/KeyboardDevice.cs | 53 ++++-- Source/OpenTK/Input/KeyboardKeyEventArgs.cs | 178 ++++++++++-------- Source/OpenTK/Input/KeyboardState.cs | 105 ++++++++--- .../OpenTK/Platform/MacOS/CarbonGLNative.cs | 33 ++-- Source/OpenTK/Platform/MacOS/HIDInput.cs | 8 +- Source/OpenTK/Platform/Windows/WMInput.cs | 12 +- Source/OpenTK/Platform/Windows/WinGLNative.cs | 57 +++--- .../OpenTK/Platform/Windows/WinRawKeyboard.cs | 25 ++- Source/OpenTK/Platform/X11/X11Input.cs | 20 +- 11 files changed, 283 insertions(+), 218 deletions(-) diff --git a/Source/Examples/Main.cs b/Source/Examples/Main.cs index 213948be..cb940537 100644 --- a/Source/Examples/Main.cs +++ b/Source/Examples/Main.cs @@ -52,6 +52,7 @@ namespace Examples // The ExampleBrowser works pretty poorly on some platforms, so you may want to start examples directly. // for example: Examples.Tutorial.T12_GLSL_Parallax.Main (); // Examples.Tutorial.T10_GLSL_Cube.Main (); + Examples.Tests.BasicMouseInput.Main (); using (Form browser = new ExampleBrowser()) { diff --git a/Source/Examples/OpenTK/Test/BasicMouseInput.cs b/Source/Examples/OpenTK/Test/BasicMouseInput.cs index c106782e..a66d8268 100644 --- a/Source/Examples/OpenTK/Test/BasicMouseInput.cs +++ b/Source/Examples/OpenTK/Test/BasicMouseInput.cs @@ -25,7 +25,7 @@ namespace Examples.Tests { public BasicMouseInput() - : base(800, 600, GraphicsMode.Default) + : base(800, 600) { } protected override void OnLoad(EventArgs e) @@ -42,6 +42,8 @@ namespace Examples.Tests protected override void OnUpdateFrame(FrameEventArgs e) { + base.OnUpdateFrame(e); + // Here's the big test! if(OpenTK.Input.Mouse.GetState()[MouseButton.Left]){ Console.WriteLine("The left mouse button is down!"); @@ -66,7 +68,7 @@ namespace Examples.Tests protected override void OnRenderFrame(FrameEventArgs e) { - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + GL.Clear(ClearBufferMask.ColorBufferBit); SwapBuffers(); } @@ -78,7 +80,8 @@ namespace Examples.Tests // Get the title and category of this example using reflection. ExampleAttribute info = ((ExampleAttribute)example.GetType().GetCustomAttributes(false)[0]); example.Title = String.Format("OpenTK | {0} {1}: {2}", info.Category, info.Difficulty, info.Title); - example.Run(30.0, 0.0); + + example.Run(30.0); } } diff --git a/Source/OpenTK/Input/KeyboardDevice.cs b/Source/OpenTK/Input/KeyboardDevice.cs index b1a14b9c..d21ca5a7 100644 --- a/Source/OpenTK/Input/KeyboardDevice.cs +++ b/Source/OpenTK/Input/KeyboardDevice.cs @@ -22,6 +22,7 @@ namespace OpenTK.Input { //private IKeyboard keyboard; private bool[] keys = new bool[Enum.GetValues(typeof(Key)).Length]; + private bool[] scancodes = new bool[256]; private string description; private int numKeys, numFKeys, numLeds; private IntPtr devID; @@ -44,24 +45,16 @@ namespace OpenTK.Input public bool this[Key key] { get { return keys[(int)key]; } - internal set - { - if (keys[(int)key] != value || KeyRepeat) - { - keys[(int)key] = value; + } - if (value && KeyDown != null) - { - args.Key = key; - KeyDown(this, args); - } - else if (!value && KeyUp != null) - { - args.Key = key; - KeyUp(this, args); - } - } - } + /// + /// Gets a value indicating the status of the specified Key. + /// + /// The scancode to check. + /// True if the scancode is pressed, false otherwise. + public bool this[uint scancode] + { + get { return scancodes[scancode]; } } /// @@ -197,12 +190,34 @@ namespace OpenTK.Input internal void ClearKeys() { for (int i = 0; i < keys.Length; i++) - if (this[(Key)i]) // Make sure KeyUp events are *not* raised for keys that are up, even if key repeat is on. - this[(Key)i] = false; + keys[i] = false; + for (uint i = 0; i < scancodes.Length; i++) + scancodes[i] = false; } #endregion + internal void SetKey(Key key, uint scancode, bool state) + { + if (keys[(int)key] != state || KeyRepeat) + { + keys[(int)key] = scancodes[scancode] = state; + + if (state && KeyDown != null) + { + args.Key = key; + args.ScanCode = scancode; + KeyDown(this, args); + } + else if (!state && KeyUp != null) + { + args.Key = key; + args.ScanCode = scancode; + KeyUp(this, args); + } + } + } + #endregion } } \ No newline at end of file diff --git a/Source/OpenTK/Input/KeyboardKeyEventArgs.cs b/Source/OpenTK/Input/KeyboardKeyEventArgs.cs index ac3ce8af..f607090c 100644 --- a/Source/OpenTK/Input/KeyboardKeyEventArgs.cs +++ b/Source/OpenTK/Input/KeyboardKeyEventArgs.cs @@ -1,83 +1,95 @@ -#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.Text; - -namespace OpenTK.Input -{ - /// - /// Defines the event data for events. - /// - /// - /// - /// Do not cache instances of this type outside their event handler. - /// If necessary, you can clone a KeyboardEventArgs instance using the - /// constructor. - /// - /// - public class KeyboardKeyEventArgs : EventArgs - { - #region Fields - - Key key; - - #endregion - - #region Constructors - - /// - /// Constructs a new KeyboardEventArgs instance. - /// - public KeyboardKeyEventArgs() { } - - /// - /// Constructs a new KeyboardEventArgs instance. - /// - /// An existing KeyboardEventArgs instance to clone. - public KeyboardKeyEventArgs(KeyboardKeyEventArgs args) - { - Key = args.Key; - } - - #endregion - - #region Public Members - - /// - /// Gets the that generated this event. - /// - public Key Key - { - get { return key; } - internal set { key = value; } - } - - #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.Text; + +namespace OpenTK.Input +{ + /// + /// Defines the event data for events. + /// + /// + /// + /// Do not cache instances of this type outside their event handler. + /// If necessary, you can clone a KeyboardEventArgs instance using the + /// constructor. + /// + /// + public class KeyboardKeyEventArgs : EventArgs + { + #region Fields + + Key key; + uint scancode; + + #endregion + + #region Constructors + + /// + /// Constructs a new KeyboardEventArgs instance. + /// + public KeyboardKeyEventArgs() { } + + /// + /// Constructs a new KeyboardEventArgs instance. + /// + /// An existing KeyboardEventArgs instance to clone. + public KeyboardKeyEventArgs(KeyboardKeyEventArgs args) + { + Key = args.Key; + ScanCode = args.ScanCode; + } + + #endregion + + #region Public Members + + /// + /// Gets the that generated this event. + /// + public Key Key + { + get { return key; } + internal set { key = value; } + } + + /// + /// Gets the scancode which generated this event. + /// + public uint ScanCode + { + get { return scancode; } + internal set { scancode = value; } + } + + + #endregion + } +} diff --git a/Source/OpenTK/Input/KeyboardState.cs b/Source/OpenTK/Input/KeyboardState.cs index d37c60da..839fa2cd 100644 --- a/Source/OpenTK/Input/KeyboardState.cs +++ b/Source/OpenTK/Input/KeyboardState.cs @@ -43,6 +43,7 @@ namespace OpenTK.Input const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize; // The following line triggers bogus CS0214 in gmcs 2.0.1, sigh... unsafe fixed int Keys[NumInts]; + unsafe fixed int Codes[256]; bool is_connected; #endregion @@ -58,13 +59,17 @@ namespace OpenTK.Input public bool this[Key key] { get { return IsKeyDown(key); } - internal set - { - if (value) - EnableBit((int)key); - else - DisableBit((int)key); - } + } + + /// + /// Gets a indicating whether the specified + /// is pressed. + /// + /// The to check. + /// True if key is pressed; false otherwise. + public bool this[short code] + { + get { return IsKeyDown(code); } } /// @@ -76,6 +81,15 @@ namespace OpenTK.Input return ReadBit((int)key); } + /// + /// Gets a indicating whether this scan code is down. + /// + /// The scan code to check. + public bool IsKeyDown(short code) + { + return ReadBit(code,true); + } + /// /// Gets a indicating whether this key is up. /// @@ -85,6 +99,15 @@ namespace OpenTK.Input return !ReadBit((int)key); } + /// + /// Gets a indicating whether this scan code is down. + /// + /// The scan code to check. + public bool IsKeyUp(short code) + { + return !ReadBit(code,true); + } + /// /// Gets a indicating whether this keyboard /// is connected. @@ -187,48 +210,62 @@ namespace OpenTK.Input #region Internal Members - internal bool ReadBit(int offset) + internal void SetKeyState(Key key, byte code, bool down) { - ValidateOffset(offset); - - int int_offset = offset / 32; - int bit_offset = offset % 32; - unsafe + if (down) { - fixed (int* k = Keys) - { - return (*(k + int_offset) & (1 << bit_offset)) != 0u; - } + EnableBit((int)key); + EnableBit(code,true); + } + else + { + DisableBit((int)key); + DisableBit(code, true); } } - internal void EnableBit(int offset) + internal bool ReadBit(int offset, bool ScanCode = false) { - ValidateOffset(offset); + ValidateOffset(offset, ScanCode); int int_offset = offset / 32; int bit_offset = offset % 32; unsafe { - fixed (int* k = Keys) - { - *(k + int_offset) |= 1 << bit_offset; - } + if (ScanCode) + fixed (int* c = Codes) { return (*(c + int_offset) & (1 << bit_offset)) != 0u; } + else + fixed (int* k = Keys) { return (*(k + int_offset) & (1 << bit_offset)) != 0u; } } } - internal void DisableBit(int offset) + internal void EnableBit(int offset, bool ScanCode = false) { - ValidateOffset(offset); + ValidateOffset(offset, ScanCode); int int_offset = offset / 32; int bit_offset = offset % 32; unsafe { - fixed (int* k = Keys) - { - *(k + int_offset) &= ~(1 << bit_offset); - } + if (ScanCode) + fixed (int* c = Codes) { *(c + int_offset) |= 1 << bit_offset; } + else + fixed (int* k = Keys) { *(k + int_offset) |= 1 << bit_offset; } + } + } + + internal void DisableBit(int offset, bool ScanCode = false) + { + ValidateOffset(offset, ScanCode); + + int int_offset = offset / 32; + int bit_offset = offset % 32; + unsafe + { + if (ScanCode) + fixed (int* c = Codes) { *(c + int_offset) &= ~(1 << bit_offset); } + else + fixed (int* k = Keys) { *(k + int_offset) &= ~(1 << bit_offset); } } } @@ -242,6 +279,12 @@ namespace OpenTK.Input for (int i = 0; i < NumInts; i++) *(k1 + i) |= *(k2 + i); } + int* c2 = other.Codes; + fixed (int* c1 = Codes) + { + for (int i = 0; i < short.MaxValue; i++) + *(c1 + i) |= *(c2 + i); + } } IsConnected |= other.IsConnected; } @@ -250,9 +293,9 @@ namespace OpenTK.Input #region Private Members - static void ValidateOffset(int offset) + static void ValidateOffset(int offset, bool ScanCode) { - if (offset < 0 || offset >= NumInts * IntSize) + if (offset < 0 || offset >= (ScanCode ? 256 : NumInts * IntSize)) throw new ArgumentOutOfRangeException("offset"); } diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs index 01696252..742847f9 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs @@ -368,6 +368,7 @@ namespace OpenTK.Platform.MacOS break; } + OpenTK.Input.Key key; switch (evt.KeyboardEventKind) { case KeyboardEventKind.RawKeyRepeat: @@ -376,25 +377,15 @@ namespace OpenTK.Platform.MacOS break; case KeyboardEventKind.RawKeyDown: - { - OpenTK.Input.Key key; - if (Keymap.TryGetValue(code, out key)) - { - InputDriver.Keyboard[0][key] = true; - OnKeyPress(mKeyPressArgs); - } + Keymap.TryGetValue(code, out key); + InputDriver.Keyboard[0].SetKey(key, (uint)code, true); + OnKeyPress(mKeyPressArgs); return OSStatus.NoError; - } case KeyboardEventKind.RawKeyUp: - { - OpenTK.Input.Key key; - if (Keymap.TryGetValue(code, out key)) - { - InputDriver.Keyboard[0][key] = false; - } + Keymap.TryGetValue(code, out key); + InputDriver.Keyboard[0].SetKey(key, (uint)code, false); return OSStatus.NoError; - } case KeyboardEventKind.RawKeyModifiersChanged: ProcessModifierKey(inEvent); @@ -614,21 +605,21 @@ namespace OpenTK.Platform.MacOS Debug.Print("Modifiers Changed: {0}", modifiers); Input.KeyboardDevice keyboard = InputDriver.Keyboard[0]; - + if (keyboard[OpenTK.Input.Key.AltLeft] ^ option) - keyboard[OpenTK.Input.Key.AltLeft] = option; + keyboard.SetKey(OpenTK.Input.Key.AltLeft, (uint)MacOSKeyModifiers.Option, option); if (keyboard[OpenTK.Input.Key.ShiftLeft] ^ shift) - keyboard[OpenTK.Input.Key.ShiftLeft] = shift; + keyboard.SetKey(OpenTK.Input.Key.ShiftLeft, (uint)MacOSKeyModifiers.Shift, shift); if (keyboard[OpenTK.Input.Key.WinLeft] ^ command) - keyboard[OpenTK.Input.Key.WinLeft] = command; + keyboard.SetKey(OpenTK.Input.Key.WinLeft, (uint)MacOSKeyModifiers.Command, command); if (keyboard[OpenTK.Input.Key.ControlLeft] ^ control) - keyboard[OpenTK.Input.Key.ControlLeft] = control; + keyboard.SetKey(OpenTK.Input.Key.ControlLeft, (uint)MacOSKeyModifiers.Control, control); if (keyboard[OpenTK.Input.Key.CapsLock] ^ caps) - keyboard[OpenTK.Input.Key.CapsLock] = caps; + keyboard.SetKey(OpenTK.Input.Key.CapsLock, (uint)MacOSKeyModifiers.CapsLock, caps); } diff --git a/Source/OpenTK/Platform/MacOS/HIDInput.cs b/Source/OpenTK/Platform/MacOS/HIDInput.cs index daa88f3f..c040ff6d 100755 --- a/Source/OpenTK/Platform/MacOS/HIDInput.cs +++ b/Source/OpenTK/Platform/MacOS/HIDInput.cs @@ -263,14 +263,12 @@ namespace OpenTK.Platform.MacOS { case HIDPage.GenericDesktop: case HIDPage.KeyboardOrKeypad: - int raw = (int) usage; - if (raw >= RawKeyMap.Length) + if (usage >= RawKeyMap.Length) { - Debug.Print("[Warning] Key {0} not mapped.", raw); + Debug.Print("[Warning] Key {0} not mapped.", usage); return state; } - Key key = RawKeyMap[raw]; - state[key] = v_int != 0; + state.SetKeyState(RawKeyMap[usage], (byte)usage, v_int != 0); break; } diff --git a/Source/OpenTK/Platform/Windows/WMInput.cs b/Source/OpenTK/Platform/Windows/WMInput.cs index f0fd2956..084f20fb 100644 --- a/Source/OpenTK/Platform/Windows/WMInput.cs +++ b/Source/OpenTK/Platform/Windows/WMInput.cs @@ -70,14 +70,12 @@ namespace OpenTK.Platform.Windows void UpdateKeyboard() { - for (int i = 0; i < 256; i++) + for (byte i = 0; i < byte.MaxValue; i++) { - VirtualKeys key = (VirtualKeys)i; - bool pressed = (Functions.GetAsyncKeyState(key) >> 8) != 0; - if (KeyMap.ContainsKey(key)) - { - keyboard[KeyMap[key]] = pressed; - } + bool pressed = (Functions.GetAsyncKeyState((VirtualKeys)i) >> 8) != 0; + Key key; + KeyMap.TryGetValue((VirtualKeys)i,out key); + keyboard.SetKeyState(key, i, pressed); } } diff --git a/Source/OpenTK/Platform/Windows/WinGLNative.cs b/Source/OpenTK/Platform/Windows/WinGLNative.cs index 261cfacf..18cbd3dd 100644 --- a/Source/OpenTK/Platform/Windows/WinGLNative.cs +++ b/Source/OpenTK/Platform/Windows/WinGLNative.cs @@ -89,7 +89,13 @@ namespace OpenTK.Platform.Windows IList keyboards = new List(1); IList mice = new List(1); const long ExtendedBit = 1 << 24; // Used to distinguish left and right control, alt and enter keys. - static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0); // Used to distinguish left and right shift keys. + + public static readonly uint ShiftLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LSHIFT, 0); + public static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0); + public static readonly uint ControlLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LCONTROL, 0); + public static readonly uint ControlRightScanCode = Functions.MapVirtualKey(VirtualKeys.RCONTROL, 0); + public static readonly uint AltLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LMENU, 0); + public static readonly uint AltRightScanCode = Functions.MapVirtualKey(VirtualKeys.RMENU, 0); KeyPressEventArgs key_press = new KeyPressEventArgs((char)0); @@ -369,6 +375,8 @@ 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) { case VirtualKeys.SHIFT: @@ -382,55 +390,50 @@ namespace OpenTK.Platform.Windows // Otherwise, the state of one key might be stuck to pressed. if (ShiftRightScanCode != 0 && pressed) { - unchecked - { - if (((lParam.ToInt64() >> 16) & 0xFF) == ShiftRightScanCode) - keyboard[Input.Key.ShiftRight] = pressed; - else - keyboard[Input.Key.ShiftLeft] = pressed; - } + if (scancode == ShiftRightScanCode) + key = Input.Key.ShiftRight; + else + key = Input.Key.ShiftLeft; } else { // Windows 9x and NT4.0 or key release event. - keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed; + keyboard.SetKey(Input.Key.ShiftLeft, ShiftLeftScanCode, pressed); + keyboard.SetKey(Input.Key.ShiftRight, ShiftRightScanCode, pressed); } - return IntPtr.Zero; + break; case VirtualKeys.CONTROL: if (extended) - keyboard[Input.Key.ControlRight] = pressed; + key = Input.Key.ControlRight; else - keyboard[Input.Key.ControlLeft] = pressed; - return IntPtr.Zero; + key = Input.Key.ControlLeft; + break; case VirtualKeys.MENU: if (extended) - keyboard[Input.Key.AltRight] = pressed; + key = Input.Key.AltRight; else - keyboard[Input.Key.AltLeft] = pressed; - return IntPtr.Zero; + key = Input.Key.AltLeft; + break; case VirtualKeys.RETURN: if (extended) - keyboard[Key.KeypadEnter] = pressed; + key = Key.KeypadEnter; else - keyboard[Key.Enter] = pressed; - return IntPtr.Zero; + key = Key.Enter; + break; default: if (!KeyMap.ContainsKey((VirtualKeys)wParam)) - { Debug.Print("Virtual key {0} ({1}) not mapped.", (VirtualKeys)wParam, (long)lParam); - break; - } else - { - keyboard[KeyMap[(VirtualKeys)wParam]] = pressed; - } - return IntPtr.Zero; + key = KeyMap[(VirtualKeys)wParam]; + break; } - break; + + keyboard.SetKey(key, scancode, pressed); + return IntPtr.Zero; case WindowMessage.SYSCHAR: return IntPtr.Zero; diff --git a/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs b/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs index a81b29b9..386f05aa 100644 --- a/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs +++ b/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs @@ -180,31 +180,30 @@ namespace OpenTK.Platform.Windows switch (rin.Data.Keyboard.VKey) { case VirtualKeys.SHIFT: - keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed; + keyboard.SetKeyState(Key.ShiftLeft, (byte)WinGLNative.ShiftLeftScanCode, pressed); + keyboard.SetKeyState(Key.ShiftRight, (byte)WinGLNative.ShiftRightScanCode, pressed); processed = true; break; case VirtualKeys.CONTROL: - keyboard[Input.Key.ControlLeft] = keyboard[Input.Key.ControlRight] = pressed; + keyboard.SetKeyState(Key.ControlLeft, (byte)WinGLNative.ControlLeftScanCode, pressed); + keyboard.SetKeyState(Key.ControlRight, (byte)WinGLNative.ControlRightScanCode, pressed); processed = true; break; case VirtualKeys.MENU: - keyboard[Input.Key.AltLeft] = keyboard[Input.Key.AltRight] = pressed; + keyboard.SetKeyState(Key.AltLeft, (byte)WinGLNative.AltLeftScanCode, pressed); + keyboard.SetKeyState(Key.AltRight, (byte)WinGLNative.AltRightScanCode, pressed); processed = true; break; default: - if (!KeyMap.ContainsKey(rin.Data.Keyboard.VKey)) - { - Debug.Print("Virtual key {0} ({1}) not mapped.", - rin.Data.Keyboard.VKey, (int)rin.Data.Keyboard.VKey); - } - else - { - keyboard[KeyMap[rin.Data.Keyboard.VKey]] = pressed; - processed = true; - } + 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; } diff --git a/Source/OpenTK/Platform/X11/X11Input.cs b/Source/OpenTK/Platform/X11/X11Input.cs index 10978019..a9193a40 100644 --- a/Source/OpenTK/Platform/X11/X11Input.cs +++ b/Source/OpenTK/Platform/X11/X11Input.cs @@ -157,20 +157,22 @@ namespace OpenTK.Platform.X11 case XEventName.KeyPress: case XEventName.KeyRelease: bool pressed = e.type == XEventName.KeyPress; + XKey keysym = (XKey)API.LookupKeysym(ref e.KeyEvent, 0); + XKey keysym2 = (XKey)API.LookupKeysym(ref e.KeyEvent, 1); + Key key = Key.Unknown; - IntPtr keysym = API.LookupKeysym(ref e.KeyEvent, 0); - IntPtr keysym2 = API.LookupKeysym(ref e.KeyEvent, 1); - - if (keymap.ContainsKey((XKey)keysym)) - keyboard[keymap[(XKey)keysym]] = pressed; - else if (keymap.ContainsKey((XKey)keysym2)) - keyboard[keymap[(XKey)keysym2]] = pressed; + if (keymap.ContainsKey(keysym)) + key = keymap[keysym]; + else if (keymap.ContainsKey(keysym2)) + key = keymap[keysym2]; else Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.KeyEvent.keycode, (XKey)keysym, (XKey)keysym2); + + keyboard.SetKey(key, (uint)e.KeyEvent.keycode, pressed); break; case XEventName.ButtonPress: - if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true; + if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true; else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = true; else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = true; else if (e.ButtonEvent.button == 4) mouse.Wheel++; @@ -190,7 +192,7 @@ namespace OpenTK.Platform.X11 break; case XEventName.ButtonRelease: - if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = false; + if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = false; else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = false; else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = false; else if (e.ButtonEvent.button == 6) mouse[OpenTK.Input.MouseButton.Button1] = false;