# HG changeset patch
# User StephaneLenclud
# Date 1423952621 -3600
# Node ID 2f34ceaf0692f1b892cf4972a7242fef949ad168
# Parent  5f1f1053a59516c03b3b7d933e0b7e5504193f02
Moving pre-parsed data to our device class.

diff -r 5f1f1053a595 -r 2f34ceaf0692 HidDevice.cs
--- a/HidDevice.cs	Sat Feb 14 22:13:31 2015 +0100
+++ b/HidDevice.cs	Sat Feb 14 23:23:41 2015 +0100
@@ -10,7 +10,7 @@
     /// <summary>
     /// Represent a HID device.
     /// </summary>
-    public class HidDevice
+    public class HidDevice: IDisposable
     {
         public string Name { get; private set; }
         public string Manufacturer { get; private set; }
@@ -18,6 +18,7 @@
         public ushort VendorId { get; private set; }
         public ushort ProductId { get; private set; }
         public ushort Version { get; private set; }
+        public IntPtr PreParsedData {get; private set;}
 
         /// <summary>
         /// Class constructor will fetch this object properties from HID sub system.
@@ -25,8 +26,12 @@
         /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
         public HidDevice(IntPtr hRawInputDevice)
         {
+            PreParsedData = IntPtr.Zero;
             //Fetch various information defining the given HID device
-            Name = Win32.Utils.RawInput.GetDeviceName(hRawInputDevice);            
+            Name = Win32.Utils.RawInput.GetDeviceName(hRawInputDevice);
+
+            //Get our HID descriptor pre-parsed data
+            PreParsedData = Win32.Utils.RawInput.GetPreParsedData(hRawInputDevice);
                 
             //Open our device from the device name/path
             SafeFileHandle handle=Win32.Function.CreateFile(Name,
@@ -71,6 +76,26 @@
             }
         }
 
+
+        /// <summary>
+        /// Make sure dispose is called even if the user forgot about it.
+        /// </summary>
+        ~HidDevice()
+        {
+            Dispose();
+        }
+
+        /// <summary>
+        /// Dispose is just for unmanaged clean-up.
+        /// Make sure calling disposed multiple times does not crash.
+        /// See: http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface/538238#538238
+        /// </summary>
+        public void Dispose()
+        {
+            Marshal.FreeHGlobal(PreParsedData);
+            PreParsedData = IntPtr.Zero;
+        }
+
         /// <summary>
         /// Print information about this device to our debug output.
         /// </summary>
@@ -86,9 +111,6 @@
             Debug.WriteLine("==============================================================================================================");
         }
 
-
-
-
     }
 
 }
\ No newline at end of file
diff -r 5f1f1053a595 -r 2f34ceaf0692 HidEvent.cs
--- a/HidEvent.cs	Sat Feb 14 22:13:31 2015 +0100
+++ b/HidEvent.cs	Sat Feb 14 23:23:41 2015 +0100
@@ -99,8 +99,6 @@
 
             //Declare some pointers
             IntPtr rawInputBuffer = IntPtr.Zero;
-            //My understanding is that this is basically our HID descriptor 
-            IntPtr preParsedData = IntPtr.Zero;
 
             try
             {
@@ -111,6 +109,7 @@
                     return;
                 }
 
+                //TODO: move this into our device class
                 //Fetch device info
                 RID_DEVICE_INFO deviceInfo = new RID_DEVICE_INFO();
                 if (!Win32.Utils.RawInput.GetDeviceInfo(rawInput.header.hDevice, ref deviceInfo))
@@ -131,8 +130,6 @@
                     UsagePage = deviceInfo.hid.usUsagePage;
                     UsageCollection = deviceInfo.hid.usUsage;
 
-                    preParsedData = Win32.Utils.RawInput.GetPreParsedData(rawInput.header.hDevice);
-
                     if (!(rawInput.hid.dwSizeHid > 1     //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now
                         && rawInput.hid.dwCount > 0))    //Check that we have at least one HID msg
                     {
@@ -167,13 +164,13 @@
 						//First query our usage count
                         uint usageCount = 0; 
                         Win32.USAGE_AND_PAGE[] usages = null;
-						Win32.HidStatus status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, preParsedData, InputReport, (uint)InputReport.Length);
+						Win32.HidStatus status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, Device.PreParsedData, InputReport, (uint)InputReport.Length);
 						if (status == Win32.HidStatus.HIDP_STATUS_BUFFER_TOO_SMALL)
 						{
 							//Allocate a large enough buffer 
 							usages = new Win32.USAGE_AND_PAGE[usageCount];
 							//...and fetch our usages
-							status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, preParsedData, InputReport, (uint)InputReport.Length);
+                            status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, Device.PreParsedData, InputReport, (uint)InputReport.Length);
 							if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS)
 							{
 								Debug.WriteLine("Second pass could not parse HID data: " + status.ToString());
@@ -186,6 +183,7 @@
 
 						Debug.WriteLine("Usage count: " + usageCount.ToString());
 
+                        //Copy usages into this event
 						if (usages != null)
 						{
 							foreach (USAGE_AND_PAGE up in usages)
@@ -195,7 +193,7 @@
 								//Add this usage to our list
 								Usages.Add(up.Usage);
 							}
-						}
+						}                       
                     }
                 }
                 else if (rawInput.header.dwType == Const.RIM_TYPEMOUSE)
@@ -223,7 +221,6 @@
             {
                 //Always executed when leaving our try block
                 Marshal.FreeHGlobal(rawInputBuffer);
-                Marshal.FreeHGlobal(preParsedData);
             }
 
             //