diff -r 9a3e77655031 -r 8f7e35c3bfd1 RawInput.cs --- a/RawInput.cs Wed Dec 03 21:54:45 2014 +0100 +++ b/RawInput.cs Fri Dec 05 22:50:39 2014 +0100 @@ -5,6 +5,9 @@ namespace Win32 { + /// + /// Provide some utility functions for raw input handling. + /// static class RawInput { /// @@ -90,5 +93,145 @@ return success; } + /// + /// + /// + /// + /// + public static IntPtr GetPreParsedData(IntPtr hDevice) + { + uint ppDataSize = 256; + int result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, IntPtr.Zero, ref ppDataSize); + if (result != 0) + { + Debug.WriteLine("Failed to get raw input pre-parsed data size" + result + Marshal.GetLastWin32Error()); + return IntPtr.Zero; + } + + IntPtr ppData = Marshal.AllocHGlobal((int)ppDataSize); + result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, ppData, ref ppDataSize); + if (result <= 0) + { + Debug.WriteLine("Failed to get raw input pre-parsed data" + result + Marshal.GetLastWin32Error()); + return IntPtr.Zero; + } + return ppData; + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /* + private bool GetUsageFromRawInput(TwinhanHidDriver driver, TwinhanHid device, NativeMethods.RAWINPUT input, IntPtr rawInput, out UsageType usageType, out int usage, out string usageName) + { + usageType = 0; + usage = 0; + usageName = string.Empty; + if (input.header.dwType == NativeMethods.RawInputDeviceType.RIM_TYPEKEYBOARD) + { + if (input.data.keyboard.Flags == NativeMethods.RawInputKeyboardFlag.RI_KEY_BREAK) + { + _modifiers = 0; + // Key up event. We don't handle repeats, so ignore this. + return false; + } + NativeMethods.VirtualKey vk = input.data.keyboard.VKey; + if (vk == NativeMethods.VirtualKey.VK_CONTROL) + { + _modifiers |= VirtualKeyModifier.Control; + return false; + } + if (vk == NativeMethods.VirtualKey.VK_SHIFT) + { + _modifiers |= VirtualKeyModifier.Shift; + return false; + } + if (vk == NativeMethods.VirtualKey.VK_MENU) + { + _modifiers |= VirtualKeyModifier.Alt; + return false; + } + usageType = UsageType.Keyboard; + usage = (int)vk | (int)_modifiers; + usageName = vk.ToString(); + if (_modifiers != 0) + { + usageName += string.Format(", modifiers = {0}", _modifiers); + } + } + else if (input.header.dwType == NativeMethods.RawInputDeviceType.RIM_TYPEHID) + { + if ((!driver.IsTerraTec && device.Name.Contains("Col03")) || (driver.IsTerraTec && device.Name.Contains("Col02"))) + { + usageType = UsageType.Raw; + usage = Marshal.ReadByte(rawInput, HID_INPUT_DATA_OFFSET + 1); + usageName = string.Format("0x{0:x2}", usage); + } + else if (device.Name.Contains("Col05")) + { + usageType = UsageType.Ascii; + usage = Marshal.ReadByte(rawInput, HID_INPUT_DATA_OFFSET + 1); + usageName = string.Format("0x{0:x2}", usage); + } + else + { + byte[] report = new byte[input.data.hid.dwSizeHid]; + Marshal.Copy(IntPtr.Add(rawInput, HID_INPUT_DATA_OFFSET), report, 0, report.Length); + uint usageCount = input.data.hid.dwCount; + NativeMethods.USAGE_AND_PAGE[] usages = new NativeMethods.USAGE_AND_PAGE[usageCount]; + NativeMethods.HidStatus status = NativeMethods.HidP_GetUsagesEx(NativeMethods.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, device.PreParsedData, report, (uint)report.Length); + if (status != NativeMethods.HidStatus.HIDP_STATUS_SUCCESS) + { + this.LogError("Twinhan HID remote: failed to get raw input HID usages, device = {0}, status = {1}", device.Name, status); + Dump.DumpBinary(rawInput, (int)input.header.dwSize); + return false; + } + if (usageCount > 1) + { + this.LogWarn("Twinhan HID remote: multiple simultaneous HID usages not supported"); + } + NativeMethods.USAGE_AND_PAGE up = usages[0]; + HidUsagePage page = (HidUsagePage)up.UsagePage; + usage = up.Usage; + if (page != HidUsagePage.MceRemote && usage == 0) + { + // Key up event. We don't handle repeats, so ignore this. + return false; + } + if (page == HidUsagePage.Consumer) + { + usageType = UsageType.Consumer; + usageName = Enum.GetName(typeof(HidConsumerUsage), up.Usage); + } + else if (page == HidUsagePage.MceRemote) + { + usageType = UsageType.Mce; + usageName = Enum.GetName(typeof(MceRemoteUsage), up.Usage); + } + else + { + this.LogError("Twinhan HID remote: unexpected usage page, device = {0}, page = {1}, usage = {2}", device.Name, page, up.Usage); + return false; + } + } + } + else + { + this.LogError("Twinhan HID remote: received input from unsupported input device type, device = {0}, type = {1}", device.Name, input.header.dwType); + return false; + } + return true; + } + * */ + } } \ No newline at end of file