[OpenTK] Refactor keyboard and mouse handling

A lot of duplicated code is now moved to NativeWindowBase and
LegacyInputDriver.
This commit is contained in:
thefiddler 2014-05-04 17:05:08 +02:00
parent e155d647de
commit d968281a1b
11 changed files with 182 additions and 280 deletions

View file

@ -21,13 +21,11 @@ namespace OpenTK.Input
public sealed class KeyboardDevice : IInputDevice public sealed class KeyboardDevice : IInputDevice
{ {
//private IKeyboard keyboard; //private IKeyboard keyboard;
private bool[] keys = new bool[(int)Key.LastKey];
private bool[] scancodes = new bool[256];
private string description; private string description;
private int numKeys, numFKeys, numLeds; private int numKeys, numFKeys, numLeds;
private IntPtr devID; private IntPtr devID;
private bool repeat; private bool repeat;
private KeyboardKeyEventArgs args = new KeyboardKeyEventArgs(); private KeyboardState state;
#region --- Constructors --- #region --- Constructors ---
@ -44,7 +42,7 @@ namespace OpenTK.Input
/// <returns>True if the Key is pressed, false otherwise.</returns> /// <returns>True if the Key is pressed, false otherwise.</returns>
public bool this[Key key] public bool this[Key key]
{ {
get { return keys[(int)key]; } get { return state[key]; }
} }
/// <summary> /// <summary>
@ -52,9 +50,10 @@ namespace OpenTK.Input
/// </summary> /// </summary>
/// <param name="scancode">The scancode to check.</param> /// <param name="scancode">The scancode to check.</param>
/// <returns>True if the scancode is pressed, false otherwise.</returns> /// <returns>True if the scancode is pressed, false otherwise.</returns>
[CLSCompliant(false)]
public bool this[uint scancode] public bool this[uint scancode]
{ {
get { return scancodes[scancode]; } get { return scancode < (uint)Key.LastKey && state[(Key)scancode]; }
} }
/// <summary> /// <summary>
@ -124,7 +123,7 @@ namespace OpenTK.Input
/// <summary> /// <summary>
/// Occurs when a key is pressed. /// Occurs when a key is pressed.
/// </summary> /// </summary>
public event EventHandler<KeyboardKeyEventArgs> KeyDown; public event EventHandler<KeyboardKeyEventArgs> KeyDown = delegate { };
#endregion #endregion
@ -133,7 +132,7 @@ namespace OpenTK.Input
/// <summary> /// <summary>
/// Occurs when a key is released. /// Occurs when a key is released.
/// </summary> /// </summary>
public event EventHandler<KeyboardKeyEventArgs> KeyUp; public event EventHandler<KeyboardKeyEventArgs> KeyUp = delegate { };
#endregion #endregion
@ -185,21 +184,28 @@ namespace OpenTK.Input
#region --- Internal Methods --- #region --- Internal Methods ---
#region internal void ClearKeys() internal void HandleKeyDown(object sender, KeyboardKeyEventArgs e)
{
state = e.Keyboard;
KeyDown(this, e);
}
internal void HandleKeyUp(object sender, KeyboardKeyEventArgs e)
{
state = e.Keyboard;
KeyUp(this, e);
}
internal void ClearKeys() internal void ClearKeys()
{ {
for (int i = 0; i < keys.Length; i++) for (Key i = 0; i < Key.LastKey; i++)
keys[i] = false; state[i] = false;
for (uint i = 0; i < scancodes.Length; i++)
scancodes[i] = false;
} }
#endregion #if false
internal void SetKey(Key key, uint scancode, KeyModifiers mods, bool pressed)
internal void SetKey(Key key, uint scancode, KeyModifiers mods, bool state)
{ {
if (keys[(int)key] != state || KeyRepeat) if (state[key] != pressed || KeyRepeat)
{ {
// limit scancode to 8bits, otherwise the assignment // limit scancode to 8bits, otherwise the assignment
// below will crash randomly // below will crash randomly
@ -209,6 +215,7 @@ namespace OpenTK.Input
if (state && KeyDown != null) if (state && KeyDown != null)
{ {
args.Key = key; args.Key = key;
args.ScanCode = scancode; args.ScanCode = scancode;
args.Modifiers = mods; args.Modifiers = mods;
@ -223,28 +230,7 @@ namespace OpenTK.Input
} }
} }
} }
#endif
internal KeyModifiers GetModifiers()
{
KeyModifiers mods = 0;
if (this[Key.AltLeft] || this[Key.AltRight])
{
mods |= KeyModifiers.Alt;
}
if (this[Key.ControlLeft] || this[Key.ControlRight])
{
mods |= KeyModifiers.Control;
}
if (this[Key.ShiftLeft] || this[Key.ShiftRight])
{
mods |= KeyModifiers.Shift;
}
return mods;
}
#endregion #endregion
} }

View file

@ -46,7 +46,7 @@ namespace OpenTK.Input
#region Fields #region Fields
Key key; Key key;
KeyModifiers mods; KeyboardState state;
uint scancode; uint scancode;
#endregion #endregion
@ -97,7 +97,7 @@ namespace OpenTK.Input
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value> /// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
public bool Alt public bool Alt
{ {
get { return (mods & KeyModifiers.Alt) != 0; } get { return state[Key.AltLeft] || state[Key.AltRight]; }
} }
/// <summary> /// <summary>
@ -106,7 +106,7 @@ namespace OpenTK.Input
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value> /// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
public bool Control public bool Control
{ {
get { return (mods & KeyModifiers.Control) != 0; } get { return state[Key.ControlLeft] || state[Key.ControlRight]; }
} }
/// <summary> /// <summary>
@ -115,7 +115,7 @@ namespace OpenTK.Input
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value> /// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
public bool Shift public bool Shift
{ {
get { return (mods & KeyModifiers.Shift) != 0; } get { return state[Key.ShiftLeft] || state[Key.ShiftRight]; }
} }
/// <summary> /// <summary>
@ -125,8 +125,24 @@ namespace OpenTK.Input
/// <value>The modifiers.</value> /// <value>The modifiers.</value>
public KeyModifiers Modifiers public KeyModifiers Modifiers
{ {
get { return mods; } get
internal set { mods = value; } {
KeyModifiers mods = 0;
mods |= Alt ? KeyModifiers.Alt : 0;
mods |= Control ? KeyModifiers.Control : 0;
mods |= Shift ? KeyModifiers.Shift : 0;
return mods;
}
}
/// <summary>
/// Gets the current <see cref="OpenTK.Input.KeyboardState"/>.
/// </summary>
/// <value>The keyboard.</value>
public KeyboardState Keyboard
{
get { return state; }
internal set { state = value; }
} }
#endregion #endregion

View file

@ -43,9 +43,6 @@ namespace OpenTK.Input
const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize; const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize;
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh... // The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
unsafe fixed int Keys[NumInts]; unsafe fixed int Keys[NumInts];
const int CodesSize = 256;
unsafe fixed int Codes[CodesSize];
bool is_connected; bool is_connected;
#endregion #endregion
@ -61,6 +58,7 @@ namespace OpenTK.Input
public bool this[Key key] public bool this[Key key]
{ {
get { return IsKeyDown(key); } get { return IsKeyDown(key); }
internal set { SetKeyState(key, value); }
} }
/// <summary> /// <summary>
@ -71,7 +69,7 @@ namespace OpenTK.Input
/// <returns>True if code is pressed; false otherwise.</returns> /// <returns>True if code is pressed; false otherwise.</returns>
public bool this[short code] public bool this[short code]
{ {
get { return IsKeyDown(code); } get { return IsKeyDown((Key)code); }
} }
/// <summary> /// <summary>
@ -89,7 +87,7 @@ namespace OpenTK.Input
/// <param name="code">The scan code to check.</param> /// <param name="code">The scan code to check.</param>
public bool IsKeyDown(short code) public bool IsKeyDown(short code)
{ {
return ReadBit(code,true); return code >= 0 && code < (short)Key.LastKey && ReadBit(code);
} }
/// <summary> /// <summary>
@ -107,7 +105,7 @@ namespace OpenTK.Input
/// <param name="code">The scan code to check.</param> /// <param name="code">The scan code to check.</param>
public bool IsKeyUp(short code) public bool IsKeyUp(short code)
{ {
return !ReadBit(code,true); return !IsKeyDown(code);
} }
/// <summary> /// <summary>
@ -212,62 +210,51 @@ namespace OpenTK.Input
#region Internal Members #region Internal Members
internal void SetKeyState(Key key, byte code, bool down) internal void SetKeyState(Key key, bool down)
{ {
if (down) if (down)
{ {
EnableBit((int)key); EnableBit((int)key);
EnableBit(code,true);
} }
else else
{ {
DisableBit((int)key); DisableBit((int)key);
DisableBit(code, true);
} }
} }
internal bool ReadBit(int offset, bool ScanCode = false) internal bool ReadBit(int offset)
{ {
ValidateOffset(offset, ScanCode); ValidateOffset(offset);
int int_offset = offset / 32; int int_offset = offset / 32;
int bit_offset = offset % 32; int bit_offset = offset % 32;
unsafe unsafe
{ {
if (ScanCode) fixed (int* k = Keys) { return (*(k + int_offset) & (1 << bit_offset)) != 0u; }
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 EnableBit(int offset, bool ScanCode = false) internal void EnableBit(int offset)
{ {
ValidateOffset(offset, ScanCode); ValidateOffset(offset);
int int_offset = offset / 32; int int_offset = offset / 32;
int bit_offset = offset % 32; int bit_offset = offset % 32;
unsafe unsafe
{ {
if (ScanCode) fixed (int* k = Keys) { *(k + int_offset) |= 1 << bit_offset; }
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) internal void DisableBit(int offset)
{ {
ValidateOffset(offset, ScanCode); ValidateOffset(offset);
int int_offset = offset / 32; int int_offset = offset / 32;
int bit_offset = offset % 32; int bit_offset = offset % 32;
unsafe unsafe
{ {
if (ScanCode) fixed (int* k = Keys) { *(k + int_offset) &= ~(1 << bit_offset); }
fixed (int* c = Codes) { *(c + int_offset) &= ~(1 << bit_offset); }
else
fixed (int* k = Keys) { *(k + int_offset) &= ~(1 << bit_offset); }
} }
} }
@ -281,12 +268,6 @@ namespace OpenTK.Input
for (int i = 0; i < NumInts; i++) for (int i = 0; i < NumInts; i++)
*(k1 + i) |= *(k2 + i); *(k1 + i) |= *(k2 + i);
} }
int* c2 = other.Codes;
fixed (int* c1 = Codes)
{
for (int i = 0; i < CodesSize; i++)
*(c1 + i) |= *(c2 + i);
}
} }
IsConnected |= other.IsConnected; IsConnected |= other.IsConnected;
} }
@ -300,10 +281,10 @@ namespace OpenTK.Input
#region Private Members #region Private Members
static void ValidateOffset(int offset, bool ScanCode) static void ValidateOffset(int offset)
{ {
if (offset < 0 || offset >= (ScanCode ? 256 : NumInts * IntSize)) if (offset < 0 || offset >= NumInts * IntSize)
throw new ArgumentOutOfRangeException("offset"); throw new ArgumentOutOfRangeException();
} }
#endregion #endregion

View file

@ -136,8 +136,6 @@ namespace OpenTK.Platform.MacOS
private Nullable<WindowBorder> deferredWindowBorder; private Nullable<WindowBorder> deferredWindowBorder;
private Nullable<WindowBorder> previousWindowBorder; private Nullable<WindowBorder> previousWindowBorder;
private WindowState windowState = WindowState.Normal; private WindowState windowState = WindowState.Normal;
private OpenTK.Input.KeyboardKeyEventArgs keyArgs = new OpenTK.Input.KeyboardKeyEventArgs();
private KeyPressEventArgs keyPressArgs = new KeyPressEventArgs((char)0);
private string title; private string title;
private RectangleF previousBounds; private RectangleF previousBounds;
private int normalLevel; private int normalLevel;
@ -387,13 +385,6 @@ namespace OpenTK.Platform.MacOS
return modifiers; return modifiers;
} }
private void GetKey(ushort keyCode, NSEventModifierMask modifierFlags, OpenTK.Input.KeyboardKeyEventArgs args)
{
args.Key = MacOSKeyMap.GetKey((Carbon.MacOSKeyCode)keyCode);
args.Modifiers = GetModifiers(modifierFlags);
args.ScanCode = (uint)keyCode;
}
private MouseButton GetMouseButton(int cocoaButtonIndex) private MouseButton GetMouseButton(int cocoaButtonIndex)
{ {
if (cocoaButtonIndex == 0) return MouseButton.Left; if (cocoaButtonIndex == 0) return MouseButton.Left;
@ -419,14 +410,15 @@ namespace OpenTK.Platform.MacOS
{ {
case NSEventType.KeyDown: case NSEventType.KeyDown:
{ {
var keyCode = Cocoa.SendUshort(e, selKeyCode); MacOSKeyCode keyCode = (MacOSKeyCode)Cocoa.SendUshort(e, selKeyCode);
var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags); //var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags);
var isARepeat = Cocoa.SendBool(e, selIsARepeat); var isARepeat = Cocoa.SendBool(e, selIsARepeat);
GetKey(keyCode, modifierFlags, keyArgs); //GetKey(keyCode, modifierFlags, keyArgs);
Key key = MacOSKeyMap.GetKey(keyCode);
if (!isARepeat || InputDriver.Keyboard[0].KeyRepeat) if (!isARepeat || InputDriver.Keyboard[0].KeyRepeat)
{ {
OnKeyDown(keyArgs); OnKeyDown(key);
} }
var s = Cocoa.FromNSString(Cocoa.SendIntPtr(e, selCharactersIgnoringModifiers)); var s = Cocoa.FromNSString(Cocoa.SendIntPtr(e, selCharactersIgnoringModifiers));
@ -435,10 +427,9 @@ namespace OpenTK.Platform.MacOS
int intVal = (int)c; int intVal = (int)c;
if (!Char.IsControl(c) && (intVal < 63232 || intVal > 63235)) if (!Char.IsControl(c) && (intVal < 63232 || intVal > 63235))
{ {
// For some reason, arrow keys (mapped 63232-63235) are seen as non-control characters, so get rid of those. // For some reason, arrow keys (mapped 63232-63235)
// are seen as non-control characters, so get rid of those.
keyPressArgs.KeyChar = c; OnKeyPress(c);
OnKeyPress(keyPressArgs);
} }
} }
} }
@ -446,11 +437,11 @@ namespace OpenTK.Platform.MacOS
case NSEventType.KeyUp: case NSEventType.KeyUp:
{ {
var keyCode = Cocoa.SendUshort(e, selKeyCode); MacOSKeyCode keyCode = (MacOSKeyCode)Cocoa.SendUshort(e, selKeyCode);
var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags); //var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags);
//GetKey(keyCode, modifierFlags, keyArgs);
GetKey(keyCode, modifierFlags, keyArgs); Key key = MacOSKeyMap.GetKey(keyCode);
OnKeyUp(keyArgs); OnKeyUp(key);
} }
break; break;
@ -521,9 +512,7 @@ namespace OpenTK.Platform.MacOS
// Only raise events when the mouse has actually moved // Only raise events when the mouse has actually moved
if (MouseState.X != p.X || MouseState.Y != p.Y) if (MouseState.X != p.X || MouseState.Y != p.Y)
{ {
MouseState.X = p.X; OnMouseMove(p.X, p.Y);
MouseState.Y = p.Y;
OnMouseMove();
} }
} }
break; break;
@ -548,8 +537,7 @@ namespace OpenTK.Platform.MacOS
// Only raise wheel events when the user has actually scrolled // Only raise wheel events when the user has actually scrolled
if (dx != 0 || dy != 0) if (dx != 0 || dy != 0)
{ {
MouseState.SetScrollRelative(dx, dy); OnMouseWheel(dx, dy);
OnMouseWheel();
} }
} }
break; break;
@ -559,8 +547,7 @@ namespace OpenTK.Platform.MacOS
case NSEventType.OtherMouseDown: case NSEventType.OtherMouseDown:
{ {
var buttonNumber = Cocoa.SendInt(e, selButtonNumber); var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
MouseState[GetMouseButton(buttonNumber)] = true; OnMouseDown(GetMouseButton(buttonNumber));
OnMouseDown();
} }
break; break;
@ -569,8 +556,7 @@ namespace OpenTK.Platform.MacOS
case NSEventType.OtherMouseUp: case NSEventType.OtherMouseUp:
{ {
var buttonNumber = Cocoa.SendInt(e, selButtonNumber); var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
MouseState[GetMouseButton(buttonNumber)] = false; OnMouseUp(GetMouseButton(buttonNumber));
OnMouseUp();
} }
break; break;
} }

View file

@ -390,7 +390,8 @@ namespace OpenTK.Platform.MacOS
{ {
Debug.Print("[Warning] Key {0} not mapped.", usage); Debug.Print("[Warning] Key {0} not mapped.", usage);
} }
keyboard.State.SetKeyState(RawKeyMap[usage], (byte)usage, v_int != 0);
keyboard.State[RawKeyMap[usage]] = v_int != 0;
break; break;
} }
} }

View file

@ -45,19 +45,22 @@ namespace OpenTK.Platform
readonly MouseMoveEventArgs MouseMoveArgs = new MouseMoveEventArgs(); readonly MouseMoveEventArgs MouseMoveArgs = new MouseMoveEventArgs();
readonly MouseWheelEventArgs MouseWheelArgs = new MouseWheelEventArgs(); readonly MouseWheelEventArgs MouseWheelArgs = new MouseWheelEventArgs();
protected readonly KeyboardKeyEventArgs KeyDownArgs = new KeyboardKeyEventArgs(); readonly KeyboardKeyEventArgs KeyDownArgs = new KeyboardKeyEventArgs();
protected readonly KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs(); readonly KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs();
protected readonly KeyPressEventArgs KeyPressArgs = new KeyPressEventArgs((char)0); readonly KeyPressEventArgs KeyPressArgs = new KeyPressEventArgs((char)0);
// In order to simplify mouse event implementation, // In order to simplify mouse event implementation,
// we can store the current mouse state here. // we can store the current mouse state here.
protected MouseState MouseState = new MouseState(); protected MouseState MouseState = new MouseState();
protected KeyboardState KeyboardState = new KeyboardState();
MouseState PreviousMouseState = new MouseState(); MouseState PreviousMouseState = new MouseState();
internal NativeWindowBase() internal NativeWindowBase()
{ {
LegacyInputDriver = new LegacyInputDriver(this); LegacyInputDriver = new LegacyInputDriver(this);
MouseState.SetIsConnected(true); MouseState.SetIsConnected(true);
KeyboardState.SetIsConnected(true);
PreviousMouseState.SetIsConnected(true); PreviousMouseState.SetIsConnected(true);
} }
@ -118,18 +121,30 @@ namespace OpenTK.Platform
WindowStateChanged(this, e); WindowStateChanged(this, e);
} }
protected void OnKeyDown(KeyboardKeyEventArgs e) protected void OnKeyDown(Key key)
{ {
KeyboardState.SetKeyState(key, true);
var e = KeyDownArgs;
e.Keyboard = KeyboardState;
e.Key = key;
KeyDown(this, e); KeyDown(this, e);
} }
protected void OnKeyPress(KeyPressEventArgs e) protected void OnKeyPress(char c)
{ {
var e = KeyPressArgs;
e.KeyChar = c;
KeyPress(this, e); KeyPress(this, e);
} }
protected void OnKeyUp(KeyboardKeyEventArgs e) protected void OnKeyUp(Key key)
{ {
KeyboardState.SetKeyState(key, false);
var e = KeyUpArgs;
e.Keyboard = KeyboardState;
e.Key = key;
KeyUp(this, e); KeyUp(this, e);
} }
@ -143,48 +158,31 @@ namespace OpenTK.Platform
MouseEnter(this, e); MouseEnter(this, e);
} }
protected void OnMouseDown() protected void OnMouseDown(MouseButton button)
{ {
MouseState[button] = true;
var e = MouseDownArgs; var e = MouseDownArgs;
e.Mouse = MouseState; e.Mouse = MouseState;
// Find which button caused this event MouseDown(this, e);
for (MouseButton b = MouseButton.Left; b < MouseButton.LastButton; b++)
{
if (!PreviousMouseState[b] && MouseState[b])
{
e.Button = b;
PreviousMouseState = MouseState;
MouseDown(this, e);
return;
}
}
Debug.WriteLine("OnMouseDown called without pressing a button");
} }
protected void OnMouseUp() protected void OnMouseUp(MouseButton button)
{ {
MouseState[button] = false;
var e = MouseUpArgs; var e = MouseUpArgs;
e.Mouse = MouseState; e.Mouse = MouseState;
// Find which button caused this event MouseUp(this, e);
for (MouseButton b = MouseButton.Left; b < MouseButton.LastButton; b++)
{
if (PreviousMouseState[b] && !MouseState[b])
{
e.Button = b;
PreviousMouseState = MouseState;
MouseUp(this, e);
return;
}
}
Debug.WriteLine("OnMouseUp called without pressing a button");
} }
protected void OnMouseMove() protected void OnMouseMove(int x, int y)
{ {
MouseState.X = x;
MouseState.Y = y;
var e = MouseMoveArgs; var e = MouseMoveArgs;
e.Mouse = MouseState; e.Mouse = MouseState;
e.XDelta = MouseState.X - PreviousMouseState.X; e.XDelta = MouseState.X - PreviousMouseState.X;
@ -199,14 +197,15 @@ namespace OpenTK.Platform
MouseMove(this, e); MouseMove(this, e);
} }
protected void OnMouseWheel() protected void OnMouseWheel(float dx, float dy)
{ {
MouseState.SetScrollRelative(dx, dy);
var e = MouseWheelArgs; var e = MouseWheelArgs;
e.Mouse = MouseState; e.Mouse = MouseState;
e.ValuePrecise = MouseState.Scroll.Y;
e.DeltaPrecise = MouseState.Scroll.Y - PreviousMouseState.Scroll.Y; e.DeltaPrecise = MouseState.Scroll.Y - PreviousMouseState.Scroll.Y;
if (e.DeltaPrecise == 0) if (dx == 0 && dy == 0)
{ {
Debug.WriteLine("OnMouseWheel called without moving the mouse wheel."); Debug.WriteLine("OnMouseWheel called without moving the mouse wheel.");
} }

View file

@ -58,16 +58,16 @@ namespace OpenTK.Platform.SDL2
{ {
Keymod mod = SDL.GetModState(); Keymod mod = SDL.GetModState();
state.SetKeyState(Key.LAlt, (byte)Scancode.LALT, (mod & Keymod.LALT) != 0); state[Key.LAlt] = (mod & Keymod.LALT) != 0;
state.SetKeyState(Key.RAlt, (byte)Scancode.RALT, (mod & Keymod.RALT) != 0); state[Key.RAlt] = (mod & Keymod.RALT) != 0;
state.SetKeyState(Key.LControl, (byte)Scancode.LCTRL, (mod & Keymod.LCTRL) != 0); state[Key.LControl] = (mod & Keymod.LCTRL) != 0;
state.SetKeyState(Key.RControl, (byte)Scancode.RCTRL, (mod & Keymod.CTRL) != 0); state[Key.RControl] = (mod & Keymod.RCTRL) != 0;
state.SetKeyState(Key.LShift, (byte)Scancode.LSHIFT, (mod & Keymod.LSHIFT) != 0); state[Key.LShift] = (mod & Keymod.LSHIFT) != 0;
state.SetKeyState(Key.RShift, (byte)Scancode.RSHIFT, (mod & Keymod.RSHIFT) != 0); state[Key.RShift] = (mod & Keymod.RSHIFT) != 0;
state.SetKeyState(Key.Menu, (byte)Scancode.APPLICATION, (mod & Keymod.GUI) != 0); state[Key.Menu] = (mod & Keymod.GUI) != 0;
state.SetKeyState(Key.CapsLock, (byte)Scancode.CAPSLOCK, (mod & Keymod.CAPS) != 0); state[Key.CapsLock] = (mod & Keymod.CAPS) != 0;
state.SetKeyState(Key.NumLock, (byte)Scancode.NUMLOCKCLEAR, (mod & Keymod.NUM) != 0); state[Key.NumLock] = (mod & Keymod.NUM) != 0;
//state.SetKeyState(Key., (byte)Scancode.MODE, (mod & Keymod.MODE) != 0); //state[Key.] = (mod & Keymod.MODE) != 0;
} }
#endregion #endregion
@ -83,7 +83,7 @@ namespace OpenTK.Platform.SDL2
if (key != Key.Unknown) if (key != Key.Unknown)
{ {
state.SetKeyState(key, (byte)scancode, pressed); state[key] = pressed;
} }
} }

View file

@ -66,12 +66,6 @@ namespace OpenTK.Platform.SDL2
// to .Net UTF16 strings // to .Net UTF16 strings
char[] DecodeTextBuffer = new char[32]; char[] DecodeTextBuffer = new char[32];
// Argument for KeyPress event (allocated once to avoid runtime allocations)
readonly KeyPressEventArgs keypress_args = new KeyPressEventArgs('\0');
// Argument for KeyDown and KeyUp events (allocated once to avoid runtime allocations)
readonly KeyboardKeyEventArgs key_args = new KeyboardKeyEventArgs();
static readonly Dictionary<uint, Sdl2NativeWindow> windows = static readonly Dictionary<uint, Sdl2NativeWindow> windows =
new Dictionary<uint, Sdl2NativeWindow>(); new Dictionary<uint, Sdl2NativeWindow>();
@ -221,36 +215,29 @@ namespace OpenTK.Platform.SDL2
button_pressed ? true : false); button_pressed ? true : false);
} }
window.MouseState[Sdl2Mouse.TranslateButton(ev.Button)] = button_pressed; MouseButton button = Sdl2Mouse.TranslateButton(ev.Button);
window.MouseState.X = ev.X;
window.MouseState.Y = ev.Y;
if (button_pressed) if (button_pressed)
{ {
window.OnMouseDown(); window.OnMouseDown(button);
} }
else else
{ {
window.OnMouseUp(); window.OnMouseUp(button);
} }
} }
static void ProcessKeyEvent(Sdl2NativeWindow window, Event ev) static void ProcessKeyEvent(Sdl2NativeWindow window, Event ev)
{ {
bool key_pressed = ev.Key.State == State.Pressed; bool key_pressed = ev.Key.State == State.Pressed;
var key = ev.Key.Keysym; Key key = TranslateKey(ev.Key.Keysym.Scancode);
window.key_args.Key = TranslateKey(key.Scancode);
window.key_args.ScanCode = (uint)key.Scancode;
window.key_args.Modifiers = Sdl2KeyMap.GetModifiers(key.Mod);
if (key_pressed) if (key_pressed)
{ {
window.OnKeyDown(window.key_args); window.OnKeyDown(key);
} }
else else
{ {
window.OnKeyUp(window.key_args); window.OnKeyUp(key);
} }
//window.keyboard.SetKey(TranslateKey(key.scancode), (uint)key.scancode, key_pressed);
} }
static unsafe void ProcessTextInputEvent(Sdl2NativeWindow window, TextInputEvent ev) static unsafe void ProcessTextInputEvent(Sdl2NativeWindow window, TextInputEvent ev)
@ -281,23 +268,19 @@ namespace OpenTK.Platform.SDL2
for (int i = 0; i < decoded_length; i++) for (int i = 0; i < decoded_length; i++)
{ {
window.keypress_args.KeyChar = window.DecodeTextBuffer[i]; window.OnKeyPress(window.DecodeTextBuffer[i]);
window.OnKeyPress(window.keypress_args);
} }
} }
static void ProcessMouseMotionEvent(Sdl2NativeWindow window, MouseMotionEvent ev) static void ProcessMouseMotionEvent(Sdl2NativeWindow window, MouseMotionEvent ev)
{ {
//float scale = window.ClientSize.Width / (float)window.Size.Width; //float scale = window.ClientSize.Width / (float)window.Size.Width;
window.MouseState.X = ev.X; window.OnMouseMove(ev.X, ev.Y);
window.MouseState.Y = ev.Y;
window.OnMouseMove();
} }
static void ProcessMouseWheelEvent(Sdl2NativeWindow window, MouseWheelEvent ev) static void ProcessMouseWheelEvent(Sdl2NativeWindow window, MouseWheelEvent ev)
{ {
window.MouseState.SetScrollRelative(ev.X, ev.Y); window.OnMouseWheel(ev.X, ev.Y);
window.OnMouseWheel();
} }
static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e) static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e)

View file

@ -393,8 +393,7 @@ namespace OpenTK.Platform.Windows
if (!Char.IsControl(c)) if (!Char.IsControl(c))
{ {
KeyPressArgs.KeyChar = c; OnKeyPress(c);
OnKeyPress(KeyPressArgs);
} }
} }
@ -437,9 +436,7 @@ namespace OpenTK.Platform.Windows
if (points == 0 || (points == -1 && lastError == Constants.ERROR_POINT_NOT_FOUND)) if (points == 0 || (points == -1 && lastError == Constants.ERROR_POINT_NOT_FOUND))
{ {
// Just use the mouse move position // Just use the mouse move position
MouseState.X = point.X; OnMouseMove(point.X, point.Y);
MouseState.Y = point.Y;
OnMouseMove();
} }
else if (points == -1) else if (points == -1)
{ {
@ -477,9 +474,7 @@ namespace OpenTK.Platform.Windows
position.Y -= 65536; position.Y -= 65536;
} }
Functions.ScreenToClient(handle, ref position); Functions.ScreenToClient(handle, ref position);
MouseState.X = position.X; OnMouseMove(position.X, position.Y);
MouseState.Y = position.Y;
OnMouseMove();
} }
} }
mouse_last_timestamp = timestamp; mouse_last_timestamp = timestamp;
@ -508,37 +503,32 @@ namespace OpenTK.Platform.Windows
{ {
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese // This is due to inconsistent behavior of the WParam value on 64bit arch, whese
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000 // wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
MouseState.SetScrollRelative(0, ((long)wParam << 32 >> 48) / 120.0f); OnMouseWheel(0, ((long)wParam << 32 >> 48) / 120.0f);
OnMouseWheel();
} }
void HandleMouseHWheel(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleMouseHWheel(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese // This is due to inconsistent behavior of the WParam value on 64bit arch, whese
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000 // wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
MouseState.SetScrollRelative(((long)wParam << 32 >> 48) / 120.0f, 0); OnMouseWheel(((long)wParam << 32 >> 48) / 120.0f, 0);
OnMouseWheel();
} }
void HandleLButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleLButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
Functions.SetCapture(window.Handle); Functions.SetCapture(window.Handle);
MouseState[MouseButton.Left] = true; OnMouseDown(MouseButton.Left);
OnMouseDown();
} }
void HandleMButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleMButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
Functions.SetCapture(window.Handle); Functions.SetCapture(window.Handle);
MouseState[MouseButton.Middle] = true; OnMouseDown(MouseButton.Middle);
OnMouseDown();
} }
void HandleRButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleRButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
Functions.SetCapture(window.Handle); Functions.SetCapture(window.Handle);
MouseState[MouseButton.Right] = true; OnMouseDown(MouseButton.Right);
OnMouseDown();
} }
void HandleXButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleXButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
@ -547,29 +537,25 @@ namespace OpenTK.Platform.Windows
MouseButton button = MouseButton button =
((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ? ((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
MouseButton.Button1 : MouseButton.Button2; MouseButton.Button1 : MouseButton.Button2;
MouseState[button] = true; OnMouseDown(button);
OnMouseDown();
} }
void HandleLButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleLButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
Functions.ReleaseCapture(); Functions.ReleaseCapture();
MouseState[MouseButton.Left] = false; OnMouseUp(MouseButton.Left);
OnMouseUp();
} }
void HandleMButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleMButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
Functions.ReleaseCapture(); Functions.ReleaseCapture();
MouseState[MouseButton.Middle] = false; OnMouseUp(MouseButton.Middle);
OnMouseUp();
} }
void HandleRButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleRButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
Functions.ReleaseCapture(); Functions.ReleaseCapture();
MouseState[MouseButton.Right] = false; OnMouseUp(MouseButton.Right);
OnMouseUp();
} }
void HandleXButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleXButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
@ -578,8 +564,7 @@ namespace OpenTK.Platform.Windows
MouseButton button = MouseButton button =
((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ? ((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
MouseButton.Button1 : MouseButton.Button2; MouseButton.Button1 : MouseButton.Button2;
MouseState[button] = false; OnMouseUp(button);
OnMouseUp();
} }
void HandleKeyboard(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) void HandleKeyboard(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
@ -605,15 +590,11 @@ namespace OpenTK.Platform.Windows
{ {
if (pressed) if (pressed)
{ {
KeyDownArgs.Key = key; OnKeyDown(key);
KeyDownArgs.Modifiers = InputDriver.Keyboard[0].GetModifiers();
OnKeyDown(KeyDownArgs);
} }
else else
{ {
KeyUpArgs.Key = key; OnKeyUp(key);
KeyUpArgs.Modifiers = InputDriver.Keyboard[0].GetModifiers();
OnKeyUp(KeyUpArgs);
} }
} }
} }

View file

@ -188,7 +188,7 @@ namespace OpenTK.Platform.Windows
if (is_valid) if (is_valid)
{ {
keyboard.SetKeyState(key, (byte)scancode, pressed); keyboard.SetKeyState(key, pressed);
processed = true; processed = true;
} }

View file

@ -763,18 +763,6 @@ namespace OpenTK.Platform.X11
return cursor; return cursor;
} }
void SetMouseClamped(int x, int y,
int left, int top, int width, int height)
{
// Clamp mouse to the specified rectangle.
x = Math.Max(x, left);
x = Math.Min(x, width);
y = Math.Max(y, top);
y = Math.Min(y, height);
MouseState.X = x;
MouseState.Y = y;
}
#endregion #endregion
#region INativeWindow Members #region INativeWindow Members
@ -861,18 +849,12 @@ namespace OpenTK.Platform.X11
if (pressed) if (pressed)
{ {
// Raise KeyDown event // Raise KeyDown event
KeyDownArgs.Key = key; OnKeyDown(key);
KeyDownArgs.ScanCode = (uint)e.KeyEvent.keycode;
//KeyDownArgs.Modifiers = keyboard.GetModifiers();
OnKeyDown(KeyDownArgs);
} }
else else
{ {
// Raise KeyUp event // Raise KeyUp event
KeyUpArgs.Key = key; OnKeyUp(key);
KeyUpArgs.ScanCode = (uint)e.KeyEvent.keycode;
//KeyUpArgs.Modifiers = keyboard.GetModifiers();
OnKeyUp(KeyUpArgs);
} }
if (pressed) if (pressed)
@ -888,8 +870,7 @@ namespace OpenTK.Platform.X11
{ {
if (!Char.IsControl(chars[i])) if (!Char.IsControl(chars[i]))
{ {
KeyPressArgs.KeyChar = chars[i]; OnKeyPress(chars[i]);
OnKeyPress(KeyPressArgs);
} }
} }
} }
@ -922,10 +903,9 @@ namespace OpenTK.Platform.X11
} }
else if (!CursorVisible) else if (!CursorVisible)
{ {
SetMouseClamped( OnMouseMove(
MouseState.X + x - mouse_rel_x, MathHelper.Clamp(MouseState.X + x - mouse_rel_x, 0, Width),
MouseState.Y + y - mouse_rel_y, MathHelper.Clamp(MouseState.Y + y - mouse_rel_y, 0, Height));
0, 0, Width, Height);
mouse_rel_x = x; mouse_rel_x = x;
mouse_rel_y = y; mouse_rel_y = y;
@ -935,53 +915,42 @@ namespace OpenTK.Platform.X11
} }
else else
{ {
SetMouseClamped(x, y, 0, 0, Width, Height); OnMouseMove(
MathHelper.Clamp(x, 0, Width),
MathHelper.Clamp(y, 0, Height));
mouse_rel_x = x; mouse_rel_x = x;
mouse_rel_y = y; mouse_rel_y = y;
} }
OnMouseMove();
break; break;
} }
case XEventName.ButtonPress: case XEventName.ButtonPress:
switch (e.ButtonEvent.button)
{ {
case 1: MouseState.EnableBit((int)MouseButton.Left); break; int dx, dy;
case 2: MouseState.EnableBit((int)MouseButton.Middle); break; MouseButton button = X11KeyMap.TranslateButton(e.ButtonEvent.button, out dx, out dy);
case 3: MouseState.EnableBit((int)MouseButton.Right); break;
case 4: MouseState.SetScrollRelative(0, 1); break; if (button != MouseButton.LastButton)
case 5: MouseState.SetScrollRelative(0, -1); break; {
case 6: MouseState.EnableBit((int)MouseButton.Button1); break; OnMouseDown(button);
case 7: MouseState.EnableBit((int)MouseButton.Button2); break; }
case 8: MouseState.EnableBit((int)MouseButton.Button3); break; else if (dx != 0 || dy != 0)
case 9: MouseState.EnableBit((int)MouseButton.Button4); break; {
case 10: MouseState.EnableBit((int)MouseButton.Button5); break; OnMouseWheel(dx, dy);
case 11: MouseState.EnableBit((int)MouseButton.Button6); break; }
case 12: MouseState.EnableBit((int)MouseButton.Button7); break;
case 13: MouseState.EnableBit((int)MouseButton.Button8); break;
case 14: MouseState.EnableBit((int)MouseButton.Button9); break;
} }
OnMouseDown();
break; break;
case XEventName.ButtonRelease: case XEventName.ButtonRelease:
switch (e.ButtonEvent.button)
{ {
case 1: MouseState.DisableBit((int)MouseButton.Left); break; int dx, dy;
case 2: MouseState.DisableBit((int)MouseButton.Middle); break; MouseButton button = X11KeyMap.TranslateButton(e.ButtonEvent.button, out dx, out dy);
case 3: MouseState.DisableBit((int)MouseButton.Right); break;
case 6: MouseState.DisableBit((int)MouseButton.Button1); break; if (button != MouseButton.LastButton)
case 7: MouseState.DisableBit((int)MouseButton.Button2); break; {
case 8: MouseState.DisableBit((int)MouseButton.Button3); break; OnMouseUp(button);
case 9: MouseState.DisableBit((int)MouseButton.Button4); break; }
case 10: MouseState.DisableBit((int)MouseButton.Button5); break;
case 11: MouseState.DisableBit((int)MouseButton.Button6); break;
case 12: MouseState.DisableBit((int)MouseButton.Button7); break;
case 13: MouseState.DisableBit((int)MouseButton.Button8); break;
case 14: MouseState.DisableBit((int)MouseButton.Button9); break;
} }
OnMouseUp();
break; break;
case XEventName.FocusIn: case XEventName.FocusIn: