1.1 --- a/RawInput.cs Wed Dec 03 21:54:45 2014 +0100
1.2 +++ b/RawInput.cs Fri Dec 05 22:50:39 2014 +0100
1.3 @@ -5,6 +5,9 @@
1.4
1.5 namespace Win32
1.6 {
1.7 + /// <summary>
1.8 + /// Provide some utility functions for raw input handling.
1.9 + /// </summary>
1.10 static class RawInput
1.11 {
1.12 /// <summary>
1.13 @@ -90,5 +93,145 @@
1.14 return success;
1.15 }
1.16
1.17 + /// <summary>
1.18 + ///
1.19 + /// </summary>
1.20 + /// <param name="device"></param>
1.21 + /// <returns></returns>
1.22 + public static IntPtr GetPreParsedData(IntPtr hDevice)
1.23 + {
1.24 + uint ppDataSize = 256;
1.25 + int result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, IntPtr.Zero, ref ppDataSize);
1.26 + if (result != 0)
1.27 + {
1.28 + Debug.WriteLine("Failed to get raw input pre-parsed data size" + result + Marshal.GetLastWin32Error());
1.29 + return IntPtr.Zero;
1.30 + }
1.31 +
1.32 + IntPtr ppData = Marshal.AllocHGlobal((int)ppDataSize);
1.33 + result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, ppData, ref ppDataSize);
1.34 + if (result <= 0)
1.35 + {
1.36 + Debug.WriteLine("Failed to get raw input pre-parsed data" + result + Marshal.GetLastWin32Error());
1.37 + return IntPtr.Zero;
1.38 + }
1.39 + return ppData;
1.40 + }
1.41 +
1.42 + /// <summary>
1.43 + ///
1.44 + /// </summary>
1.45 + /// <param name="driver"></param>
1.46 + /// <param name="device"></param>
1.47 + /// <param name="input"></param>
1.48 + /// <param name="rawInput"></param>
1.49 + /// <param name="usageType"></param>
1.50 + /// <param name="usage"></param>
1.51 + /// <param name="usageName"></param>
1.52 + /// <returns></returns>
1.53 + ///
1.54 + /*
1.55 + private bool GetUsageFromRawInput(TwinhanHidDriver driver, TwinhanHid device, NativeMethods.RAWINPUT input, IntPtr rawInput, out UsageType usageType, out int usage, out string usageName)
1.56 + {
1.57 + usageType = 0;
1.58 + usage = 0;
1.59 + usageName = string.Empty;
1.60 + if (input.header.dwType == NativeMethods.RawInputDeviceType.RIM_TYPEKEYBOARD)
1.61 + {
1.62 + if (input.data.keyboard.Flags == NativeMethods.RawInputKeyboardFlag.RI_KEY_BREAK)
1.63 + {
1.64 + _modifiers = 0;
1.65 + // Key up event. We don't handle repeats, so ignore this.
1.66 + return false;
1.67 + }
1.68 + NativeMethods.VirtualKey vk = input.data.keyboard.VKey;
1.69 + if (vk == NativeMethods.VirtualKey.VK_CONTROL)
1.70 + {
1.71 + _modifiers |= VirtualKeyModifier.Control;
1.72 + return false;
1.73 + }
1.74 + if (vk == NativeMethods.VirtualKey.VK_SHIFT)
1.75 + {
1.76 + _modifiers |= VirtualKeyModifier.Shift;
1.77 + return false;
1.78 + }
1.79 + if (vk == NativeMethods.VirtualKey.VK_MENU)
1.80 + {
1.81 + _modifiers |= VirtualKeyModifier.Alt;
1.82 + return false;
1.83 + }
1.84 + usageType = UsageType.Keyboard;
1.85 + usage = (int)vk | (int)_modifiers;
1.86 + usageName = vk.ToString();
1.87 + if (_modifiers != 0)
1.88 + {
1.89 + usageName += string.Format(", modifiers = {0}", _modifiers);
1.90 + }
1.91 + }
1.92 + else if (input.header.dwType == NativeMethods.RawInputDeviceType.RIM_TYPEHID)
1.93 + {
1.94 + if ((!driver.IsTerraTec && device.Name.Contains("Col03")) || (driver.IsTerraTec && device.Name.Contains("Col02")))
1.95 + {
1.96 + usageType = UsageType.Raw;
1.97 + usage = Marshal.ReadByte(rawInput, HID_INPUT_DATA_OFFSET + 1);
1.98 + usageName = string.Format("0x{0:x2}", usage);
1.99 + }
1.100 + else if (device.Name.Contains("Col05"))
1.101 + {
1.102 + usageType = UsageType.Ascii;
1.103 + usage = Marshal.ReadByte(rawInput, HID_INPUT_DATA_OFFSET + 1);
1.104 + usageName = string.Format("0x{0:x2}", usage);
1.105 + }
1.106 + else
1.107 + {
1.108 + byte[] report = new byte[input.data.hid.dwSizeHid];
1.109 + Marshal.Copy(IntPtr.Add(rawInput, HID_INPUT_DATA_OFFSET), report, 0, report.Length);
1.110 + uint usageCount = input.data.hid.dwCount;
1.111 + NativeMethods.USAGE_AND_PAGE[] usages = new NativeMethods.USAGE_AND_PAGE[usageCount];
1.112 + NativeMethods.HidStatus status = NativeMethods.HidP_GetUsagesEx(NativeMethods.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, device.PreParsedData, report, (uint)report.Length);
1.113 + if (status != NativeMethods.HidStatus.HIDP_STATUS_SUCCESS)
1.114 + {
1.115 + this.LogError("Twinhan HID remote: failed to get raw input HID usages, device = {0}, status = {1}", device.Name, status);
1.116 + Dump.DumpBinary(rawInput, (int)input.header.dwSize);
1.117 + return false;
1.118 + }
1.119 + if (usageCount > 1)
1.120 + {
1.121 + this.LogWarn("Twinhan HID remote: multiple simultaneous HID usages not supported");
1.122 + }
1.123 + NativeMethods.USAGE_AND_PAGE up = usages[0];
1.124 + HidUsagePage page = (HidUsagePage)up.UsagePage;
1.125 + usage = up.Usage;
1.126 + if (page != HidUsagePage.MceRemote && usage == 0)
1.127 + {
1.128 + // Key up event. We don't handle repeats, so ignore this.
1.129 + return false;
1.130 + }
1.131 + if (page == HidUsagePage.Consumer)
1.132 + {
1.133 + usageType = UsageType.Consumer;
1.134 + usageName = Enum.GetName(typeof(HidConsumerUsage), up.Usage);
1.135 + }
1.136 + else if (page == HidUsagePage.MceRemote)
1.137 + {
1.138 + usageType = UsageType.Mce;
1.139 + usageName = Enum.GetName(typeof(MceRemoteUsage), up.Usage);
1.140 + }
1.141 + else
1.142 + {
1.143 + this.LogError("Twinhan HID remote: unexpected usage page, device = {0}, page = {1}, usage = {2}", device.Name, page, up.Usage);
1.144 + return false;
1.145 + }
1.146 + }
1.147 + }
1.148 + else
1.149 + {
1.150 + this.LogError("Twinhan HID remote: received input from unsupported input device type, device = {0}, type = {1}", device.Name, input.header.dwType);
1.151 + return false;
1.152 + }
1.153 + return true;
1.154 + }
1.155 + * */
1.156 +
1.157 }
1.158 }
1.159 \ No newline at end of file