diff -r 72885c950813 -r cdc5f8f1b79e Win32/RawInput.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Win32/RawInput.cs Sun Mar 15 20:25:58 2015 +0100
@@ -0,0 +1,250 @@
+//
+// Copyright (C) 2014-2015 Stéphane Lenclud.
+//
+// This file is part of SharpLibHid.
+//
+// SharpDisplayManager is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SharpDisplayManager is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SharpDisplayManager. If not, see .
+//
+
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using System.Windows.Forms;
+
+namespace SharpLib.Win32
+{
+ ///
+ /// Provide some utility functions for raw input handling.
+ ///
+ static public class RawInput
+ {
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// Caller must free up memory on the pointer using Marshal.FreeHGlobal
+ ///
+ public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
+ {
+ bool success = true;
+ rawInputBuffer = IntPtr.Zero;
+
+ try
+ {
+ uint dwSize = 0;
+ uint sizeOfHeader = (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
+
+ //Get the size of our raw input data.
+ Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);
+
+ //Allocate a large enough buffer
+ rawInputBuffer = Marshal.AllocHGlobal((int)dwSize);
+
+ //Now read our RAWINPUT data
+ if (Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
+ {
+ return false;
+ }
+
+ //Cast our buffer
+ aRawInput = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
+ }
+ catch
+ {
+ Debug.WriteLine("GetRawInputData failed!");
+ success = false;
+ }
+
+ return success;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
+ {
+ bool success = true;
+ IntPtr deviceInfoBuffer = IntPtr.Zero;
+ try
+ {
+ //Get Device Info
+ uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
+ deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
+
+ int res = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.RawInputDeviceInfoType.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
+ if (res <= 0)
+ {
+ Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
+ return false;
+ }
+
+ //Cast our buffer
+ deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
+ }
+ catch
+ {
+ Debug.WriteLine("GetRawInputData failed!");
+ success = false;
+ }
+ finally
+ {
+ //Always executes, prevents memory leak
+ Marshal.FreeHGlobal(deviceInfoBuffer);
+ }
+
+
+ return success;
+ }
+
+ ///
+ /// Fetch pre-parsed data corresponding to HID descriptor for the given HID device.
+ ///
+ ///
+ ///
+ public static IntPtr GetPreParsedData(IntPtr hDevice)
+ {
+ uint ppDataSize = 0;
+ int result = Win32.Function.GetRawInputDeviceInfo(hDevice, RawInputDeviceInfoType.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, RawInputDeviceInfoType.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;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string GetDeviceName(IntPtr device)
+ {
+ uint deviceNameSize = 256;
+ int result = Win32.Function.GetRawInputDeviceInfo(device, RawInputDeviceInfoType.RIDI_DEVICENAME, IntPtr.Zero, ref deviceNameSize);
+ if (result != 0)
+ {
+ return string.Empty;
+ }
+
+ IntPtr deviceName = Marshal.AllocHGlobal((int)deviceNameSize * 2); // size is the character count not byte count
+ try
+ {
+ result = Win32.Function.GetRawInputDeviceInfo(device, RawInputDeviceInfoType.RIDI_DEVICENAME, deviceName, ref deviceNameSize);
+ if (result > 0)
+ {
+ return Marshal.PtrToStringAnsi(deviceName, result - 1); // -1 for NULL termination
+ }
+
+ return string.Empty;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(deviceName);
+ }
+ }
+
+
+ ///
+ /// Populate the given tree-view control with our Raw Input Devices.
+ ///
+ ///
+ public static void PopulateDeviceList(TreeView aTreeView)
+ {
+
+ //Get our list of devices
+ RAWINPUTDEVICELIST[] ridList = null;
+ uint deviceCount = 0;
+ int res = Win32.Function.GetRawInputDeviceList(ridList, ref deviceCount,(uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST)));
+ if (res == -1)
+ {
+ //Just give up then
+ return;
+ }
+
+ ridList = new RAWINPUTDEVICELIST[deviceCount];
+ res = Win32.Function.GetRawInputDeviceList(ridList, ref deviceCount, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST)));
+ if (res != deviceCount)
+ {
+ //Just give up then
+ return;
+ }
+
+ //For each our device add a node to our treeview
+ foreach (RAWINPUTDEVICELIST device in ridList)
+ {
+ SharpLib.Hid.HidDevice hidDevice=new SharpLib.Hid.HidDevice(device.hDevice);
+
+ TreeNode node = null;
+ if (hidDevice.Product != null && hidDevice.Product.Length > 1)
+ {
+ //Add the devices with a proper name at the top
+ node = aTreeView.Nodes.Insert(0, hidDevice.Name, hidDevice.FriendlyName);
+ }
+ else
+ {
+ //Add other once at the bottom
+ node = aTreeView.Nodes.Add(hidDevice.Name, hidDevice.FriendlyName);
+ }
+
+ node.Nodes.Add("Manufacturer: " + hidDevice.Manufacturer);
+ node.Nodes.Add("Product ID: 0x" + hidDevice.ProductId.ToString("X4"));
+ node.Nodes.Add("Vendor ID: 0x" + hidDevice.VendorId.ToString("X4"));
+ node.Nodes.Add("Version: " + hidDevice.Version);
+ node.Nodes.Add(hidDevice.Info.dwType.ToString());
+ if (hidDevice.Info.dwType == RawInputDeviceType.RIM_TYPEHID)
+ {
+ node.Nodes.Add("UsagePage / UsageCollection: 0x" + hidDevice.Info.hid.usUsagePage.ToString("X4") + " / 0x" + hidDevice.Info.hid.usUsage.ToString("X4"));
+ }
+
+ if (hidDevice.InputCapabilitiesDescription != null)
+ {
+ node.Nodes.Add(hidDevice.InputCapabilitiesDescription);
+ }
+
+ //Add button count
+ node.Nodes.Add("Button Count: " + hidDevice.ButtonCount);
+
+ //Those can be joystick/gamepad axis
+ if (hidDevice.InputValueCapabilities != null)
+ {
+ foreach (HIDP_VALUE_CAPS caps in hidDevice.InputValueCapabilities)
+ {
+ string des = SharpLib.Hid.HidDevice.InputValueCapabilityDescription(caps);
+ if (des != null)
+ {
+ node.Nodes.Add(des);
+ }
+ }
+
+ }
+
+ node.Nodes.Add(hidDevice.Name);
+ }
+ }
+
+ }
+}
\ No newline at end of file