Implemented WinRawKeyboard input driver.

This commit is contained in:
the_fiddler 2010-10-28 08:42:38 +00:00
parent 73326138ee
commit 505399ba9f

View file

@ -41,7 +41,10 @@ namespace OpenTK.Platform.Windows
{ {
internal class WinRawKeyboard : IKeyboardDriver, IDisposable internal class WinRawKeyboard : IKeyboardDriver, IDisposable
{ {
private List<KeyboardDevice> keyboards = new List<KeyboardDevice>(); readonly List<KeyboardState> keyboards = new List<KeyboardState>();
// ContextHandle instead of IntPtr for fast dictionary access
readonly Dictionary<ContextHandle, int> rawids = new Dictionary<ContextHandle, int>();
private List<KeyboardDevice> keyboards_old = new List<KeyboardDevice>();
private IntPtr window; private IntPtr window;
#region --- Constructors --- #region --- Constructors ---
@ -134,8 +137,11 @@ namespace OpenTK.Platform.Windows
//if (!keyboards.Contains(kb)) //if (!keyboards.Contains(kb))
//{ //{
this.RegisterKeyboardDevice(kb); this.RegisterKeyboardDevice(kb);
keyboards.Add(kb); keyboards_old.Add(kb);
//} //}
keyboards.Add(new KeyboardState());
rawids.Add(new ContextHandle(ridl[i].Device), keyboards.Count - 1);
} }
} }
} }
@ -181,58 +187,56 @@ namespace OpenTK.Platform.Windows
/// <returns></returns> /// <returns></returns>
internal bool ProcessKeyboardEvent(RawInput rin) internal bool ProcessKeyboardEvent(RawInput rin)
{ {
//Keyboard key = keyboards[0]; bool processed = false;
//rin.Header.Device;
switch (rin.Header.Type) bool pressed =
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN ||
rin.Data.Keyboard.Message == (int)WindowMessage.SYSKEYDOWN;
ContextHandle handle = new ContextHandle(rin.Header.Device);
KeyboardState keyboard;
if (!rawids.ContainsKey(handle))
{ {
case RawInputDeviceType.KEYBOARD: keyboards.Add(new KeyboardState());
bool pressed = rawids.Add(handle, keyboards.Count - 1);
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN || }
rin.Data.Keyboard.Message == (int)WindowMessage.SYSKEYDOWN; keyboard = keyboards[rawids[handle]];
// Find the device where the button was pressed. It can be that the input notification
// came not from a physical keyboard device but from a code-generated input message - in
// that case, the event goes to the default (first) keyboard.
// TODO: Send the event to all keyboards instead of the default one.
// TODO: Optimize this! The predicate allocates way to much memory.
//int index = keyboards.FindIndex(delegate(KeyboardDevice kb)
//{
// return kb.DeviceID == rin.Header.Device;
//});
//if (index == -1) index = 0;
int index;
if (keyboards.Count > 0) index = 0;
else return false;
// Generic control, shift, alt keys may be sent instead of left/right. // Generic control, shift, alt keys may be sent instead of left/right.
// It seems you have to explicitly register left/right events. // It seems you have to explicitly register left/right events.
switch (rin.Data.Keyboard.VKey) switch (rin.Data.Keyboard.VKey)
{ {
case VirtualKeys.SHIFT: case VirtualKeys.SHIFT:
keyboards[index][Input.Key.ShiftLeft] = keyboards[index][Input.Key.ShiftRight] = pressed; keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed;
return true; processed = true;
break;
case VirtualKeys.CONTROL: case VirtualKeys.CONTROL:
keyboards[index][Input.Key.ControlLeft] = keyboards[index][Input.Key.ControlRight] = pressed; keyboard[Input.Key.ControlLeft] = keyboard[Input.Key.ControlRight] = pressed;
return true; processed = true;
break;
case VirtualKeys.MENU: case VirtualKeys.MENU:
keyboards[index][Input.Key.AltLeft] = keyboards[index][Input.Key.AltRight] = pressed; keyboard[Input.Key.AltLeft] = keyboard[Input.Key.AltRight] = pressed;
return true; processed = true;
break;
default:
if (!WMInput.KeyMap.ContainsKey(rin.Data.Keyboard.VKey))
Debug.Print("Virtual key {0} ({1}) not mapped.",
rin.Data.Keyboard.VKey, (int)rin.Data.Keyboard.VKey);
else
keyboards[index][WMInput.KeyMap[rin.Data.Keyboard.VKey]] = pressed;
return false;
}
default: default:
throw new ApplicationException("Windows raw keyboard driver received invalid data."); if (!WMInput.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[WMInput.KeyMap[rin.Data.Keyboard.VKey]] = pressed;
processed = true;
}
break;
} }
keyboards[rawids[handle]] = keyboard;
return processed;
} }
#endregion #endregion
@ -255,17 +259,23 @@ namespace OpenTK.Platform.Windows
public IList<KeyboardDevice> Keyboard public IList<KeyboardDevice> Keyboard
{ {
get { return keyboards; } get { return keyboards_old; }
} }
public KeyboardState GetState() public KeyboardState GetState()
{ {
throw new NotImplementedException(); if (keyboards.Count > 0)
return keyboards[0];
else
return new KeyboardState();
} }
public KeyboardState GetState(int index) public KeyboardState GetState(int index)
{ {
throw new NotImplementedException(); if (keyboards.Count > index)
return keyboards[index];
else
return new KeyboardState();
} }
#endregion #endregion
@ -286,7 +296,7 @@ namespace OpenTK.Platform.Windows
{ {
if (manual) if (manual)
{ {
keyboards.Clear(); keyboards_old.Clear();
} }
disposed = true; disposed = true;
} }