mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-02-25 11:17:02 +00:00
[Win] Raw input parsing moved to input drivers
This commit is contained in:
parent
a51a85c517
commit
3fee0bd8d0
|
@ -94,30 +94,28 @@ 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)
|
||||
{
|
||||
case RawInputDeviceType.KEYBOARD:
|
||||
if (((WinRawKeyboard)KeyboardDriver).ProcessKeyboardEvent(ref data))
|
||||
return IntPtr.Zero;
|
||||
break;
|
||||
switch (header.Type)
|
||||
{
|
||||
case RawInputDeviceType.KEYBOARD:
|
||||
if (((WinRawKeyboard)KeyboardDriver).ProcessKeyboardEvent(lParam))
|
||||
return IntPtr.Zero;
|
||||
break;
|
||||
|
||||
case RawInputDeviceType.MOUSE:
|
||||
if (((WinRawMouse)MouseDriver).ProcessMouseEvent(ref data))
|
||||
return IntPtr.Zero;
|
||||
break;
|
||||
case RawInputDeviceType.MOUSE:
|
||||
if (((WinRawMouse)MouseDriver).ProcessMouseEvent(lParam))
|
||||
return IntPtr.Zero;
|
||||
break;
|
||||
|
||||
case RawInputDeviceType.HID:
|
||||
if (((WinRawJoystick)JoystickDriver).ProcessEvent(ref data))
|
||||
return IntPtr.Zero;
|
||||
break;
|
||||
case RawInputDeviceType.HID:
|
||||
if (((WinRawJoystick)JoystickDriver).ProcessEvent(lParam))
|
||||
return IntPtr.Zero;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -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,64 +217,80 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
}
|
||||
|
||||
public unsafe bool ProcessEvent(ref RawInput rin)
|
||||
public unsafe bool ProcessEvent(IntPtr raw)
|
||||
{
|
||||
IntPtr handle = rin.Header.Device;
|
||||
Device stick = GetDevice(handle);
|
||||
if (stick == null)
|
||||
// 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)
|
||||
{
|
||||
Debug.Print("[WinRawJoystick] Unknown device {0}", handle);
|
||||
return false;
|
||||
Array.Resize(ref HIDData, size);
|
||||
}
|
||||
|
||||
if (!GetPreparsedData(handle, ref PreparsedData))
|
||||
// Retrieve the raw HID data buffer
|
||||
if (Functions.GetRawInputData(raw, HIDData) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Detect which axes / buttons are contained in this report
|
||||
HidProtocolCaps caps;
|
||||
int axis_caps_count;
|
||||
int button_caps_count;
|
||||
if (!GetDeviceCaps(PreparsedData, out caps,
|
||||
ref AxisCaps, out axis_caps_count,
|
||||
ref ButtonCaps, out button_caps_count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Query current state
|
||||
// Allocate enough storage to hold the data of the current report
|
||||
int size = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData);
|
||||
if (size == 0)
|
||||
{
|
||||
Debug.Print("[WinRawJoystick] HidProtocol.MaxDataListLength() failed with {0}",
|
||||
Marshal.GetLastWin32Error());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill the data buffer
|
||||
if (DataBuffer.Length < size)
|
||||
{
|
||||
Array.Resize(ref DataBuffer, size);
|
||||
}
|
||||
|
||||
fixed (void* pdata = &rin.Data.HID.RawData)
|
||||
{
|
||||
if (HidProtocol.GetData(HidProtocolReportType.Input,
|
||||
DataBuffer, ref size, PreparsedData,
|
||||
(IntPtr)pdata, rin.Data.HID.Size) != HidProtocolStatus.Success)
|
||||
fixed (byte* pdata = HIDData)
|
||||
{
|
||||
Debug.Print("[WinRawJoystick] HidProtocol.GetData() failed with {0}",
|
||||
Marshal.GetLastWin32Error());
|
||||
return false;
|
||||
RawInput* rin = (RawInput*)pdata;
|
||||
|
||||
IntPtr handle = rin->Header.Device;
|
||||
Device stick = GetDevice(handle);
|
||||
if (stick == null)
|
||||
{
|
||||
Debug.Print("[WinRawJoystick] Unknown device {0}", handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetPreparsedData(handle, ref PreparsedData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Detect which axes / buttons are contained in this report
|
||||
HidProtocolCaps caps;
|
||||
int axis_caps_count;
|
||||
int button_caps_count;
|
||||
if (!GetDeviceCaps(PreparsedData, out caps,
|
||||
ref AxisCaps, out axis_caps_count,
|
||||
ref ButtonCaps, out button_caps_count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Query current state
|
||||
// Allocate enough storage to hold the data of the current report
|
||||
int report_count = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData);
|
||||
if (report_count == 0)
|
||||
{
|
||||
Debug.Print("[WinRawJoystick] HidProtocol.MaxDataListLength() failed with {0}",
|
||||
Marshal.GetLastWin32Error());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill the data buffer
|
||||
if (DataBuffer.Length < report_count)
|
||||
{
|
||||
Array.Resize(ref DataBuffer, report_count);
|
||||
}
|
||||
|
||||
if (HidProtocol.GetData(HidProtocolReportType.Input,
|
||||
DataBuffer, ref size, PreparsedData,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAxes(stick, caps, AxisCaps, axis_caps_count, DataBuffer);
|
||||
UpdateButtons(stick, caps, ButtonCaps, button_caps_count, DataBuffer);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -153,51 +153,57 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
}
|
||||
|
||||
public bool ProcessKeyboardEvent(ref RawInput rin)
|
||||
public bool ProcessKeyboardEvent(IntPtr raw)
|
||||
{
|
||||
bool processed = false;
|
||||
|
||||
bool pressed =
|
||||
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN ||
|
||||
rin.Data.Keyboard.Message == (int)WindowMessage.SYSKEYDOWN;
|
||||
var scancode = rin.Data.Keyboard.MakeCode;
|
||||
var vkey = rin.Data.Keyboard.VKey;
|
||||
|
||||
bool extended0 = (int)(rin.Data.Keyboard.Flags & RawInputKeyboardDataFlags.E0) != 0;
|
||||
bool extended1 = (int)(rin.Data.Keyboard.Flags & RawInputKeyboardDataFlags.E1) != 0;
|
||||
|
||||
bool is_valid = true;
|
||||
|
||||
ContextHandle handle = new ContextHandle(rin.Header.Device);
|
||||
KeyboardState keyboard;
|
||||
if (!rawids.ContainsKey(handle))
|
||||
RawInput rin;
|
||||
if (Functions.GetRawInputData(raw, out rin) > 0)
|
||||
{
|
||||
RefreshDevices();
|
||||
bool pressed =
|
||||
rin.Data.Keyboard.Message == (int)WindowMessage.KEYDOWN ||
|
||||
rin.Data.Keyboard.Message == (int)WindowMessage.SYSKEYDOWN;
|
||||
var scancode = rin.Data.Keyboard.MakeCode;
|
||||
var vkey = rin.Data.Keyboard.VKey;
|
||||
|
||||
bool extended0 = (int)(rin.Data.Keyboard.Flags & RawInputKeyboardDataFlags.E0) != 0;
|
||||
bool extended1 = (int)(rin.Data.Keyboard.Flags & RawInputKeyboardDataFlags.E1) != 0;
|
||||
|
||||
bool is_valid = true;
|
||||
|
||||
ContextHandle handle = new ContextHandle(rin.Header.Device);
|
||||
KeyboardState keyboard;
|
||||
if (!rawids.ContainsKey(handle))
|
||||
{
|
||||
RefreshDevices();
|
||||
}
|
||||
|
||||
if (keyboards.Count == 0)
|
||||
return false;
|
||||
|
||||
// Note:For some reason, my Microsoft Digital 3000 keyboard reports 0
|
||||
// as rin.Header.Device for the "zoom-in/zoom-out" buttons.
|
||||
// That's problematic, because no device has a "0" id.
|
||||
// As a workaround, we'll add those buttons to the first device (if any).
|
||||
int keyboard_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
||||
keyboard = keyboards[keyboard_handle];
|
||||
|
||||
Key key = WinKeyMap.TranslateKey(scancode, vkey, extended0, extended1, out is_valid);
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
keyboard.SetKeyState(key, pressed);
|
||||
processed = true;
|
||||
}
|
||||
|
||||
lock (UpdateLock)
|
||||
{
|
||||
keyboards[keyboard_handle] = keyboard;
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyboards.Count == 0)
|
||||
return false;
|
||||
|
||||
// Note:For some reason, my Microsoft Digital 3000 keyboard reports 0
|
||||
// as rin.Header.Device for the "zoom-in/zoom-out" buttons.
|
||||
// That's problematic, because no device has a "0" id.
|
||||
// As a workaround, we'll add those buttons to the first device (if any).
|
||||
int keyboard_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
||||
keyboard = keyboards[keyboard_handle];
|
||||
|
||||
Key key = WinKeyMap.TranslateKey(scancode, vkey, extended0, extended1, out is_valid);
|
||||
|
||||
if (is_valid)
|
||||
{
|
||||
keyboard.SetKeyState(key, pressed);
|
||||
processed = true;
|
||||
}
|
||||
|
||||
lock (UpdateLock)
|
||||
{
|
||||
keyboards[keyboard_handle] = keyboard;
|
||||
return processed;
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -149,100 +149,109 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
}
|
||||
|
||||
public bool ProcessMouseEvent(ref RawInput rin)
|
||||
public bool ProcessMouseEvent(IntPtr raw_buffer)
|
||||
{
|
||||
RawMouse raw = rin.Data.Mouse;
|
||||
ContextHandle handle = new ContextHandle(rin.Header.Device);
|
||||
bool processed = false;
|
||||
|
||||
MouseState mouse;
|
||||
if (!rawids.ContainsKey(handle))
|
||||
RawInput rin;
|
||||
if (Functions.GetRawInputData(raw_buffer, out rin) > 0)
|
||||
{
|
||||
RefreshDevices();
|
||||
RawMouse raw = rin.Data.Mouse;
|
||||
ContextHandle handle = new ContextHandle(rin.Header.Device);
|
||||
|
||||
MouseState mouse;
|
||||
if (!rawids.ContainsKey(handle))
|
||||
{
|
||||
RefreshDevices();
|
||||
}
|
||||
|
||||
if (mice.Count == 0)
|
||||
return false;
|
||||
|
||||
// Note:For some reason, my Microsoft Digital 3000 keyboard reports 0
|
||||
// as rin.Header.Device for the "zoom-in/zoom-out" buttons.
|
||||
// That's problematic, because no device has a "0" id.
|
||||
// As a workaround, we'll add those buttons to the first device (if any).
|
||||
int mouse_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
||||
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)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Left);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Left);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Right);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Right);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Middle);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Middle);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Button1);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Button1);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Button2);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Button2);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
|
||||
if ((raw.ButtonFlags & RawInputMouseState.WHEEL) != 0)
|
||||
mouse.SetScrollRelative(0, (short)raw.ButtonData / 120.0f);
|
||||
|
||||
if ((raw.ButtonFlags & RawInputMouseState.HWHEEL) != 0)
|
||||
mouse.SetScrollRelative((short)raw.ButtonData / 120.0f, 0);
|
||||
|
||||
if ((raw.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
|
||||
{
|
||||
mouse.X = raw.LastX;
|
||||
mouse.Y = raw.LastY;
|
||||
}
|
||||
else
|
||||
{ // Seems like MOUSE_MOVE_RELATIVE is the default, unless otherwise noted.
|
||||
mouse.X += raw.LastX;
|
||||
mouse.Y += raw.LastY;
|
||||
}
|
||||
|
||||
lock (UpdateLock)
|
||||
{
|
||||
mice[mouse_handle] = mouse;
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mice.Count == 0)
|
||||
return false;
|
||||
|
||||
// Note:For some reason, my Microsoft Digital 3000 keyboard reports 0
|
||||
// as rin.Header.Device for the "zoom-in/zoom-out" buttons.
|
||||
// That's problematic, because no device has a "0" id.
|
||||
// As a workaround, we'll add those buttons to the first device (if any).
|
||||
int mouse_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
|
||||
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){
|
||||
mouse.EnableBit((int)MouseButton.Left);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Left);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Right);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Right);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Middle);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Middle);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Button1);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Button1);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_DOWN) != 0)
|
||||
{
|
||||
mouse.EnableBit((int)MouseButton.Button2);
|
||||
Functions.SetCapture(Window);
|
||||
}
|
||||
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_UP) != 0)
|
||||
{
|
||||
mouse.DisableBit((int)MouseButton.Button2);
|
||||
Functions.ReleaseCapture();
|
||||
}
|
||||
|
||||
if ((raw.ButtonFlags & RawInputMouseState.WHEEL) != 0)
|
||||
mouse.SetScrollRelative(0, (short)raw.ButtonData / 120.0f);
|
||||
|
||||
if ((raw.ButtonFlags & RawInputMouseState.HWHEEL) != 0)
|
||||
mouse.SetScrollRelative((short)raw.ButtonData / 120.0f, 0);
|
||||
|
||||
if ((raw.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
|
||||
{
|
||||
mouse.X = raw.LastX;
|
||||
mouse.Y = raw.LastY;
|
||||
}
|
||||
else
|
||||
{ // Seems like MOUSE_MOVE_RELATIVE is the default, unless otherwise noted.
|
||||
mouse.X += raw.LastX;
|
||||
mouse.Y += raw.LastY;
|
||||
}
|
||||
|
||||
lock (UpdateLock)
|
||||
{
|
||||
mice[mouse_handle] = mouse;
|
||||
return true;
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
Loading…
Reference in a new issue