[Win] Raw input parsing moved to input drivers

This commit is contained in:
thefiddler 2014-07-31 15:44:11 +02:00
parent a51a85c517
commit 3fee0bd8d0
4 changed files with 231 additions and 200 deletions

View file

@ -94,32 +94,30 @@ namespace OpenTK.Platform.Windows
switch (message)
{
case WindowMessage.INPUT:
int size = BlittableValueType<RawInput>.Stride;
RawInput data;
//RawInput data;
// Read the actual raw input structure
if (size == Functions.GetRawInputData(lParam, GetRawInputDataEnum.INPUT,
out data, ref size, API.RawInputHeaderSize))
{
switch (data.Header.Type)
// Retrieve the raw input data buffer
RawInputHeader header;
if (Functions.GetRawInputData(lParam, out header) == RawInputHeader.SizeInBytes)
{
switch (header.Type)
{
case RawInputDeviceType.KEYBOARD:
if (((WinRawKeyboard)KeyboardDriver).ProcessKeyboardEvent(ref data))
if (((WinRawKeyboard)KeyboardDriver).ProcessKeyboardEvent(lParam))
return IntPtr.Zero;
break;
case RawInputDeviceType.MOUSE:
if (((WinRawMouse)MouseDriver).ProcessMouseEvent(ref data))
if (((WinRawMouse)MouseDriver).ProcessMouseEvent(lParam))
return IntPtr.Zero;
break;
case RawInputDeviceType.HID:
if (((WinRawJoystick)JoystickDriver).ProcessEvent(ref data))
if (((WinRawJoystick)JoystickDriver).ProcessEvent(lParam))
return IntPtr.Zero;
break;
}
}
}
break;
case WindowMessage.DEVICECHANGE:

View file

@ -137,6 +137,7 @@ namespace OpenTK.Platform.Windows
readonly object UpdateLock = new object();
readonly DeviceCollection<Device> Devices = new DeviceCollection<Device>();
byte[] HIDData = new byte[1024];
byte[] PreparsedData = new byte[1024];
HidProtocolValueCaps[] AxisCaps = new HidProtocolValueCaps[4];
HidProtocolButtonCaps[] ButtonCaps = new HidProtocolButtonCaps[4];
@ -153,8 +154,8 @@ namespace OpenTK.Platform.Windows
Window = window;
DeviceTypes = new RawInputDevice[]
{
new RawInputDevice(HIDUsageGD.Joystick, RawInputDeviceFlags.INPUTSINK, window),
new RawInputDevice(HIDUsageGD.GamePad, RawInputDeviceFlags.INPUTSINK, window),
new RawInputDevice(HIDUsageGD.Joystick, RawInputDeviceFlags.DEVNOTIFY | RawInputDeviceFlags.EXINPUTSINK, window),
new RawInputDevice(HIDUsageGD.GamePad, RawInputDeviceFlags.DEVNOTIFY | RawInputDeviceFlags.EXINPUTSINK, window),
};
if (!Functions.RegisterRawInputDevices(DeviceTypes, DeviceTypes.Length, API.RawInputDeviceSize))
@ -192,7 +193,8 @@ namespace OpenTK.Platform.Windows
IntPtr handle = dev.Device;
Guid guid = GetDeviceGuid(handle);
long hardware_id = guid.GetHashCode();
//long hardware_id = guid.GetHashCode();
long hardware_id = handle.ToInt64();
Device device = Devices.FromHardwareId(hardware_id);
if (device != null)
@ -215,9 +217,24 @@ namespace OpenTK.Platform.Windows
}
}
public unsafe bool ProcessEvent(ref RawInput rin)
public unsafe bool ProcessEvent(IntPtr raw)
{
IntPtr handle = rin.Header.Device;
// Query the size of the raw HID data buffer
int size = 0;
Functions.GetRawInputData(raw, GetRawInputDataEnum.INPUT, IntPtr.Zero, ref size, RawInputHeader.SizeInBytes);
if (size > HIDData.Length)
{
Array.Resize(ref HIDData, size);
}
// Retrieve the raw HID data buffer
if (Functions.GetRawInputData(raw, HIDData) > 0)
{
fixed (byte* pdata = HIDData)
{
RawInput* rin = (RawInput*)pdata;
IntPtr handle = rin->Header.Device;
Device stick = GetDevice(handle);
if (stick == null)
{
@ -243,8 +260,8 @@ namespace OpenTK.Platform.Windows
// Query current state
// Allocate enough storage to hold the data of the current report
int size = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData);
if (size == 0)
int report_count = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData);
if (report_count == 0)
{
Debug.Print("[WinRawJoystick] HidProtocol.MaxDataListLength() failed with {0}",
Marshal.GetLastWin32Error());
@ -252,28 +269,29 @@ namespace OpenTK.Platform.Windows
}
// Fill the data buffer
if (DataBuffer.Length < size)
if (DataBuffer.Length < report_count)
{
Array.Resize(ref DataBuffer, size);
Array.Resize(ref DataBuffer, report_count);
}
fixed (void* pdata = &rin.Data.HID.RawData)
{
if (HidProtocol.GetData(HidProtocolReportType.Input,
DataBuffer, ref size, PreparsedData,
(IntPtr)pdata, rin.Data.HID.Size) != HidProtocolStatus.Success)
new IntPtr((void*)&rin->Data.HID.RawData),
rin->Data.HID.Size) != HidProtocolStatus.Success)
{
Debug.Print("[WinRawJoystick] HidProtocol.GetData() failed with {0}",
Marshal.GetLastWin32Error());
return false;
}
}
UpdateAxes(stick, caps, AxisCaps, axis_caps_count, DataBuffer);
UpdateButtons(stick, caps, ButtonCaps, button_caps_count, DataBuffer);
return true;
}
}
return false;
}
#endregion

View file

@ -153,10 +153,13 @@ namespace OpenTK.Platform.Windows
}
}
public bool ProcessKeyboardEvent(ref RawInput rin)
public bool ProcessKeyboardEvent(IntPtr raw)
{
bool processed = false;
RawInput rin;
if (Functions.GetRawInputData(raw, out rin) > 0)
{
bool pressed =
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN ||
rin.Data.Keyboard.Message == (int)WindowMessage.SYSKEYDOWN;
@ -196,10 +199,13 @@ namespace OpenTK.Platform.Windows
lock (UpdateLock)
{
keyboards[keyboard_handle] = keyboard;
return processed;
processed = true;
}
}
return processed;
}
#endregion
#region Private Members

View file

@ -149,7 +149,12 @@ namespace OpenTK.Platform.Windows
}
}
public bool ProcessMouseEvent(ref RawInput rin)
public bool ProcessMouseEvent(IntPtr raw_buffer)
{
bool processed = false;
RawInput rin;
if (Functions.GetRawInputData(raw_buffer, out rin) > 0)
{
RawMouse raw = rin.Data.Mouse;
ContextHandle handle = new ContextHandle(rin.Header.Device);
@ -171,7 +176,8 @@ namespace OpenTK.Platform.Windows
mouse = mice[mouse_handle];
// Set and release capture of the mouse to fix http://www.opentk.com/node/2133, Patch by Artfunkel
if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_DOWN) != 0){
if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_DOWN) != 0)
{
mouse.EnableBit((int)MouseButton.Left);
Functions.SetCapture(Window);
}
@ -241,10 +247,13 @@ namespace OpenTK.Platform.Windows
lock (UpdateLock)
{
mice[mouse_handle] = mouse;
return true;
processed = true;
}
}
return processed;
}
#endregion
#region Private Members