Moving files around.
authorStephaneLenclud
Sun, 15 Mar 2015 20:25:58 +0100
changeset 79cdc5f8f1b79e
parent 78 72885c950813
child 80 e2acfa51664f
Moving files around.
Hid/HidDevice.cs
Hid/HidEvent.cs
Hid/HidHandler.cs
Hid/HidUsageTables.cs
Hid/HidUtils.cs
HidDevice.cs
HidEvent.cs
HidHandler.cs
HidUsageTables.cs
HidUtils.cs
RawInput.cs
SharpLibHid.csproj
Win32/RawInput.cs
Win32/Win32AppCommand.cs
Win32/Win32CreateFile.cs
Win32/Win32Hid.cs
Win32/Win32RawInput.cs
Win32AppCommand.cs
Win32CreateFile.cs
Win32Hid.cs
Win32RawInput.cs
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Hid/HidDevice.cs	Sun Mar 15 20:25:58 2015 +0100
     1.3 @@ -0,0 +1,372 @@
     1.4 +//
     1.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
     1.6 +//
     1.7 +// This file is part of SharpLibHid.
     1.8 +//
     1.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
    1.10 +// it under the terms of the GNU General Public License as published by
    1.11 +// the Free Software Foundation, either version 3 of the License, or
    1.12 +// (at your option) any later version.
    1.13 +//
    1.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
    1.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.17 +// GNU General Public License for more details.
    1.18 +//
    1.19 +// You should have received a copy of the GNU General Public License
    1.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    1.21 +//
    1.22 +
    1.23 +
    1.24 +using System;
    1.25 +using System.Windows.Forms;
    1.26 +using System.Runtime.InteropServices;
    1.27 +using System.Diagnostics;
    1.28 +using System.Text;
    1.29 +using Microsoft.Win32.SafeHandles;
    1.30 +using SharpLib.Win32;
    1.31 +
    1.32 +namespace SharpLib.Hid
    1.33 +{
    1.34 +    /// <summary>
    1.35 +    /// Represent a HID device.
    1.36 +    /// Rename to RawInputDevice?
    1.37 +    /// </summary>
    1.38 +    public class HidDevice: IDisposable
    1.39 +    {
    1.40 +        /// <summary>
    1.41 +        /// Unique name of that HID device.
    1.42 +        /// Notably used as input to CreateFile.
    1.43 +        /// </summary>
    1.44 +        public string Name { get; private set; }
    1.45 +
    1.46 +        /// <summary>
    1.47 +        /// Friendly name that people should be able to read.
    1.48 +        /// </summary>
    1.49 +        public string FriendlyName { get; private set; }
    1.50 +
    1.51 +        //
    1.52 +        public string Manufacturer { get; private set; }
    1.53 +        public string Product { get; private set; }
    1.54 +        public ushort VendorId { get; private set; }
    1.55 +        public ushort ProductId { get; private set; }
    1.56 +        public ushort Version { get; private set; }
    1.57 +        //Pre-parsed HID descriptor
    1.58 +        public IntPtr PreParsedData {get; private set;}
    1.59 +        //Info
    1.60 +        public RID_DEVICE_INFO Info { get {return iInfo;} }
    1.61 +        private RID_DEVICE_INFO iInfo;
    1.62 +        //Capabilities
    1.63 +        public HIDP_CAPS Capabilities { get { return iCapabilities; } }
    1.64 +        private HIDP_CAPS iCapabilities;
    1.65 +        public string InputCapabilitiesDescription { get; private set; }
    1.66 +        //Input Button Capabilities
    1.67 +        public HIDP_BUTTON_CAPS[] InputButtonCapabilities { get { return iInputButtonCapabilities; } }
    1.68 +        private HIDP_BUTTON_CAPS[] iInputButtonCapabilities;
    1.69 +        //Input Value Capabilities
    1.70 +        public HIDP_VALUE_CAPS[] InputValueCapabilities { get { return iInputValueCapabilities; } }
    1.71 +        private HIDP_VALUE_CAPS[] iInputValueCapabilities;
    1.72 +
    1.73 +        //
    1.74 +        public int ButtonCount { get; private set; }
    1.75 +
    1.76 +        /// <summary>
    1.77 +        /// Class constructor will fetch this object properties from HID sub system.
    1.78 +        /// </summary>
    1.79 +        /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
    1.80 +        public HidDevice(IntPtr hRawInputDevice)
    1.81 +        {
    1.82 +            //Try construct and rollback if needed
    1.83 +            try
    1.84 +            {
    1.85 +                Construct(hRawInputDevice);
    1.86 +            }
    1.87 +            catch (System.Exception ex)
    1.88 +            {
    1.89 +                //Just rollback and propagate
    1.90 +                Dispose();
    1.91 +                throw ex;
    1.92 +            }
    1.93 +        }
    1.94 +
    1.95 +
    1.96 +        /// <summary>
    1.97 +        /// Make sure dispose is called even if the user forgot about it.
    1.98 +        /// </summary>
    1.99 +        ~HidDevice()
   1.100 +        {
   1.101 +            Dispose();
   1.102 +        }
   1.103 +
   1.104 +        /// <summary>
   1.105 +        /// Private constructor.
   1.106 +        /// </summary>
   1.107 +        /// <param name="hRawInputDevice"></param>
   1.108 +        private void Construct(IntPtr hRawInputDevice)
   1.109 +        {
   1.110 +            PreParsedData = IntPtr.Zero;
   1.111 +            iInputButtonCapabilities = null;
   1.112 +            iInputValueCapabilities = null;
   1.113 +
   1.114 +            //Fetch various information defining the given HID device
   1.115 +            Name = Win32.RawInput.GetDeviceName(hRawInputDevice);
   1.116 +
   1.117 +            //Fetch device info
   1.118 +            iInfo = new RID_DEVICE_INFO();
   1.119 +            if (!Win32.RawInput.GetDeviceInfo(hRawInputDevice, ref iInfo))
   1.120 +            {
   1.121 +                throw new Exception("HidDevice: GetDeviceInfo failed: " + Marshal.GetLastWin32Error().ToString());
   1.122 +            }
   1.123 +
   1.124 +            //Open our device from the device name/path
   1.125 +            SafeFileHandle handle = Win32.Function.CreateFile(Name,
   1.126 +                Win32.FileAccess.NONE,
   1.127 +                Win32.FileShare.FILE_SHARE_READ | Win32.FileShare.FILE_SHARE_WRITE,
   1.128 +                IntPtr.Zero,
   1.129 +                Win32.CreationDisposition.OPEN_EXISTING,
   1.130 +                Win32.FileFlagsAttributes.FILE_FLAG_OVERLAPPED,
   1.131 +                IntPtr.Zero
   1.132 +                );
   1.133 +
   1.134 +            //Check if CreateFile worked
   1.135 +            if (handle.IsInvalid)
   1.136 +            {
   1.137 +                throw new Exception("HidDevice: CreateFile failed: " + Marshal.GetLastWin32Error().ToString());
   1.138 +            }
   1.139 +
   1.140 +            //Get manufacturer string
   1.141 +            StringBuilder manufacturerString = new StringBuilder(256);
   1.142 +            if (Win32.Function.HidD_GetManufacturerString(handle, manufacturerString, manufacturerString.Capacity))
   1.143 +            {
   1.144 +                Manufacturer = manufacturerString.ToString();
   1.145 +            }
   1.146 +
   1.147 +            //Get product string
   1.148 +            StringBuilder productString = new StringBuilder(256);
   1.149 +            if (Win32.Function.HidD_GetProductString(handle, productString, productString.Capacity))
   1.150 +            {
   1.151 +                Product = productString.ToString();
   1.152 +            }
   1.153 +
   1.154 +            //Get attributes
   1.155 +            Win32.HIDD_ATTRIBUTES attributes = new Win32.HIDD_ATTRIBUTES();
   1.156 +            if (Win32.Function.HidD_GetAttributes(handle, ref attributes))
   1.157 +            {
   1.158 +                VendorId = attributes.VendorID;
   1.159 +                ProductId = attributes.ProductID;
   1.160 +                Version = attributes.VersionNumber;
   1.161 +            }
   1.162 +
   1.163 +            handle.Close();
   1.164 +
   1.165 +            SetFriendlyName();            
   1.166 +
   1.167 +            //Get our HID descriptor pre-parsed data
   1.168 +            PreParsedData = Win32.RawInput.GetPreParsedData(hRawInputDevice);
   1.169 +
   1.170 +            if (PreParsedData == IntPtr.Zero)
   1.171 +            {
   1.172 +                //We are done then.
   1.173 +                //Some devices don't have pre-parsed data.
   1.174 +                return;
   1.175 +            }
   1.176 +
   1.177 +            //Get capabilities
   1.178 +            HidStatus status = Win32.Function.HidP_GetCaps(PreParsedData, ref iCapabilities);
   1.179 +            if (status != HidStatus.HIDP_STATUS_SUCCESS)
   1.180 +            {
   1.181 +                throw new Exception("HidDevice: HidP_GetCaps failed: " + status.ToString());
   1.182 +            }
   1.183 +
   1.184 +            SetInputCapabilitiesDescription();
   1.185 +
   1.186 +            //Get input button caps if needed
   1.187 +            if (Capabilities.NumberInputButtonCaps > 0)
   1.188 +            {
   1.189 +                iInputButtonCapabilities = new HIDP_BUTTON_CAPS[Capabilities.NumberInputButtonCaps];
   1.190 +                ushort buttonCapabilitiesLength = Capabilities.NumberInputButtonCaps;
   1.191 +                status = Win32.Function.HidP_GetButtonCaps(HIDP_REPORT_TYPE.HidP_Input, iInputButtonCapabilities, ref buttonCapabilitiesLength, PreParsedData);
   1.192 +                if (status != HidStatus.HIDP_STATUS_SUCCESS || buttonCapabilitiesLength != Capabilities.NumberInputButtonCaps)
   1.193 +                {
   1.194 +                    throw new Exception("HidDevice: HidP_GetButtonCaps failed: " + status.ToString());
   1.195 +                }
   1.196 +
   1.197 +                ComputeButtonCount();
   1.198 +            }
   1.199 +
   1.200 +            //Get input value caps if needed
   1.201 +            if (Capabilities.NumberInputValueCaps > 0)
   1.202 +            {
   1.203 +                iInputValueCapabilities = new HIDP_VALUE_CAPS[Capabilities.NumberInputValueCaps];
   1.204 +                ushort valueCapabilitiesLength = Capabilities.NumberInputValueCaps;
   1.205 +                status = Win32.Function.HidP_GetValueCaps(HIDP_REPORT_TYPE.HidP_Input, iInputValueCapabilities, ref valueCapabilitiesLength, PreParsedData);
   1.206 +                if (status != HidStatus.HIDP_STATUS_SUCCESS || valueCapabilitiesLength != Capabilities.NumberInputValueCaps)
   1.207 +                {
   1.208 +                    throw new Exception("HidDevice: HidP_GetValueCaps failed: " + status.ToString());
   1.209 +                }
   1.210 +            }
   1.211 +        }
   1.212 +
   1.213 +
   1.214 +        /// <summary>
   1.215 +        /// Useful for gamepads.
   1.216 +        /// </summary>
   1.217 +        void ComputeButtonCount()
   1.218 +        {
   1.219 +            ButtonCount = 0;
   1.220 +            foreach (HIDP_BUTTON_CAPS bc in iInputButtonCapabilities)
   1.221 +            {
   1.222 +                if (bc.IsRange)
   1.223 +                {
   1.224 +                    ButtonCount += (bc.Range.UsageMax - bc.Range.UsageMin + 1);
   1.225 +                }
   1.226 +            }            
   1.227 +        }
   1.228 +
   1.229 +
   1.230 +        /// <summary>
   1.231 +        /// 
   1.232 +        /// </summary>
   1.233 +        void SetInputCapabilitiesDescription()
   1.234 +        {
   1.235 +            InputCapabilitiesDescription = "[ Input Capabilities ] Button: " + Capabilities.NumberInputButtonCaps + " - Value: " + Capabilities.NumberInputValueCaps + " - Data indices: " + Capabilities.NumberInputDataIndices;
   1.236 +        }
   1.237 +
   1.238 +        /// <summary>
   1.239 +        /// 
   1.240 +        /// </summary>
   1.241 +        private void SetFriendlyName()
   1.242 +        {
   1.243 +            //Work out proper suffix for our device root node.
   1.244 +            //That allows users to see in a glance what kind of device this is.
   1.245 +            string suffix = "";
   1.246 +            Type usageCollectionType = null;
   1.247 +            if (Info.dwType == RawInputDeviceType.RIM_TYPEHID)
   1.248 +            {
   1.249 +                //Process usage page
   1.250 +                if (Enum.IsDefined(typeof(UsagePage), Info.hid.usUsagePage))
   1.251 +                {
   1.252 +                    //We know this usage page, add its name
   1.253 +                    UsagePage usagePage = (UsagePage)Info.hid.usUsagePage;
   1.254 +                    suffix += " ( " + usagePage.ToString() + ", ";
   1.255 +                    usageCollectionType = Utils.UsageCollectionType(usagePage);
   1.256 +                }
   1.257 +                else
   1.258 +                {
   1.259 +                    //We don't know this usage page, add its value
   1.260 +                    suffix += " ( 0x" + Info.hid.usUsagePage.ToString("X4") + ", ";
   1.261 +                }
   1.262 +
   1.263 +                //Process usage collection
   1.264 +                //We don't know this usage page, add its value
   1.265 +                if (usageCollectionType == null || !Enum.IsDefined(usageCollectionType, Info.hid.usUsage))
   1.266 +                {
   1.267 +                    //Show Hexa
   1.268 +                    suffix += "0x" + Info.hid.usUsage.ToString("X4") + " )";
   1.269 +                }
   1.270 +                else
   1.271 +                {
   1.272 +                    //We know this usage page, add its name
   1.273 +                    suffix += Enum.GetName(usageCollectionType, Info.hid.usUsage) + " )";
   1.274 +                }
   1.275 +            }
   1.276 +            else if (Info.dwType == RawInputDeviceType.RIM_TYPEKEYBOARD)
   1.277 +            {
   1.278 +                suffix = " - Keyboard";
   1.279 +            }
   1.280 +            else if (Info.dwType == RawInputDeviceType.RIM_TYPEMOUSE)
   1.281 +            {
   1.282 +                suffix = " - Mouse";
   1.283 +            }
   1.284 +
   1.285 +            if (Product != null && Product.Length > 1)
   1.286 +            {
   1.287 +                //This device as a proper name, use it
   1.288 +                FriendlyName = Product + suffix;
   1.289 +            }
   1.290 +            else
   1.291 +            {   
   1.292 +                //Extract friendly name from name
   1.293 +                char[] delimiterChars = { '#', '&'};
   1.294 +                string[] words = Name.Split(delimiterChars);
   1.295 +                if (words.Length >= 2)
   1.296 +                {
   1.297 +                    //Use our name sub-string to describe this device
   1.298 +                    FriendlyName = words[1] + " - 0x" + ProductId.ToString("X4") + suffix;
   1.299 +                }
   1.300 +                else
   1.301 +                {
   1.302 +                    //No proper name just use the device ID instead
   1.303 +                    FriendlyName = "0x" + ProductId.ToString("X4") + suffix;
   1.304 +                }
   1.305 +            }
   1.306 +
   1.307 +        }
   1.308 +
   1.309 +        /// <summary>
   1.310 +        /// Dispose is just for unmanaged clean-up.
   1.311 +        /// Make sure calling disposed multiple times does not crash.
   1.312 +        /// See: http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface/538238#538238
   1.313 +        /// </summary>
   1.314 +        public void Dispose()
   1.315 +        {
   1.316 +            Marshal.FreeHGlobal(PreParsedData);
   1.317 +            PreParsedData = IntPtr.Zero;
   1.318 +        }
   1.319 +
   1.320 +        /// <summary>
   1.321 +        /// Provide a description for the given capabilities.
   1.322 +        /// Notably describes axis on a gamepad/joystick.
   1.323 +        /// </summary>
   1.324 +        /// <param name="aCaps"></param>
   1.325 +        /// <returns></returns>
   1.326 +        static public string InputValueCapabilityDescription(HIDP_VALUE_CAPS aCaps)
   1.327 +        {
   1.328 +            if (!aCaps.IsRange && Enum.IsDefined(typeof(UsagePage), aCaps.UsagePage))
   1.329 +            {
   1.330 +                Type usageType = Utils.UsageType((UsagePage)aCaps.UsagePage);
   1.331 +                string name = Enum.GetName(usageType, aCaps.NotRange.Usage);
   1.332 +                if (name == null)
   1.333 +                {
   1.334 +                    //Could not find that usage in our enum.
   1.335 +                    //Provide a relevant warning instead.
   1.336 +                    name = "Usage 0x" + aCaps.NotRange.Usage.ToString("X2") + " not defined in " + usageType.Name;
   1.337 +                }
   1.338 +                else
   1.339 +                {
   1.340 +                    //Prepend our usage type name
   1.341 +                    name = usageType.Name + "." + name;
   1.342 +                }
   1.343 +                return "Input Value: " + name;
   1.344 +            }
   1.345 +
   1.346 +            return null;
   1.347 +        }
   1.348 +
   1.349 +        public bool IsGamePad
   1.350 +        {
   1.351 +            get
   1.352 +            {
   1.353 +                return ((UsagePage)iCapabilities.UsagePage == UsagePage.GenericDesktopControls && (UsageCollection.GenericDesktop)iCapabilities.Usage == UsageCollection.GenericDesktop.GamePad);
   1.354 +            }
   1.355 +        }
   1.356 +
   1.357 +
   1.358 +        /// <summary>
   1.359 +        /// Print information about this device to our debug output.
   1.360 +        /// </summary>
   1.361 +        public void DebugWrite()
   1.362 +        {
   1.363 +            Debug.WriteLine("================ HID =========================================================================================");
   1.364 +            Debug.WriteLine("==== Name: " + Name);
   1.365 +            Debug.WriteLine("==== Manufacturer: " + Manufacturer);
   1.366 +            Debug.WriteLine("==== Product: " + Product);
   1.367 +            Debug.WriteLine("==== VendorID: 0x" + VendorId.ToString("X4"));
   1.368 +            Debug.WriteLine("==== ProductID: 0x" + ProductId.ToString("X4"));
   1.369 +            Debug.WriteLine("==== Version: " + Version.ToString());
   1.370 +            Debug.WriteLine("==============================================================================================================");
   1.371 +        }
   1.372 +
   1.373 +    }
   1.374 +
   1.375 +}
   1.376 \ No newline at end of file
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Hid/HidEvent.cs	Sun Mar 15 20:25:58 2015 +0100
     2.3 @@ -0,0 +1,598 @@
     2.4 +//
     2.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
     2.6 +//
     2.7 +// This file is part of SharpLibHid.
     2.8 +//
     2.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
    2.10 +// it under the terms of the GNU General Public License as published by
    2.11 +// the Free Software Foundation, either version 3 of the License, or
    2.12 +// (at your option) any later version.
    2.13 +//
    2.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
    2.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.17 +// GNU General Public License for more details.
    2.18 +//
    2.19 +// You should have received a copy of the GNU General Public License
    2.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    2.21 +//
    2.22 +
    2.23 +
    2.24 +using System;
    2.25 +using System.Windows.Forms;
    2.26 +using System.Runtime.InteropServices;
    2.27 +using System.Diagnostics;
    2.28 +using System.Text;
    2.29 +using Microsoft.Win32.SafeHandles;
    2.30 +using SharpLib.Win32;
    2.31 +using System.Collections.Generic;
    2.32 +using System.Timers;
    2.33 +using SharpLib.Hid.Usage;
    2.34 +
    2.35 +
    2.36 +namespace SharpLib.Hid
    2.37 +{
    2.38 +    /// <summary>
    2.39 +    /// We provide utility functions to interpret gamepad dpad state.
    2.40 +    /// </summary>
    2.41 +    public enum DirectionPadState
    2.42 +    {
    2.43 +        Rest=-1,
    2.44 +        Up=0,
    2.45 +        UpRight=1,
    2.46 +        Right=2,
    2.47 +        DownRight=3,
    2.48 +        Down=4,
    2.49 +        DownLeft=5,
    2.50 +        Left=6,
    2.51 +        UpLeft=7
    2.52 +    }
    2.53 +
    2.54 +    /// <summary>
    2.55 +    /// Represent a HID event.
    2.56 +    /// TODO: Rename this into HidRawInput?
    2.57 +    /// </summary>
    2.58 +    public class HidEvent : IDisposable
    2.59 +    {
    2.60 +        public bool IsValid { get; private set; }
    2.61 +        public bool IsForeground { get; private set; }
    2.62 +        public bool IsBackground { get { return !IsForeground; } }
    2.63 +        public bool IsMouse { get; private set; }
    2.64 +        public bool IsKeyboard { get; private set; }
    2.65 +        /// <summary>
    2.66 +        /// If this not a mouse or keyboard event then it's a generic HID event.
    2.67 +        /// </summary>
    2.68 +        public bool IsGeneric { get; private set; }
    2.69 +        public bool IsButtonDown { get { return Usages.Count == 1 && Usages[0] != 0; } }
    2.70 +        public bool IsButtonUp { get { return Usages.Count == 0; } }
    2.71 +        public bool IsRepeat { get { return RepeatCount != 0; } }
    2.72 +        public uint RepeatCount { get; private set; }
    2.73 +
    2.74 +        public HidDevice Device { get; private set; }
    2.75 +        public RAWINPUT RawInput { get {return iRawInput;} } 
    2.76 +        private RAWINPUT iRawInput;
    2.77 +
    2.78 +        public ushort UsagePage { get; private set; }
    2.79 +        public ushort UsageCollection { get; private set; }
    2.80 +        public uint UsageId { get { return ((uint)UsagePage << 16 | (uint)UsageCollection); } }
    2.81 +        public List<ushort> Usages { get; private set; }
    2.82 +        /// <summary>
    2.83 +        /// Sorted in the same order as Device.InputValueCapabilities.
    2.84 +        /// </summary>
    2.85 +        public Dictionary<HIDP_VALUE_CAPS,uint> UsageValues { get; private set; }
    2.86 +        //TODO: We need a collection of input report
    2.87 +        public byte[] InputReport { get; private set; }
    2.88 +        //
    2.89 +        public delegate void HidEventRepeatDelegate(HidEvent aHidEvent);
    2.90 +        public event HidEventRepeatDelegate OnHidEventRepeat;
    2.91 +
    2.92 +        private System.Timers.Timer Timer { get; set; }
    2.93 +        public DateTime Time { get; private set; }
    2.94 +        public DateTime OriginalTime { get; private set; }
    2.95 +
    2.96 +        //Compute repeat delay and speed based on system settings
    2.97 +        //Those computations were taken from the Petzold here: ftp://ftp.charlespetzold.com/ProgWinForms/4%20Custom%20Controls/NumericScan/NumericScan/ClickmaticButton.cs
    2.98 +        private int iRepeatDelay = 250 * (1 + SystemInformation.KeyboardDelay);
    2.99 +        private int iRepeatSpeed = 405 - 12 * SystemInformation.KeyboardSpeed;
   2.100 +
   2.101 +        /// <summary>
   2.102 +        /// Tells whether this event has already been disposed of.
   2.103 +        /// </summary>
   2.104 +        public bool IsStray { get { return Timer == null; } }
   2.105 +
   2.106 +        /// <summary>
   2.107 +        /// We typically dispose of events as soon as we get the corresponding key up signal.
   2.108 +        /// </summary>
   2.109 +        public void Dispose()
   2.110 +        {
   2.111 +            Timer.Enabled = false;
   2.112 +            Timer.Dispose();
   2.113 +            //Mark this event as a stray
   2.114 +            Timer = null;
   2.115 +        }
   2.116 +
   2.117 +        /// <summary>
   2.118 +        /// Initialize an HidEvent from a WM_INPUT message
   2.119 +        /// </summary>
   2.120 +        /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
   2.121 +        public HidEvent(Message aMessage, HidEventRepeatDelegate aRepeatDelegate)
   2.122 +        {
   2.123 +            RepeatCount = 0;
   2.124 +            IsValid = false;
   2.125 +            IsKeyboard = false;
   2.126 +            IsGeneric = false;
   2.127 +
   2.128 +            Time = DateTime.Now;
   2.129 +            OriginalTime = DateTime.Now;
   2.130 +            Timer = new System.Timers.Timer();
   2.131 +            Timer.Elapsed += (sender, e) => OnRepeatTimerElapsed(sender, e, this);
   2.132 +            Usages = new List<ushort>();
   2.133 +            UsageValues = new Dictionary<HIDP_VALUE_CAPS,uint>();
   2.134 +            OnHidEventRepeat += aRepeatDelegate;
   2.135 +
   2.136 +            if (aMessage.Msg != Const.WM_INPUT)
   2.137 +            {
   2.138 +                //Has to be a WM_INPUT message
   2.139 +                return;
   2.140 +            }
   2.141 +
   2.142 +            if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUT)
   2.143 +            {
   2.144 +                IsForeground = true;
   2.145 +            }
   2.146 +            else if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUTSINK)
   2.147 +            {
   2.148 +                IsForeground = false;
   2.149 +            }
   2.150 +
   2.151 +            //Declare some pointers
   2.152 +            IntPtr rawInputBuffer = IntPtr.Zero;
   2.153 +
   2.154 +            try
   2.155 +            {
   2.156 +                //Fetch raw input
   2.157 +                iRawInput = new RAWINPUT();
   2.158 +                if (!Win32.RawInput.GetRawInputData(aMessage.LParam, ref iRawInput, ref rawInputBuffer))
   2.159 +                {
   2.160 +                    Debug.WriteLine("GetRawInputData failed!");
   2.161 +                    return;
   2.162 +                }
   2.163 +
   2.164 +                //Our device can actually be null.
   2.165 +                //This is notably happening for some keyboard events
   2.166 +                if (RawInput.header.hDevice != IntPtr.Zero)
   2.167 +                {
   2.168 +                    //Get various information about this HID device
   2.169 +                    Device = new HidDevice(RawInput.header.hDevice);
   2.170 +                }
   2.171 +
   2.172 +                if (RawInput.header.dwType == Win32.RawInputDeviceType.RIM_TYPEHID)  //Check that our raw input is HID                        
   2.173 +                {
   2.174 +                    IsGeneric = true;
   2.175 +
   2.176 +                    Debug.WriteLine("WM_INPUT source device is HID.");
   2.177 +                    //Get Usage Page and Usage
   2.178 +                    //Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage ID: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
   2.179 +                    UsagePage = Device.Info.hid.usUsagePage;
   2.180 +                    UsageCollection = Device.Info.hid.usUsage;
   2.181 +
   2.182 +                    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
   2.183 +                        && RawInput.hid.dwCount > 0))    //Check that we have at least one HID msg
   2.184 +                    {
   2.185 +                        return;
   2.186 +                    }
   2.187 +
   2.188 +                    //Allocate a buffer for one HID input
   2.189 +                    InputReport = new byte[RawInput.hid.dwSizeHid];
   2.190 +
   2.191 +                    Debug.WriteLine("Raw input contains " + RawInput.hid.dwCount + " HID input report(s)");
   2.192 +
   2.193 +                    //For each HID input report in our raw input
   2.194 +                    for (int i = 0; i < RawInput.hid.dwCount; i++)
   2.195 +                    {
   2.196 +                        //Compute the address from which to copy our HID input
   2.197 +                        int hidInputOffset = 0;
   2.198 +                        unsafe
   2.199 +                        {
   2.200 +                            byte* source = (byte*)rawInputBuffer;
   2.201 +                            source += sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + (RawInput.hid.dwSizeHid * i);
   2.202 +                            hidInputOffset = (int)source;
   2.203 +                        }
   2.204 +
   2.205 +                        //Copy HID input into our buffer
   2.206 +                        Marshal.Copy(new IntPtr(hidInputOffset), InputReport, 0, (int)RawInput.hid.dwSizeHid);
   2.207 +                        //
   2.208 +                        ProcessInputReport(InputReport);
   2.209 +                    }
   2.210 +                }
   2.211 +                else if (RawInput.header.dwType == RawInputDeviceType.RIM_TYPEMOUSE)
   2.212 +                {
   2.213 +                    IsMouse = true;
   2.214 +
   2.215 +                    Debug.WriteLine("WM_INPUT source device is Mouse.");
   2.216 +                    // do mouse handling...
   2.217 +                }
   2.218 +                else if (RawInput.header.dwType == RawInputDeviceType.RIM_TYPEKEYBOARD)
   2.219 +                {
   2.220 +                    IsKeyboard = true;
   2.221 +
   2.222 +                    Debug.WriteLine("WM_INPUT source device is Keyboard.");
   2.223 +                    // do keyboard handling...
   2.224 +                    if (Device != null)
   2.225 +                    {
   2.226 +                        Debug.WriteLine("Type: " + Device.Info.keyboard.dwType.ToString());
   2.227 +                        Debug.WriteLine("SubType: " + Device.Info.keyboard.dwSubType.ToString());
   2.228 +                        Debug.WriteLine("Mode: " + Device.Info.keyboard.dwKeyboardMode.ToString());
   2.229 +                        Debug.WriteLine("Number of function keys: " + Device.Info.keyboard.dwNumberOfFunctionKeys.ToString());
   2.230 +                        Debug.WriteLine("Number of indicators: " + Device.Info.keyboard.dwNumberOfIndicators.ToString());
   2.231 +                        Debug.WriteLine("Number of keys total: " + Device.Info.keyboard.dwNumberOfKeysTotal.ToString());
   2.232 +                    }
   2.233 +                }
   2.234 +            }
   2.235 +            finally
   2.236 +            {
   2.237 +                //Always executed when leaving our try block
   2.238 +                Marshal.FreeHGlobal(rawInputBuffer);
   2.239 +            }
   2.240 +
   2.241 +            //
   2.242 +            if (IsButtonDown)
   2.243 +            {
   2.244 +                //TODO: Make this optional
   2.245 +                //StartRepeatTimer(iRepeatDelay);
   2.246 +            }
   2.247 +
   2.248 +            IsValid = true;
   2.249 +        }
   2.250 +
   2.251 +        /// <summary>
   2.252 +        /// 
   2.253 +        /// </summary>
   2.254 +        private void ProcessInputReport(byte[] aInputReport)
   2.255 +        {
   2.256 +            //Print HID input report in our debug output
   2.257 +            //string hidDump = "HID input report: " + InputReportString();
   2.258 +            //Debug.WriteLine(hidDump);
   2.259 +
   2.260 +            //Get all our usages, those are typically the buttons currently pushed on a gamepad.
   2.261 +            //For a remote control it's usually just the one button that was pushed.
   2.262 +            GetUsages(aInputReport);
   2.263 +
   2.264 +            //Now process direction pad (d-pad, dpad) and axes
   2.265 +            GetUsageValues(aInputReport);
   2.266 +        }
   2.267 +
   2.268 +        /// <summary>
   2.269 +        /// Typically fetches values of a joystick/gamepad axis and dpad directions.
   2.270 +        /// </summary>
   2.271 +        /// <param name="aInputReport"></param>
   2.272 +        private void GetUsageValues(byte[] aInputReport)
   2.273 +        {
   2.274 +            if (Device.InputValueCapabilities == null)
   2.275 +            {
   2.276 +                return;
   2.277 +            }
   2.278 +
   2.279 +            foreach (HIDP_VALUE_CAPS caps in Device.InputValueCapabilities)
   2.280 +            {                
   2.281 +                if (caps.IsRange)
   2.282 +                {
   2.283 +                    //What should we do with those guys?
   2.284 +                    continue;
   2.285 +                }
   2.286 +
   2.287 +                //Now fetch and add our usage value
   2.288 +                uint usageValue = 0;
   2.289 +                Win32.HidStatus status = Win32.Function.HidP_GetUsageValue(Win32.HIDP_REPORT_TYPE.HidP_Input, caps.UsagePage, caps.LinkCollection, caps.NotRange.Usage, ref usageValue, Device.PreParsedData, aInputReport, (uint)aInputReport.Length);
   2.290 +                if (status == Win32.HidStatus.HIDP_STATUS_SUCCESS)
   2.291 +                {
   2.292 +                    UsageValues[caps]=usageValue;
   2.293 +                }
   2.294 +            }
   2.295 +        }
   2.296 +
   2.297 +        /// <summary>
   2.298 +        /// Get all our usages, those are typically the buttons currently pushed on a gamepad.
   2.299 +        /// For a remote control it's usually just the one button that was pushed.
   2.300 +        /// </summary>
   2.301 +        private void GetUsages(byte[] aInputReport)
   2.302 +        {
   2.303 +            //Do proper parsing of our HID report
   2.304 +            //First query our usage count
   2.305 +            uint usageCount = 0;
   2.306 +            Win32.USAGE_AND_PAGE[] usages = null;
   2.307 +            Win32.HidStatus status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, Device.PreParsedData, aInputReport, (uint)aInputReport.Length);
   2.308 +            if (status == Win32.HidStatus.HIDP_STATUS_BUFFER_TOO_SMALL)
   2.309 +            {
   2.310 +                //Allocate a large enough buffer 
   2.311 +                usages = new Win32.USAGE_AND_PAGE[usageCount];
   2.312 +                //...and fetch our usages
   2.313 +                status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, Device.PreParsedData, aInputReport, (uint)aInputReport.Length);
   2.314 +                if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS)
   2.315 +                {
   2.316 +                    Debug.WriteLine("Second pass could not parse HID data: " + status.ToString());
   2.317 +                }
   2.318 +            }
   2.319 +            else if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS)
   2.320 +            {
   2.321 +                Debug.WriteLine("First pass could not parse HID data: " + status.ToString());
   2.322 +            }
   2.323 +
   2.324 +            Debug.WriteLine("Usage count: " + usageCount.ToString());
   2.325 +
   2.326 +            //Copy usages into this event
   2.327 +            if (usages != null)
   2.328 +            {
   2.329 +                foreach (USAGE_AND_PAGE up in usages)
   2.330 +                {
   2.331 +                    //Debug.WriteLine("UsagePage: 0x" + usages[0].UsagePage.ToString("X4"));
   2.332 +                    //Debug.WriteLine("Usage: 0x" + usages[0].Usage.ToString("X4"));
   2.333 +                    //Add this usage to our list
   2.334 +                    Usages.Add(up.Usage);
   2.335 +                }
   2.336 +            }
   2.337 +        }
   2.338 +
   2.339 +        /// <summary>
   2.340 +        /// 
   2.341 +        /// </summary>
   2.342 +        /// <param name="aUsagePage"></param>
   2.343 +        /// <param name="Usage"></param>
   2.344 +        /// <returns></returns>
   2.345 +        public uint GetUsageValue(ushort aUsagePage, ushort aUsage)
   2.346 +        {
   2.347 +            foreach (HIDP_VALUE_CAPS caps in Device.InputValueCapabilities)
   2.348 +            {                
   2.349 +                if (caps.IsRange)
   2.350 +                {
   2.351 +                    //What should we do with those guys?
   2.352 +                    continue;
   2.353 +                }
   2.354 +
   2.355 +                //Check if we have a match
   2.356 +                if (caps.UsagePage == aUsagePage && caps.NotRange.Usage == aUsage)
   2.357 +                {
   2.358 +                    return UsageValues[caps];
   2.359 +                }
   2.360 +            }
   2.361 +
   2.362 +            return 0;
   2.363 +        }
   2.364 +
   2.365 +        /// <summary>
   2.366 +        /// 
   2.367 +        /// </summary>
   2.368 +        /// <param name="aUsagePage"></param>
   2.369 +        /// <param name="aUsage"></param>
   2.370 +        /// <returns></returns>
   2.371 +        public int GetValueCapabilitiesIndex(ushort aUsagePage, ushort aUsage)
   2.372 +        {
   2.373 +            int i = -1;
   2.374 +            foreach (HIDP_VALUE_CAPS caps in Device.InputValueCapabilities)
   2.375 +            {
   2.376 +                i++;
   2.377 +                if (caps.IsRange)
   2.378 +                {
   2.379 +                    //What should we do with those guys?
   2.380 +                    continue;
   2.381 +                }
   2.382 +
   2.383 +                //Check if we have a match
   2.384 +                if (caps.UsagePage == aUsagePage && caps.NotRange.Usage == aUsage)
   2.385 +                {
   2.386 +                    return i;
   2.387 +                }
   2.388 +            }
   2.389 +
   2.390 +            return i;
   2.391 +        }        
   2.392 +
   2.393 +
   2.394 +        /// <summary>
   2.395 +        /// TODO: Move this to another level?
   2.396 +        /// </summary>
   2.397 +        /// <param name="aInterval"></param>
   2.398 +        public void StartRepeatTimer(double aInterval)
   2.399 +        {
   2.400 +            if (Timer == null)
   2.401 +            {
   2.402 +                return;
   2.403 +            }
   2.404 +            Timer.Enabled = false;
   2.405 +            //Initial delay do not use auto reset
   2.406 +            //After our initial delay however we do setup our timer one more time using auto reset
   2.407 +            Timer.AutoReset = (RepeatCount != 0);
   2.408 +            Timer.Interval = aInterval;
   2.409 +            Timer.Enabled = true;
   2.410 +        }
   2.411 +
   2.412 +        static private void OnRepeatTimerElapsed(object sender, ElapsedEventArgs e, HidEvent aHidEvent)
   2.413 +        {
   2.414 +            if (aHidEvent.IsStray)
   2.415 +            {
   2.416 +                //Skip events if canceled
   2.417 +                return;
   2.418 +            }
   2.419 +
   2.420 +            aHidEvent.RepeatCount++;
   2.421 +            aHidEvent.Time = DateTime.Now;
   2.422 +            if (aHidEvent.RepeatCount == 1)
   2.423 +            {
   2.424 +                //Re-Start our timer only after the initial delay 
   2.425 +                aHidEvent.StartRepeatTimer(aHidEvent.iRepeatSpeed);
   2.426 +            }
   2.427 +
   2.428 +            //Broadcast our repeat event
   2.429 +            aHidEvent.OnHidEventRepeat(aHidEvent);
   2.430 +        }
   2.431 +
   2.432 +        /// <summary>
   2.433 +        /// Provide the state of the dpad or hat switch if any.
   2.434 +        /// If no dpad is found we return 'at rest'.
   2.435 +        /// </summary>
   2.436 +        /// <returns></returns>
   2.437 +        public DirectionPadState GetDirectionPadState()
   2.438 +        {
   2.439 +            int index=GetValueCapabilitiesIndex((ushort)Hid.UsagePage.GenericDesktopControls, (ushort)GenericDesktop.HatSwitch);
   2.440 +            if (index < 0)
   2.441 +            {
   2.442 +                //No hat switch found
   2.443 +                return DirectionPadState.Rest;
   2.444 +            }
   2.445 +
   2.446 +            HIDP_VALUE_CAPS caps=Device.InputValueCapabilities[index];
   2.447 +            if (caps.IsRange)
   2.448 +            {
   2.449 +                //Defensive
   2.450 +                return DirectionPadState.Rest;
   2.451 +            }
   2.452 +
   2.453 +            uint dpadUsageValue = UsageValues[caps]; 
   2.454 +
   2.455 +            if (dpadUsageValue < caps.LogicalMin || dpadUsageValue > caps.LogicalMax)
   2.456 +            {
   2.457 +                //Out of range means at rest
   2.458 +                return DirectionPadState.Rest;
   2.459 +            }
   2.460 +
   2.461 +            //Normalize value to start at zero
   2.462 +            //TODO: more error check here?
   2.463 +            DirectionPadState res = (DirectionPadState)((int)dpadUsageValue - caps.LogicalMin);            
   2.464 +            return res;
   2.465 +        }
   2.466 +
   2.467 +        /// <summary>
   2.468 +        /// Print information about this device to our debug output.
   2.469 +        /// </summary>
   2.470 +        public void DebugWrite()
   2.471 +        {
   2.472 +            if (!IsValid)
   2.473 +            {
   2.474 +                Debug.WriteLine("==== Invalid HidEvent");
   2.475 +                return;
   2.476 +            }
   2.477 +
   2.478 +            if (Device!=null)
   2.479 +            {
   2.480 +                Device.DebugWrite();
   2.481 +            }
   2.482 +            
   2.483 +            if (IsGeneric) Debug.WriteLine("==== Generic");
   2.484 +            if (IsKeyboard) Debug.WriteLine("==== Keyboard");
   2.485 +            if (IsMouse) Debug.WriteLine("==== Mouse");
   2.486 +            Debug.WriteLine("==== Foreground: " + IsForeground.ToString());
   2.487 +            Debug.WriteLine("==== UsagePage: 0x" + UsagePage.ToString("X4"));
   2.488 +            Debug.WriteLine("==== UsageCollection: 0x" + UsageCollection.ToString("X4"));
   2.489 +            Debug.WriteLine("==== InputReport: 0x" + InputReportString());
   2.490 +            foreach (ushort usage in Usages)
   2.491 +            {
   2.492 +                Debug.WriteLine("==== Usage: 0x" + usage.ToString("X4"));
   2.493 +            }
   2.494 +        }
   2.495 +
   2.496 +        /// <summary>
   2.497 +        /// 
   2.498 +        /// </summary>
   2.499 +        /// <returns></returns>
   2.500 +        public string InputReportString()
   2.501 +        {
   2.502 +            if (InputReport == null)
   2.503 +            {
   2.504 +                return "null";
   2.505 +            }
   2.506 +
   2.507 +            string hidDump = "";
   2.508 +            foreach (byte b in InputReport)
   2.509 +            {
   2.510 +                hidDump += b.ToString("X2");
   2.511 +            }
   2.512 +            return hidDump;
   2.513 +        }
   2.514 +
   2.515 +
   2.516 +        /// <summary>
   2.517 +        /// Create a list view item describing this HidEvent
   2.518 +        /// </summary>
   2.519 +        /// <returns></returns>
   2.520 +        public ListViewItem ToListViewItem()
   2.521 +        {
   2.522 +            string usageText = "";
   2.523 +
   2.524 +            foreach (ushort usage in Usages)
   2.525 +            {
   2.526 +                if (usageText != "")
   2.527 +                {
   2.528 +                    //Add a separator
   2.529 +                    usageText += ", ";
   2.530 +                }
   2.531 +
   2.532 +                UsagePage usagePage = (UsagePage)UsagePage;
   2.533 +                switch (usagePage)
   2.534 +                {
   2.535 +                    case Hid.UsagePage.Consumer:
   2.536 +                        usageText += ((ConsumerControl)usage).ToString();
   2.537 +                        break;
   2.538 +
   2.539 +                    case Hid.UsagePage.WindowsMediaCenterRemoteControl:
   2.540 +                        usageText += ((WindowsMediaCenterRemoteControl)usage).ToString();
   2.541 +                        break;
   2.542 +
   2.543 +                    default:
   2.544 +                        usageText += usage.ToString("X2");
   2.545 +                        break;
   2.546 +                }
   2.547 +            }
   2.548 +
   2.549 +            //If we are a gamepad display axis and dpad values
   2.550 +            if (Device.IsGamePad)
   2.551 +            {
   2.552 +                //uint dpadUsageValue = GetUsageValue((ushort)Hid.UsagePage.GenericDesktopControls, (ushort)Hid.Usage.GenericDesktop.HatSwitch);
   2.553 +                //usageText = dpadUsageValue.ToString("X") + " (dpad), " + usageText;
   2.554 +              
   2.555 +                if (usageText != "")
   2.556 +                {
   2.557 +                    //Add a separator
   2.558 +                    usageText += " (Buttons)";
   2.559 +                }
   2.560 +
   2.561 +                if (usageText != "")
   2.562 +                {
   2.563 +                    //Add a separator
   2.564 +                    usageText += ", ";
   2.565 +                }
   2.566 +
   2.567 +                usageText += GetDirectionPadState().ToString();
   2.568 +
   2.569 +                foreach (KeyValuePair<HIDP_VALUE_CAPS, uint> entry in UsageValues)
   2.570 +                {
   2.571 +                    if (entry.Key.IsRange)
   2.572 +                    {
   2.573 +                        continue;
   2.574 +                    }
   2.575 +
   2.576 +                    Type usageType = Utils.UsageType((UsagePage)entry.Key.UsagePage);
   2.577 +                    if (usageType == null)
   2.578 +                    {
   2.579 +                        //TODO: check why this is happening on Logitech rumble gamepad 2.
   2.580 +                        //Probably some of our axis are hiding in there.
   2.581 +                        continue;
   2.582 +                    }
   2.583 +                    string name = Enum.GetName(usageType, entry.Key.NotRange.Usage);
   2.584 +
   2.585 +                    if (usageText != "")
   2.586 +                    {
   2.587 +                        //Add a separator
   2.588 +                        usageText += ", ";
   2.589 +                    }
   2.590 +                    usageText += entry.Value.ToString("X") + " ("+ name +")";        
   2.591 +                }
   2.592 +            }
   2.593 +
   2.594 +            //Now create our list item
   2.595 +            ListViewItem item = new ListViewItem(new[] { usageText, InputReportString(), UsagePage.ToString("X2"), UsageCollection.ToString("X2"), RepeatCount.ToString(), Time.ToString("HH:mm:ss:fff") });
   2.596 +            return item;
   2.597 +        }
   2.598 +
   2.599 +    }
   2.600 +
   2.601 +}
   2.602 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Hid/HidHandler.cs	Sun Mar 15 20:25:58 2015 +0100
     3.3 @@ -0,0 +1,104 @@
     3.4 +//
     3.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
     3.6 +//
     3.7 +// This file is part of SharpLibHid.
     3.8 +//
     3.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
    3.10 +// it under the terms of the GNU General Public License as published by
    3.11 +// the Free Software Foundation, either version 3 of the License, or
    3.12 +// (at your option) any later version.
    3.13 +//
    3.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
    3.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.17 +// GNU General Public License for more details.
    3.18 +//
    3.19 +// You should have received a copy of the GNU General Public License
    3.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    3.21 +//
    3.22 +
    3.23 +
    3.24 +using System;
    3.25 +using System.Windows.Forms;
    3.26 +using System.Runtime.InteropServices;
    3.27 +using System.Diagnostics;
    3.28 +using System.Text;
    3.29 +using Microsoft.Win32.SafeHandles;
    3.30 +using SharpLib.Win32;
    3.31 +using System.Collections.Generic;
    3.32 +
    3.33 +
    3.34 +namespace SharpLib.Hid
    3.35 +{
    3.36 +    /// <summary>
    3.37 +    /// Our HID handler manages raw input registrations, processes WM_INPUT messages and broadcasts HID events in return.
    3.38 +    /// </summary>
    3.39 +    public class HidHandler
    3.40 +    {
    3.41 +        public delegate void HidEventHandler(object aSender, HidEvent aHidEvent);
    3.42 +        public event HidEventHandler OnHidEvent;
    3.43 +        List<HidEvent> iHidEvents;
    3.44 +
    3.45 +
    3.46 +        public bool IsRegistered { get; private set; }
    3.47 +
    3.48 +        public HidHandler(RAWINPUTDEVICE[] aRawInputDevices)
    3.49 +        {
    3.50 +            iHidEvents=new List<HidEvent>();
    3.51 +            IsRegistered = Function.RegisterRawInputDevices(aRawInputDevices, (uint)aRawInputDevices.Length, (uint)Marshal.SizeOf(aRawInputDevices[0]));
    3.52 +        }
    3.53 +
    3.54 +        /// <summary>
    3.55 +        /// Process a WM_INPUT message.
    3.56 +        /// </summary>
    3.57 +        /// <param name="aMessage"></param>
    3.58 +        public void ProcessInput(ref Message aMessage)
    3.59 +        {
    3.60 +            if (aMessage.Msg != Const.WM_INPUT)
    3.61 +            {
    3.62 +                //We only process WM_INPUT messages
    3.63 +                return;
    3.64 +            }
    3.65 +
    3.66 +            HidEvent hidEvent = new HidEvent(aMessage, OnHidEventRepeat);
    3.67 +            hidEvent.DebugWrite();
    3.68 +
    3.69 +            if (!hidEvent.IsValid || !hidEvent.IsGeneric)
    3.70 +            {
    3.71 +                Debug.WriteLine("Skipping HID message.");
    3.72 +                return;
    3.73 +            }
    3.74 +
    3.75 +            //
    3.76 +            if (hidEvent.IsButtonUp)
    3.77 +            {
    3.78 +                //This is a key up event
    3.79 +                //We need to discard any events belonging to the same page and collection
    3.80 +                for (int i = (iHidEvents.Count-1); i >= 0; i--)
    3.81 +                {
    3.82 +                    if (iHidEvents[i].UsageId == hidEvent.UsageId)
    3.83 +                    {
    3.84 +                        iHidEvents[i].Dispose();
    3.85 +                        iHidEvents.RemoveAt(i);
    3.86 +                    }
    3.87 +                }
    3.88 +            }
    3.89 +            else
    3.90 +            {
    3.91 +                //Keep that event until we get a key up message
    3.92 +                iHidEvents.Add(hidEvent);
    3.93 +            }
    3.94 +
    3.95 +            //Broadcast our events
    3.96 +            OnHidEvent(this, hidEvent);    
    3.97 +        }
    3.98 +
    3.99 +        public void OnHidEventRepeat(HidEvent aHidEvent)
   3.100 +        {
   3.101 +            //Broadcast our events
   3.102 +            OnHidEvent(this, aHidEvent);    
   3.103 +        }
   3.104 +
   3.105 +    }
   3.106 +
   3.107 +}
   3.108 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Hid/HidUsageTables.cs	Sun Mar 15 20:25:58 2015 +0100
     4.3 @@ -0,0 +1,928 @@
     4.4 +//
     4.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
     4.6 +//
     4.7 +// This file is part of SharpLibHid.
     4.8 +//
     4.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
    4.10 +// it under the terms of the GNU General Public License as published by
    4.11 +// the Free Software Foundation, either version 3 of the License, or
    4.12 +// (at your option) any later version.
    4.13 +//
    4.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
    4.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.17 +// GNU General Public License for more details.
    4.18 +//
    4.19 +// You should have received a copy of the GNU General Public License
    4.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    4.21 +//
    4.22 +
    4.23 +namespace SharpLib.Hid
    4.24 +{
    4.25 +    /// <summary>
    4.26 +    /// From USB HID usage tables.
    4.27 +    /// http://www.usb.org/developers/hidpage#HID_Usage
    4.28 +    /// http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf
    4.29 +    /// </summary>
    4.30 +    public enum UsagePage : ushort
    4.31 +    {
    4.32 +        Undefined = 0,
    4.33 +        GenericDesktopControls,
    4.34 +        SimulationControls,
    4.35 +        VirtualRealityControls,
    4.36 +        SportControls,
    4.37 +        GameControls,
    4.38 +        GenericDeviceControls,
    4.39 +        Keyboard,
    4.40 +        LightEmittingDiode,
    4.41 +        Button,
    4.42 +        Ordinal,
    4.43 +        Telephony,
    4.44 +        Consumer,
    4.45 +        Digitiser,
    4.46 +        PhysicalInterfaceDevice = 0x0f,
    4.47 +        Unicode = 0x10,
    4.48 +        AlphaNumericDisplay = 0x14,
    4.49 +        MedicalInstruments = 0x40,
    4.50 +        MonitorPage0 = 0x80,
    4.51 +        MonitorPage1,
    4.52 +        MonitorPage2,
    4.53 +        MonitorPage3,
    4.54 +        PowerPage0,
    4.55 +        PowerPage1,
    4.56 +        PowerPage2,
    4.57 +        PowerPage3,
    4.58 +        BarCodeScanner = 0x8c,
    4.59 +        Scale,
    4.60 +        MagneticStripeReader,
    4.61 +        ReservedPointOfSale,
    4.62 +        CameraControl,
    4.63 +        Arcade,
    4.64 +        // http://msdn.microsoft.com/en-us/library/windows/desktop/bb417079.aspx
    4.65 +        WindowsMediaCenterRemoteControl = 0xffbc,
    4.66 +        TerraTecRemote = 0xffcc
    4.67 +    }
    4.68 +
    4.69 +    /// <summary>
    4.70 +    /// Usage Collections are special values from our Usage enumeration.
    4.71 +    /// Thus they are also part of the corresponding Usage enumeration.
    4.72 +    /// </summary>
    4.73 +    namespace UsageCollection
    4.74 +    {
    4.75 +        /// <summary>
    4.76 +        /// Usage Collection for usage page GenericDesktopControls.
    4.77 +        /// </summary>
    4.78 +        public enum GenericDesktop : ushort
    4.79 +        {
    4.80 +            Pointer = 0x01,
    4.81 +            Mouse = 0x02,
    4.82 +            Joystick = 0x04,
    4.83 +            GamePad = 0x05,
    4.84 +            Keyboard = 0x06,
    4.85 +            KeyPad = 0x07,
    4.86 +            MultiAxisController = 0x08,
    4.87 +            TabletPCSystemControls = 0x09,
    4.88 +            SystemControl = 0x80
    4.89 +        }
    4.90 +
    4.91 +        /// <summary>
    4.92 +        /// Usage Collection for usage page Consumer.
    4.93 +        /// </summary>
    4.94 +        public enum Consumer : ushort
    4.95 +        {
    4.96 +            ConsumerControl = 0x01,
    4.97 +            NumericKeyPad = 0x02,
    4.98 +            ProgrammableButtons = 0x03,
    4.99 +            Microphone = 0x04,
   4.100 +            Headphone = 0x05,
   4.101 +            GraphicEqualizer = 0x06,
   4.102 +            FunctionButtons = 0x36,
   4.103 +            Selection = 0x80,
   4.104 +            MediaSelection = 0x0087,
   4.105 +            SelectDisc = 0x00BA,
   4.106 +            PlaybackSpeed = 0x00F1,
   4.107 +            Proximity = 0x0109,
   4.108 +            SpeakerSystem = 0x0160,
   4.109 +            ChannelLeft = 0x0161,
   4.110 +            ChannelRight = 0x0162,
   4.111 +            ChannelCenter = 0x0163,
   4.112 +            ChannelFront = 0x0164,
   4.113 +            ChannelCenterFront = 0x0165,
   4.114 +            ChannelSide = 0x0166,
   4.115 +            ChannelSurrond = 0x0167,
   4.116 +            ChannelLowFrequencyEnhancement = 0x0168,
   4.117 +            ChannelTop = 0x0169,
   4.118 +            ChannelUnknown = 0x016A,
   4.119 +            ApplicationLaunchButtons = 0x016A,
   4.120 +            GenericGuiApplicationControls = 0x0200,
   4.121 +        }
   4.122 +
   4.123 +
   4.124 +        public enum WindowsMediaCenter : ushort
   4.125 +        {
   4.126 +            WindowsMediaCenterRemoteControl = 0x88
   4.127 +        }
   4.128 +
   4.129 +    }
   4.130 +
   4.131 +
   4.132 +
   4.133 +    namespace Usage
   4.134 +    {
   4.135 +        /// <summary>
   4.136 +        ///
   4.137 +        /// </summary>
   4.138 +        public enum WindowsMediaCenterRemoteControl : ushort
   4.139 +        {
   4.140 +            /// <summary>
   4.141 +            /// Not defined by the Microsoft specs.
   4.142 +            /// </summary>
   4.143 +            Null = 0x00,
   4.144 +            GreenStart = 0x0D,
   4.145 +            ClosedCaptioning = 0x2B,
   4.146 +            Teletext = 0x5A,
   4.147 +            TeletextRed = 0x5B,
   4.148 +            TeletextGreen = 0x5C,
   4.149 +            TeletextYellow = 0x5D,
   4.150 +            TeletextBlue = 0x5E,
   4.151 +            LiveTv = 0x25,
   4.152 +            Tv = 0x46,
   4.153 +            Music = 0x47,
   4.154 +            RecordedTv = 0x48,
   4.155 +            Pictures = 0x49,
   4.156 +            Videos = 0x4A,
   4.157 +            FmRadio = 0x50,
   4.158 +            Extras = 0x3C,
   4.159 +            ExtrasApp = 0x3D,
   4.160 +            DvdMenu = 0x24,
   4.161 +            DvdAngle = 0x4B,
   4.162 +            DvdAudio = 0x4C,
   4.163 +            DvdSubtitle = 0x4D,
   4.164 +            /// <summary>
   4.165 +            /// First press action: Ejects a DVD drive.
   4.166 +            /// <para />
   4.167 +            /// Second press action: Repeats first press action.
   4.168 +            /// <para />
   4.169 +            /// Notably issued by XBOX360 remote as defined in irplus - Remote Control - Android application.
   4.170 +            /// </summary>
   4.171 +            Eject = 0x28,
   4.172 +            DvdTopMenu = 0x43,
   4.173 +            /// <summary>
   4.174 +            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   4.175 +            /// Collection (page 0xFFBC, usage 0x88).
   4.176 +            /// <para />
   4.177 +            /// Second press action: Repeats message.
   4.178 +            /// <para />
   4.179 +            /// Auto-repeat: No
   4.180 +            /// <para />
   4.181 +            /// Notably sent by the 'Visualization' button of HP Windows Media Center Remote (TSGH-IR08).
   4.182 +            /// <para />
   4.183 +            /// According to HP specs it displays visual imagery that is synchronized to the sound of your music tracks.
   4.184 +            /// </summary>
   4.185 +            Ext0 = 0x32,
   4.186 +            /// <summary>
   4.187 +            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   4.188 +            /// Collection (page 0xFFBC, usage 0x88).
   4.189 +            /// <para />
   4.190 +            /// Second press action: Repeats message.
   4.191 +            /// <para />
   4.192 +            /// Auto-repeat: No
   4.193 +            /// <para />
   4.194 +            /// Notably sent by the 'Slide Show' button of HP Windows Media Center Remote (TSGH-IR08).
   4.195 +            /// <para />
   4.196 +            /// According to HP specs it plays a slide show of all the pictures on your hard disk drive.
   4.197 +            /// </summary>
   4.198 +            Ext1 = 0x33,
   4.199 +            /// <summary>
   4.200 +            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   4.201 +            /// Collection (page 0xFFBC, usage 0x88).
   4.202 +            /// <para />
   4.203 +            /// Second press action: Repeats message.
   4.204 +            /// <para />
   4.205 +            /// Auto-repeat: No
   4.206 +            /// <para />
   4.207 +            /// Notably sent by the 'Eject' button of HP Windows Media Center Remote (TSGH-IR08).
   4.208 +            /// Also interpreted as 'Eject' action by SoundGraph iMON Manager in MCE mode (OrigenAE VF310).
   4.209 +            /// </summary>
   4.210 +            Ext2 = 0x34,
   4.211 +            /// <summary>
   4.212 +            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   4.213 +            /// Collection (page 0xFFBC, usage 0x88).
   4.214 +            /// <para />
   4.215 +            /// Second press action: Repeats message.
   4.216 +            /// <para />
   4.217 +            /// Auto-repeat: No
   4.218 +            /// <para />
   4.219 +            /// Notably sent by the 'Input selection' button of HP Windows Media Center Remote (TSGH-IR08).
   4.220 +            /// </summary>
   4.221 +            Ext3 = 0x35,
   4.222 +            Ext4 = 0x36,
   4.223 +            Ext5 = 0x37,
   4.224 +            Ext6 = 0x38,
   4.225 +            Ext7 = 0x39,
   4.226 +            Ext8 = 0x3A,
   4.227 +            Ext9 = 0x80,
   4.228 +            Ext10 = 0x81,
   4.229 +            Ext11 = 0x6F,
   4.230 +            Zoom = 0x27,
   4.231 +            ChannelInput = 0x42,
   4.232 +            SubAudio = 0x2D,
   4.233 +            Channel10 = 0x3E,
   4.234 +            Channel11 = 0x3F,
   4.235 +            Channel12 = 0x40,
   4.236 +            /// <summary>
   4.237 +            /// First press action: Generates OEM2 HID message in the Media Center Vendor Specific
   4.238 +            /// Collection. This button is intended to control the front panel display of home entertainment
   4.239 +            /// computers. When this button is pressed, the display could be turned on or off, or the display
   4.240 +            /// mode could change.
   4.241 +            /// <para />
   4.242 +            /// Second press action: Repeats message.
   4.243 +            /// <para />
   4.244 +            /// Auto-repeat: No
   4.245 +            /// <para />
   4.246 +            /// Notably issued by XBOX360 remote as defined in irplus - Remote Control - Android application.
   4.247 +            /// </summary>
   4.248 +            Display = 0x4F,
   4.249 +            /// <summary>
   4.250 +            /// First press action: To be determined.
   4.251 +            /// <para />
   4.252 +            /// Second press action: Repeats message.
   4.253 +            /// <para />
   4.254 +            /// Auto-repeat: No
   4.255 +            /// </summary>
   4.256 +            Kiosk = 0x6A,
   4.257 +            NetworkSelection = 0x2C,
   4.258 +            BlueRayTool = 0x78,
   4.259 +            ChannelInfo = 0x41,
   4.260 +            VideoSelection = 0x61
   4.261 +        }
   4.262 +
   4.263 +        /// <summary>
   4.264 +        /// Those codes come from experimenting with HP remotes.
   4.265 +        /// </summary>
   4.266 +        public enum HpWindowsMediaCenterRemoteControl : ushort
   4.267 +        {
   4.268 +            /// <summary>
   4.269 +            /// Displays visual imagery that is synchronized to the sound of your music tracks.
   4.270 +            /// <para />
   4.271 +            /// Second press action: Repeats message.
   4.272 +            /// <para />
   4.273 +            /// Auto-repeat: No
   4.274 +            /// <para />
   4.275 +            /// Notably sent by the 'Visualization' button of HP Windows Media Center Remote (TSGH-IR08).
   4.276 +            /// <para />
   4.277 +            /// According to HP specs it displays visual imagery that is synchronized to the sound of your music tracks.
   4.278 +            /// </summary>
   4.279 +            Visualization = WindowsMediaCenterRemoteControl.Ext0,
   4.280 +            /// <summary>
   4.281 +            /// Plays a slide show of all the pictures on your hard disk drive.
   4.282 +            /// <para />
   4.283 +            /// Second press action: Repeats message.
   4.284 +            /// <para />
   4.285 +            /// Auto-repeat: No
   4.286 +            /// <para />
   4.287 +            /// Notably sent by the 'Slide Show' button of HP Windows Media Center Remote (TSGH-IR08).
   4.288 +            /// <para />
   4.289 +            /// According to HP specs it plays a slide show of all the pictures on your hard disk drive.
   4.290 +            /// </summary>
   4.291 +            SlideShow = WindowsMediaCenterRemoteControl.Ext1,
   4.292 +            /// <summary>
   4.293 +            /// Eject optical drive.
   4.294 +            /// <para />
   4.295 +            /// Second press action: Repeats message.
   4.296 +            /// <para />
   4.297 +            /// Auto-repeat: No
   4.298 +            /// <para />
   4.299 +            /// Notably sent by the 'Eject' button of HP Windows Media Center Remote (TSGH-IR08).
   4.300 +            /// Also interpreted as 'Eject' action by SoundGraph iMON Manager in MCE mode (OrigenAE VF310).
   4.301 +            /// </summary>
   4.302 +            HpEject = WindowsMediaCenterRemoteControl.Ext2,
   4.303 +            /// <summary>
   4.304 +            /// Not sure what this should do.
   4.305 +            /// <para />
   4.306 +            /// Second press action: Repeats message.
   4.307 +            /// <para />
   4.308 +            /// Auto-repeat: No
   4.309 +            /// <para />
   4.310 +            /// Notably sent by the 'Input selection' button of HP Windows Media Center Remote (TSGH-IR08).
   4.311 +            /// </summary>
   4.312 +            InputSelection = WindowsMediaCenterRemoteControl.Ext3,
   4.313 +        }
   4.314 +
   4.315 +        /// <summary>
   4.316 +        /// Usage Table for Consumer Controls
   4.317 +        /// 0x0C 0X01
   4.318 +        /// </summary>
   4.319 +        public enum ConsumerControl : ushort
   4.320 +        {
   4.321 +            Null = 0x00,
   4.322 +            ConsumerControl = 0x01,
   4.323 +            NumericKeyPad = 0x02,
   4.324 +            ProgrammableButtons = 0x03,
   4.325 +            Microphone = 0x04,
   4.326 +            Headphone = 0x05,
   4.327 +            GraphicEqualizer = 0x06,
   4.328 +            Plus10 = 0x20,
   4.329 +            Plus100 = 0x21,
   4.330 +            AmPm = 0x22,
   4.331 +            Power = 0x30,
   4.332 +            Reset = 0x31,
   4.333 +            Sleep = 0x32,
   4.334 +            SleepAfter = 0x33,
   4.335 +            SleepMode = 0x34,
   4.336 +            Illumination = 0x35,
   4.337 +            FunctionButtons = 0x36,
   4.338 +            Menu = 0x40,
   4.339 +            MenuPick = 0x41,
   4.340 +            MenuUp = 0x42,
   4.341 +            MenuDown = 0x43,
   4.342 +            MenuLeft = 0x44,
   4.343 +            MenuRight = 0x45,
   4.344 +            MenuEscape = 0x46,
   4.345 +            MenuValueIncrease = 0x47,
   4.346 +            MenuValueDecrease = 0x48,
   4.347 +            DataOnScreen = 0x60,
   4.348 +            ClosedCaption = 0x61,
   4.349 +            ClosedCaptionSelect = 0x62,
   4.350 +            VcrTv = 0x63,
   4.351 +            BroadcastMode = 0x64,
   4.352 +            Snapshot = 0x65,
   4.353 +            Still = 0x66,
   4.354 +            Selection = 0x80,
   4.355 +            AssignSelection = 0x81,
   4.356 +            ModeStep = 0x82,
   4.357 +            RecallLast = 0x83,
   4.358 +            EnterChannel = 0x84,
   4.359 +            OrderMovie = 0x85,
   4.360 +            Channel = 0x86,
   4.361 +            MediaSelection = 0x87,
   4.362 +            MediaSelectComputer = 0x88,
   4.363 +            MediaSelectTv = 0x89,
   4.364 +            MediaSelectWww = 0x8A,
   4.365 +            MediaSelectDvd = 0x8B,
   4.366 +            MediaSelectTelephone = 0x8C,
   4.367 +            MediaSelectProgramGuide = 0x8D,
   4.368 +            MediaSelectVideoPhone = 0x8E,
   4.369 +            MediaSelectGames = 0x8F,
   4.370 +            MediaSelectMessages = 0x90,
   4.371 +            MediaSelectCd = 0x91,
   4.372 +            MediaSelectVcr = 0x92,
   4.373 +            MediaSelectTuner = 0x93,
   4.374 +            Quit = 0x94,
   4.375 +            Help = 0x95,
   4.376 +            MediaSelectTape = 0x96,
   4.377 +            MediaSelectCable = 0x97,
   4.378 +            MediaSelectSatellite = 0x98,
   4.379 +            MediaSelectSecurity = 0x99,
   4.380 +            MediaSelectHome = 0x9A,
   4.381 +            MediaSelectCall = 0x9B,
   4.382 +            ChannelIncrement = 0x9C,
   4.383 +            ChannelDecrement = 0x9D,
   4.384 +            MediaSelectSap = 0x9E,
   4.385 +            VcrPlus = 0xA0,
   4.386 +            Once = 0xA1,
   4.387 +            Daily = 0xA2,
   4.388 +            Weekly = 0xA3,
   4.389 +            Monthly = 0xA4,
   4.390 +            Play = 0xB0,
   4.391 +            Pause = 0xB1,
   4.392 +            Record = 0xB2,
   4.393 +            FastForward = 0xB3,
   4.394 +            Rewind = 0xB4,
   4.395 +            ScanNextTrack = 0xB5,
   4.396 +            ScanPreviousTrack = 0xB6,
   4.397 +            Stop = 0xB7,
   4.398 +            Eject = 0xB8,
   4.399 +            RandomPlay = 0xB9,
   4.400 +            SelectDisc = 0xBA,
   4.401 +            EnterDisc = 0xBB,
   4.402 +            Repeat = 0xBC,
   4.403 +            Tracking = 0xBD,
   4.404 +            TrackNormal = 0xBE,
   4.405 +            SlowTracking = 0xBF,
   4.406 +            FrameForward = 0xC0,
   4.407 +            FrameBack = 0xC1,
   4.408 +            Mark = 0xC2,
   4.409 +            ClearMark = 0xC3,
   4.410 +            RepeatFromMark = 0xC4,
   4.411 +            ReturnToMark = 0xC5,
   4.412 +            SearchMarkForward = 0xC6,
   4.413 +            SearchMarkBackwards = 0xC7,
   4.414 +            CounterReset = 0xC8,
   4.415 +            ShowCounter = 0xC9,
   4.416 +            TrackingIncrement = 0xCA,
   4.417 +            TrackingDecrement = 0xCB,
   4.418 +            StopEject = 0xCC,
   4.419 +            PlayPause = 0xCD,
   4.420 +            PlaySkip = 0xCE,
   4.421 +            Volume = 0xE0,
   4.422 +            Balance = 0xE1,
   4.423 +            Mute = 0xE2,
   4.424 +            Bass = 0xE3,
   4.425 +            Treble = 0xE4,
   4.426 +            BassBoost = 0xE5,
   4.427 +            SurroundMode = 0xE6,
   4.428 +            Loudness = 0xE7,
   4.429 +            Mpx = 0xE8,
   4.430 +            VolumeIncrement = 0xE9,
   4.431 +            VolumeDecrement = 0xEA,
   4.432 +            SpeedSelect = 0xF0,
   4.433 +            PlaybackSpeed = 0xF1,
   4.434 +            StandardPlay = 0xF2,
   4.435 +            LongPlay = 0xF3,
   4.436 +            ExtendedPlay = 0xF4,
   4.437 +            Slow = 0xF5,
   4.438 +            FanEnable = 0x100,
   4.439 +            FanSpeed = 0x101,
   4.440 +            LightEnable = 0x102,
   4.441 +            LightIlluminationLevel = 0x103,
   4.442 +            ClimateControlEnable = 0x104,
   4.443 +            RoomTemperature = 0x105,
   4.444 +            SecurityEnable = 0x106,
   4.445 +            FireAlarm = 0x107,
   4.446 +            PoliceAlarm = 0x108,
   4.447 +            Proximity = 0x109,
   4.448 +            Motion = 0x10A,
   4.449 +            DuressAlarm = 0x10B,
   4.450 +            HoldupAlarm = 0x10C,
   4.451 +            MedicalAlarm = 0x10D,
   4.452 +            BalanceRight = 0x150,
   4.453 +            BalanceLeft = 0x151,
   4.454 +            BassIncrement = 0x152,
   4.455 +            BassDecrement = 0x153,
   4.456 +            TrebleIncrement = 0x154,
   4.457 +            TrebleDecrement = 0x155,
   4.458 +            SpeakerSystem = 0x160,
   4.459 +            ChannelLeft = 0x161,
   4.460 +            ChannelRight = 0x162,
   4.461 +            ChannelCenter = 0x163,
   4.462 +            ChannelFront = 0x164,
   4.463 +            ChannelCenterFront = 0x165,
   4.464 +            ChannelSide = 0x166,
   4.465 +            ChannelSurround = 0x167,
   4.466 +            ChannelLowFrequencyEnhancement = 0x168,
   4.467 +            ChannelTop = 0x169,
   4.468 +            ChannelUnknown = 0x16A,
   4.469 +            SubChannel = 0x170,
   4.470 +            SubChannelIncrement = 0x171,
   4.471 +            SubChannelDecrement = 0x172,
   4.472 +            AlternateAudioIncrement = 0x173,
   4.473 +            AlternateAudioDecrement = 0x174,
   4.474 +            ApplicationLaunchButtons = 0x180,
   4.475 +            AppLaunchLaunchButtonConfigurationTool = 0x181,
   4.476 +            AppLaunchProgrammableButtonConfiguration = 0x182,
   4.477 +            AppLaunchConsumerControlConfiguration = 0x183,
   4.478 +            AppLaunchWordProcessor = 0x184,
   4.479 +            AppLaunchTextEditor = 0x185,
   4.480 +            AppLaunchSpreadsheet = 0x186,
   4.481 +            AppLaunchGraphicsEditor = 0x187,
   4.482 +            AppLaunchPresentationApp = 0x188,
   4.483 +            AppLaunchDatabaseApp = 0x189,
   4.484 +            AppLaunchEmailReader = 0x18A,
   4.485 +            AppLaunchNewsreader = 0x18B,
   4.486 +            AppLaunchVoicemail = 0x18C,
   4.487 +            AppLaunchContactsAddressBook = 0x18D,
   4.488 +            AppLaunchCalendarSchedule = 0x18E,
   4.489 +            AppLaunchTaskProjectManager = 0x18F,
   4.490 +            AppLaunchLogJournalTimecard = 0x190,
   4.491 +            AppLaunchCheckbookFinance = 0x191,
   4.492 +            AppLaunchCalculator = 0x192,
   4.493 +            AppLaunchAVCapturePlayback = 0x193,
   4.494 +            AppLaunchLocalMachineBrowser = 0x194,
   4.495 +            AppLaunchLanWanBrowser = 0x195,
   4.496 +            AppLaunchInternetBrowser = 0x196,
   4.497 +            AppLaunchRemoteNetworkingIspConnect = 0x197,
   4.498 +            AppLaunchNetworkConference = 0x198,
   4.499 +            AppLaunchNetworkChat = 0x199,
   4.500 +            AppLaunchTelephonyDialer = 0x19A,
   4.501 +            AppLaunchLogon = 0x19B,
   4.502 +            AppLaunchLogoff = 0x19C,
   4.503 +            AppLaunchLogonLogoff = 0x19D,
   4.504 +            AppLaunchTerminalLockScreensaver = 0x19E,
   4.505 +            AppLaunchControlPanel = 0x19F,
   4.506 +            AppLaunchCommandLineProcessorRun = 0x1A0,
   4.507 +            AppLaunchProcessTaskManager = 0x1A1,
   4.508 +            AppLaunchSelectTaskApplication = 0x1A2,
   4.509 +            AppLaunchNextTaskApplication = 0x1A3,
   4.510 +            AppLaunchPreviousTaskApplication = 0x1A4,
   4.511 +            AppLaunchPreemptiveHaltTaskApplication = 0x1A5,
   4.512 +            AppLaunchIntegratedHelpCenter = 0x1A6,
   4.513 +            AppLaunchDocuments = 0x1A7,
   4.514 +            AppLaunchThesaurus = 0x1A8,
   4.515 +            AppLaunchDictionary = 0x1A9,
   4.516 +            AppLaunchDesktop = 0x1AA,
   4.517 +            AppLaunchSpellCheck = 0x1AB,
   4.518 +            AppLaunchGrammarCheck = 0x1AC,
   4.519 +            AppLaunchWirelessStatus = 0x1AD,
   4.520 +            AppLaunchKeyboardLayout = 0x1AE,
   4.521 +            AppLaunchVirusProtection = 0x1AF,
   4.522 +            AppLaunchEncryption = 0x1B0,
   4.523 +            AppLaunchScreenSaver = 0x1B1,
   4.524 +            AppLaunchAlarms = 0x1B2,
   4.525 +            AppLaunchClock = 0x1B3,
   4.526 +            AppLaunchFileBrowser = 0x1B4,
   4.527 +            AppLaunchPowerStatus = 0x1B5,
   4.528 +            AppLaunchImageBrowser = 0x1B6,
   4.529 +            AppLaunchAudioBrowser = 0x1B7,
   4.530 +            AppLaunchMovieBrowser = 0x1B8,
   4.531 +            AppLaunchDigitalRightsManager = 0x1B9,
   4.532 +            AppLaunchDigitalWallet = 0x1BA,
   4.533 +            AppLaunchInstantMessaging = 0x1BC,
   4.534 +            AppLaunchOemFeaturesTipsTutorialBrowser = 0x1BD,
   4.535 +            AppLaunchOemHelp = 0x1BE,
   4.536 +            AppLaunchOnlineCommunity = 0x1BF,
   4.537 +            AppLaunchEntertainmentContentBrowser = 0x1C0,
   4.538 +            AppLaunchOnlineShoppingBrowser = 0x1C1,
   4.539 +            AppLaunchSmartcardInformationHelp = 0x1C2,
   4.540 +            AppLaunchMarketMonitorFinanceBrowser = 0x1C3,
   4.541 +            AppLaunchCustomizedCorporateNewsBrowser = 0x1C4,
   4.542 +            AppLaunchOnlineActivityBrowser = 0x1C5,
   4.543 +            AppLaunchResearchSearchBrowser = 0x1C6,
   4.544 +            AppLaunchAudioPlayer = 0x1C7,
   4.545 +            GenericGuiApplicationControls = 0x200,
   4.546 +            AppCtrlNew = 0x201,
   4.547 +            AppCtrlOpen = 0x202,
   4.548 +            AppCtrlClose = 0x203,
   4.549 +            AppCtrlExit = 0x204,
   4.550 +            AppCtrlMaximize = 0x205,
   4.551 +            AppCtrlMinimize = 0x206,
   4.552 +            AppCtrlSave = 0x207,
   4.553 +            AppCtrlPrint = 0x208,
   4.554 +            AppCtrlProperties = 0x209,
   4.555 +            AppCtrlUndo = 0x21A,
   4.556 +            AppCtrlCopy = 0x21B,
   4.557 +            AppCtrlCut = 0x21C,
   4.558 +            AppCtrlPaste = 0x21D,
   4.559 +            AppCtrlSelectAll = 0x21E,
   4.560 +            AppCtrlFind = 0x21F,
   4.561 +            AppCtrlFindAndReplace = 0x220,
   4.562 +            AppCtrlSearch = 0x221,
   4.563 +            AppCtrlGoTo = 0x222,
   4.564 +            AppCtrlHome = 0x223,
   4.565 +            AppCtrlBack = 0x224,
   4.566 +            AppCtrlForward = 0x225,
   4.567 +            AppCtrlStop = 0x226,
   4.568 +            AppCtrlRefresh = 0x227,
   4.569 +            AppCtrlPreviousLink = 0x228,
   4.570 +            AppCtrlNextLink = 0x229,
   4.571 +            AppCtrlBookmarks = 0x22A,
   4.572 +            AppCtrlHistory = 0x22B,
   4.573 +            AppCtrlSubscriptions = 0x22C,
   4.574 +            AppCtrlZoomIn = 0x22D,
   4.575 +            AppCtrlZoomOut = 0x22E,
   4.576 +            AppCtrlZoom = 0x22F,
   4.577 +            AppCtrlFullScreenView = 0x230,
   4.578 +            AppCtrlNormalView = 0x231,
   4.579 +            AppCtrlViewToggle = 0x232,
   4.580 +            AppCtrlScrollUp = 0x233,
   4.581 +            AppCtrlScrollDown = 0x234,
   4.582 +            AppCtrlScroll = 0x235,
   4.583 +            AppCtrlPanLeft = 0x236,
   4.584 +            AppCtrlPanRight = 0x237,
   4.585 +            AppCtrlPan = 0x238,
   4.586 +            AppCtrlNewWindow = 0x239,
   4.587 +            AppCtrlTileHorizontally = 0x23A,
   4.588 +            AppCtrlTileVertically = 0x23B,
   4.589 +            AppCtrlFormat = 0x23C,
   4.590 +            AppCtrlEdit = 0x23D,
   4.591 +            AppCtrlBold = 0x23E,
   4.592 +            AppCtrlItalics = 0x23F,
   4.593 +            AppCtrlUnderline = 0x240,
   4.594 +            AppCtrlStrikethrough = 0x241,
   4.595 +            AppCtrlSubscript = 0x242,
   4.596 +            AppCtrlSuperscript = 0x243,
   4.597 +            AppCtrlAllCaps = 0x244,
   4.598 +            AppCtrlRotate = 0x245,
   4.599 +            AppCtrlResize = 0x246,
   4.600 +            AppCtrlFlipHorizontal = 0x247,
   4.601 +            AppCtrlFlipVertical = 0x248,
   4.602 +            AppCtrlMirrorHorizontal = 0x249,
   4.603 +            AppCtrlMirrorVertical = 0x24A,
   4.604 +            AppCtrlFontSelect = 0x24B,
   4.605 +            AppCtrlFontColor = 0x24C,
   4.606 +            AppCtrlFontSize = 0x24D,
   4.607 +            AppCtrlJustifyLeft = 0x24E,
   4.608 +            AppCtrlJustifyCenterH = 0x24F,
   4.609 +            AppCtrlJustifyRight = 0x250,
   4.610 +            AppCtrlJustifyBlockH = 0x251,
   4.611 +            AppCtrlJustifyTop = 0x252,
   4.612 +            AppCtrlJustifyCenterV = 0x253,
   4.613 +            AppCtrlJustifyBottom = 0x254,
   4.614 +            AppCtrlJustifyBlockV = 0x255,
   4.615 +            AppCtrlIndentDecrease = 0x256,
   4.616 +            AppCtrlIndentIncrease = 0x257,
   4.617 +            AppCtrlNumberedList = 0x258,
   4.618 +            AppCtrlRestartNumbering = 0x259,
   4.619 +            AppCtrlBulletedList = 0x25A,
   4.620 +            AppCtrlPromote = 0x25B,
   4.621 +            AppCtrlDemote = 0x25C,
   4.622 +            AppCtrlYes = 0x25D,
   4.623 +            AppCtrlNo = 0x25E,
   4.624 +            AppCtrlCancel = 0x25F,
   4.625 +            AppCtrlCatalog = 0x260,
   4.626 +            AppCtrlBuyCheckout = 0x261,
   4.627 +            AppCtrlAddToCart = 0x262,
   4.628 +            AppCtrlExpand = 0x263,
   4.629 +            AppCtrlExpandAll = 0x264,
   4.630 +            AppCtrlCollapse = 0x265,
   4.631 +            AppCtrlCollapseAll = 0x266,
   4.632 +            AppCtrlPrintPreview = 0x267,
   4.633 +            AppCtrlPasteSpecial = 0x268,
   4.634 +            AppCtrlInsertMode = 0x269,
   4.635 +            AppCtrlDelete = 0x26A,
   4.636 +            AppCtrlLock = 0x26B,
   4.637 +            AppCtrlUnlock = 0x26C,
   4.638 +            AppCtrlProtect = 0x26D,
   4.639 +            AppCtrlUnprotect = 0x26E,
   4.640 +            AppCtrlAttachComment = 0x26F,
   4.641 +            AppCtrlDeleteComment = 0x270,
   4.642 +            AppCtrlViewComment = 0x271,
   4.643 +            AppCtrlSelectWord = 0x272,
   4.644 +            AppCtrlSelectSentence = 0x273,
   4.645 +            AppCtrlSelectParagraph = 0x274,
   4.646 +            AppCtrlSelectColumn = 0x275,
   4.647 +            AppCtrlSelectRow = 0x276,
   4.648 +            AppCtrlSelectTable = 0x277,
   4.649 +            AppCtrlSelectObject = 0x278,
   4.650 +            AppCtrlRedoRepeat = 0x279,
   4.651 +            AppCtrlSort = 0x27A,
   4.652 +            AppCtrlSortAscending = 0x27B,
   4.653 +            AppCtrlSortDescending = 0x27C,
   4.654 +            AppCtrlFilter = 0x27D,
   4.655 +            AppCtrlSetClock = 0x27E,
   4.656 +            AppCtrlViewClock = 0x27F,
   4.657 +            AppCtrlSelectTimeZone = 0x280,
   4.658 +            AppCtrlEditTimeZones = 0x281,
   4.659 +            AppCtrlSetAlarm = 0x282,
   4.660 +            AppCtrlClearAlarm = 0x283,
   4.661 +            AppCtrlSnoozeAlarm = 0x284,
   4.662 +            AppCtrlResetAlarm = 0x285,
   4.663 +            AppCtrlSynchronize = 0x286,
   4.664 +            AppCtrlSendReceive = 0x287,
   4.665 +            AppCtrlSendTo = 0x288,
   4.666 +            AppCtrlReply = 0x289,
   4.667 +            AppCtrlReplyAll = 0x28A,
   4.668 +            AppCtrlForwardMsg = 0x28B,
   4.669 +            AppCtrlSend = 0x28C,
   4.670 +            AppCtrlAttachFile = 0x28D,
   4.671 +            AppCtrlUpload = 0x28E,
   4.672 +            AppCtrlDownloadSaveTargetAs = 0x28F,
   4.673 +            AppCtrlSetBorders = 0x290,
   4.674 +            AppCtrlInsertRow = 0x291,
   4.675 +            AppCtrlInsertColumn = 0x292,
   4.676 +            AppCtrlInsertFile = 0x293,
   4.677 +            AppCtrlInsertPicture = 0x294,
   4.678 +            AppCtrlInsertObject = 0x295,
   4.679 +            AppCtrlInsertSymbol = 0x296,
   4.680 +            AppCtrlSaveAndClose = 0x297,
   4.681 +            AppCtrlRename = 0x298,
   4.682 +            AppCtrlMerge = 0x299,
   4.683 +            AppCtrlSplit = 0x29A,
   4.684 +            AppCtrlDistributeHorizontally = 0x29B,
   4.685 +            AppCtrlDistributeVertically = 0x29C
   4.686 +        }
   4.687 +
   4.688 +        /// <summary>
   4.689 +        ///
   4.690 +        /// </summary>
   4.691 +        enum GenericDesktop : ushort
   4.692 +        {
   4.693 +            Null = 0x00,
   4.694 +            Pointer = 0x01,
   4.695 +            Mouse = 0x02,
   4.696 +            Joystick = 0x04,
   4.697 +            GamePad = 0x05,
   4.698 +            Keyboard = 0x06,
   4.699 +            Keypad = 0x07,
   4.700 +            MultiAxisController = 0x08,
   4.701 +            TabletPcSystemControls = 0x09,
   4.702 +            X = 0x30,
   4.703 +            Y = 0x31,
   4.704 +            Z = 0x32,
   4.705 +            Rx = 0x33,
   4.706 +            Ry = 0x34,
   4.707 +            Rz = 0x35,
   4.708 +            Slider = 0x36,
   4.709 +            Dial = 0x37,
   4.710 +            Wheel = 0x38,
   4.711 +            HatSwitch = 0x39,
   4.712 +            CountedBuffer = 0x3A,
   4.713 +            ByteCount = 0x3B,
   4.714 +            MotionWakeup = 0x3C,
   4.715 +            Start = 0x3D,
   4.716 +            Select = 0x3E,
   4.717 +            Vx = 0x40,
   4.718 +            Vy = 0x41,
   4.719 +            Vz = 0x42,
   4.720 +            Vbrx = 0x43,
   4.721 +            Vbry = 0x44,
   4.722 +            Vbrz = 0x45,
   4.723 +            Vno = 0x46,
   4.724 +            SystemControl = 0x80,
   4.725 +            SystemPowerDown = 0x81,
   4.726 +            SystemSleep = 0x82,
   4.727 +            SystemWakeUp = 0x83,
   4.728 +            SystemContextMenu = 0x84,
   4.729 +            SystemMainMenu = 0x85,
   4.730 +            SystemAppMenu = 0x86,
   4.731 +            SystemMenuHelp = 0x87,
   4.732 +            SystemMenuExit = 0x88,
   4.733 +            SystemMenuSelect = 0x89,
   4.734 +            SystemMenuRight = 0x8A,
   4.735 +            SystemMenuLeft = 0x8B,
   4.736 +            SystemMenuUp = 0x8C,
   4.737 +            SystemMenuDown = 0x8D,
   4.738 +            SystemColdRestart = 0x8E,
   4.739 +            SystemWarmRestart = 0x8F,
   4.740 +            DPadUp = 0x90,
   4.741 +            DPadDown = 0x91,
   4.742 +            DPadRight = 0x92,
   4.743 +            DPadLeft = 0x93,
   4.744 +            SystemDock = 0xA0,
   4.745 +            SystemUndock = 0xA1,
   4.746 +            SystemSetup = 0xA2,
   4.747 +            SystemBreak = 0xA3,
   4.748 +            SystemDebuggerBreak = 0xA4,
   4.749 +            ApplicationBreak = 0xA5,
   4.750 +            ApplicationDebuggerBreak = 0xA6,
   4.751 +            SystemSpeakerMute = 0xA7,
   4.752 +            SystemHibernate = 0xA8,
   4.753 +            SystemDisplayInvert = 0xB0,
   4.754 +            SystemDisplayInternal = 0xB1,
   4.755 +            SystemDisplayExternal = 0xB2,
   4.756 +            SystemDisplayBoth = 0xB3,
   4.757 +            SystemDisplayDual = 0xB4,
   4.758 +            SystemDisplayToggleIntExt = 0xB5,
   4.759 +            SystemDisplaySwapPrimarySecondary = 0xB6,
   4.760 +            SystemDisplayLcdAutoscale = 0xB7
   4.761 +        }
   4.762 +
   4.763 +        /// <summary>
   4.764 +        ///
   4.765 +        /// </summary>
   4.766 +        enum SimulationControl : ushort
   4.767 +        {
   4.768 +            Null = 0x00,
   4.769 +            FlightSimulationDevice = 0x01,
   4.770 +            AutomobileSimulationDevice = 0x02,
   4.771 +            TankSimulationDevice = 0x03,
   4.772 +            SpaceshipSimulationDevice = 0x04,
   4.773 +            SubmarineSimulationDevice = 0x05,
   4.774 +            SailingSimulationDevice = 0x06,
   4.775 +            MotorcycleSimulationDevice = 0x07,
   4.776 +            SportsSimulationDevice = 0x08,
   4.777 +            AirplaneSimulationDevice = 0x09,
   4.778 +            HelicopterSimulationDevice = 0x0A,
   4.779 +            MagicCarpetSimulationDevice = 0x0B,
   4.780 +            BicycleSimulationDevice = 0x0C,
   4.781 +            FlightControlStick = 0x20,
   4.782 +            FlightStick = 0x21,
   4.783 +            CyclicControl = 0x22,
   4.784 +            CyclicTrim = 0x23,
   4.785 +            FlightYoke = 0x24,
   4.786 +            TrackControl = 0x25,
   4.787 +            Aileron = 0xB0,
   4.788 +            AileronTrim = 0xB1,
   4.789 +            AntiTorqueControl = 0xB2,
   4.790 +            AutopilotEnable = 0xB3,
   4.791 +            ChaffRelease = 0xB4,
   4.792 +            CollectiveControl = 0xB5,
   4.793 +            DiveBrake = 0xB6,
   4.794 +            ElectronicCountermeasures = 0xB7,
   4.795 +            Elevator = 0xB8,
   4.796 +            ElevatorTrim = 0xB9,
   4.797 +            Rudder = 0xBA,
   4.798 +            Throttle = 0xBB,
   4.799 +            FlightCommunications = 0xBC,
   4.800 +            FlareRelease = 0xBD,
   4.801 +            LandingGear = 0xBE,
   4.802 +            ToeBrake = 0xBF,
   4.803 +            Trigger = 0xC0,
   4.804 +            WeaponsArm = 0xC1,
   4.805 +            WeaponsSelect = 0xC2,
   4.806 +            WingFlaps = 0xC3,
   4.807 +            Accelerator = 0xC4,
   4.808 +            Brake = 0xC5,
   4.809 +            Clutch = 0xC6,
   4.810 +            Shifter = 0xC7,
   4.811 +            Steering = 0xC8,
   4.812 +            TurretDirection = 0xC9,
   4.813 +            BarrelElevation = 0xCA,
   4.814 +            DivePlane = 0xCB,
   4.815 +            Ballast = 0xCC,
   4.816 +            BicycleCrank = 0xCD,
   4.817 +            HandleBars = 0xCE,
   4.818 +            FrontBrake = 0xCF,
   4.819 +            RearBrake = 0xD0
   4.820 +        }
   4.821 +
   4.822 +        /// <summary>
   4.823 +        ///
   4.824 +        /// </summary>
   4.825 +        enum GameControl : ushort
   4.826 +        {
   4.827 +            Null = 0x00,
   4.828 +            GameController3D = 0x01,
   4.829 +            PinballDevice = 0x02,
   4.830 +            GunDevice = 0x03,
   4.831 +            PointOfView = 0x20,
   4.832 +            TurnRightLeft = 0x21,
   4.833 +            PitchForwardBackward = 0x22,
   4.834 +            RollRightLeft = 0x23,
   4.835 +            MoveRightLeft = 0x24,
   4.836 +            MoveForwardBackward = 0x25,
   4.837 +            MoveUpDown = 0x26,
   4.838 +            LeanRightLeft = 0x27,
   4.839 +            LeanForwardBackward = 0x28,
   4.840 +            HeightOfPov = 0x29,
   4.841 +            Flipper = 0x2A,
   4.842 +            SecondaryFlipper = 0x2B,
   4.843 +            Bump = 0x2C,
   4.844 +            NewGame = 0x2D,
   4.845 +            ShootBall = 0x2E,
   4.846 +            Player = 0x2F,
   4.847 +            GunBolt = 0x30,
   4.848 +            GunClip = 0x31,
   4.849 +            GunSelector = 0x32,
   4.850 +            GunSingleShot = 0x33,
   4.851 +            GunBurst = 0x34,
   4.852 +            GunAutomatic = 0x35,
   4.853 +            GunSafety = 0x36,
   4.854 +            GamepadFireJump = 0x37,
   4.855 +            GamepadTrigger = 0x39
   4.856 +        }
   4.857 +
   4.858 +        /// <summary>
   4.859 +        ///
   4.860 +        /// </summary>
   4.861 +        enum TelephonyDevice : ushort
   4.862 +        {
   4.863 +            Null = 0x00,
   4.864 +            Phone = 0x01,
   4.865 +            AnsweringMachine = 0x02,
   4.866 +            MessageControls = 0x03,
   4.867 +            Handset = 0x04,
   4.868 +            Headset = 0x05,
   4.869 +            TelephonyKeyPad = 0x06,
   4.870 +            ProgrammableButton = 0x07,
   4.871 +            HookSwitch = 0x20,
   4.872 +            Flash = 0x21,
   4.873 +            Feature = 0x22,
   4.874 +            Hold = 0x23,
   4.875 +            Redial = 0x24,
   4.876 +            Transfer = 0x25,
   4.877 +            Drop = 0x26,
   4.878 +            Park = 0x27,
   4.879 +            ForwardCalls = 0x28,
   4.880 +            AlternateFunction = 0x29,
   4.881 +            Line = 0x2A,
   4.882 +            SpeakerPhone = 0x2B,
   4.883 +            Conference = 0x2C,
   4.884 +            RingEnable = 0x2D,
   4.885 +            RingSelect = 0x2E,
   4.886 +            PhoneMute = 0x2F,
   4.887 +            CallerId = 0x30,
   4.888 +            Send = 0x31,
   4.889 +            SpeedDial = 0x50,
   4.890 +            StoreNumber = 0x51,
   4.891 +            RecallNumber = 0x52,
   4.892 +            PhoneDirectory = 0x53,
   4.893 +            VoiceMail = 0x70,
   4.894 +            ScreenCalls = 0x71,
   4.895 +            DoNotDisturb = 0x72,
   4.896 +            Message = 0x73,
   4.897 +            AnswerOnOff = 0x74,
   4.898 +            InsideDialTone = 0x90,
   4.899 +            OutsideDialTone = 0x91,
   4.900 +            InsideRingTone = 0x92,
   4.901 +            OutsideRingTone = 0x93,
   4.902 +            PriorityRingTone = 0x94,
   4.903 +            InsideRingback = 0x95,
   4.904 +            PriorityRingback = 0x96,
   4.905 +            LineBusyTone = 0x97,
   4.906 +            ReorderTone = 0x98,
   4.907 +            CallWaitingTone = 0x99,
   4.908 +            ConfirmationTone1 = 0x9A,
   4.909 +            ConfirmationTone2 = 0x9B,
   4.910 +            TonesOff = 0x9C,
   4.911 +            OutsideRingback = 0x9D,
   4.912 +            Ringer = 0x9E,
   4.913 +            PhoneKey0 = 0xB0,
   4.914 +            PhoneKey1 = 0xB1,
   4.915 +            PhoneKey2 = 0xB2,
   4.916 +            PhoneKey3 = 0xB3,
   4.917 +            PhoneKey4 = 0xB4,
   4.918 +            PhoneKey5 = 0xB5,
   4.919 +            PhoneKey6 = 0xB6,
   4.920 +            PhoneKey7 = 0xB7,
   4.921 +            PhoneKey8 = 0xB8,
   4.922 +            PhoneKey9 = 0xB9,
   4.923 +            PhoneKeyStar = 0xBA,
   4.924 +            PhoneKeyPound = 0xBB,
   4.925 +            PhoneKeyA = 0xBC,
   4.926 +            PhoneKeyB = 0xBD,
   4.927 +            PhoneKeyC = 0xBE,
   4.928 +            PhoneKeyD = 0xBF
   4.929 +        }
   4.930 +    }
   4.931 +}
   4.932 \ No newline at end of file
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/Hid/HidUtils.cs	Sun Mar 15 20:25:58 2015 +0100
     5.3 @@ -0,0 +1,84 @@
     5.4 +//
     5.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
     5.6 +//
     5.7 +// This file is part of SharpLibHid.
     5.8 +//
     5.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
    5.10 +// it under the terms of the GNU General Public License as published by
    5.11 +// the Free Software Foundation, either version 3 of the License, or
    5.12 +// (at your option) any later version.
    5.13 +//
    5.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
    5.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.17 +// GNU General Public License for more details.
    5.18 +//
    5.19 +// You should have received a copy of the GNU General Public License
    5.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    5.21 +//
    5.22 +
    5.23 +using System;
    5.24 +using System.Collections.Generic;
    5.25 +using System.Text;
    5.26 +
    5.27 +namespace SharpLib.Hid
    5.28 +{
    5.29 +    static class Utils
    5.30 +    {
    5.31 +        /// <summary>
    5.32 +        /// Provide the type for the usage collection corresponding to the given usage page.
    5.33 +        /// </summary>
    5.34 +        /// <param name="aUsagePage"></param>
    5.35 +        /// <returns></returns>
    5.36 +        public static Type UsageCollectionType(UsagePage aUsagePage)
    5.37 +        {
    5.38 +            switch (aUsagePage)
    5.39 +            {
    5.40 +                case UsagePage.GenericDesktopControls:
    5.41 +                    return typeof(UsageCollection.GenericDesktop);
    5.42 +
    5.43 +                case UsagePage.Consumer:
    5.44 +                    return typeof(UsageCollection.Consumer);
    5.45 +
    5.46 +                case UsagePage.WindowsMediaCenterRemoteControl:
    5.47 +                    return typeof(UsageCollection.WindowsMediaCenter);
    5.48 +
    5.49 +                default:
    5.50 +                    return null;
    5.51 +            }
    5.52 +        }
    5.53 +
    5.54 +        /// <summary>
    5.55 +        /// Provide the type for the usage corresponding to the given usage page.
    5.56 +        /// </summary>
    5.57 +        /// <param name="aUsagePage"></param>
    5.58 +        /// <returns></returns>
    5.59 +        public static Type UsageType(UsagePage aUsagePage)
    5.60 +        {
    5.61 +            switch (aUsagePage)
    5.62 +            {
    5.63 +                case UsagePage.GenericDesktopControls:
    5.64 +                    return typeof(Usage.GenericDesktop);
    5.65 +
    5.66 +                case UsagePage.Consumer:
    5.67 +                    return typeof(Usage.ConsumerControl);
    5.68 +
    5.69 +                case UsagePage.WindowsMediaCenterRemoteControl:
    5.70 +                    return typeof(Usage.WindowsMediaCenterRemoteControl);
    5.71 +
    5.72 +                case UsagePage.Telephony:
    5.73 +                    return typeof(Usage.TelephonyDevice);
    5.74 +
    5.75 +                case UsagePage.SimulationControls:
    5.76 +                    return typeof(Usage.SimulationControl);
    5.77 +
    5.78 +                case UsagePage.GameControls:
    5.79 +                    return typeof(Usage.GameControl);
    5.80 +
    5.81 +                default:
    5.82 +                    return null;
    5.83 +            }
    5.84 +        }
    5.85 +
    5.86 +    }
    5.87 +}
     6.1 --- a/HidDevice.cs	Sun Mar 15 16:56:31 2015 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,372 +0,0 @@
     6.4 -//
     6.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
     6.6 -//
     6.7 -// This file is part of SharpLibHid.
     6.8 -//
     6.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
    6.10 -// it under the terms of the GNU General Public License as published by
    6.11 -// the Free Software Foundation, either version 3 of the License, or
    6.12 -// (at your option) any later version.
    6.13 -//
    6.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
    6.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.17 -// GNU General Public License for more details.
    6.18 -//
    6.19 -// You should have received a copy of the GNU General Public License
    6.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    6.21 -//
    6.22 -
    6.23 -
    6.24 -using System;
    6.25 -using System.Windows.Forms;
    6.26 -using System.Runtime.InteropServices;
    6.27 -using System.Diagnostics;
    6.28 -using System.Text;
    6.29 -using Microsoft.Win32.SafeHandles;
    6.30 -using SharpLib.Win32;
    6.31 -
    6.32 -namespace SharpLib.Hid
    6.33 -{
    6.34 -    /// <summary>
    6.35 -    /// Represent a HID device.
    6.36 -    /// Rename to RawInputDevice?
    6.37 -    /// </summary>
    6.38 -    public class HidDevice: IDisposable
    6.39 -    {
    6.40 -        /// <summary>
    6.41 -        /// Unique name of that HID device.
    6.42 -        /// Notably used as input to CreateFile.
    6.43 -        /// </summary>
    6.44 -        public string Name { get; private set; }
    6.45 -
    6.46 -        /// <summary>
    6.47 -        /// Friendly name that people should be able to read.
    6.48 -        /// </summary>
    6.49 -        public string FriendlyName { get; private set; }
    6.50 -
    6.51 -        //
    6.52 -        public string Manufacturer { get; private set; }
    6.53 -        public string Product { get; private set; }
    6.54 -        public ushort VendorId { get; private set; }
    6.55 -        public ushort ProductId { get; private set; }
    6.56 -        public ushort Version { get; private set; }
    6.57 -        //Pre-parsed HID descriptor
    6.58 -        public IntPtr PreParsedData {get; private set;}
    6.59 -        //Info
    6.60 -        public RID_DEVICE_INFO Info { get {return iInfo;} }
    6.61 -        private RID_DEVICE_INFO iInfo;
    6.62 -        //Capabilities
    6.63 -        public HIDP_CAPS Capabilities { get { return iCapabilities; } }
    6.64 -        private HIDP_CAPS iCapabilities;
    6.65 -        public string InputCapabilitiesDescription { get; private set; }
    6.66 -        //Input Button Capabilities
    6.67 -        public HIDP_BUTTON_CAPS[] InputButtonCapabilities { get { return iInputButtonCapabilities; } }
    6.68 -        private HIDP_BUTTON_CAPS[] iInputButtonCapabilities;
    6.69 -        //Input Value Capabilities
    6.70 -        public HIDP_VALUE_CAPS[] InputValueCapabilities { get { return iInputValueCapabilities; } }
    6.71 -        private HIDP_VALUE_CAPS[] iInputValueCapabilities;
    6.72 -
    6.73 -        //
    6.74 -        public int ButtonCount { get; private set; }
    6.75 -
    6.76 -        /// <summary>
    6.77 -        /// Class constructor will fetch this object properties from HID sub system.
    6.78 -        /// </summary>
    6.79 -        /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
    6.80 -        public HidDevice(IntPtr hRawInputDevice)
    6.81 -        {
    6.82 -            //Try construct and rollback if needed
    6.83 -            try
    6.84 -            {
    6.85 -                Construct(hRawInputDevice);
    6.86 -            }
    6.87 -            catch (System.Exception ex)
    6.88 -            {
    6.89 -                //Just rollback and propagate
    6.90 -                Dispose();
    6.91 -                throw ex;
    6.92 -            }
    6.93 -        }
    6.94 -
    6.95 -
    6.96 -        /// <summary>
    6.97 -        /// Make sure dispose is called even if the user forgot about it.
    6.98 -        /// </summary>
    6.99 -        ~HidDevice()
   6.100 -        {
   6.101 -            Dispose();
   6.102 -        }
   6.103 -
   6.104 -        /// <summary>
   6.105 -        /// Private constructor.
   6.106 -        /// </summary>
   6.107 -        /// <param name="hRawInputDevice"></param>
   6.108 -        private void Construct(IntPtr hRawInputDevice)
   6.109 -        {
   6.110 -            PreParsedData = IntPtr.Zero;
   6.111 -            iInputButtonCapabilities = null;
   6.112 -            iInputValueCapabilities = null;
   6.113 -
   6.114 -            //Fetch various information defining the given HID device
   6.115 -            Name = Win32.RawInput.GetDeviceName(hRawInputDevice);
   6.116 -
   6.117 -            //Fetch device info
   6.118 -            iInfo = new RID_DEVICE_INFO();
   6.119 -            if (!Win32.RawInput.GetDeviceInfo(hRawInputDevice, ref iInfo))
   6.120 -            {
   6.121 -                throw new Exception("HidDevice: GetDeviceInfo failed: " + Marshal.GetLastWin32Error().ToString());
   6.122 -            }
   6.123 -
   6.124 -            //Open our device from the device name/path
   6.125 -            SafeFileHandle handle = Win32.Function.CreateFile(Name,
   6.126 -                Win32.FileAccess.NONE,
   6.127 -                Win32.FileShare.FILE_SHARE_READ | Win32.FileShare.FILE_SHARE_WRITE,
   6.128 -                IntPtr.Zero,
   6.129 -                Win32.CreationDisposition.OPEN_EXISTING,
   6.130 -                Win32.FileFlagsAttributes.FILE_FLAG_OVERLAPPED,
   6.131 -                IntPtr.Zero
   6.132 -                );
   6.133 -
   6.134 -            //Check if CreateFile worked
   6.135 -            if (handle.IsInvalid)
   6.136 -            {
   6.137 -                throw new Exception("HidDevice: CreateFile failed: " + Marshal.GetLastWin32Error().ToString());
   6.138 -            }
   6.139 -
   6.140 -            //Get manufacturer string
   6.141 -            StringBuilder manufacturerString = new StringBuilder(256);
   6.142 -            if (Win32.Function.HidD_GetManufacturerString(handle, manufacturerString, manufacturerString.Capacity))
   6.143 -            {
   6.144 -                Manufacturer = manufacturerString.ToString();
   6.145 -            }
   6.146 -
   6.147 -            //Get product string
   6.148 -            StringBuilder productString = new StringBuilder(256);
   6.149 -            if (Win32.Function.HidD_GetProductString(handle, productString, productString.Capacity))
   6.150 -            {
   6.151 -                Product = productString.ToString();
   6.152 -            }
   6.153 -
   6.154 -            //Get attributes
   6.155 -            Win32.HIDD_ATTRIBUTES attributes = new Win32.HIDD_ATTRIBUTES();
   6.156 -            if (Win32.Function.HidD_GetAttributes(handle, ref attributes))
   6.157 -            {
   6.158 -                VendorId = attributes.VendorID;
   6.159 -                ProductId = attributes.ProductID;
   6.160 -                Version = attributes.VersionNumber;
   6.161 -            }
   6.162 -
   6.163 -            handle.Close();
   6.164 -
   6.165 -            SetFriendlyName();            
   6.166 -
   6.167 -            //Get our HID descriptor pre-parsed data
   6.168 -            PreParsedData = Win32.RawInput.GetPreParsedData(hRawInputDevice);
   6.169 -
   6.170 -            if (PreParsedData == IntPtr.Zero)
   6.171 -            {
   6.172 -                //We are done then.
   6.173 -                //Some devices don't have pre-parsed data.
   6.174 -                return;
   6.175 -            }
   6.176 -
   6.177 -            //Get capabilities
   6.178 -            HidStatus status = Win32.Function.HidP_GetCaps(PreParsedData, ref iCapabilities);
   6.179 -            if (status != HidStatus.HIDP_STATUS_SUCCESS)
   6.180 -            {
   6.181 -                throw new Exception("HidDevice: HidP_GetCaps failed: " + status.ToString());
   6.182 -            }
   6.183 -
   6.184 -            SetInputCapabilitiesDescription();
   6.185 -
   6.186 -            //Get input button caps if needed
   6.187 -            if (Capabilities.NumberInputButtonCaps > 0)
   6.188 -            {
   6.189 -                iInputButtonCapabilities = new HIDP_BUTTON_CAPS[Capabilities.NumberInputButtonCaps];
   6.190 -                ushort buttonCapabilitiesLength = Capabilities.NumberInputButtonCaps;
   6.191 -                status = Win32.Function.HidP_GetButtonCaps(HIDP_REPORT_TYPE.HidP_Input, iInputButtonCapabilities, ref buttonCapabilitiesLength, PreParsedData);
   6.192 -                if (status != HidStatus.HIDP_STATUS_SUCCESS || buttonCapabilitiesLength != Capabilities.NumberInputButtonCaps)
   6.193 -                {
   6.194 -                    throw new Exception("HidDevice: HidP_GetButtonCaps failed: " + status.ToString());
   6.195 -                }
   6.196 -
   6.197 -                ComputeButtonCount();
   6.198 -            }
   6.199 -
   6.200 -            //Get input value caps if needed
   6.201 -            if (Capabilities.NumberInputValueCaps > 0)
   6.202 -            {
   6.203 -                iInputValueCapabilities = new HIDP_VALUE_CAPS[Capabilities.NumberInputValueCaps];
   6.204 -                ushort valueCapabilitiesLength = Capabilities.NumberInputValueCaps;
   6.205 -                status = Win32.Function.HidP_GetValueCaps(HIDP_REPORT_TYPE.HidP_Input, iInputValueCapabilities, ref valueCapabilitiesLength, PreParsedData);
   6.206 -                if (status != HidStatus.HIDP_STATUS_SUCCESS || valueCapabilitiesLength != Capabilities.NumberInputValueCaps)
   6.207 -                {
   6.208 -                    throw new Exception("HidDevice: HidP_GetValueCaps failed: " + status.ToString());
   6.209 -                }
   6.210 -            }
   6.211 -        }
   6.212 -
   6.213 -
   6.214 -        /// <summary>
   6.215 -        /// Useful for gamepads.
   6.216 -        /// </summary>
   6.217 -        void ComputeButtonCount()
   6.218 -        {
   6.219 -            ButtonCount = 0;
   6.220 -            foreach (HIDP_BUTTON_CAPS bc in iInputButtonCapabilities)
   6.221 -            {
   6.222 -                if (bc.IsRange)
   6.223 -                {
   6.224 -                    ButtonCount += (bc.Range.UsageMax - bc.Range.UsageMin + 1);
   6.225 -                }
   6.226 -            }            
   6.227 -        }
   6.228 -
   6.229 -
   6.230 -        /// <summary>
   6.231 -        /// 
   6.232 -        /// </summary>
   6.233 -        void SetInputCapabilitiesDescription()
   6.234 -        {
   6.235 -            InputCapabilitiesDescription = "[ Input Capabilities ] Button: " + Capabilities.NumberInputButtonCaps + " - Value: " + Capabilities.NumberInputValueCaps + " - Data indices: " + Capabilities.NumberInputDataIndices;
   6.236 -        }
   6.237 -
   6.238 -        /// <summary>
   6.239 -        /// 
   6.240 -        /// </summary>
   6.241 -        private void SetFriendlyName()
   6.242 -        {
   6.243 -            //Work out proper suffix for our device root node.
   6.244 -            //That allows users to see in a glance what kind of device this is.
   6.245 -            string suffix = "";
   6.246 -            Type usageCollectionType = null;
   6.247 -            if (Info.dwType == RawInputDeviceType.RIM_TYPEHID)
   6.248 -            {
   6.249 -                //Process usage page
   6.250 -                if (Enum.IsDefined(typeof(UsagePage), Info.hid.usUsagePage))
   6.251 -                {
   6.252 -                    //We know this usage page, add its name
   6.253 -                    UsagePage usagePage = (UsagePage)Info.hid.usUsagePage;
   6.254 -                    suffix += " ( " + usagePage.ToString() + ", ";
   6.255 -                    usageCollectionType = Utils.UsageCollectionType(usagePage);
   6.256 -                }
   6.257 -                else
   6.258 -                {
   6.259 -                    //We don't know this usage page, add its value
   6.260 -                    suffix += " ( 0x" + Info.hid.usUsagePage.ToString("X4") + ", ";
   6.261 -                }
   6.262 -
   6.263 -                //Process usage collection
   6.264 -                //We don't know this usage page, add its value
   6.265 -                if (usageCollectionType == null || !Enum.IsDefined(usageCollectionType, Info.hid.usUsage))
   6.266 -                {
   6.267 -                    //Show Hexa
   6.268 -                    suffix += "0x" + Info.hid.usUsage.ToString("X4") + " )";
   6.269 -                }
   6.270 -                else
   6.271 -                {
   6.272 -                    //We know this usage page, add its name
   6.273 -                    suffix += Enum.GetName(usageCollectionType, Info.hid.usUsage) + " )";
   6.274 -                }
   6.275 -            }
   6.276 -            else if (Info.dwType == RawInputDeviceType.RIM_TYPEKEYBOARD)
   6.277 -            {
   6.278 -                suffix = " - Keyboard";
   6.279 -            }
   6.280 -            else if (Info.dwType == RawInputDeviceType.RIM_TYPEMOUSE)
   6.281 -            {
   6.282 -                suffix = " - Mouse";
   6.283 -            }
   6.284 -
   6.285 -            if (Product != null && Product.Length > 1)
   6.286 -            {
   6.287 -                //This device as a proper name, use it
   6.288 -                FriendlyName = Product + suffix;
   6.289 -            }
   6.290 -            else
   6.291 -            {   
   6.292 -                //Extract friendly name from name
   6.293 -                char[] delimiterChars = { '#', '&'};
   6.294 -                string[] words = Name.Split(delimiterChars);
   6.295 -                if (words.Length >= 2)
   6.296 -                {
   6.297 -                    //Use our name sub-string to describe this device
   6.298 -                    FriendlyName = words[1] + " - 0x" + ProductId.ToString("X4") + suffix;
   6.299 -                }
   6.300 -                else
   6.301 -                {
   6.302 -                    //No proper name just use the device ID instead
   6.303 -                    FriendlyName = "0x" + ProductId.ToString("X4") + suffix;
   6.304 -                }
   6.305 -            }
   6.306 -
   6.307 -        }
   6.308 -
   6.309 -        /// <summary>
   6.310 -        /// Dispose is just for unmanaged clean-up.
   6.311 -        /// Make sure calling disposed multiple times does not crash.
   6.312 -        /// See: http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface/538238#538238
   6.313 -        /// </summary>
   6.314 -        public void Dispose()
   6.315 -        {
   6.316 -            Marshal.FreeHGlobal(PreParsedData);
   6.317 -            PreParsedData = IntPtr.Zero;
   6.318 -        }
   6.319 -
   6.320 -        /// <summary>
   6.321 -        /// Provide a description for the given capabilities.
   6.322 -        /// Notably describes axis on a gamepad/joystick.
   6.323 -        /// </summary>
   6.324 -        /// <param name="aCaps"></param>
   6.325 -        /// <returns></returns>
   6.326 -        static public string InputValueCapabilityDescription(HIDP_VALUE_CAPS aCaps)
   6.327 -        {
   6.328 -            if (!aCaps.IsRange && Enum.IsDefined(typeof(UsagePage), aCaps.UsagePage))
   6.329 -            {
   6.330 -                Type usageType = Utils.UsageType((UsagePage)aCaps.UsagePage);
   6.331 -                string name = Enum.GetName(usageType, aCaps.NotRange.Usage);
   6.332 -                if (name == null)
   6.333 -                {
   6.334 -                    //Could not find that usage in our enum.
   6.335 -                    //Provide a relevant warning instead.
   6.336 -                    name = "Usage 0x" + aCaps.NotRange.Usage.ToString("X2") + " not defined in " + usageType.Name;
   6.337 -                }
   6.338 -                else
   6.339 -                {
   6.340 -                    //Prepend our usage type name
   6.341 -                    name = usageType.Name + "." + name;
   6.342 -                }
   6.343 -                return "Input Value: " + name;
   6.344 -            }
   6.345 -
   6.346 -            return null;
   6.347 -        }
   6.348 -
   6.349 -        public bool IsGamePad
   6.350 -        {
   6.351 -            get
   6.352 -            {
   6.353 -                return ((UsagePage)iCapabilities.UsagePage == UsagePage.GenericDesktopControls && (UsageCollection.GenericDesktop)iCapabilities.Usage == UsageCollection.GenericDesktop.GamePad);
   6.354 -            }
   6.355 -        }
   6.356 -
   6.357 -
   6.358 -        /// <summary>
   6.359 -        /// Print information about this device to our debug output.
   6.360 -        /// </summary>
   6.361 -        public void DebugWrite()
   6.362 -        {
   6.363 -            Debug.WriteLine("================ HID =========================================================================================");
   6.364 -            Debug.WriteLine("==== Name: " + Name);
   6.365 -            Debug.WriteLine("==== Manufacturer: " + Manufacturer);
   6.366 -            Debug.WriteLine("==== Product: " + Product);
   6.367 -            Debug.WriteLine("==== VendorID: 0x" + VendorId.ToString("X4"));
   6.368 -            Debug.WriteLine("==== ProductID: 0x" + ProductId.ToString("X4"));
   6.369 -            Debug.WriteLine("==== Version: " + Version.ToString());
   6.370 -            Debug.WriteLine("==============================================================================================================");
   6.371 -        }
   6.372 -
   6.373 -    }
   6.374 -
   6.375 -}
   6.376 \ No newline at end of file
     7.1 --- a/HidEvent.cs	Sun Mar 15 16:56:31 2015 +0100
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,598 +0,0 @@
     7.4 -//
     7.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
     7.6 -//
     7.7 -// This file is part of SharpLibHid.
     7.8 -//
     7.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
    7.10 -// it under the terms of the GNU General Public License as published by
    7.11 -// the Free Software Foundation, either version 3 of the License, or
    7.12 -// (at your option) any later version.
    7.13 -//
    7.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
    7.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.17 -// GNU General Public License for more details.
    7.18 -//
    7.19 -// You should have received a copy of the GNU General Public License
    7.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    7.21 -//
    7.22 -
    7.23 -
    7.24 -using System;
    7.25 -using System.Windows.Forms;
    7.26 -using System.Runtime.InteropServices;
    7.27 -using System.Diagnostics;
    7.28 -using System.Text;
    7.29 -using Microsoft.Win32.SafeHandles;
    7.30 -using SharpLib.Win32;
    7.31 -using System.Collections.Generic;
    7.32 -using System.Timers;
    7.33 -using SharpLib.Hid.Usage;
    7.34 -
    7.35 -
    7.36 -namespace SharpLib.Hid
    7.37 -{
    7.38 -    /// <summary>
    7.39 -    /// We provide utility functions to interpret gamepad dpad state.
    7.40 -    /// </summary>
    7.41 -    public enum DirectionPadState
    7.42 -    {
    7.43 -        Rest=-1,
    7.44 -        Up=0,
    7.45 -        UpRight=1,
    7.46 -        Right=2,
    7.47 -        DownRight=3,
    7.48 -        Down=4,
    7.49 -        DownLeft=5,
    7.50 -        Left=6,
    7.51 -        UpLeft=7
    7.52 -    }
    7.53 -
    7.54 -    /// <summary>
    7.55 -    /// Represent a HID event.
    7.56 -    /// TODO: Rename this into HidRawInput?
    7.57 -    /// </summary>
    7.58 -    public class HidEvent : IDisposable
    7.59 -    {
    7.60 -        public bool IsValid { get; private set; }
    7.61 -        public bool IsForeground { get; private set; }
    7.62 -        public bool IsBackground { get { return !IsForeground; } }
    7.63 -        public bool IsMouse { get; private set; }
    7.64 -        public bool IsKeyboard { get; private set; }
    7.65 -        /// <summary>
    7.66 -        /// If this not a mouse or keyboard event then it's a generic HID event.
    7.67 -        /// </summary>
    7.68 -        public bool IsGeneric { get; private set; }
    7.69 -        public bool IsButtonDown { get { return Usages.Count == 1 && Usages[0] != 0; } }
    7.70 -        public bool IsButtonUp { get { return Usages.Count == 0; } }
    7.71 -        public bool IsRepeat { get { return RepeatCount != 0; } }
    7.72 -        public uint RepeatCount { get; private set; }
    7.73 -
    7.74 -        public HidDevice Device { get; private set; }
    7.75 -        public RAWINPUT RawInput { get {return iRawInput;} } 
    7.76 -        private RAWINPUT iRawInput;
    7.77 -
    7.78 -        public ushort UsagePage { get; private set; }
    7.79 -        public ushort UsageCollection { get; private set; }
    7.80 -        public uint UsageId { get { return ((uint)UsagePage << 16 | (uint)UsageCollection); } }
    7.81 -        public List<ushort> Usages { get; private set; }
    7.82 -        /// <summary>
    7.83 -        /// Sorted in the same order as Device.InputValueCapabilities.
    7.84 -        /// </summary>
    7.85 -        public Dictionary<HIDP_VALUE_CAPS,uint> UsageValues { get; private set; }
    7.86 -        //TODO: We need a collection of input report
    7.87 -        public byte[] InputReport { get; private set; }
    7.88 -        //
    7.89 -        public delegate void HidEventRepeatDelegate(HidEvent aHidEvent);
    7.90 -        public event HidEventRepeatDelegate OnHidEventRepeat;
    7.91 -
    7.92 -        private System.Timers.Timer Timer { get; set; }
    7.93 -        public DateTime Time { get; private set; }
    7.94 -        public DateTime OriginalTime { get; private set; }
    7.95 -
    7.96 -        //Compute repeat delay and speed based on system settings
    7.97 -        //Those computations were taken from the Petzold here: ftp://ftp.charlespetzold.com/ProgWinForms/4%20Custom%20Controls/NumericScan/NumericScan/ClickmaticButton.cs
    7.98 -        private int iRepeatDelay = 250 * (1 + SystemInformation.KeyboardDelay);
    7.99 -        private int iRepeatSpeed = 405 - 12 * SystemInformation.KeyboardSpeed;
   7.100 -
   7.101 -        /// <summary>
   7.102 -        /// Tells whether this event has already been disposed of.
   7.103 -        /// </summary>
   7.104 -        public bool IsStray { get { return Timer == null; } }
   7.105 -
   7.106 -        /// <summary>
   7.107 -        /// We typically dispose of events as soon as we get the corresponding key up signal.
   7.108 -        /// </summary>
   7.109 -        public void Dispose()
   7.110 -        {
   7.111 -            Timer.Enabled = false;
   7.112 -            Timer.Dispose();
   7.113 -            //Mark this event as a stray
   7.114 -            Timer = null;
   7.115 -        }
   7.116 -
   7.117 -        /// <summary>
   7.118 -        /// Initialize an HidEvent from a WM_INPUT message
   7.119 -        /// </summary>
   7.120 -        /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
   7.121 -        public HidEvent(Message aMessage, HidEventRepeatDelegate aRepeatDelegate)
   7.122 -        {
   7.123 -            RepeatCount = 0;
   7.124 -            IsValid = false;
   7.125 -            IsKeyboard = false;
   7.126 -            IsGeneric = false;
   7.127 -
   7.128 -            Time = DateTime.Now;
   7.129 -            OriginalTime = DateTime.Now;
   7.130 -            Timer = new System.Timers.Timer();
   7.131 -            Timer.Elapsed += (sender, e) => OnRepeatTimerElapsed(sender, e, this);
   7.132 -            Usages = new List<ushort>();
   7.133 -            UsageValues = new Dictionary<HIDP_VALUE_CAPS,uint>();
   7.134 -            OnHidEventRepeat += aRepeatDelegate;
   7.135 -
   7.136 -            if (aMessage.Msg != Const.WM_INPUT)
   7.137 -            {
   7.138 -                //Has to be a WM_INPUT message
   7.139 -                return;
   7.140 -            }
   7.141 -
   7.142 -            if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUT)
   7.143 -            {
   7.144 -                IsForeground = true;
   7.145 -            }
   7.146 -            else if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUTSINK)
   7.147 -            {
   7.148 -                IsForeground = false;
   7.149 -            }
   7.150 -
   7.151 -            //Declare some pointers
   7.152 -            IntPtr rawInputBuffer = IntPtr.Zero;
   7.153 -
   7.154 -            try
   7.155 -            {
   7.156 -                //Fetch raw input
   7.157 -                iRawInput = new RAWINPUT();
   7.158 -                if (!Win32.RawInput.GetRawInputData(aMessage.LParam, ref iRawInput, ref rawInputBuffer))
   7.159 -                {
   7.160 -                    Debug.WriteLine("GetRawInputData failed!");
   7.161 -                    return;
   7.162 -                }
   7.163 -
   7.164 -                //Our device can actually be null.
   7.165 -                //This is notably happening for some keyboard events
   7.166 -                if (RawInput.header.hDevice != IntPtr.Zero)
   7.167 -                {
   7.168 -                    //Get various information about this HID device
   7.169 -                    Device = new HidDevice(RawInput.header.hDevice);
   7.170 -                }
   7.171 -
   7.172 -                if (RawInput.header.dwType == Win32.RawInputDeviceType.RIM_TYPEHID)  //Check that our raw input is HID                        
   7.173 -                {
   7.174 -                    IsGeneric = true;
   7.175 -
   7.176 -                    Debug.WriteLine("WM_INPUT source device is HID.");
   7.177 -                    //Get Usage Page and Usage
   7.178 -                    //Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage ID: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
   7.179 -                    UsagePage = Device.Info.hid.usUsagePage;
   7.180 -                    UsageCollection = Device.Info.hid.usUsage;
   7.181 -
   7.182 -                    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
   7.183 -                        && RawInput.hid.dwCount > 0))    //Check that we have at least one HID msg
   7.184 -                    {
   7.185 -                        return;
   7.186 -                    }
   7.187 -
   7.188 -                    //Allocate a buffer for one HID input
   7.189 -                    InputReport = new byte[RawInput.hid.dwSizeHid];
   7.190 -
   7.191 -                    Debug.WriteLine("Raw input contains " + RawInput.hid.dwCount + " HID input report(s)");
   7.192 -
   7.193 -                    //For each HID input report in our raw input
   7.194 -                    for (int i = 0; i < RawInput.hid.dwCount; i++)
   7.195 -                    {
   7.196 -                        //Compute the address from which to copy our HID input
   7.197 -                        int hidInputOffset = 0;
   7.198 -                        unsafe
   7.199 -                        {
   7.200 -                            byte* source = (byte*)rawInputBuffer;
   7.201 -                            source += sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + (RawInput.hid.dwSizeHid * i);
   7.202 -                            hidInputOffset = (int)source;
   7.203 -                        }
   7.204 -
   7.205 -                        //Copy HID input into our buffer
   7.206 -                        Marshal.Copy(new IntPtr(hidInputOffset), InputReport, 0, (int)RawInput.hid.dwSizeHid);
   7.207 -                        //
   7.208 -                        ProcessInputReport(InputReport);
   7.209 -                    }
   7.210 -                }
   7.211 -                else if (RawInput.header.dwType == RawInputDeviceType.RIM_TYPEMOUSE)
   7.212 -                {
   7.213 -                    IsMouse = true;
   7.214 -
   7.215 -                    Debug.WriteLine("WM_INPUT source device is Mouse.");
   7.216 -                    // do mouse handling...
   7.217 -                }
   7.218 -                else if (RawInput.header.dwType == RawInputDeviceType.RIM_TYPEKEYBOARD)
   7.219 -                {
   7.220 -                    IsKeyboard = true;
   7.221 -
   7.222 -                    Debug.WriteLine("WM_INPUT source device is Keyboard.");
   7.223 -                    // do keyboard handling...
   7.224 -                    if (Device != null)
   7.225 -                    {
   7.226 -                        Debug.WriteLine("Type: " + Device.Info.keyboard.dwType.ToString());
   7.227 -                        Debug.WriteLine("SubType: " + Device.Info.keyboard.dwSubType.ToString());
   7.228 -                        Debug.WriteLine("Mode: " + Device.Info.keyboard.dwKeyboardMode.ToString());
   7.229 -                        Debug.WriteLine("Number of function keys: " + Device.Info.keyboard.dwNumberOfFunctionKeys.ToString());
   7.230 -                        Debug.WriteLine("Number of indicators: " + Device.Info.keyboard.dwNumberOfIndicators.ToString());
   7.231 -                        Debug.WriteLine("Number of keys total: " + Device.Info.keyboard.dwNumberOfKeysTotal.ToString());
   7.232 -                    }
   7.233 -                }
   7.234 -            }
   7.235 -            finally
   7.236 -            {
   7.237 -                //Always executed when leaving our try block
   7.238 -                Marshal.FreeHGlobal(rawInputBuffer);
   7.239 -            }
   7.240 -
   7.241 -            //
   7.242 -            if (IsButtonDown)
   7.243 -            {
   7.244 -                //TODO: Make this optional
   7.245 -                //StartRepeatTimer(iRepeatDelay);
   7.246 -            }
   7.247 -
   7.248 -            IsValid = true;
   7.249 -        }
   7.250 -
   7.251 -        /// <summary>
   7.252 -        /// 
   7.253 -        /// </summary>
   7.254 -        private void ProcessInputReport(byte[] aInputReport)
   7.255 -        {
   7.256 -            //Print HID input report in our debug output
   7.257 -            //string hidDump = "HID input report: " + InputReportString();
   7.258 -            //Debug.WriteLine(hidDump);
   7.259 -
   7.260 -            //Get all our usages, those are typically the buttons currently pushed on a gamepad.
   7.261 -            //For a remote control it's usually just the one button that was pushed.
   7.262 -            GetUsages(aInputReport);
   7.263 -
   7.264 -            //Now process direction pad (d-pad, dpad) and axes
   7.265 -            GetUsageValues(aInputReport);
   7.266 -        }
   7.267 -
   7.268 -        /// <summary>
   7.269 -        /// Typically fetches values of a joystick/gamepad axis and dpad directions.
   7.270 -        /// </summary>
   7.271 -        /// <param name="aInputReport"></param>
   7.272 -        private void GetUsageValues(byte[] aInputReport)
   7.273 -        {
   7.274 -            if (Device.InputValueCapabilities == null)
   7.275 -            {
   7.276 -                return;
   7.277 -            }
   7.278 -
   7.279 -            foreach (HIDP_VALUE_CAPS caps in Device.InputValueCapabilities)
   7.280 -            {                
   7.281 -                if (caps.IsRange)
   7.282 -                {
   7.283 -                    //What should we do with those guys?
   7.284 -                    continue;
   7.285 -                }
   7.286 -
   7.287 -                //Now fetch and add our usage value
   7.288 -                uint usageValue = 0;
   7.289 -                Win32.HidStatus status = Win32.Function.HidP_GetUsageValue(Win32.HIDP_REPORT_TYPE.HidP_Input, caps.UsagePage, caps.LinkCollection, caps.NotRange.Usage, ref usageValue, Device.PreParsedData, aInputReport, (uint)aInputReport.Length);
   7.290 -                if (status == Win32.HidStatus.HIDP_STATUS_SUCCESS)
   7.291 -                {
   7.292 -                    UsageValues[caps]=usageValue;
   7.293 -                }
   7.294 -            }
   7.295 -        }
   7.296 -
   7.297 -        /// <summary>
   7.298 -        /// Get all our usages, those are typically the buttons currently pushed on a gamepad.
   7.299 -        /// For a remote control it's usually just the one button that was pushed.
   7.300 -        /// </summary>
   7.301 -        private void GetUsages(byte[] aInputReport)
   7.302 -        {
   7.303 -            //Do proper parsing of our HID report
   7.304 -            //First query our usage count
   7.305 -            uint usageCount = 0;
   7.306 -            Win32.USAGE_AND_PAGE[] usages = null;
   7.307 -            Win32.HidStatus status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, Device.PreParsedData, aInputReport, (uint)aInputReport.Length);
   7.308 -            if (status == Win32.HidStatus.HIDP_STATUS_BUFFER_TOO_SMALL)
   7.309 -            {
   7.310 -                //Allocate a large enough buffer 
   7.311 -                usages = new Win32.USAGE_AND_PAGE[usageCount];
   7.312 -                //...and fetch our usages
   7.313 -                status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, Device.PreParsedData, aInputReport, (uint)aInputReport.Length);
   7.314 -                if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS)
   7.315 -                {
   7.316 -                    Debug.WriteLine("Second pass could not parse HID data: " + status.ToString());
   7.317 -                }
   7.318 -            }
   7.319 -            else if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS)
   7.320 -            {
   7.321 -                Debug.WriteLine("First pass could not parse HID data: " + status.ToString());
   7.322 -            }
   7.323 -
   7.324 -            Debug.WriteLine("Usage count: " + usageCount.ToString());
   7.325 -
   7.326 -            //Copy usages into this event
   7.327 -            if (usages != null)
   7.328 -            {
   7.329 -                foreach (USAGE_AND_PAGE up in usages)
   7.330 -                {
   7.331 -                    //Debug.WriteLine("UsagePage: 0x" + usages[0].UsagePage.ToString("X4"));
   7.332 -                    //Debug.WriteLine("Usage: 0x" + usages[0].Usage.ToString("X4"));
   7.333 -                    //Add this usage to our list
   7.334 -                    Usages.Add(up.Usage);
   7.335 -                }
   7.336 -            }
   7.337 -        }
   7.338 -
   7.339 -        /// <summary>
   7.340 -        /// 
   7.341 -        /// </summary>
   7.342 -        /// <param name="aUsagePage"></param>
   7.343 -        /// <param name="Usage"></param>
   7.344 -        /// <returns></returns>
   7.345 -        public uint GetUsageValue(ushort aUsagePage, ushort aUsage)
   7.346 -        {
   7.347 -            foreach (HIDP_VALUE_CAPS caps in Device.InputValueCapabilities)
   7.348 -            {                
   7.349 -                if (caps.IsRange)
   7.350 -                {
   7.351 -                    //What should we do with those guys?
   7.352 -                    continue;
   7.353 -                }
   7.354 -
   7.355 -                //Check if we have a match
   7.356 -                if (caps.UsagePage == aUsagePage && caps.NotRange.Usage == aUsage)
   7.357 -                {
   7.358 -                    return UsageValues[caps];
   7.359 -                }
   7.360 -            }
   7.361 -
   7.362 -            return 0;
   7.363 -        }
   7.364 -
   7.365 -        /// <summary>
   7.366 -        /// 
   7.367 -        /// </summary>
   7.368 -        /// <param name="aUsagePage"></param>
   7.369 -        /// <param name="aUsage"></param>
   7.370 -        /// <returns></returns>
   7.371 -        public int GetValueCapabilitiesIndex(ushort aUsagePage, ushort aUsage)
   7.372 -        {
   7.373 -            int i = -1;
   7.374 -            foreach (HIDP_VALUE_CAPS caps in Device.InputValueCapabilities)
   7.375 -            {
   7.376 -                i++;
   7.377 -                if (caps.IsRange)
   7.378 -                {
   7.379 -                    //What should we do with those guys?
   7.380 -                    continue;
   7.381 -                }
   7.382 -
   7.383 -                //Check if we have a match
   7.384 -                if (caps.UsagePage == aUsagePage && caps.NotRange.Usage == aUsage)
   7.385 -                {
   7.386 -                    return i;
   7.387 -                }
   7.388 -            }
   7.389 -
   7.390 -            return i;
   7.391 -        }        
   7.392 -
   7.393 -
   7.394 -        /// <summary>
   7.395 -        /// TODO: Move this to another level?
   7.396 -        /// </summary>
   7.397 -        /// <param name="aInterval"></param>
   7.398 -        public void StartRepeatTimer(double aInterval)
   7.399 -        {
   7.400 -            if (Timer == null)
   7.401 -            {
   7.402 -                return;
   7.403 -            }
   7.404 -            Timer.Enabled = false;
   7.405 -            //Initial delay do not use auto reset
   7.406 -            //After our initial delay however we do setup our timer one more time using auto reset
   7.407 -            Timer.AutoReset = (RepeatCount != 0);
   7.408 -            Timer.Interval = aInterval;
   7.409 -            Timer.Enabled = true;
   7.410 -        }
   7.411 -
   7.412 -        static private void OnRepeatTimerElapsed(object sender, ElapsedEventArgs e, HidEvent aHidEvent)
   7.413 -        {
   7.414 -            if (aHidEvent.IsStray)
   7.415 -            {
   7.416 -                //Skip events if canceled
   7.417 -                return;
   7.418 -            }
   7.419 -
   7.420 -            aHidEvent.RepeatCount++;
   7.421 -            aHidEvent.Time = DateTime.Now;
   7.422 -            if (aHidEvent.RepeatCount == 1)
   7.423 -            {
   7.424 -                //Re-Start our timer only after the initial delay 
   7.425 -                aHidEvent.StartRepeatTimer(aHidEvent.iRepeatSpeed);
   7.426 -            }
   7.427 -
   7.428 -            //Broadcast our repeat event
   7.429 -            aHidEvent.OnHidEventRepeat(aHidEvent);
   7.430 -        }
   7.431 -
   7.432 -        /// <summary>
   7.433 -        /// Provide the state of the dpad or hat switch if any.
   7.434 -        /// If no dpad is found we return 'at rest'.
   7.435 -        /// </summary>
   7.436 -        /// <returns></returns>
   7.437 -        public DirectionPadState GetDirectionPadState()
   7.438 -        {
   7.439 -            int index=GetValueCapabilitiesIndex((ushort)Hid.UsagePage.GenericDesktopControls, (ushort)GenericDesktop.HatSwitch);
   7.440 -            if (index < 0)
   7.441 -            {
   7.442 -                //No hat switch found
   7.443 -                return DirectionPadState.Rest;
   7.444 -            }
   7.445 -
   7.446 -            HIDP_VALUE_CAPS caps=Device.InputValueCapabilities[index];
   7.447 -            if (caps.IsRange)
   7.448 -            {
   7.449 -                //Defensive
   7.450 -                return DirectionPadState.Rest;
   7.451 -            }
   7.452 -
   7.453 -            uint dpadUsageValue = UsageValues[caps]; 
   7.454 -
   7.455 -            if (dpadUsageValue < caps.LogicalMin || dpadUsageValue > caps.LogicalMax)
   7.456 -            {
   7.457 -                //Out of range means at rest
   7.458 -                return DirectionPadState.Rest;
   7.459 -            }
   7.460 -
   7.461 -            //Normalize value to start at zero
   7.462 -            //TODO: more error check here?
   7.463 -            DirectionPadState res = (DirectionPadState)((int)dpadUsageValue - caps.LogicalMin);            
   7.464 -            return res;
   7.465 -        }
   7.466 -
   7.467 -        /// <summary>
   7.468 -        /// Print information about this device to our debug output.
   7.469 -        /// </summary>
   7.470 -        public void DebugWrite()
   7.471 -        {
   7.472 -            if (!IsValid)
   7.473 -            {
   7.474 -                Debug.WriteLine("==== Invalid HidEvent");
   7.475 -                return;
   7.476 -            }
   7.477 -
   7.478 -            if (Device!=null)
   7.479 -            {
   7.480 -                Device.DebugWrite();
   7.481 -            }
   7.482 -            
   7.483 -            if (IsGeneric) Debug.WriteLine("==== Generic");
   7.484 -            if (IsKeyboard) Debug.WriteLine("==== Keyboard");
   7.485 -            if (IsMouse) Debug.WriteLine("==== Mouse");
   7.486 -            Debug.WriteLine("==== Foreground: " + IsForeground.ToString());
   7.487 -            Debug.WriteLine("==== UsagePage: 0x" + UsagePage.ToString("X4"));
   7.488 -            Debug.WriteLine("==== UsageCollection: 0x" + UsageCollection.ToString("X4"));
   7.489 -            Debug.WriteLine("==== InputReport: 0x" + InputReportString());
   7.490 -            foreach (ushort usage in Usages)
   7.491 -            {
   7.492 -                Debug.WriteLine("==== Usage: 0x" + usage.ToString("X4"));
   7.493 -            }
   7.494 -        }
   7.495 -
   7.496 -        /// <summary>
   7.497 -        /// 
   7.498 -        /// </summary>
   7.499 -        /// <returns></returns>
   7.500 -        public string InputReportString()
   7.501 -        {
   7.502 -            if (InputReport == null)
   7.503 -            {
   7.504 -                return "null";
   7.505 -            }
   7.506 -
   7.507 -            string hidDump = "";
   7.508 -            foreach (byte b in InputReport)
   7.509 -            {
   7.510 -                hidDump += b.ToString("X2");
   7.511 -            }
   7.512 -            return hidDump;
   7.513 -        }
   7.514 -
   7.515 -
   7.516 -        /// <summary>
   7.517 -        /// Create a list view item describing this HidEvent
   7.518 -        /// </summary>
   7.519 -        /// <returns></returns>
   7.520 -        public ListViewItem ToListViewItem()
   7.521 -        {
   7.522 -            string usageText = "";
   7.523 -
   7.524 -            foreach (ushort usage in Usages)
   7.525 -            {
   7.526 -                if (usageText != "")
   7.527 -                {
   7.528 -                    //Add a separator
   7.529 -                    usageText += ", ";
   7.530 -                }
   7.531 -
   7.532 -                UsagePage usagePage = (UsagePage)UsagePage;
   7.533 -                switch (usagePage)
   7.534 -                {
   7.535 -                    case Hid.UsagePage.Consumer:
   7.536 -                        usageText += ((ConsumerControl)usage).ToString();
   7.537 -                        break;
   7.538 -
   7.539 -                    case Hid.UsagePage.WindowsMediaCenterRemoteControl:
   7.540 -                        usageText += ((WindowsMediaCenterRemoteControl)usage).ToString();
   7.541 -                        break;
   7.542 -
   7.543 -                    default:
   7.544 -                        usageText += usage.ToString("X2");
   7.545 -                        break;
   7.546 -                }
   7.547 -            }
   7.548 -
   7.549 -            //If we are a gamepad display axis and dpad values
   7.550 -            if (Device.IsGamePad)
   7.551 -            {
   7.552 -                //uint dpadUsageValue = GetUsageValue((ushort)Hid.UsagePage.GenericDesktopControls, (ushort)Hid.Usage.GenericDesktop.HatSwitch);
   7.553 -                //usageText = dpadUsageValue.ToString("X") + " (dpad), " + usageText;
   7.554 -              
   7.555 -                if (usageText != "")
   7.556 -                {
   7.557 -                    //Add a separator
   7.558 -                    usageText += " (Buttons)";
   7.559 -                }
   7.560 -
   7.561 -                if (usageText != "")
   7.562 -                {
   7.563 -                    //Add a separator
   7.564 -                    usageText += ", ";
   7.565 -                }
   7.566 -
   7.567 -                usageText += GetDirectionPadState().ToString();
   7.568 -
   7.569 -                foreach (KeyValuePair<HIDP_VALUE_CAPS, uint> entry in UsageValues)
   7.570 -                {
   7.571 -                    if (entry.Key.IsRange)
   7.572 -                    {
   7.573 -                        continue;
   7.574 -                    }
   7.575 -
   7.576 -                    Type usageType = Utils.UsageType((UsagePage)entry.Key.UsagePage);
   7.577 -                    if (usageType == null)
   7.578 -                    {
   7.579 -                        //TODO: check why this is happening on Logitech rumble gamepad 2.
   7.580 -                        //Probably some of our axis are hiding in there.
   7.581 -                        continue;
   7.582 -                    }
   7.583 -                    string name = Enum.GetName(usageType, entry.Key.NotRange.Usage);
   7.584 -
   7.585 -                    if (usageText != "")
   7.586 -                    {
   7.587 -                        //Add a separator
   7.588 -                        usageText += ", ";
   7.589 -                    }
   7.590 -                    usageText += entry.Value.ToString("X") + " ("+ name +")";        
   7.591 -                }
   7.592 -            }
   7.593 -
   7.594 -            //Now create our list item
   7.595 -            ListViewItem item = new ListViewItem(new[] { usageText, InputReportString(), UsagePage.ToString("X2"), UsageCollection.ToString("X2"), RepeatCount.ToString(), Time.ToString("HH:mm:ss:fff") });
   7.596 -            return item;
   7.597 -        }
   7.598 -
   7.599 -    }
   7.600 -
   7.601 -}
   7.602 \ No newline at end of file
     8.1 --- a/HidHandler.cs	Sun Mar 15 16:56:31 2015 +0100
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,104 +0,0 @@
     8.4 -//
     8.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
     8.6 -//
     8.7 -// This file is part of SharpLibHid.
     8.8 -//
     8.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
    8.10 -// it under the terms of the GNU General Public License as published by
    8.11 -// the Free Software Foundation, either version 3 of the License, or
    8.12 -// (at your option) any later version.
    8.13 -//
    8.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
    8.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.17 -// GNU General Public License for more details.
    8.18 -//
    8.19 -// You should have received a copy of the GNU General Public License
    8.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    8.21 -//
    8.22 -
    8.23 -
    8.24 -using System;
    8.25 -using System.Windows.Forms;
    8.26 -using System.Runtime.InteropServices;
    8.27 -using System.Diagnostics;
    8.28 -using System.Text;
    8.29 -using Microsoft.Win32.SafeHandles;
    8.30 -using SharpLib.Win32;
    8.31 -using System.Collections.Generic;
    8.32 -
    8.33 -
    8.34 -namespace SharpLib.Hid
    8.35 -{
    8.36 -    /// <summary>
    8.37 -    /// Our HID handler manages raw input registrations, processes WM_INPUT messages and broadcasts HID events in return.
    8.38 -    /// </summary>
    8.39 -    public class HidHandler
    8.40 -    {
    8.41 -        public delegate void HidEventHandler(object aSender, HidEvent aHidEvent);
    8.42 -        public event HidEventHandler OnHidEvent;
    8.43 -        List<HidEvent> iHidEvents;
    8.44 -
    8.45 -
    8.46 -        public bool IsRegistered { get; private set; }
    8.47 -
    8.48 -        public HidHandler(RAWINPUTDEVICE[] aRawInputDevices)
    8.49 -        {
    8.50 -            iHidEvents=new List<HidEvent>();
    8.51 -            IsRegistered = Function.RegisterRawInputDevices(aRawInputDevices, (uint)aRawInputDevices.Length, (uint)Marshal.SizeOf(aRawInputDevices[0]));
    8.52 -        }
    8.53 -
    8.54 -        /// <summary>
    8.55 -        /// Process a WM_INPUT message.
    8.56 -        /// </summary>
    8.57 -        /// <param name="aMessage"></param>
    8.58 -        public void ProcessInput(ref Message aMessage)
    8.59 -        {
    8.60 -            if (aMessage.Msg != Const.WM_INPUT)
    8.61 -            {
    8.62 -                //We only process WM_INPUT messages
    8.63 -                return;
    8.64 -            }
    8.65 -
    8.66 -            HidEvent hidEvent = new HidEvent(aMessage, OnHidEventRepeat);
    8.67 -            hidEvent.DebugWrite();
    8.68 -
    8.69 -            if (!hidEvent.IsValid || !hidEvent.IsGeneric)
    8.70 -            {
    8.71 -                Debug.WriteLine("Skipping HID message.");
    8.72 -                return;
    8.73 -            }
    8.74 -
    8.75 -            //
    8.76 -            if (hidEvent.IsButtonUp)
    8.77 -            {
    8.78 -                //This is a key up event
    8.79 -                //We need to discard any events belonging to the same page and collection
    8.80 -                for (int i = (iHidEvents.Count-1); i >= 0; i--)
    8.81 -                {
    8.82 -                    if (iHidEvents[i].UsageId == hidEvent.UsageId)
    8.83 -                    {
    8.84 -                        iHidEvents[i].Dispose();
    8.85 -                        iHidEvents.RemoveAt(i);
    8.86 -                    }
    8.87 -                }
    8.88 -            }
    8.89 -            else
    8.90 -            {
    8.91 -                //Keep that event until we get a key up message
    8.92 -                iHidEvents.Add(hidEvent);
    8.93 -            }
    8.94 -
    8.95 -            //Broadcast our events
    8.96 -            OnHidEvent(this, hidEvent);    
    8.97 -        }
    8.98 -
    8.99 -        public void OnHidEventRepeat(HidEvent aHidEvent)
   8.100 -        {
   8.101 -            //Broadcast our events
   8.102 -            OnHidEvent(this, aHidEvent);    
   8.103 -        }
   8.104 -
   8.105 -    }
   8.106 -
   8.107 -}
   8.108 \ No newline at end of file
     9.1 --- a/HidUsageTables.cs	Sun Mar 15 16:56:31 2015 +0100
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,928 +0,0 @@
     9.4 -//
     9.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
     9.6 -//
     9.7 -// This file is part of SharpLibHid.
     9.8 -//
     9.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
    9.10 -// it under the terms of the GNU General Public License as published by
    9.11 -// the Free Software Foundation, either version 3 of the License, or
    9.12 -// (at your option) any later version.
    9.13 -//
    9.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
    9.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.17 -// GNU General Public License for more details.
    9.18 -//
    9.19 -// You should have received a copy of the GNU General Public License
    9.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    9.21 -//
    9.22 -
    9.23 -namespace SharpLib.Hid
    9.24 -{
    9.25 -    /// <summary>
    9.26 -    /// From USB HID usage tables.
    9.27 -    /// http://www.usb.org/developers/hidpage#HID_Usage
    9.28 -    /// http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf
    9.29 -    /// </summary>
    9.30 -    public enum UsagePage : ushort
    9.31 -    {
    9.32 -        Undefined = 0,
    9.33 -        GenericDesktopControls,
    9.34 -        SimulationControls,
    9.35 -        VirtualRealityControls,
    9.36 -        SportControls,
    9.37 -        GameControls,
    9.38 -        GenericDeviceControls,
    9.39 -        Keyboard,
    9.40 -        LightEmittingDiode,
    9.41 -        Button,
    9.42 -        Ordinal,
    9.43 -        Telephony,
    9.44 -        Consumer,
    9.45 -        Digitiser,
    9.46 -        PhysicalInterfaceDevice = 0x0f,
    9.47 -        Unicode = 0x10,
    9.48 -        AlphaNumericDisplay = 0x14,
    9.49 -        MedicalInstruments = 0x40,
    9.50 -        MonitorPage0 = 0x80,
    9.51 -        MonitorPage1,
    9.52 -        MonitorPage2,
    9.53 -        MonitorPage3,
    9.54 -        PowerPage0,
    9.55 -        PowerPage1,
    9.56 -        PowerPage2,
    9.57 -        PowerPage3,
    9.58 -        BarCodeScanner = 0x8c,
    9.59 -        Scale,
    9.60 -        MagneticStripeReader,
    9.61 -        ReservedPointOfSale,
    9.62 -        CameraControl,
    9.63 -        Arcade,
    9.64 -        // http://msdn.microsoft.com/en-us/library/windows/desktop/bb417079.aspx
    9.65 -        WindowsMediaCenterRemoteControl = 0xffbc,
    9.66 -        TerraTecRemote = 0xffcc
    9.67 -    }
    9.68 -
    9.69 -    /// <summary>
    9.70 -    /// Usage Collections are special values from our Usage enumeration.
    9.71 -    /// Thus they are also part of the corresponding Usage enumeration.
    9.72 -    /// </summary>
    9.73 -    namespace UsageCollection
    9.74 -    {
    9.75 -        /// <summary>
    9.76 -        /// Usage Collection for usage page GenericDesktopControls.
    9.77 -        /// </summary>
    9.78 -        public enum GenericDesktop : ushort
    9.79 -        {
    9.80 -            Pointer = 0x01,
    9.81 -            Mouse = 0x02,
    9.82 -            Joystick = 0x04,
    9.83 -            GamePad = 0x05,
    9.84 -            Keyboard = 0x06,
    9.85 -            KeyPad = 0x07,
    9.86 -            MultiAxisController = 0x08,
    9.87 -            TabletPCSystemControls = 0x09,
    9.88 -            SystemControl = 0x80
    9.89 -        }
    9.90 -
    9.91 -        /// <summary>
    9.92 -        /// Usage Collection for usage page Consumer.
    9.93 -        /// </summary>
    9.94 -        public enum Consumer : ushort
    9.95 -        {
    9.96 -            ConsumerControl = 0x01,
    9.97 -            NumericKeyPad = 0x02,
    9.98 -            ProgrammableButtons = 0x03,
    9.99 -            Microphone = 0x04,
   9.100 -            Headphone = 0x05,
   9.101 -            GraphicEqualizer = 0x06,
   9.102 -            FunctionButtons = 0x36,
   9.103 -            Selection = 0x80,
   9.104 -            MediaSelection = 0x0087,
   9.105 -            SelectDisc = 0x00BA,
   9.106 -            PlaybackSpeed = 0x00F1,
   9.107 -            Proximity = 0x0109,
   9.108 -            SpeakerSystem = 0x0160,
   9.109 -            ChannelLeft = 0x0161,
   9.110 -            ChannelRight = 0x0162,
   9.111 -            ChannelCenter = 0x0163,
   9.112 -            ChannelFront = 0x0164,
   9.113 -            ChannelCenterFront = 0x0165,
   9.114 -            ChannelSide = 0x0166,
   9.115 -            ChannelSurrond = 0x0167,
   9.116 -            ChannelLowFrequencyEnhancement = 0x0168,
   9.117 -            ChannelTop = 0x0169,
   9.118 -            ChannelUnknown = 0x016A,
   9.119 -            ApplicationLaunchButtons = 0x016A,
   9.120 -            GenericGuiApplicationControls = 0x0200,
   9.121 -        }
   9.122 -
   9.123 -
   9.124 -        public enum WindowsMediaCenter : ushort
   9.125 -        {
   9.126 -            WindowsMediaCenterRemoteControl = 0x88
   9.127 -        }
   9.128 -
   9.129 -    }
   9.130 -
   9.131 -
   9.132 -
   9.133 -    namespace Usage
   9.134 -    {
   9.135 -        /// <summary>
   9.136 -        ///
   9.137 -        /// </summary>
   9.138 -        public enum WindowsMediaCenterRemoteControl : ushort
   9.139 -        {
   9.140 -            /// <summary>
   9.141 -            /// Not defined by the Microsoft specs.
   9.142 -            /// </summary>
   9.143 -            Null = 0x00,
   9.144 -            GreenStart = 0x0D,
   9.145 -            ClosedCaptioning = 0x2B,
   9.146 -            Teletext = 0x5A,
   9.147 -            TeletextRed = 0x5B,
   9.148 -            TeletextGreen = 0x5C,
   9.149 -            TeletextYellow = 0x5D,
   9.150 -            TeletextBlue = 0x5E,
   9.151 -            LiveTv = 0x25,
   9.152 -            Tv = 0x46,
   9.153 -            Music = 0x47,
   9.154 -            RecordedTv = 0x48,
   9.155 -            Pictures = 0x49,
   9.156 -            Videos = 0x4A,
   9.157 -            FmRadio = 0x50,
   9.158 -            Extras = 0x3C,
   9.159 -            ExtrasApp = 0x3D,
   9.160 -            DvdMenu = 0x24,
   9.161 -            DvdAngle = 0x4B,
   9.162 -            DvdAudio = 0x4C,
   9.163 -            DvdSubtitle = 0x4D,
   9.164 -            /// <summary>
   9.165 -            /// First press action: Ejects a DVD drive.
   9.166 -            /// <para />
   9.167 -            /// Second press action: Repeats first press action.
   9.168 -            /// <para />
   9.169 -            /// Notably issued by XBOX360 remote as defined in irplus - Remote Control - Android application.
   9.170 -            /// </summary>
   9.171 -            Eject = 0x28,
   9.172 -            DvdTopMenu = 0x43,
   9.173 -            /// <summary>
   9.174 -            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   9.175 -            /// Collection (page 0xFFBC, usage 0x88).
   9.176 -            /// <para />
   9.177 -            /// Second press action: Repeats message.
   9.178 -            /// <para />
   9.179 -            /// Auto-repeat: No
   9.180 -            /// <para />
   9.181 -            /// Notably sent by the 'Visualization' button of HP Windows Media Center Remote (TSGH-IR08).
   9.182 -            /// <para />
   9.183 -            /// According to HP specs it displays visual imagery that is synchronized to the sound of your music tracks.
   9.184 -            /// </summary>
   9.185 -            Ext0 = 0x32,
   9.186 -            /// <summary>
   9.187 -            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   9.188 -            /// Collection (page 0xFFBC, usage 0x88).
   9.189 -            /// <para />
   9.190 -            /// Second press action: Repeats message.
   9.191 -            /// <para />
   9.192 -            /// Auto-repeat: No
   9.193 -            /// <para />
   9.194 -            /// Notably sent by the 'Slide Show' button of HP Windows Media Center Remote (TSGH-IR08).
   9.195 -            /// <para />
   9.196 -            /// According to HP specs it plays a slide show of all the pictures on your hard disk drive.
   9.197 -            /// </summary>
   9.198 -            Ext1 = 0x33,
   9.199 -            /// <summary>
   9.200 -            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   9.201 -            /// Collection (page 0xFFBC, usage 0x88).
   9.202 -            /// <para />
   9.203 -            /// Second press action: Repeats message.
   9.204 -            /// <para />
   9.205 -            /// Auto-repeat: No
   9.206 -            /// <para />
   9.207 -            /// Notably sent by the 'Eject' button of HP Windows Media Center Remote (TSGH-IR08).
   9.208 -            /// Also interpreted as 'Eject' action by SoundGraph iMON Manager in MCE mode (OrigenAE VF310).
   9.209 -            /// </summary>
   9.210 -            Ext2 = 0x34,
   9.211 -            /// <summary>
   9.212 -            /// First press action: Generates EXTn HID message in the Media Center Vendor Specific
   9.213 -            /// Collection (page 0xFFBC, usage 0x88).
   9.214 -            /// <para />
   9.215 -            /// Second press action: Repeats message.
   9.216 -            /// <para />
   9.217 -            /// Auto-repeat: No
   9.218 -            /// <para />
   9.219 -            /// Notably sent by the 'Input selection' button of HP Windows Media Center Remote (TSGH-IR08).
   9.220 -            /// </summary>
   9.221 -            Ext3 = 0x35,
   9.222 -            Ext4 = 0x36,
   9.223 -            Ext5 = 0x37,
   9.224 -            Ext6 = 0x38,
   9.225 -            Ext7 = 0x39,
   9.226 -            Ext8 = 0x3A,
   9.227 -            Ext9 = 0x80,
   9.228 -            Ext10 = 0x81,
   9.229 -            Ext11 = 0x6F,
   9.230 -            Zoom = 0x27,
   9.231 -            ChannelInput = 0x42,
   9.232 -            SubAudio = 0x2D,
   9.233 -            Channel10 = 0x3E,
   9.234 -            Channel11 = 0x3F,
   9.235 -            Channel12 = 0x40,
   9.236 -            /// <summary>
   9.237 -            /// First press action: Generates OEM2 HID message in the Media Center Vendor Specific
   9.238 -            /// Collection. This button is intended to control the front panel display of home entertainment
   9.239 -            /// computers. When this button is pressed, the display could be turned on or off, or the display
   9.240 -            /// mode could change.
   9.241 -            /// <para />
   9.242 -            /// Second press action: Repeats message.
   9.243 -            /// <para />
   9.244 -            /// Auto-repeat: No
   9.245 -            /// <para />
   9.246 -            /// Notably issued by XBOX360 remote as defined in irplus - Remote Control - Android application.
   9.247 -            /// </summary>
   9.248 -            Display = 0x4F,
   9.249 -            /// <summary>
   9.250 -            /// First press action: To be determined.
   9.251 -            /// <para />
   9.252 -            /// Second press action: Repeats message.
   9.253 -            /// <para />
   9.254 -            /// Auto-repeat: No
   9.255 -            /// </summary>
   9.256 -            Kiosk = 0x6A,
   9.257 -            NetworkSelection = 0x2C,
   9.258 -            BlueRayTool = 0x78,
   9.259 -            ChannelInfo = 0x41,
   9.260 -            VideoSelection = 0x61
   9.261 -        }
   9.262 -
   9.263 -        /// <summary>
   9.264 -        /// Those codes come from experimenting with HP remotes.
   9.265 -        /// </summary>
   9.266 -        public enum HpWindowsMediaCenterRemoteControl : ushort
   9.267 -        {
   9.268 -            /// <summary>
   9.269 -            /// Displays visual imagery that is synchronized to the sound of your music tracks.
   9.270 -            /// <para />
   9.271 -            /// Second press action: Repeats message.
   9.272 -            /// <para />
   9.273 -            /// Auto-repeat: No
   9.274 -            /// <para />
   9.275 -            /// Notably sent by the 'Visualization' button of HP Windows Media Center Remote (TSGH-IR08).
   9.276 -            /// <para />
   9.277 -            /// According to HP specs it displays visual imagery that is synchronized to the sound of your music tracks.
   9.278 -            /// </summary>
   9.279 -            Visualization = WindowsMediaCenterRemoteControl.Ext0,
   9.280 -            /// <summary>
   9.281 -            /// Plays a slide show of all the pictures on your hard disk drive.
   9.282 -            /// <para />
   9.283 -            /// Second press action: Repeats message.
   9.284 -            /// <para />
   9.285 -            /// Auto-repeat: No
   9.286 -            /// <para />
   9.287 -            /// Notably sent by the 'Slide Show' button of HP Windows Media Center Remote (TSGH-IR08).
   9.288 -            /// <para />
   9.289 -            /// According to HP specs it plays a slide show of all the pictures on your hard disk drive.
   9.290 -            /// </summary>
   9.291 -            SlideShow = WindowsMediaCenterRemoteControl.Ext1,
   9.292 -            /// <summary>
   9.293 -            /// Eject optical drive.
   9.294 -            /// <para />
   9.295 -            /// Second press action: Repeats message.
   9.296 -            /// <para />
   9.297 -            /// Auto-repeat: No
   9.298 -            /// <para />
   9.299 -            /// Notably sent by the 'Eject' button of HP Windows Media Center Remote (TSGH-IR08).
   9.300 -            /// Also interpreted as 'Eject' action by SoundGraph iMON Manager in MCE mode (OrigenAE VF310).
   9.301 -            /// </summary>
   9.302 -            HpEject = WindowsMediaCenterRemoteControl.Ext2,
   9.303 -            /// <summary>
   9.304 -            /// Not sure what this should do.
   9.305 -            /// <para />
   9.306 -            /// Second press action: Repeats message.
   9.307 -            /// <para />
   9.308 -            /// Auto-repeat: No
   9.309 -            /// <para />
   9.310 -            /// Notably sent by the 'Input selection' button of HP Windows Media Center Remote (TSGH-IR08).
   9.311 -            /// </summary>
   9.312 -            InputSelection = WindowsMediaCenterRemoteControl.Ext3,
   9.313 -        }
   9.314 -
   9.315 -        /// <summary>
   9.316 -        /// Usage Table for Consumer Controls
   9.317 -        /// 0x0C 0X01
   9.318 -        /// </summary>
   9.319 -        public enum ConsumerControl : ushort
   9.320 -        {
   9.321 -            Null = 0x00,
   9.322 -            ConsumerControl = 0x01,
   9.323 -            NumericKeyPad = 0x02,
   9.324 -            ProgrammableButtons = 0x03,
   9.325 -            Microphone = 0x04,
   9.326 -            Headphone = 0x05,
   9.327 -            GraphicEqualizer = 0x06,
   9.328 -            Plus10 = 0x20,
   9.329 -            Plus100 = 0x21,
   9.330 -            AmPm = 0x22,
   9.331 -            Power = 0x30,
   9.332 -            Reset = 0x31,
   9.333 -            Sleep = 0x32,
   9.334 -            SleepAfter = 0x33,
   9.335 -            SleepMode = 0x34,
   9.336 -            Illumination = 0x35,
   9.337 -            FunctionButtons = 0x36,
   9.338 -            Menu = 0x40,
   9.339 -            MenuPick = 0x41,
   9.340 -            MenuUp = 0x42,
   9.341 -            MenuDown = 0x43,
   9.342 -            MenuLeft = 0x44,
   9.343 -            MenuRight = 0x45,
   9.344 -            MenuEscape = 0x46,
   9.345 -            MenuValueIncrease = 0x47,
   9.346 -            MenuValueDecrease = 0x48,
   9.347 -            DataOnScreen = 0x60,
   9.348 -            ClosedCaption = 0x61,
   9.349 -            ClosedCaptionSelect = 0x62,
   9.350 -            VcrTv = 0x63,
   9.351 -            BroadcastMode = 0x64,
   9.352 -            Snapshot = 0x65,
   9.353 -            Still = 0x66,
   9.354 -            Selection = 0x80,
   9.355 -            AssignSelection = 0x81,
   9.356 -            ModeStep = 0x82,
   9.357 -            RecallLast = 0x83,
   9.358 -            EnterChannel = 0x84,
   9.359 -            OrderMovie = 0x85,
   9.360 -            Channel = 0x86,
   9.361 -            MediaSelection = 0x87,
   9.362 -            MediaSelectComputer = 0x88,
   9.363 -            MediaSelectTv = 0x89,
   9.364 -            MediaSelectWww = 0x8A,
   9.365 -            MediaSelectDvd = 0x8B,
   9.366 -            MediaSelectTelephone = 0x8C,
   9.367 -            MediaSelectProgramGuide = 0x8D,
   9.368 -            MediaSelectVideoPhone = 0x8E,
   9.369 -            MediaSelectGames = 0x8F,
   9.370 -            MediaSelectMessages = 0x90,
   9.371 -            MediaSelectCd = 0x91,
   9.372 -            MediaSelectVcr = 0x92,
   9.373 -            MediaSelectTuner = 0x93,
   9.374 -            Quit = 0x94,
   9.375 -            Help = 0x95,
   9.376 -            MediaSelectTape = 0x96,
   9.377 -            MediaSelectCable = 0x97,
   9.378 -            MediaSelectSatellite = 0x98,
   9.379 -            MediaSelectSecurity = 0x99,
   9.380 -            MediaSelectHome = 0x9A,
   9.381 -            MediaSelectCall = 0x9B,
   9.382 -            ChannelIncrement = 0x9C,
   9.383 -            ChannelDecrement = 0x9D,
   9.384 -            MediaSelectSap = 0x9E,
   9.385 -            VcrPlus = 0xA0,
   9.386 -            Once = 0xA1,
   9.387 -            Daily = 0xA2,
   9.388 -            Weekly = 0xA3,
   9.389 -            Monthly = 0xA4,
   9.390 -            Play = 0xB0,
   9.391 -            Pause = 0xB1,
   9.392 -            Record = 0xB2,
   9.393 -            FastForward = 0xB3,
   9.394 -            Rewind = 0xB4,
   9.395 -            ScanNextTrack = 0xB5,
   9.396 -            ScanPreviousTrack = 0xB6,
   9.397 -            Stop = 0xB7,
   9.398 -            Eject = 0xB8,
   9.399 -            RandomPlay = 0xB9,
   9.400 -            SelectDisc = 0xBA,
   9.401 -            EnterDisc = 0xBB,
   9.402 -            Repeat = 0xBC,
   9.403 -            Tracking = 0xBD,
   9.404 -            TrackNormal = 0xBE,
   9.405 -            SlowTracking = 0xBF,
   9.406 -            FrameForward = 0xC0,
   9.407 -            FrameBack = 0xC1,
   9.408 -            Mark = 0xC2,
   9.409 -            ClearMark = 0xC3,
   9.410 -            RepeatFromMark = 0xC4,
   9.411 -            ReturnToMark = 0xC5,
   9.412 -            SearchMarkForward = 0xC6,
   9.413 -            SearchMarkBackwards = 0xC7,
   9.414 -            CounterReset = 0xC8,
   9.415 -            ShowCounter = 0xC9,
   9.416 -            TrackingIncrement = 0xCA,
   9.417 -            TrackingDecrement = 0xCB,
   9.418 -            StopEject = 0xCC,
   9.419 -            PlayPause = 0xCD,
   9.420 -            PlaySkip = 0xCE,
   9.421 -            Volume = 0xE0,
   9.422 -            Balance = 0xE1,
   9.423 -            Mute = 0xE2,
   9.424 -            Bass = 0xE3,
   9.425 -            Treble = 0xE4,
   9.426 -            BassBoost = 0xE5,
   9.427 -            SurroundMode = 0xE6,
   9.428 -            Loudness = 0xE7,
   9.429 -            Mpx = 0xE8,
   9.430 -            VolumeIncrement = 0xE9,
   9.431 -            VolumeDecrement = 0xEA,
   9.432 -            SpeedSelect = 0xF0,
   9.433 -            PlaybackSpeed = 0xF1,
   9.434 -            StandardPlay = 0xF2,
   9.435 -            LongPlay = 0xF3,
   9.436 -            ExtendedPlay = 0xF4,
   9.437 -            Slow = 0xF5,
   9.438 -            FanEnable = 0x100,
   9.439 -            FanSpeed = 0x101,
   9.440 -            LightEnable = 0x102,
   9.441 -            LightIlluminationLevel = 0x103,
   9.442 -            ClimateControlEnable = 0x104,
   9.443 -            RoomTemperature = 0x105,
   9.444 -            SecurityEnable = 0x106,
   9.445 -            FireAlarm = 0x107,
   9.446 -            PoliceAlarm = 0x108,
   9.447 -            Proximity = 0x109,
   9.448 -            Motion = 0x10A,
   9.449 -            DuressAlarm = 0x10B,
   9.450 -            HoldupAlarm = 0x10C,
   9.451 -            MedicalAlarm = 0x10D,
   9.452 -            BalanceRight = 0x150,
   9.453 -            BalanceLeft = 0x151,
   9.454 -            BassIncrement = 0x152,
   9.455 -            BassDecrement = 0x153,
   9.456 -            TrebleIncrement = 0x154,
   9.457 -            TrebleDecrement = 0x155,
   9.458 -            SpeakerSystem = 0x160,
   9.459 -            ChannelLeft = 0x161,
   9.460 -            ChannelRight = 0x162,
   9.461 -            ChannelCenter = 0x163,
   9.462 -            ChannelFront = 0x164,
   9.463 -            ChannelCenterFront = 0x165,
   9.464 -            ChannelSide = 0x166,
   9.465 -            ChannelSurround = 0x167,
   9.466 -            ChannelLowFrequencyEnhancement = 0x168,
   9.467 -            ChannelTop = 0x169,
   9.468 -            ChannelUnknown = 0x16A,
   9.469 -            SubChannel = 0x170,
   9.470 -            SubChannelIncrement = 0x171,
   9.471 -            SubChannelDecrement = 0x172,
   9.472 -            AlternateAudioIncrement = 0x173,
   9.473 -            AlternateAudioDecrement = 0x174,
   9.474 -            ApplicationLaunchButtons = 0x180,
   9.475 -            AppLaunchLaunchButtonConfigurationTool = 0x181,
   9.476 -            AppLaunchProgrammableButtonConfiguration = 0x182,
   9.477 -            AppLaunchConsumerControlConfiguration = 0x183,
   9.478 -            AppLaunchWordProcessor = 0x184,
   9.479 -            AppLaunchTextEditor = 0x185,
   9.480 -            AppLaunchSpreadsheet = 0x186,
   9.481 -            AppLaunchGraphicsEditor = 0x187,
   9.482 -            AppLaunchPresentationApp = 0x188,
   9.483 -            AppLaunchDatabaseApp = 0x189,
   9.484 -            AppLaunchEmailReader = 0x18A,
   9.485 -            AppLaunchNewsreader = 0x18B,
   9.486 -            AppLaunchVoicemail = 0x18C,
   9.487 -            AppLaunchContactsAddressBook = 0x18D,
   9.488 -            AppLaunchCalendarSchedule = 0x18E,
   9.489 -            AppLaunchTaskProjectManager = 0x18F,
   9.490 -            AppLaunchLogJournalTimecard = 0x190,
   9.491 -            AppLaunchCheckbookFinance = 0x191,
   9.492 -            AppLaunchCalculator = 0x192,
   9.493 -            AppLaunchAVCapturePlayback = 0x193,
   9.494 -            AppLaunchLocalMachineBrowser = 0x194,
   9.495 -            AppLaunchLanWanBrowser = 0x195,
   9.496 -            AppLaunchInternetBrowser = 0x196,
   9.497 -            AppLaunchRemoteNetworkingIspConnect = 0x197,
   9.498 -            AppLaunchNetworkConference = 0x198,
   9.499 -            AppLaunchNetworkChat = 0x199,
   9.500 -            AppLaunchTelephonyDialer = 0x19A,
   9.501 -            AppLaunchLogon = 0x19B,
   9.502 -            AppLaunchLogoff = 0x19C,
   9.503 -            AppLaunchLogonLogoff = 0x19D,
   9.504 -            AppLaunchTerminalLockScreensaver = 0x19E,
   9.505 -            AppLaunchControlPanel = 0x19F,
   9.506 -            AppLaunchCommandLineProcessorRun = 0x1A0,
   9.507 -            AppLaunchProcessTaskManager = 0x1A1,
   9.508 -            AppLaunchSelectTaskApplication = 0x1A2,
   9.509 -            AppLaunchNextTaskApplication = 0x1A3,
   9.510 -            AppLaunchPreviousTaskApplication = 0x1A4,
   9.511 -            AppLaunchPreemptiveHaltTaskApplication = 0x1A5,
   9.512 -            AppLaunchIntegratedHelpCenter = 0x1A6,
   9.513 -            AppLaunchDocuments = 0x1A7,
   9.514 -            AppLaunchThesaurus = 0x1A8,
   9.515 -            AppLaunchDictionary = 0x1A9,
   9.516 -            AppLaunchDesktop = 0x1AA,
   9.517 -            AppLaunchSpellCheck = 0x1AB,
   9.518 -            AppLaunchGrammarCheck = 0x1AC,
   9.519 -            AppLaunchWirelessStatus = 0x1AD,
   9.520 -            AppLaunchKeyboardLayout = 0x1AE,
   9.521 -            AppLaunchVirusProtection = 0x1AF,
   9.522 -            AppLaunchEncryption = 0x1B0,
   9.523 -            AppLaunchScreenSaver = 0x1B1,
   9.524 -            AppLaunchAlarms = 0x1B2,
   9.525 -            AppLaunchClock = 0x1B3,
   9.526 -            AppLaunchFileBrowser = 0x1B4,
   9.527 -            AppLaunchPowerStatus = 0x1B5,
   9.528 -            AppLaunchImageBrowser = 0x1B6,
   9.529 -            AppLaunchAudioBrowser = 0x1B7,
   9.530 -            AppLaunchMovieBrowser = 0x1B8,
   9.531 -            AppLaunchDigitalRightsManager = 0x1B9,
   9.532 -            AppLaunchDigitalWallet = 0x1BA,
   9.533 -            AppLaunchInstantMessaging = 0x1BC,
   9.534 -            AppLaunchOemFeaturesTipsTutorialBrowser = 0x1BD,
   9.535 -            AppLaunchOemHelp = 0x1BE,
   9.536 -            AppLaunchOnlineCommunity = 0x1BF,
   9.537 -            AppLaunchEntertainmentContentBrowser = 0x1C0,
   9.538 -            AppLaunchOnlineShoppingBrowser = 0x1C1,
   9.539 -            AppLaunchSmartcardInformationHelp = 0x1C2,
   9.540 -            AppLaunchMarketMonitorFinanceBrowser = 0x1C3,
   9.541 -            AppLaunchCustomizedCorporateNewsBrowser = 0x1C4,
   9.542 -            AppLaunchOnlineActivityBrowser = 0x1C5,
   9.543 -            AppLaunchResearchSearchBrowser = 0x1C6,
   9.544 -            AppLaunchAudioPlayer = 0x1C7,
   9.545 -            GenericGuiApplicationControls = 0x200,
   9.546 -            AppCtrlNew = 0x201,
   9.547 -            AppCtrlOpen = 0x202,
   9.548 -            AppCtrlClose = 0x203,
   9.549 -            AppCtrlExit = 0x204,
   9.550 -            AppCtrlMaximize = 0x205,
   9.551 -            AppCtrlMinimize = 0x206,
   9.552 -            AppCtrlSave = 0x207,
   9.553 -            AppCtrlPrint = 0x208,
   9.554 -            AppCtrlProperties = 0x209,
   9.555 -            AppCtrlUndo = 0x21A,
   9.556 -            AppCtrlCopy = 0x21B,
   9.557 -            AppCtrlCut = 0x21C,
   9.558 -            AppCtrlPaste = 0x21D,
   9.559 -            AppCtrlSelectAll = 0x21E,
   9.560 -            AppCtrlFind = 0x21F,
   9.561 -            AppCtrlFindAndReplace = 0x220,
   9.562 -            AppCtrlSearch = 0x221,
   9.563 -            AppCtrlGoTo = 0x222,
   9.564 -            AppCtrlHome = 0x223,
   9.565 -            AppCtrlBack = 0x224,
   9.566 -            AppCtrlForward = 0x225,
   9.567 -            AppCtrlStop = 0x226,
   9.568 -            AppCtrlRefresh = 0x227,
   9.569 -            AppCtrlPreviousLink = 0x228,
   9.570 -            AppCtrlNextLink = 0x229,
   9.571 -            AppCtrlBookmarks = 0x22A,
   9.572 -            AppCtrlHistory = 0x22B,
   9.573 -            AppCtrlSubscriptions = 0x22C,
   9.574 -            AppCtrlZoomIn = 0x22D,
   9.575 -            AppCtrlZoomOut = 0x22E,
   9.576 -            AppCtrlZoom = 0x22F,
   9.577 -            AppCtrlFullScreenView = 0x230,
   9.578 -            AppCtrlNormalView = 0x231,
   9.579 -            AppCtrlViewToggle = 0x232,
   9.580 -            AppCtrlScrollUp = 0x233,
   9.581 -            AppCtrlScrollDown = 0x234,
   9.582 -            AppCtrlScroll = 0x235,
   9.583 -            AppCtrlPanLeft = 0x236,
   9.584 -            AppCtrlPanRight = 0x237,
   9.585 -            AppCtrlPan = 0x238,
   9.586 -            AppCtrlNewWindow = 0x239,
   9.587 -            AppCtrlTileHorizontally = 0x23A,
   9.588 -            AppCtrlTileVertically = 0x23B,
   9.589 -            AppCtrlFormat = 0x23C,
   9.590 -            AppCtrlEdit = 0x23D,
   9.591 -            AppCtrlBold = 0x23E,
   9.592 -            AppCtrlItalics = 0x23F,
   9.593 -            AppCtrlUnderline = 0x240,
   9.594 -            AppCtrlStrikethrough = 0x241,
   9.595 -            AppCtrlSubscript = 0x242,
   9.596 -            AppCtrlSuperscript = 0x243,
   9.597 -            AppCtrlAllCaps = 0x244,
   9.598 -            AppCtrlRotate = 0x245,
   9.599 -            AppCtrlResize = 0x246,
   9.600 -            AppCtrlFlipHorizontal = 0x247,
   9.601 -            AppCtrlFlipVertical = 0x248,
   9.602 -            AppCtrlMirrorHorizontal = 0x249,
   9.603 -            AppCtrlMirrorVertical = 0x24A,
   9.604 -            AppCtrlFontSelect = 0x24B,
   9.605 -            AppCtrlFontColor = 0x24C,
   9.606 -            AppCtrlFontSize = 0x24D,
   9.607 -            AppCtrlJustifyLeft = 0x24E,
   9.608 -            AppCtrlJustifyCenterH = 0x24F,
   9.609 -            AppCtrlJustifyRight = 0x250,
   9.610 -            AppCtrlJustifyBlockH = 0x251,
   9.611 -            AppCtrlJustifyTop = 0x252,
   9.612 -            AppCtrlJustifyCenterV = 0x253,
   9.613 -            AppCtrlJustifyBottom = 0x254,
   9.614 -            AppCtrlJustifyBlockV = 0x255,
   9.615 -            AppCtrlIndentDecrease = 0x256,
   9.616 -            AppCtrlIndentIncrease = 0x257,
   9.617 -            AppCtrlNumberedList = 0x258,
   9.618 -            AppCtrlRestartNumbering = 0x259,
   9.619 -            AppCtrlBulletedList = 0x25A,
   9.620 -            AppCtrlPromote = 0x25B,
   9.621 -            AppCtrlDemote = 0x25C,
   9.622 -            AppCtrlYes = 0x25D,
   9.623 -            AppCtrlNo = 0x25E,
   9.624 -            AppCtrlCancel = 0x25F,
   9.625 -            AppCtrlCatalog = 0x260,
   9.626 -            AppCtrlBuyCheckout = 0x261,
   9.627 -            AppCtrlAddToCart = 0x262,
   9.628 -            AppCtrlExpand = 0x263,
   9.629 -            AppCtrlExpandAll = 0x264,
   9.630 -            AppCtrlCollapse = 0x265,
   9.631 -            AppCtrlCollapseAll = 0x266,
   9.632 -            AppCtrlPrintPreview = 0x267,
   9.633 -            AppCtrlPasteSpecial = 0x268,
   9.634 -            AppCtrlInsertMode = 0x269,
   9.635 -            AppCtrlDelete = 0x26A,
   9.636 -            AppCtrlLock = 0x26B,
   9.637 -            AppCtrlUnlock = 0x26C,
   9.638 -            AppCtrlProtect = 0x26D,
   9.639 -            AppCtrlUnprotect = 0x26E,
   9.640 -            AppCtrlAttachComment = 0x26F,
   9.641 -            AppCtrlDeleteComment = 0x270,
   9.642 -            AppCtrlViewComment = 0x271,
   9.643 -            AppCtrlSelectWord = 0x272,
   9.644 -            AppCtrlSelectSentence = 0x273,
   9.645 -            AppCtrlSelectParagraph = 0x274,
   9.646 -            AppCtrlSelectColumn = 0x275,
   9.647 -            AppCtrlSelectRow = 0x276,
   9.648 -            AppCtrlSelectTable = 0x277,
   9.649 -            AppCtrlSelectObject = 0x278,
   9.650 -            AppCtrlRedoRepeat = 0x279,
   9.651 -            AppCtrlSort = 0x27A,
   9.652 -            AppCtrlSortAscending = 0x27B,
   9.653 -            AppCtrlSortDescending = 0x27C,
   9.654 -            AppCtrlFilter = 0x27D,
   9.655 -            AppCtrlSetClock = 0x27E,
   9.656 -            AppCtrlViewClock = 0x27F,
   9.657 -            AppCtrlSelectTimeZone = 0x280,
   9.658 -            AppCtrlEditTimeZones = 0x281,
   9.659 -            AppCtrlSetAlarm = 0x282,
   9.660 -            AppCtrlClearAlarm = 0x283,
   9.661 -            AppCtrlSnoozeAlarm = 0x284,
   9.662 -            AppCtrlResetAlarm = 0x285,
   9.663 -            AppCtrlSynchronize = 0x286,
   9.664 -            AppCtrlSendReceive = 0x287,
   9.665 -            AppCtrlSendTo = 0x288,
   9.666 -            AppCtrlReply = 0x289,
   9.667 -            AppCtrlReplyAll = 0x28A,
   9.668 -            AppCtrlForwardMsg = 0x28B,
   9.669 -            AppCtrlSend = 0x28C,
   9.670 -            AppCtrlAttachFile = 0x28D,
   9.671 -            AppCtrlUpload = 0x28E,
   9.672 -            AppCtrlDownloadSaveTargetAs = 0x28F,
   9.673 -            AppCtrlSetBorders = 0x290,
   9.674 -            AppCtrlInsertRow = 0x291,
   9.675 -            AppCtrlInsertColumn = 0x292,
   9.676 -            AppCtrlInsertFile = 0x293,
   9.677 -            AppCtrlInsertPicture = 0x294,
   9.678 -            AppCtrlInsertObject = 0x295,
   9.679 -            AppCtrlInsertSymbol = 0x296,
   9.680 -            AppCtrlSaveAndClose = 0x297,
   9.681 -            AppCtrlRename = 0x298,
   9.682 -            AppCtrlMerge = 0x299,
   9.683 -            AppCtrlSplit = 0x29A,
   9.684 -            AppCtrlDistributeHorizontally = 0x29B,
   9.685 -            AppCtrlDistributeVertically = 0x29C
   9.686 -        }
   9.687 -
   9.688 -        /// <summary>
   9.689 -        ///
   9.690 -        /// </summary>
   9.691 -        enum GenericDesktop : ushort
   9.692 -        {
   9.693 -            Null = 0x00,
   9.694 -            Pointer = 0x01,
   9.695 -            Mouse = 0x02,
   9.696 -            Joystick = 0x04,
   9.697 -            GamePad = 0x05,
   9.698 -            Keyboard = 0x06,
   9.699 -            Keypad = 0x07,
   9.700 -            MultiAxisController = 0x08,
   9.701 -            TabletPcSystemControls = 0x09,
   9.702 -            X = 0x30,
   9.703 -            Y = 0x31,
   9.704 -            Z = 0x32,
   9.705 -            Rx = 0x33,
   9.706 -            Ry = 0x34,
   9.707 -            Rz = 0x35,
   9.708 -            Slider = 0x36,
   9.709 -            Dial = 0x37,
   9.710 -            Wheel = 0x38,
   9.711 -            HatSwitch = 0x39,
   9.712 -            CountedBuffer = 0x3A,
   9.713 -            ByteCount = 0x3B,
   9.714 -            MotionWakeup = 0x3C,
   9.715 -            Start = 0x3D,
   9.716 -            Select = 0x3E,
   9.717 -            Vx = 0x40,
   9.718 -            Vy = 0x41,
   9.719 -            Vz = 0x42,
   9.720 -            Vbrx = 0x43,
   9.721 -            Vbry = 0x44,
   9.722 -            Vbrz = 0x45,
   9.723 -            Vno = 0x46,
   9.724 -            SystemControl = 0x80,
   9.725 -            SystemPowerDown = 0x81,
   9.726 -            SystemSleep = 0x82,
   9.727 -            SystemWakeUp = 0x83,
   9.728 -            SystemContextMenu = 0x84,
   9.729 -            SystemMainMenu = 0x85,
   9.730 -            SystemAppMenu = 0x86,
   9.731 -            SystemMenuHelp = 0x87,
   9.732 -            SystemMenuExit = 0x88,
   9.733 -            SystemMenuSelect = 0x89,
   9.734 -            SystemMenuRight = 0x8A,
   9.735 -            SystemMenuLeft = 0x8B,
   9.736 -            SystemMenuUp = 0x8C,
   9.737 -            SystemMenuDown = 0x8D,
   9.738 -            SystemColdRestart = 0x8E,
   9.739 -            SystemWarmRestart = 0x8F,
   9.740 -            DPadUp = 0x90,
   9.741 -            DPadDown = 0x91,
   9.742 -            DPadRight = 0x92,
   9.743 -            DPadLeft = 0x93,
   9.744 -            SystemDock = 0xA0,
   9.745 -            SystemUndock = 0xA1,
   9.746 -            SystemSetup = 0xA2,
   9.747 -            SystemBreak = 0xA3,
   9.748 -            SystemDebuggerBreak = 0xA4,
   9.749 -            ApplicationBreak = 0xA5,
   9.750 -            ApplicationDebuggerBreak = 0xA6,
   9.751 -            SystemSpeakerMute = 0xA7,
   9.752 -            SystemHibernate = 0xA8,
   9.753 -            SystemDisplayInvert = 0xB0,
   9.754 -            SystemDisplayInternal = 0xB1,
   9.755 -            SystemDisplayExternal = 0xB2,
   9.756 -            SystemDisplayBoth = 0xB3,
   9.757 -            SystemDisplayDual = 0xB4,
   9.758 -            SystemDisplayToggleIntExt = 0xB5,
   9.759 -            SystemDisplaySwapPrimarySecondary = 0xB6,
   9.760 -            SystemDisplayLcdAutoscale = 0xB7
   9.761 -        }
   9.762 -
   9.763 -        /// <summary>
   9.764 -        ///
   9.765 -        /// </summary>
   9.766 -        enum SimulationControl : ushort
   9.767 -        {
   9.768 -            Null = 0x00,
   9.769 -            FlightSimulationDevice = 0x01,
   9.770 -            AutomobileSimulationDevice = 0x02,
   9.771 -            TankSimulationDevice = 0x03,
   9.772 -            SpaceshipSimulationDevice = 0x04,
   9.773 -            SubmarineSimulationDevice = 0x05,
   9.774 -            SailingSimulationDevice = 0x06,
   9.775 -            MotorcycleSimulationDevice = 0x07,
   9.776 -            SportsSimulationDevice = 0x08,
   9.777 -            AirplaneSimulationDevice = 0x09,
   9.778 -            HelicopterSimulationDevice = 0x0A,
   9.779 -            MagicCarpetSimulationDevice = 0x0B,
   9.780 -            BicycleSimulationDevice = 0x0C,
   9.781 -            FlightControlStick = 0x20,
   9.782 -            FlightStick = 0x21,
   9.783 -            CyclicControl = 0x22,
   9.784 -            CyclicTrim = 0x23,
   9.785 -            FlightYoke = 0x24,
   9.786 -            TrackControl = 0x25,
   9.787 -            Aileron = 0xB0,
   9.788 -            AileronTrim = 0xB1,
   9.789 -            AntiTorqueControl = 0xB2,
   9.790 -            AutopilotEnable = 0xB3,
   9.791 -            ChaffRelease = 0xB4,
   9.792 -            CollectiveControl = 0xB5,
   9.793 -            DiveBrake = 0xB6,
   9.794 -            ElectronicCountermeasures = 0xB7,
   9.795 -            Elevator = 0xB8,
   9.796 -            ElevatorTrim = 0xB9,
   9.797 -            Rudder = 0xBA,
   9.798 -            Throttle = 0xBB,
   9.799 -            FlightCommunications = 0xBC,
   9.800 -            FlareRelease = 0xBD,
   9.801 -            LandingGear = 0xBE,
   9.802 -            ToeBrake = 0xBF,
   9.803 -            Trigger = 0xC0,
   9.804 -            WeaponsArm = 0xC1,
   9.805 -            WeaponsSelect = 0xC2,
   9.806 -            WingFlaps = 0xC3,
   9.807 -            Accelerator = 0xC4,
   9.808 -            Brake = 0xC5,
   9.809 -            Clutch = 0xC6,
   9.810 -            Shifter = 0xC7,
   9.811 -            Steering = 0xC8,
   9.812 -            TurretDirection = 0xC9,
   9.813 -            BarrelElevation = 0xCA,
   9.814 -            DivePlane = 0xCB,
   9.815 -            Ballast = 0xCC,
   9.816 -            BicycleCrank = 0xCD,
   9.817 -            HandleBars = 0xCE,
   9.818 -            FrontBrake = 0xCF,
   9.819 -            RearBrake = 0xD0
   9.820 -        }
   9.821 -
   9.822 -        /// <summary>
   9.823 -        ///
   9.824 -        /// </summary>
   9.825 -        enum GameControl : ushort
   9.826 -        {
   9.827 -            Null = 0x00,
   9.828 -            GameController3D = 0x01,
   9.829 -            PinballDevice = 0x02,
   9.830 -            GunDevice = 0x03,
   9.831 -            PointOfView = 0x20,
   9.832 -            TurnRightLeft = 0x21,
   9.833 -            PitchForwardBackward = 0x22,
   9.834 -            RollRightLeft = 0x23,
   9.835 -            MoveRightLeft = 0x24,
   9.836 -            MoveForwardBackward = 0x25,
   9.837 -            MoveUpDown = 0x26,
   9.838 -            LeanRightLeft = 0x27,
   9.839 -            LeanForwardBackward = 0x28,
   9.840 -            HeightOfPov = 0x29,
   9.841 -            Flipper = 0x2A,
   9.842 -            SecondaryFlipper = 0x2B,
   9.843 -            Bump = 0x2C,
   9.844 -            NewGame = 0x2D,
   9.845 -            ShootBall = 0x2E,
   9.846 -            Player = 0x2F,
   9.847 -            GunBolt = 0x30,
   9.848 -            GunClip = 0x31,
   9.849 -            GunSelector = 0x32,
   9.850 -            GunSingleShot = 0x33,
   9.851 -            GunBurst = 0x34,
   9.852 -            GunAutomatic = 0x35,
   9.853 -            GunSafety = 0x36,
   9.854 -            GamepadFireJump = 0x37,
   9.855 -            GamepadTrigger = 0x39
   9.856 -        }
   9.857 -
   9.858 -        /// <summary>
   9.859 -        ///
   9.860 -        /// </summary>
   9.861 -        enum TelephonyDevice : ushort
   9.862 -        {
   9.863 -            Null = 0x00,
   9.864 -            Phone = 0x01,
   9.865 -            AnsweringMachine = 0x02,
   9.866 -            MessageControls = 0x03,
   9.867 -            Handset = 0x04,
   9.868 -            Headset = 0x05,
   9.869 -            TelephonyKeyPad = 0x06,
   9.870 -            ProgrammableButton = 0x07,
   9.871 -            HookSwitch = 0x20,
   9.872 -            Flash = 0x21,
   9.873 -            Feature = 0x22,
   9.874 -            Hold = 0x23,
   9.875 -            Redial = 0x24,
   9.876 -            Transfer = 0x25,
   9.877 -            Drop = 0x26,
   9.878 -            Park = 0x27,
   9.879 -            ForwardCalls = 0x28,
   9.880 -            AlternateFunction = 0x29,
   9.881 -            Line = 0x2A,
   9.882 -            SpeakerPhone = 0x2B,
   9.883 -            Conference = 0x2C,
   9.884 -            RingEnable = 0x2D,
   9.885 -            RingSelect = 0x2E,
   9.886 -            PhoneMute = 0x2F,
   9.887 -            CallerId = 0x30,
   9.888 -            Send = 0x31,
   9.889 -            SpeedDial = 0x50,
   9.890 -            StoreNumber = 0x51,
   9.891 -            RecallNumber = 0x52,
   9.892 -            PhoneDirectory = 0x53,
   9.893 -            VoiceMail = 0x70,
   9.894 -            ScreenCalls = 0x71,
   9.895 -            DoNotDisturb = 0x72,
   9.896 -            Message = 0x73,
   9.897 -            AnswerOnOff = 0x74,
   9.898 -            InsideDialTone = 0x90,
   9.899 -            OutsideDialTone = 0x91,
   9.900 -            InsideRingTone = 0x92,
   9.901 -            OutsideRingTone = 0x93,
   9.902 -            PriorityRingTone = 0x94,
   9.903 -            InsideRingback = 0x95,
   9.904 -            PriorityRingback = 0x96,
   9.905 -            LineBusyTone = 0x97,
   9.906 -            ReorderTone = 0x98,
   9.907 -            CallWaitingTone = 0x99,
   9.908 -            ConfirmationTone1 = 0x9A,
   9.909 -            ConfirmationTone2 = 0x9B,
   9.910 -            TonesOff = 0x9C,
   9.911 -            OutsideRingback = 0x9D,
   9.912 -            Ringer = 0x9E,
   9.913 -            PhoneKey0 = 0xB0,
   9.914 -            PhoneKey1 = 0xB1,
   9.915 -            PhoneKey2 = 0xB2,
   9.916 -            PhoneKey3 = 0xB3,
   9.917 -            PhoneKey4 = 0xB4,
   9.918 -            PhoneKey5 = 0xB5,
   9.919 -            PhoneKey6 = 0xB6,
   9.920 -            PhoneKey7 = 0xB7,
   9.921 -            PhoneKey8 = 0xB8,
   9.922 -            PhoneKey9 = 0xB9,
   9.923 -            PhoneKeyStar = 0xBA,
   9.924 -            PhoneKeyPound = 0xBB,
   9.925 -            PhoneKeyA = 0xBC,
   9.926 -            PhoneKeyB = 0xBD,
   9.927 -            PhoneKeyC = 0xBE,
   9.928 -            PhoneKeyD = 0xBF
   9.929 -        }
   9.930 -    }
   9.931 -}
   9.932 \ No newline at end of file
    10.1 --- a/HidUtils.cs	Sun Mar 15 16:56:31 2015 +0100
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,84 +0,0 @@
    10.4 -//
    10.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
    10.6 -//
    10.7 -// This file is part of SharpLibHid.
    10.8 -//
    10.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
   10.10 -// it under the terms of the GNU General Public License as published by
   10.11 -// the Free Software Foundation, either version 3 of the License, or
   10.12 -// (at your option) any later version.
   10.13 -//
   10.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
   10.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.17 -// GNU General Public License for more details.
   10.18 -//
   10.19 -// You should have received a copy of the GNU General Public License
   10.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   10.21 -//
   10.22 -
   10.23 -using System;
   10.24 -using System.Collections.Generic;
   10.25 -using System.Text;
   10.26 -
   10.27 -namespace SharpLib.Hid
   10.28 -{
   10.29 -    static class Utils
   10.30 -    {
   10.31 -        /// <summary>
   10.32 -        /// Provide the type for the usage collection corresponding to the given usage page.
   10.33 -        /// </summary>
   10.34 -        /// <param name="aUsagePage"></param>
   10.35 -        /// <returns></returns>
   10.36 -        public static Type UsageCollectionType(UsagePage aUsagePage)
   10.37 -        {
   10.38 -            switch (aUsagePage)
   10.39 -            {
   10.40 -                case UsagePage.GenericDesktopControls:
   10.41 -                    return typeof(UsageCollection.GenericDesktop);
   10.42 -
   10.43 -                case UsagePage.Consumer:
   10.44 -                    return typeof(UsageCollection.Consumer);
   10.45 -
   10.46 -                case UsagePage.WindowsMediaCenterRemoteControl:
   10.47 -                    return typeof(UsageCollection.WindowsMediaCenter);
   10.48 -
   10.49 -                default:
   10.50 -                    return null;
   10.51 -            }
   10.52 -        }
   10.53 -
   10.54 -        /// <summary>
   10.55 -        /// Provide the type for the usage corresponding to the given usage page.
   10.56 -        /// </summary>
   10.57 -        /// <param name="aUsagePage"></param>
   10.58 -        /// <returns></returns>
   10.59 -        public static Type UsageType(UsagePage aUsagePage)
   10.60 -        {
   10.61 -            switch (aUsagePage)
   10.62 -            {
   10.63 -                case UsagePage.GenericDesktopControls:
   10.64 -                    return typeof(Usage.GenericDesktop);
   10.65 -
   10.66 -                case UsagePage.Consumer:
   10.67 -                    return typeof(Usage.ConsumerControl);
   10.68 -
   10.69 -                case UsagePage.WindowsMediaCenterRemoteControl:
   10.70 -                    return typeof(Usage.WindowsMediaCenterRemoteControl);
   10.71 -
   10.72 -                case UsagePage.Telephony:
   10.73 -                    return typeof(Usage.TelephonyDevice);
   10.74 -
   10.75 -                case UsagePage.SimulationControls:
   10.76 -                    return typeof(Usage.SimulationControl);
   10.77 -
   10.78 -                case UsagePage.GameControls:
   10.79 -                    return typeof(Usage.GameControl);
   10.80 -
   10.81 -                default:
   10.82 -                    return null;
   10.83 -            }
   10.84 -        }
   10.85 -
   10.86 -    }
   10.87 -}
    11.1 --- a/RawInput.cs	Sun Mar 15 16:56:31 2015 +0100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,250 +0,0 @@
    11.4 -//
    11.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
    11.6 -//
    11.7 -// This file is part of SharpLibHid.
    11.8 -//
    11.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
   11.10 -// it under the terms of the GNU General Public License as published by
   11.11 -// the Free Software Foundation, either version 3 of the License, or
   11.12 -// (at your option) any later version.
   11.13 -//
   11.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
   11.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.17 -// GNU General Public License for more details.
   11.18 -//
   11.19 -// You should have received a copy of the GNU General Public License
   11.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   11.21 -//
   11.22 -
   11.23 -using System;
   11.24 -using System.Runtime.InteropServices;
   11.25 -using System.Diagnostics;
   11.26 -using System.Windows.Forms;
   11.27 -
   11.28 -namespace SharpLib.Win32
   11.29 -{
   11.30 -    /// <summary>
   11.31 -    /// Provide some utility functions for raw input handling.
   11.32 -    /// </summary>
   11.33 -    static public class RawInput
   11.34 -    {
   11.35 -        /// <summary>
   11.36 -        /// 
   11.37 -        /// </summary>
   11.38 -        /// <param name="aRawInputHandle"></param>
   11.39 -        /// <param name="aRawInput"></param>
   11.40 -        /// <param name="rawInputBuffer">Caller must free up memory on the pointer using Marshal.FreeHGlobal</param>
   11.41 -        /// <returns></returns>
   11.42 -        public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
   11.43 -        {
   11.44 -            bool success = true;
   11.45 -            rawInputBuffer = IntPtr.Zero;
   11.46 -
   11.47 -            try
   11.48 -            {
   11.49 -                uint dwSize = 0;
   11.50 -                uint sizeOfHeader = (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
   11.51 -
   11.52 -                //Get the size of our raw input data.
   11.53 -                Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);
   11.54 -
   11.55 -                //Allocate a large enough buffer
   11.56 -                 rawInputBuffer = Marshal.AllocHGlobal((int)dwSize);
   11.57 -
   11.58 -                //Now read our RAWINPUT data
   11.59 -                if (Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
   11.60 -                {
   11.61 -                    return false;
   11.62 -                }
   11.63 -
   11.64 -                //Cast our buffer
   11.65 -                aRawInput = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
   11.66 -            }
   11.67 -            catch
   11.68 -            {
   11.69 -                Debug.WriteLine("GetRawInputData failed!");
   11.70 -                success = false;
   11.71 -            }
   11.72 -
   11.73 -            return success;
   11.74 -        }
   11.75 -
   11.76 -        /// <summary>
   11.77 -        /// 
   11.78 -        /// </summary>
   11.79 -        /// <param name="hDevice"></param>
   11.80 -        /// <param name="deviceInfo"></param>
   11.81 -        /// <returns></returns>
   11.82 -        public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
   11.83 -        {
   11.84 -            bool success = true;
   11.85 -            IntPtr deviceInfoBuffer = IntPtr.Zero;
   11.86 -            try
   11.87 -            {
   11.88 -                //Get Device Info
   11.89 -                uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
   11.90 -                deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
   11.91 -
   11.92 -                int res = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.RawInputDeviceInfoType.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
   11.93 -                if (res <= 0)
   11.94 -                {
   11.95 -                    Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
   11.96 -                    return false;
   11.97 -                }
   11.98 -
   11.99 -                //Cast our buffer
  11.100 -                deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
  11.101 -            }
  11.102 -            catch
  11.103 -            {
  11.104 -                Debug.WriteLine("GetRawInputData failed!");
  11.105 -                success = false;
  11.106 -            }
  11.107 -            finally
  11.108 -            {
  11.109 -                //Always executes, prevents memory leak
  11.110 -                Marshal.FreeHGlobal(deviceInfoBuffer);
  11.111 -            }
  11.112 -
  11.113 -            
  11.114 -            return success;
  11.115 -        }
  11.116 -
  11.117 -        /// <summary>
  11.118 -        /// Fetch pre-parsed data corresponding to HID descriptor for the given HID device.
  11.119 -        /// </summary>
  11.120 -        /// <param name="device"></param>
  11.121 -        /// <returns></returns>
  11.122 -        public static IntPtr GetPreParsedData(IntPtr hDevice)
  11.123 -        {
  11.124 -            uint ppDataSize = 0;
  11.125 -            int result = Win32.Function.GetRawInputDeviceInfo(hDevice, RawInputDeviceInfoType.RIDI_PREPARSEDDATA, IntPtr.Zero, ref ppDataSize);
  11.126 -            if (result != 0)
  11.127 -            {
  11.128 -                Debug.WriteLine("Failed to get raw input pre-parsed data size: " + result + " : " + Marshal.GetLastWin32Error());
  11.129 -                return IntPtr.Zero;
  11.130 -            }
  11.131 -
  11.132 -            IntPtr ppData = Marshal.AllocHGlobal((int)ppDataSize);
  11.133 -            result = Win32.Function.GetRawInputDeviceInfo(hDevice, RawInputDeviceInfoType.RIDI_PREPARSEDDATA, ppData, ref ppDataSize);
  11.134 -            if (result <= 0)
  11.135 -            {
  11.136 -                Debug.WriteLine("Failed to get raw input pre-parsed data: " + result + " : " + Marshal.GetLastWin32Error());
  11.137 -                return IntPtr.Zero;
  11.138 -            }
  11.139 -            return ppData;
  11.140 -        }
  11.141 -
  11.142 -        /// <summary>
  11.143 -        /// 
  11.144 -        /// </summary>
  11.145 -        /// <param name="device"></param>
  11.146 -        /// <returns></returns>
  11.147 -        public static string GetDeviceName(IntPtr device)
  11.148 -        {
  11.149 -            uint deviceNameSize = 256;
  11.150 -            int result = Win32.Function.GetRawInputDeviceInfo(device, RawInputDeviceInfoType.RIDI_DEVICENAME, IntPtr.Zero, ref deviceNameSize);
  11.151 -            if (result != 0)
  11.152 -            {
  11.153 -                return string.Empty;
  11.154 -            }
  11.155 -
  11.156 -            IntPtr deviceName = Marshal.AllocHGlobal((int)deviceNameSize * 2);  // size is the character count not byte count
  11.157 -            try
  11.158 -            {
  11.159 -                result = Win32.Function.GetRawInputDeviceInfo(device, RawInputDeviceInfoType.RIDI_DEVICENAME, deviceName, ref deviceNameSize);
  11.160 -                if (result > 0)
  11.161 -                {
  11.162 -                    return Marshal.PtrToStringAnsi(deviceName, result - 1); // -1 for NULL termination
  11.163 -                }
  11.164 -
  11.165 -                return string.Empty;
  11.166 -            }
  11.167 -            finally
  11.168 -            {
  11.169 -                Marshal.FreeHGlobal(deviceName);
  11.170 -            }
  11.171 -        }
  11.172 -
  11.173 -
  11.174 -        /// <summary>
  11.175 -        /// Populate the given tree-view control with our Raw Input Devices.
  11.176 -        /// </summary>
  11.177 -        /// <param name="aTreeView"></param>
  11.178 -        public static void PopulateDeviceList(TreeView aTreeView)
  11.179 -        {
  11.180 -
  11.181 -            //Get our list of devices
  11.182 -            RAWINPUTDEVICELIST[] ridList = null;
  11.183 -            uint deviceCount = 0;
  11.184 -            int res = Win32.Function.GetRawInputDeviceList(ridList, ref deviceCount,(uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST)));
  11.185 -            if (res == -1)
  11.186 -            {
  11.187 -                //Just give up then
  11.188 -                return;
  11.189 -            }
  11.190 -
  11.191 -            ridList = new RAWINPUTDEVICELIST[deviceCount];
  11.192 -            res = Win32.Function.GetRawInputDeviceList(ridList, ref deviceCount, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST)));
  11.193 -            if (res != deviceCount)
  11.194 -            {
  11.195 -                //Just give up then
  11.196 -                return;
  11.197 -            }
  11.198 -
  11.199 -            //For each our device add a node to our treeview
  11.200 -            foreach (RAWINPUTDEVICELIST device in ridList)
  11.201 -            {
  11.202 -                SharpLib.Hid.HidDevice hidDevice=new SharpLib.Hid.HidDevice(device.hDevice);
  11.203 -
  11.204 -                TreeNode node = null;
  11.205 -                if (hidDevice.Product != null && hidDevice.Product.Length > 1)
  11.206 -                {
  11.207 -                    //Add the devices with a proper name at the top
  11.208 -                    node = aTreeView.Nodes.Insert(0, hidDevice.Name, hidDevice.FriendlyName);
  11.209 -                }
  11.210 -                else
  11.211 -                {
  11.212 -                    //Add other once at the bottom
  11.213 -                    node = aTreeView.Nodes.Add(hidDevice.Name, hidDevice.FriendlyName);
  11.214 -                }
  11.215 -
  11.216 -                node.Nodes.Add("Manufacturer: " + hidDevice.Manufacturer);
  11.217 -                node.Nodes.Add("Product ID: 0x" + hidDevice.ProductId.ToString("X4"));
  11.218 -                node.Nodes.Add("Vendor ID: 0x" + hidDevice.VendorId.ToString("X4"));
  11.219 -                node.Nodes.Add("Version: " + hidDevice.Version);
  11.220 -                node.Nodes.Add(hidDevice.Info.dwType.ToString());
  11.221 -                if (hidDevice.Info.dwType == RawInputDeviceType.RIM_TYPEHID)
  11.222 -                {
  11.223 -                    node.Nodes.Add("UsagePage / UsageCollection: 0x" + hidDevice.Info.hid.usUsagePage.ToString("X4") + " / 0x" + hidDevice.Info.hid.usUsage.ToString("X4"));
  11.224 -                }
  11.225 -
  11.226 -                if (hidDevice.InputCapabilitiesDescription != null)
  11.227 -                {
  11.228 -                    node.Nodes.Add(hidDevice.InputCapabilitiesDescription);
  11.229 -                }
  11.230 -
  11.231 -                //Add button count
  11.232 -                node.Nodes.Add("Button Count: " + hidDevice.ButtonCount);
  11.233 -
  11.234 -                //Those can be joystick/gamepad axis
  11.235 -                if (hidDevice.InputValueCapabilities != null)
  11.236 -                {
  11.237 -                    foreach (HIDP_VALUE_CAPS caps in hidDevice.InputValueCapabilities)
  11.238 -                    {
  11.239 -                        string des = SharpLib.Hid.HidDevice.InputValueCapabilityDescription(caps);
  11.240 -                        if (des != null)
  11.241 -                        {
  11.242 -                            node.Nodes.Add(des);
  11.243 -                        }
  11.244 -                    }
  11.245 -
  11.246 -                }
  11.247 -
  11.248 -                node.Nodes.Add(hidDevice.Name);
  11.249 -            }
  11.250 -        }
  11.251 -
  11.252 -    }
  11.253 -}
  11.254 \ No newline at end of file
    12.1 --- a/SharpLibHid.csproj	Sun Mar 15 16:56:31 2015 +0100
    12.2 +++ b/SharpLibHid.csproj	Sun Mar 15 20:25:58 2015 +0100
    12.3 @@ -42,17 +42,27 @@
    12.4      <Reference Include="System.Xml" />
    12.5    </ItemGroup>
    12.6    <ItemGroup>
    12.7 -    <Compile Include="HidDevice.cs" />
    12.8 -    <Compile Include="HidEvent.cs" />
    12.9 -    <Compile Include="HidHandler.cs" />
   12.10 -    <Compile Include="HidUsageTables.cs" />
   12.11 -    <Compile Include="HidUtils.cs" />
   12.12 +    <Compile Include="Hid\HidDevice.cs">
   12.13 +      <SubType>Code</SubType>
   12.14 +    </Compile>
   12.15 +    <Compile Include="Hid\HidEvent.cs">
   12.16 +      <SubType>Code</SubType>
   12.17 +    </Compile>
   12.18 +    <Compile Include="Hid\HidHandler.cs">
   12.19 +      <SubType>Code</SubType>
   12.20 +    </Compile>
   12.21 +    <Compile Include="Hid\HidUsageTables.cs">
   12.22 +      <SubType>Code</SubType>
   12.23 +    </Compile>
   12.24 +    <Compile Include="Hid\HidUtils.cs">
   12.25 +      <SubType>Code</SubType>
   12.26 +    </Compile>
   12.27      <Compile Include="Properties\AssemblyInfo.cs" />
   12.28 -    <Compile Include="RawInput.cs" />
   12.29 -    <Compile Include="Win32AppCommand.cs" />
   12.30 -    <Compile Include="Win32CreateFile.cs" />
   12.31 -    <Compile Include="Win32Hid.cs" />
   12.32 -    <Compile Include="Win32RawInput.cs" />
   12.33 +    <Compile Include="Win32\RawInput.cs" />
   12.34 +    <Compile Include="Win32\Win32AppCommand.cs" />
   12.35 +    <Compile Include="Win32\Win32CreateFile.cs" />
   12.36 +    <Compile Include="Win32\Win32Hid.cs" />
   12.37 +    <Compile Include="Win32\Win32RawInput.cs" />
   12.38    </ItemGroup>
   12.39    <ItemGroup>
   12.40      <COMReference Include="stdole">
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/Win32/RawInput.cs	Sun Mar 15 20:25:58 2015 +0100
    13.3 @@ -0,0 +1,250 @@
    13.4 +//
    13.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
    13.6 +//
    13.7 +// This file is part of SharpLibHid.
    13.8 +//
    13.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
   13.10 +// it under the terms of the GNU General Public License as published by
   13.11 +// the Free Software Foundation, either version 3 of the License, or
   13.12 +// (at your option) any later version.
   13.13 +//
   13.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
   13.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.17 +// GNU General Public License for more details.
   13.18 +//
   13.19 +// You should have received a copy of the GNU General Public License
   13.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   13.21 +//
   13.22 +
   13.23 +using System;
   13.24 +using System.Runtime.InteropServices;
   13.25 +using System.Diagnostics;
   13.26 +using System.Windows.Forms;
   13.27 +
   13.28 +namespace SharpLib.Win32
   13.29 +{
   13.30 +    /// <summary>
   13.31 +    /// Provide some utility functions for raw input handling.
   13.32 +    /// </summary>
   13.33 +    static public class RawInput
   13.34 +    {
   13.35 +        /// <summary>
   13.36 +        /// 
   13.37 +        /// </summary>
   13.38 +        /// <param name="aRawInputHandle"></param>
   13.39 +        /// <param name="aRawInput"></param>
   13.40 +        /// <param name="rawInputBuffer">Caller must free up memory on the pointer using Marshal.FreeHGlobal</param>
   13.41 +        /// <returns></returns>
   13.42 +        public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
   13.43 +        {
   13.44 +            bool success = true;
   13.45 +            rawInputBuffer = IntPtr.Zero;
   13.46 +
   13.47 +            try
   13.48 +            {
   13.49 +                uint dwSize = 0;
   13.50 +                uint sizeOfHeader = (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
   13.51 +
   13.52 +                //Get the size of our raw input data.
   13.53 +                Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);
   13.54 +
   13.55 +                //Allocate a large enough buffer
   13.56 +                 rawInputBuffer = Marshal.AllocHGlobal((int)dwSize);
   13.57 +
   13.58 +                //Now read our RAWINPUT data
   13.59 +                if (Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
   13.60 +                {
   13.61 +                    return false;
   13.62 +                }
   13.63 +
   13.64 +                //Cast our buffer
   13.65 +                aRawInput = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
   13.66 +            }
   13.67 +            catch
   13.68 +            {
   13.69 +                Debug.WriteLine("GetRawInputData failed!");
   13.70 +                success = false;
   13.71 +            }
   13.72 +
   13.73 +            return success;
   13.74 +        }
   13.75 +
   13.76 +        /// <summary>
   13.77 +        /// 
   13.78 +        /// </summary>
   13.79 +        /// <param name="hDevice"></param>
   13.80 +        /// <param name="deviceInfo"></param>
   13.81 +        /// <returns></returns>
   13.82 +        public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
   13.83 +        {
   13.84 +            bool success = true;
   13.85 +            IntPtr deviceInfoBuffer = IntPtr.Zero;
   13.86 +            try
   13.87 +            {
   13.88 +                //Get Device Info
   13.89 +                uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
   13.90 +                deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
   13.91 +
   13.92 +                int res = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.RawInputDeviceInfoType.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
   13.93 +                if (res <= 0)
   13.94 +                {
   13.95 +                    Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
   13.96 +                    return false;
   13.97 +                }
   13.98 +
   13.99 +                //Cast our buffer
  13.100 +                deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
  13.101 +            }
  13.102 +            catch
  13.103 +            {
  13.104 +                Debug.WriteLine("GetRawInputData failed!");
  13.105 +                success = false;
  13.106 +            }
  13.107 +            finally
  13.108 +            {
  13.109 +                //Always executes, prevents memory leak
  13.110 +                Marshal.FreeHGlobal(deviceInfoBuffer);
  13.111 +            }
  13.112 +
  13.113 +            
  13.114 +            return success;
  13.115 +        }
  13.116 +
  13.117 +        /// <summary>
  13.118 +        /// Fetch pre-parsed data corresponding to HID descriptor for the given HID device.
  13.119 +        /// </summary>
  13.120 +        /// <param name="device"></param>
  13.121 +        /// <returns></returns>
  13.122 +        public static IntPtr GetPreParsedData(IntPtr hDevice)
  13.123 +        {
  13.124 +            uint ppDataSize = 0;
  13.125 +            int result = Win32.Function.GetRawInputDeviceInfo(hDevice, RawInputDeviceInfoType.RIDI_PREPARSEDDATA, IntPtr.Zero, ref ppDataSize);
  13.126 +            if (result != 0)
  13.127 +            {
  13.128 +                Debug.WriteLine("Failed to get raw input pre-parsed data size: " + result + " : " + Marshal.GetLastWin32Error());
  13.129 +                return IntPtr.Zero;
  13.130 +            }
  13.131 +
  13.132 +            IntPtr ppData = Marshal.AllocHGlobal((int)ppDataSize);
  13.133 +            result = Win32.Function.GetRawInputDeviceInfo(hDevice, RawInputDeviceInfoType.RIDI_PREPARSEDDATA, ppData, ref ppDataSize);
  13.134 +            if (result <= 0)
  13.135 +            {
  13.136 +                Debug.WriteLine("Failed to get raw input pre-parsed data: " + result + " : " + Marshal.GetLastWin32Error());
  13.137 +                return IntPtr.Zero;
  13.138 +            }
  13.139 +            return ppData;
  13.140 +        }
  13.141 +
  13.142 +        /// <summary>
  13.143 +        /// 
  13.144 +        /// </summary>
  13.145 +        /// <param name="device"></param>
  13.146 +        /// <returns></returns>
  13.147 +        public static string GetDeviceName(IntPtr device)
  13.148 +        {
  13.149 +            uint deviceNameSize = 256;
  13.150 +            int result = Win32.Function.GetRawInputDeviceInfo(device, RawInputDeviceInfoType.RIDI_DEVICENAME, IntPtr.Zero, ref deviceNameSize);
  13.151 +            if (result != 0)
  13.152 +            {
  13.153 +                return string.Empty;
  13.154 +            }
  13.155 +
  13.156 +            IntPtr deviceName = Marshal.AllocHGlobal((int)deviceNameSize * 2);  // size is the character count not byte count
  13.157 +            try
  13.158 +            {
  13.159 +                result = Win32.Function.GetRawInputDeviceInfo(device, RawInputDeviceInfoType.RIDI_DEVICENAME, deviceName, ref deviceNameSize);
  13.160 +                if (result > 0)
  13.161 +                {
  13.162 +                    return Marshal.PtrToStringAnsi(deviceName, result - 1); // -1 for NULL termination
  13.163 +                }
  13.164 +
  13.165 +                return string.Empty;
  13.166 +            }
  13.167 +            finally
  13.168 +            {
  13.169 +                Marshal.FreeHGlobal(deviceName);
  13.170 +            }
  13.171 +        }
  13.172 +
  13.173 +
  13.174 +        /// <summary>
  13.175 +        /// Populate the given tree-view control with our Raw Input Devices.
  13.176 +        /// </summary>
  13.177 +        /// <param name="aTreeView"></param>
  13.178 +        public static void PopulateDeviceList(TreeView aTreeView)
  13.179 +        {
  13.180 +
  13.181 +            //Get our list of devices
  13.182 +            RAWINPUTDEVICELIST[] ridList = null;
  13.183 +            uint deviceCount = 0;
  13.184 +            int res = Win32.Function.GetRawInputDeviceList(ridList, ref deviceCount,(uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST)));
  13.185 +            if (res == -1)
  13.186 +            {
  13.187 +                //Just give up then
  13.188 +                return;
  13.189 +            }
  13.190 +
  13.191 +            ridList = new RAWINPUTDEVICELIST[deviceCount];
  13.192 +            res = Win32.Function.GetRawInputDeviceList(ridList, ref deviceCount, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST)));
  13.193 +            if (res != deviceCount)
  13.194 +            {
  13.195 +                //Just give up then
  13.196 +                return;
  13.197 +            }
  13.198 +
  13.199 +            //For each our device add a node to our treeview
  13.200 +            foreach (RAWINPUTDEVICELIST device in ridList)
  13.201 +            {
  13.202 +                SharpLib.Hid.HidDevice hidDevice=new SharpLib.Hid.HidDevice(device.hDevice);
  13.203 +
  13.204 +                TreeNode node = null;
  13.205 +                if (hidDevice.Product != null && hidDevice.Product.Length > 1)
  13.206 +                {
  13.207 +                    //Add the devices with a proper name at the top
  13.208 +                    node = aTreeView.Nodes.Insert(0, hidDevice.Name, hidDevice.FriendlyName);
  13.209 +                }
  13.210 +                else
  13.211 +                {
  13.212 +                    //Add other once at the bottom
  13.213 +                    node = aTreeView.Nodes.Add(hidDevice.Name, hidDevice.FriendlyName);
  13.214 +                }
  13.215 +
  13.216 +                node.Nodes.Add("Manufacturer: " + hidDevice.Manufacturer);
  13.217 +                node.Nodes.Add("Product ID: 0x" + hidDevice.ProductId.ToString("X4"));
  13.218 +                node.Nodes.Add("Vendor ID: 0x" + hidDevice.VendorId.ToString("X4"));
  13.219 +                node.Nodes.Add("Version: " + hidDevice.Version);
  13.220 +                node.Nodes.Add(hidDevice.Info.dwType.ToString());
  13.221 +                if (hidDevice.Info.dwType == RawInputDeviceType.RIM_TYPEHID)
  13.222 +                {
  13.223 +                    node.Nodes.Add("UsagePage / UsageCollection: 0x" + hidDevice.Info.hid.usUsagePage.ToString("X4") + " / 0x" + hidDevice.Info.hid.usUsage.ToString("X4"));
  13.224 +                }
  13.225 +
  13.226 +                if (hidDevice.InputCapabilitiesDescription != null)
  13.227 +                {
  13.228 +                    node.Nodes.Add(hidDevice.InputCapabilitiesDescription);
  13.229 +                }
  13.230 +
  13.231 +                //Add button count
  13.232 +                node.Nodes.Add("Button Count: " + hidDevice.ButtonCount);
  13.233 +
  13.234 +                //Those can be joystick/gamepad axis
  13.235 +                if (hidDevice.InputValueCapabilities != null)
  13.236 +                {
  13.237 +                    foreach (HIDP_VALUE_CAPS caps in hidDevice.InputValueCapabilities)
  13.238 +                    {
  13.239 +                        string des = SharpLib.Hid.HidDevice.InputValueCapabilityDescription(caps);
  13.240 +                        if (des != null)
  13.241 +                        {
  13.242 +                            node.Nodes.Add(des);
  13.243 +                        }
  13.244 +                    }
  13.245 +
  13.246 +                }
  13.247 +
  13.248 +                node.Nodes.Add(hidDevice.Name);
  13.249 +            }
  13.250 +        }
  13.251 +
  13.252 +    }
  13.253 +}
  13.254 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/Win32/Win32AppCommand.cs	Sun Mar 15 20:25:58 2015 +0100
    14.3 @@ -0,0 +1,37 @@
    14.4 +//
    14.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
    14.6 +//
    14.7 +// This file is part of SharpLibHid.
    14.8 +//
    14.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
   14.10 +// it under the terms of the GNU General Public License as published by
   14.11 +// the Free Software Foundation, either version 3 of the License, or
   14.12 +// (at your option) any later version.
   14.13 +//
   14.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
   14.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.17 +// GNU General Public License for more details.
   14.18 +//
   14.19 +// You should have received a copy of the GNU General Public License
   14.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   14.21 +//
   14.22 +
   14.23 +using System;
   14.24 +using System.Runtime.InteropServices;
   14.25 +
   14.26 +namespace SharpLib.Win32
   14.27 +{
   14.28 +    static public partial class Const
   14.29 +    {
   14.30 +        public const int WM_APPCOMMAND = 0x0319;
   14.31 +    }
   14.32 +
   14.33 +    static public partial class Macro
   14.34 +    {
   14.35 +        public static int GET_APPCOMMAND_LPARAM(IntPtr lParam)
   14.36 +        {
   14.37 +            return ((short)HIWORD(lParam.ToInt32()) & ~Const.FAPPCOMMAND_MASK);
   14.38 +        }
   14.39 +    }
   14.40 +}
   14.41 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/Win32/Win32CreateFile.cs	Sun Mar 15 20:25:58 2015 +0100
    15.3 @@ -0,0 +1,228 @@
    15.4 +//
    15.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
    15.6 +//
    15.7 +// This file is part of SharpLibHid.
    15.8 +//
    15.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
   15.10 +// it under the terms of the GNU General Public License as published by
   15.11 +// the Free Software Foundation, either version 3 of the License, or
   15.12 +// (at your option) any later version.
   15.13 +//
   15.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
   15.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.17 +// GNU General Public License for more details.
   15.18 +//
   15.19 +// You should have received a copy of the GNU General Public License
   15.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   15.21 +//
   15.22 +
   15.23 +using System;
   15.24 +using System.Runtime.InteropServices;
   15.25 +using Microsoft.Win32.SafeHandles;
   15.26 +
   15.27 +namespace SharpLib.Win32
   15.28 +{
   15.29 +
   15.30 +    static partial class Function
   15.31 +    {
   15.32 +        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
   15.33 +        public static extern SafeFileHandle CreateFile(
   15.34 +             [MarshalAs(UnmanagedType.LPTStr)] string lpFileName,
   15.35 +             [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
   15.36 +             [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
   15.37 +             IntPtr lpSecurityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
   15.38 +             [MarshalAs(UnmanagedType.U4)] CreationDisposition dwCreationDisposition,
   15.39 +             [MarshalAs(UnmanagedType.U4)] FileFlagsAttributes dwFlagsAndAttributes,
   15.40 +             IntPtr hTemplateFile);
   15.41 +
   15.42 +        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
   15.43 +        public static extern SafeFileHandle CreateFileA(
   15.44 +             [MarshalAs(UnmanagedType.LPStr)] string lpFileName,
   15.45 +             [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
   15.46 +             [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
   15.47 +             IntPtr lpSecurityAttributes,
   15.48 +             [MarshalAs(UnmanagedType.U4)] CreationDisposition dwCreationDisposition,
   15.49 +             [MarshalAs(UnmanagedType.U4)] FileFlagsAttributes dwFlagsAndAttributes,
   15.50 +             IntPtr hTemplateFile);
   15.51 +
   15.52 +        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
   15.53 +        public static extern SafeFileHandle CreateFileW(
   15.54 +             [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
   15.55 +             [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
   15.56 +             [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
   15.57 +             IntPtr lpSecurityAttributes,
   15.58 +             [MarshalAs(UnmanagedType.U4)] CreationDisposition dwCreationDisposition,
   15.59 +             [MarshalAs(UnmanagedType.U4)] FileFlagsAttributes dwFlagsAndAttributes,
   15.60 +             IntPtr hTemplateFile);
   15.61 +    }
   15.62 +
   15.63 +
   15.64 +    static partial class Macro
   15.65 +    {
   15.66 +
   15.67 +    }
   15.68 +
   15.69 +
   15.70 +
   15.71 +    static partial class Const
   15.72 +    {
   15.73 +
   15.74 +    }
   15.75 +
   15.76 +    [Flags]
   15.77 +    enum FileAccess : uint
   15.78 +    {
   15.79 +        NONE = 0,
   15.80 +
   15.81 +        GENERIC_ALL = 0x10000000,
   15.82 +        GENERIC_EXECUTE = 0x20000000,
   15.83 +        GENERIC_READ = 0x80000000,
   15.84 +        GENERIC_WRITE = 0x40000000,
   15.85 +
   15.86 +        FILE_READ_DATA = (0x0001),  // file & pipe
   15.87 +        FILE_LIST_DIRECTORY = (0x0001),  // directory
   15.88 +
   15.89 +        FILE_WRITE_DATA = (0x0002),   // file & pipe
   15.90 +        FILE_ADD_FILE = (0x0002),  // directory
   15.91 +
   15.92 +        FILE_APPEND_DATA = (0x0004), // file
   15.93 +        FILE_ADD_SUBDIRECTORY = (0x0004),  // directory
   15.94 +        FILE_CREATE_PIPE_INSTANCE = (0x0004),   // named pipe
   15.95 +
   15.96 +        FILE_READ_EA = (0x0008),  // file & directory
   15.97 +
   15.98 +        FILE_WRITE_EA = (0x0010),    // file & directory
   15.99 +
  15.100 +        FILE_EXECUTE = (0x0020),    // file
  15.101 +        FILE_TRAVERSE = (0x0020),    // directory
  15.102 +
  15.103 +        FILE_DELETE_CHILD = (0x0040),    // directory
  15.104 +
  15.105 +        FILE_READ_ATTRIBUTES = (0x0080),    // all
  15.106 +
  15.107 +        FILE_WRITE_ATTRIBUTES = (0x0100),    // all
  15.108 +
  15.109 +        FILE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF),
  15.110 +
  15.111 +        FILE_GENERIC_READ = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE),
  15.112 +        FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE),
  15.113 +        FILE_GENERIC_EXECUTE = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE),
  15.114 +
  15.115 +        DELETE = (0x00010000),
  15.116 +        READ_CONTROL = (0x00020000),
  15.117 +        WRITE_DAC = (0x00040000),
  15.118 +        WRITE_OWNER = (0x00080000),
  15.119 +        SYNCHRONIZE = (0x00100000),
  15.120 +
  15.121 +        STANDARD_RIGHTS_REQUIRED = (0x000F0000),
  15.122 +
  15.123 +        STANDARD_RIGHTS_READ = (READ_CONTROL),
  15.124 +        STANDARD_RIGHTS_WRITE = (READ_CONTROL),
  15.125 +        STANDARD_RIGHTS_EXECUTE = (READ_CONTROL),
  15.126 +
  15.127 +        STANDARD_RIGHTS_ALL = (0x001F0000),
  15.128 +
  15.129 +        SPECIFIC_RIGHTS_ALL = (0x0000FFFF),
  15.130 +
  15.131 +        ACCESS_SYSTEM_SECURITY = (0x01000000),
  15.132 +
  15.133 +        MAXIMUM_ALLOWED = (0x02000000)
  15.134 +    }
  15.135 +    
  15.136 +
  15.137 +
  15.138 +    [Flags]
  15.139 +    public enum FileShare : uint
  15.140 +    {
  15.141 +        /// <summary>
  15.142 +        /// Prevents other processes from opening a file or device if they request delete, read, or write access.
  15.143 +        /// </summary>
  15.144 +        FILE_SHARE_NONE = 0x00000000,
  15.145 +        /// <summary>
  15.146 +        /// Enables subsequent open operations on an object to request read access.
  15.147 +        /// Otherwise, other processes cannot open the object if they request read access.
  15.148 +        /// If this flag is not specified, but the object has been opened for read access, the function fails.
  15.149 +        /// </summary>
  15.150 +        FILE_SHARE_READ = 0x00000001,
  15.151 +        /// <summary>
  15.152 +        /// Enables subsequent open operations on an object to request write access.
  15.153 +        /// Otherwise, other processes cannot open the object if they request write access.
  15.154 +        /// If this flag is not specified, but the object has been opened for write access, the function fails.
  15.155 +        /// </summary>
  15.156 +        FILE_SHARE_WRITE = 0x00000002,
  15.157 +        /// <summary>
  15.158 +        /// Enables subsequent open operations on an object to request delete access.
  15.159 +        /// Otherwise, other processes cannot open the object if they request delete access.
  15.160 +        /// If this flag is not specified, but the object has been opened for delete access, the function fails.
  15.161 +        /// </summary>
  15.162 +        FILE_SHARE_DELETE = 0x00000004
  15.163 +    }
  15.164 +
  15.165 +    public enum CreationDisposition : uint
  15.166 +    {
  15.167 +        /// <summary>
  15.168 +        /// Creates a new file. The function fails if a specified file exists.
  15.169 +        /// </summary>
  15.170 +        CREATE_NEW = 1,
  15.171 +        /// <summary>
  15.172 +        /// Creates a new file, always.
  15.173 +        /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
  15.174 +        /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
  15.175 +        /// </summary>
  15.176 +        CREATE_ALWAYS = 2,
  15.177 +        /// <summary>
  15.178 +        /// Opens a file. The function fails if the file does not exist.
  15.179 +        /// </summary>
  15.180 +        OPEN_EXISTING = 3,
  15.181 +        /// <summary>
  15.182 +        /// Opens a file, always.
  15.183 +        /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
  15.184 +        /// </summary>
  15.185 +        OPEN_ALWAYS = 4,
  15.186 +        /// <summary>
  15.187 +        /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
  15.188 +        /// The calling process must open the file with the GENERIC_WRITE access right.
  15.189 +        /// </summary>
  15.190 +        TRUNCATE_EXISTING = 5
  15.191 +    }
  15.192 +
  15.193 +    [Flags]
  15.194 +    public enum FileFlagsAttributes : uint
  15.195 +    {
  15.196 +        FILE_ATTRIBUTE_READONLY = 0x00000001,
  15.197 +        FILE_ATTRIBUTE_HIDDEN = 0x00000002,
  15.198 +        FILE_ATTRIBUTE_SYSTEM = 0x00000004,
  15.199 +        FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
  15.200 +        FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
  15.201 +        FILE_ATTRIBUTE_DEVICE = 0x00000040,
  15.202 +        FILE_ATTRIBUTE_NORMAL = 0x00000080,
  15.203 +        FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
  15.204 +        FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
  15.205 +        FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
  15.206 +        FILE_ATTRIBUTE_COMPRESSED = 0x00000800,
  15.207 +        FILE_ATTRIBUTE_OFFLINE = 0x00001000,
  15.208 +        FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
  15.209 +        FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
  15.210 +        FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000,
  15.211 +        FILE_ATTRIBUTE_VIRTUAL = 0x00010000,
  15.212 +        FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000,
  15.213 +        //  These are flags supported through CreateFile (W7) and CreateFile2 (W8 and beyond)
  15.214 +        FILE_FLAG_WRITE_THROUGH = 0x80000000,
  15.215 +        FILE_FLAG_OVERLAPPED = 0x40000000,
  15.216 +        FILE_FLAG_NO_BUFFERING = 0x20000000,
  15.217 +        FILE_FLAG_RANDOM_ACCESS = 0x10000000,
  15.218 +        FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000,
  15.219 +        FILE_FLAG_DELETE_ON_CLOSE = 0x04000000,
  15.220 +        FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
  15.221 +        FILE_FLAG_POSIX_SEMANTICS = 0x01000000,
  15.222 +        FILE_FLAG_SESSION_AWARE = 0x00800000,
  15.223 +        FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,
  15.224 +        FILE_FLAG_OPEN_NO_RECALL = 0x00100000,
  15.225 +        FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000
  15.226 +    }
  15.227 +
  15.228 +
  15.229 +
  15.230 +
  15.231 +}
  15.232 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/Win32/Win32Hid.cs	Sun Mar 15 20:25:58 2015 +0100
    16.3 @@ -0,0 +1,515 @@
    16.4 +//
    16.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
    16.6 +//
    16.7 +// This file is part of SharpLibHid.
    16.8 +//
    16.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
   16.10 +// it under the terms of the GNU General Public License as published by
   16.11 +// the Free Software Foundation, either version 3 of the License, or
   16.12 +// (at your option) any later version.
   16.13 +//
   16.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
   16.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.17 +// GNU General Public License for more details.
   16.18 +//
   16.19 +// You should have received a copy of the GNU General Public License
   16.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   16.21 +//
   16.22 +
   16.23 +using System;
   16.24 +using System.Runtime.InteropServices;
   16.25 +using Microsoft.Win32.SafeHandles;
   16.26 +using System.Text;
   16.27 +
   16.28 +namespace SharpLib.Win32
   16.29 +{
   16.30 +
   16.31 +    static partial class Function
   16.32 +    {
   16.33 +        [DllImport("hid.dll", CharSet = CharSet.Unicode)]
   16.34 +        public static extern HidStatus HidP_GetUsagesEx(HIDP_REPORT_TYPE ReportType, ushort LinkCollection, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] USAGE_AND_PAGE[] ButtonList, ref uint UsageLength, IntPtr PreparsedData, [MarshalAs(UnmanagedType.LPArray)] byte[] Report, uint ReportLength);
   16.35 +
   16.36 +        [DllImport("hid.dll", CharSet = CharSet.Auto, SetLastError = true)]
   16.37 +        public static extern Boolean HidD_GetManufacturerString(SafeFileHandle HidDeviceObject, StringBuilder Buffer, Int32 BufferLength);
   16.38 +
   16.39 +        [DllImport("hid.dll", CharSet = CharSet.Auto, SetLastError = true)]
   16.40 +        public static extern Boolean HidD_GetProductString(SafeFileHandle HidDeviceObject, StringBuilder Buffer, Int32 BufferLength);
   16.41 +
   16.42 +        [DllImport("hid.dll", CharSet = CharSet.Auto, SetLastError = true)]
   16.43 +        public static extern Boolean HidD_GetAttributes(SafeFileHandle HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
   16.44 +
   16.45 +        /// Return Type: NTSTATUS->LONG->int
   16.46 +        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   16.47 +        ///Capabilities: PHIDP_CAPS->_HIDP_CAPS*
   16.48 +        [DllImport("hid.dll", EntryPoint = "HidP_GetCaps", CallingConvention = CallingConvention.StdCall)]
   16.49 +        public static extern HidStatus HidP_GetCaps(System.IntPtr PreparsedData, ref HIDP_CAPS Capabilities);
   16.50 +
   16.51 +        /// Return Type: NTSTATUS->LONG->int
   16.52 +        ///ReportType: HIDP_REPORT_TYPE->_HIDP_REPORT_TYPE
   16.53 +        ///ButtonCaps: PHIDP_BUTTON_CAPS->_HIDP_BUTTON_CAPS*
   16.54 +        ///ButtonCapsLength: PUSHORT->USHORT*
   16.55 +        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   16.56 +        [DllImport("hid.dll", EntryPoint = "HidP_GetButtonCaps", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
   16.57 +        public static extern HidStatus HidP_GetButtonCaps(HIDP_REPORT_TYPE ReportType, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] HIDP_BUTTON_CAPS[] ButtonCaps, ref ushort ButtonCapsLength, System.IntPtr PreparsedData);
   16.58 +
   16.59 +        /// Return Type: NTSTATUS->LONG->int
   16.60 +        ///ReportType: HIDP_REPORT_TYPE->_HIDP_REPORT_TYPE
   16.61 +        ///ValueCaps: PHIDP_VALUE_CAPS->_HIDP_VALUE_CAPS*
   16.62 +        ///ValueCapsLength: PUSHORT->USHORT*
   16.63 +        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   16.64 +        [DllImport("hid.dll", EntryPoint = "HidP_GetValueCaps", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
   16.65 +        public static extern HidStatus HidP_GetValueCaps(HIDP_REPORT_TYPE ReportType, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] HIDP_VALUE_CAPS[] ValueCaps, ref ushort ValueCapsLength, System.IntPtr PreparsedData);
   16.66 +
   16.67 +        /// Return Type: NTSTATUS->LONG->int
   16.68 +        ///ReportType: HIDP_REPORT_TYPE->_HIDP_REPORT_TYPE
   16.69 +        ///UsagePage: USAGE->USHORT->unsigned short
   16.70 +        ///LinkCollection: USHORT->unsigned short
   16.71 +        ///Usage: USAGE->USHORT->unsigned short
   16.72 +        ///UsageValue: PULONG->ULONG*
   16.73 +        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   16.74 +        ///Report: PCHAR->CHAR*
   16.75 +        ///ReportLength: ULONG->unsigned int
   16.76 +        [DllImport("hid.dll", EntryPoint = "HidP_GetUsageValue", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
   16.77 +        public static extern HidStatus HidP_GetUsageValue(HIDP_REPORT_TYPE ReportType, ushort UsagePage, ushort LinkCollection, ushort Usage, ref uint UsageValue, System.IntPtr PreparsedData, [MarshalAs(UnmanagedType.LPArray)] byte[] Report, uint ReportLength);
   16.78 +
   16.79 +
   16.80 +
   16.81 +    }
   16.82 +
   16.83 +
   16.84 +    static partial class Macro
   16.85 +    {
   16.86 +
   16.87 +
   16.88 +    }
   16.89 +
   16.90 +
   16.91 +    static partial class Const
   16.92 +    {
   16.93 +
   16.94 +
   16.95 +    }
   16.96 +
   16.97 +
   16.98 +    public enum HIDP_REPORT_TYPE : ushort
   16.99 +    {
  16.100 +        HidP_Input = 0,
  16.101 +        HidP_Output,
  16.102 +        HidP_Feature
  16.103 +    }
  16.104 +
  16.105 +
  16.106 +    public enum HidStatus : uint
  16.107 +    {
  16.108 +        HIDP_STATUS_SUCCESS = 0x110000,
  16.109 +        HIDP_STATUS_NULL = 0x80110001,
  16.110 +        HIDP_STATUS_INVALID_PREPARSED_DATA = 0xc0110001,
  16.111 +        HIDP_STATUS_INVALID_REPORT_TYPE = 0xc0110002,
  16.112 +        HIDP_STATUS_INVALID_REPORT_LENGTH = 0xc0110003,
  16.113 +        HIDP_STATUS_USAGE_NOT_FOUND = 0xc0110004,
  16.114 +        HIDP_STATUS_VALUE_OUT_OF_RANGE = 0xc0110005,
  16.115 +        HIDP_STATUS_BAD_LOG_PHY_VALUES = 0xc0110006,
  16.116 +        HIDP_STATUS_BUFFER_TOO_SMALL = 0xc0110007,
  16.117 +        HIDP_STATUS_INTERNAL_ERROR = 0xc0110008,
  16.118 +        HIDP_STATUS_I8042_TRANS_UNKNOWN = 0xc0110009,
  16.119 +        HIDP_STATUS_INCOMPATIBLE_REPORT_ID = 0xc011000a,
  16.120 +        HIDP_STATUS_NOT_VALUE_ARRAY = 0xc011000b,
  16.121 +        HIDP_STATUS_IS_VALUE_ARRAY = 0xc011000c,
  16.122 +        HIDP_STATUS_DATA_INDEX_NOT_FOUND = 0xc011000d,
  16.123 +        HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE = 0xc011000e,
  16.124 +        HIDP_STATUS_BUTTON_NOT_PRESSED = 0xc011000f,
  16.125 +        HIDP_STATUS_REPORT_DOES_NOT_EXIST = 0xc0110010,
  16.126 +        HIDP_STATUS_NOT_IMPLEMENTED = 0xc0110020,
  16.127 +        HIDP_STATUS_I8242_TRANS_UNKNOWN = 0xc0110009
  16.128 +    }
  16.129 +
  16.130 +
  16.131 +    [StructLayout(LayoutKind.Sequential)]
  16.132 +    public struct USAGE_AND_PAGE
  16.133 +    {
  16.134 +        public ushort Usage;
  16.135 +        public ushort UsagePage;
  16.136 +    };
  16.137 +
  16.138 +    [StructLayout(LayoutKind.Sequential)]
  16.139 +    public struct HIDD_ATTRIBUTES
  16.140 +    {
  16.141 +        public uint Size;
  16.142 +        public ushort VendorID;
  16.143 +        public ushort ProductID;
  16.144 +        public ushort VersionNumber;
  16.145 +    }
  16.146 +
  16.147 +
  16.148 +    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  16.149 +    public struct HIDP_CAPS
  16.150 +    {
  16.151 +        /// USAGE->USHORT->unsigned short
  16.152 +        public ushort Usage;
  16.153 +
  16.154 +        /// USAGE->USHORT->unsigned short
  16.155 +        public ushort UsagePage;
  16.156 +
  16.157 +        /// USHORT->unsigned short
  16.158 +        public ushort InputReportByteLength;
  16.159 +
  16.160 +        /// USHORT->unsigned short
  16.161 +        public ushort OutputReportByteLength;
  16.162 +
  16.163 +        /// USHORT->unsigned short
  16.164 +        public ushort FeatureReportByteLength;
  16.165 +
  16.166 +        /// USHORT[17]
  16.167 +        [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 17, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U2)]
  16.168 +        public ushort[] Reserved;
  16.169 +
  16.170 +        /// USHORT->unsigned short
  16.171 +        public ushort NumberLinkCollectionNodes;
  16.172 +
  16.173 +        /// USHORT->unsigned short
  16.174 +        public ushort NumberInputButtonCaps;
  16.175 +
  16.176 +        /// USHORT->unsigned short
  16.177 +        public ushort NumberInputValueCaps;
  16.178 +
  16.179 +        /// USHORT->unsigned short
  16.180 +        public ushort NumberInputDataIndices;
  16.181 +
  16.182 +        /// USHORT->unsigned short
  16.183 +        public ushort NumberOutputButtonCaps;
  16.184 +
  16.185 +        /// USHORT->unsigned short
  16.186 +        public ushort NumberOutputValueCaps;
  16.187 +
  16.188 +        /// USHORT->unsigned short
  16.189 +        public ushort NumberOutputDataIndices;
  16.190 +
  16.191 +        /// USHORT->unsigned short
  16.192 +        public ushort NumberFeatureButtonCaps;
  16.193 +
  16.194 +        /// USHORT->unsigned short
  16.195 +        public ushort NumberFeatureValueCaps;
  16.196 +
  16.197 +        /// USHORT->unsigned short
  16.198 +        public ushort NumberFeatureDataIndices;
  16.199 +    }
  16.200 +
  16.201 +    /// <summary>
  16.202 +    /// Type created in place of an anonymous struct
  16.203 +    /// </summary>
  16.204 +    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  16.205 +    public struct HIDP_BUTTON_CAPS_RANGE
  16.206 +    {
  16.207 +
  16.208 +        /// USAGE->USHORT->unsigned short
  16.209 +        public ushort UsageMin;
  16.210 +
  16.211 +        /// USAGE->USHORT->unsigned short
  16.212 +        public ushort UsageMax;
  16.213 +
  16.214 +        /// USHORT->unsigned short
  16.215 +        public ushort StringMin;
  16.216 +
  16.217 +        /// USHORT->unsigned short
  16.218 +        public ushort StringMax;
  16.219 +
  16.220 +        /// USHORT->unsigned short
  16.221 +        public ushort DesignatorMin;
  16.222 +
  16.223 +        /// USHORT->unsigned short
  16.224 +        public ushort DesignatorMax;
  16.225 +
  16.226 +        /// USHORT->unsigned short
  16.227 +        public ushort DataIndexMin;
  16.228 +
  16.229 +        /// USHORT->unsigned short
  16.230 +        public ushort DataIndexMax;
  16.231 +    }
  16.232 +
  16.233 +    /// <summary>
  16.234 +    /// Type created in place of an anonymous struct
  16.235 +    /// </summary>
  16.236 +    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  16.237 +    public struct HIDP_BUTTON_CAPS_NOT_RANGE
  16.238 +    {
  16.239 +
  16.240 +        /// USAGE->USHORT->unsigned short
  16.241 +        public ushort Usage;
  16.242 +
  16.243 +        /// USAGE->USHORT->unsigned short
  16.244 +        public ushort Reserved1;
  16.245 +
  16.246 +        /// USHORT->unsigned short
  16.247 +        public ushort StringIndex;
  16.248 +
  16.249 +        /// USHORT->unsigned short
  16.250 +        public ushort Reserved2;
  16.251 +
  16.252 +        /// USHORT->unsigned short
  16.253 +        public ushort DesignatorIndex;
  16.254 +
  16.255 +        /// USHORT->unsigned short
  16.256 +        public ushort Reserved3;
  16.257 +
  16.258 +        /// USHORT->unsigned short
  16.259 +        public ushort DataIndex;
  16.260 +
  16.261 +        /// USHORT->unsigned short
  16.262 +        public ushort Reserved4;
  16.263 +    }
  16.264 +
  16.265 +    /// <summary>
  16.266 +    /// 
  16.267 +    /// </summary>
  16.268 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  16.269 +    public struct HIDP_BUTTON_CAPS
  16.270 +    {
  16.271 +        /// USAGE->USHORT->unsigned short
  16.272 +        [FieldOffset(0)]
  16.273 +        public ushort UsagePage;
  16.274 +
  16.275 +        /// UCHAR->unsigned char
  16.276 +        [FieldOffset(2)]
  16.277 +        public byte ReportID;
  16.278 +
  16.279 +        /// BOOLEAN->BYTE->unsigned char
  16.280 +        [FieldOffset(3)]
  16.281 +        [MarshalAs(UnmanagedType.U1)]
  16.282 +        public bool IsAlias;
  16.283 +
  16.284 +        /// USHORT->unsigned short
  16.285 +        [FieldOffset(4)]
  16.286 +        public ushort BitField;
  16.287 +
  16.288 +        /// USHORT->unsigned short
  16.289 +        [FieldOffset(6)]
  16.290 +        public ushort LinkCollection;
  16.291 +
  16.292 +        /// USAGE->USHORT->unsigned short
  16.293 +        [FieldOffset(8)]
  16.294 +        public ushort LinkUsage;
  16.295 +
  16.296 +        /// USAGE->USHORT->unsigned short
  16.297 +        [FieldOffset(10)]
  16.298 +        public ushort LinkUsagePage;
  16.299 +
  16.300 +        /// BOOLEAN->BYTE->unsigned char
  16.301 +        [FieldOffset(12)]
  16.302 +        [MarshalAs(UnmanagedType.U1)]
  16.303 +        public bool IsRange;
  16.304 +
  16.305 +        /// BOOLEAN->BYTE->unsigned char
  16.306 +        [FieldOffset(13)]
  16.307 +        [MarshalAs(UnmanagedType.U1)]
  16.308 +        public bool IsStringRange;
  16.309 +
  16.310 +        /// BOOLEAN->BYTE->unsigned char
  16.311 +        [FieldOffset(14)]
  16.312 +        [MarshalAs(UnmanagedType.U1)]
  16.313 +        public bool IsDesignatorRange;
  16.314 +
  16.315 +        /// BOOLEAN->BYTE->unsigned char
  16.316 +        [FieldOffset(15)]
  16.317 +        [MarshalAs(UnmanagedType.U1)]
  16.318 +        public bool IsAbsolute;
  16.319 +
  16.320 +        /// ULONG[10]
  16.321 +        [FieldOffset(16)]
  16.322 +        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10, ArraySubType = UnmanagedType.U4)]
  16.323 +        public uint[] Reserved;
  16.324 +
  16.325 +        /// Union Range/NotRange
  16.326 +        [FieldOffset(56)]
  16.327 +        public HIDP_BUTTON_CAPS_RANGE Range;
  16.328 +
  16.329 +        [FieldOffset(56)]
  16.330 +        public HIDP_BUTTON_CAPS_NOT_RANGE NotRange;       
  16.331 +    }
  16.332 +
  16.333 +    /// <summary>
  16.334 +    /// Type created in place of an anonymous struct
  16.335 +    /// </summary>
  16.336 +    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  16.337 +    public struct HIDP_VALUE_CAPS_RANGE
  16.338 +    {
  16.339 +
  16.340 +        /// USAGE->USHORT->unsigned short
  16.341 +        public ushort UsageMin;
  16.342 +
  16.343 +        /// USAGE->USHORT->unsigned short
  16.344 +        public ushort UsageMax;
  16.345 +
  16.346 +        /// USHORT->unsigned short
  16.347 +        public ushort StringMin;
  16.348 +
  16.349 +        /// USHORT->unsigned short
  16.350 +        public ushort StringMax;
  16.351 +
  16.352 +        /// USHORT->unsigned short
  16.353 +        public ushort DesignatorMin;
  16.354 +
  16.355 +        /// USHORT->unsigned short
  16.356 +        public ushort DesignatorMax;
  16.357 +
  16.358 +        /// USHORT->unsigned short
  16.359 +        public ushort DataIndexMin;
  16.360 +
  16.361 +        /// USHORT->unsigned short
  16.362 +        public ushort DataIndexMax;
  16.363 +    }
  16.364 +
  16.365 +    /// <summary>
  16.366 +    /// Type created in place of an anonymous struct
  16.367 +    /// </summary>
  16.368 +    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  16.369 +    public struct HIDP_VALUE_CAPS_NOT_RANGE
  16.370 +    {
  16.371 +
  16.372 +        /// USAGE->USHORT->unsigned short
  16.373 +        public ushort Usage;
  16.374 +
  16.375 +        /// USAGE->USHORT->unsigned short
  16.376 +        public ushort Reserved1;
  16.377 +
  16.378 +        /// USHORT->unsigned short
  16.379 +        public ushort StringIndex;
  16.380 +
  16.381 +        /// USHORT->unsigned short
  16.382 +        public ushort Reserved2;
  16.383 +
  16.384 +        /// USHORT->unsigned short
  16.385 +        public ushort DesignatorIndex;
  16.386 +
  16.387 +        /// USHORT->unsigned short
  16.388 +        public ushort Reserved3;
  16.389 +
  16.390 +        /// USHORT->unsigned short
  16.391 +        public ushort DataIndex;
  16.392 +
  16.393 +        /// USHORT->unsigned short
  16.394 +        public ushort Reserved4;
  16.395 +    }
  16.396 +
  16.397 +
  16.398 +    /// <summary>
  16.399 +    /// 
  16.400 +    /// </summary>
  16.401 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  16.402 +    public struct HIDP_VALUE_CAPS
  16.403 +    {
  16.404 +
  16.405 +        /// USAGE->USHORT->unsigned short
  16.406 +        [FieldOffset(0)]
  16.407 +        public ushort UsagePage;
  16.408 +
  16.409 +        /// UCHAR->unsigned char
  16.410 +        [FieldOffset(2)]
  16.411 +        public byte ReportID;
  16.412 +
  16.413 +        /// BOOLEAN->BYTE->unsigned char
  16.414 +        [FieldOffset(3)]
  16.415 +        [MarshalAs(UnmanagedType.U1)]
  16.416 +        public bool IsAlias;
  16.417 +
  16.418 +        /// USHORT->unsigned short
  16.419 +        [FieldOffset(4)]
  16.420 +        public ushort BitField;
  16.421 +
  16.422 +        /// USHORT->unsigned short
  16.423 +        [FieldOffset(6)]
  16.424 +        public ushort LinkCollection;
  16.425 +
  16.426 +        /// USAGE->USHORT->unsigned short
  16.427 +        [FieldOffset(8)]
  16.428 +        public ushort LinkUsage;
  16.429 +
  16.430 +        /// USAGE->USHORT->unsigned short
  16.431 +        [FieldOffset(10)]
  16.432 +        public ushort LinkUsagePage;
  16.433 +
  16.434 +        /// BOOLEAN->BYTE->unsigned char
  16.435 +        [FieldOffset(12)]
  16.436 +        [MarshalAs(UnmanagedType.U1)]
  16.437 +        public bool IsRange;
  16.438 +
  16.439 +        /// BOOLEAN->BYTE->unsigned char
  16.440 +        [FieldOffset(13)]
  16.441 +        [MarshalAs(UnmanagedType.U1)]
  16.442 +        public bool IsStringRange;
  16.443 +
  16.444 +        /// BOOLEAN->BYTE->unsigned char
  16.445 +        [FieldOffset(14)]
  16.446 +        [MarshalAs(UnmanagedType.U1)]
  16.447 +        public bool IsDesignatorRange;
  16.448 +
  16.449 +        /// BOOLEAN->BYTE->unsigned char
  16.450 +        [FieldOffset(15)]
  16.451 +        [MarshalAs(UnmanagedType.U1)]
  16.452 +        public bool IsAbsolute;
  16.453 +
  16.454 +        /// BOOLEAN->BYTE->unsigned char
  16.455 +        [FieldOffset(16)]
  16.456 +        [MarshalAs(UnmanagedType.U1)]
  16.457 +        public bool HasNull;
  16.458 +
  16.459 +        /// UCHAR->unsigned char
  16.460 +        [FieldOffset(17)]
  16.461 +        public byte Reserved;
  16.462 +
  16.463 +        /// USHORT->unsigned short
  16.464 +        [FieldOffset(18)]
  16.465 +        public ushort BitSize;
  16.466 +
  16.467 +        /// USHORT->unsigned short
  16.468 +        [FieldOffset(20)]
  16.469 +        public ushort ReportCount;
  16.470 +
  16.471 +        /// USHORT[5]
  16.472 +        /// We had to use 5 ushorts instead of an array to avoid alignment exception issues.
  16.473 +        [FieldOffset(22)]
  16.474 +        public ushort Reserved21;
  16.475 +        [FieldOffset(24)]
  16.476 +        public ushort Reserved22;
  16.477 +        [FieldOffset(26)]
  16.478 +        public ushort Reserved23;
  16.479 +        [FieldOffset(28)]
  16.480 +        public ushort Reserved24;
  16.481 +        [FieldOffset(30)]
  16.482 +        public ushort Reserved25;
  16.483 +
  16.484 +        /// ULONG->unsigned int
  16.485 +        [FieldOffset(32)]
  16.486 +        public uint UnitsExp;
  16.487 +
  16.488 +        /// ULONG->unsigned int
  16.489 +        [FieldOffset(36)]
  16.490 +        public uint Units;
  16.491 +
  16.492 +        /// LONG->int
  16.493 +        [FieldOffset(40)]
  16.494 +        public int LogicalMin;
  16.495 +
  16.496 +        /// LONG->int
  16.497 +        [FieldOffset(44)]
  16.498 +        public int LogicalMax;
  16.499 +
  16.500 +        /// LONG->int
  16.501 +        [FieldOffset(48)]
  16.502 +        public int PhysicalMin;
  16.503 +
  16.504 +        /// LONG->int
  16.505 +        [FieldOffset(52)]
  16.506 +        public int PhysicalMax;
  16.507 +
  16.508 +        /// Union Range/NotRange
  16.509 +        [FieldOffset(56)]
  16.510 +        public HIDP_VALUE_CAPS_RANGE Range;
  16.511 +
  16.512 +        [FieldOffset(56)]
  16.513 +        public HIDP_VALUE_CAPS_NOT_RANGE NotRange;
  16.514 +    }
  16.515 +    
  16.516 +}
  16.517 +
  16.518 +
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/Win32/Win32RawInput.cs	Sun Mar 15 20:25:58 2015 +0100
    17.3 @@ -0,0 +1,386 @@
    17.4 +//
    17.5 +// Copyright (C) 2014-2015 Stéphane Lenclud.
    17.6 +//
    17.7 +// This file is part of SharpLibHid.
    17.8 +//
    17.9 +// SharpDisplayManager is free software: you can redistribute it and/or modify
   17.10 +// it under the terms of the GNU General Public License as published by
   17.11 +// the Free Software Foundation, either version 3 of the License, or
   17.12 +// (at your option) any later version.
   17.13 +//
   17.14 +// SharpDisplayManager is distributed in the hope that it will be useful,
   17.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.17 +// GNU General Public License for more details.
   17.18 +//
   17.19 +// You should have received a copy of the GNU General Public License
   17.20 +// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   17.21 +//
   17.22 +
   17.23 +using System;
   17.24 +using System.Runtime.InteropServices;
   17.25 +
   17.26 +namespace SharpLib.Win32
   17.27 +{
   17.28 +
   17.29 +    static partial class Function
   17.30 +    {
   17.31 +        [DllImport("User32.dll", SetLastError = true)]
   17.32 +		public extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
   17.33 +
   17.34 +        [DllImport("User32.dll", SetLastError = true)]
   17.35 +		public extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
   17.36 +
   17.37 +   		[DllImport("User32.dll", SetLastError=true)]
   17.38 +        public extern static int GetRawInputDeviceInfo(IntPtr hDevice, RawInputDeviceInfoType uiCommand, IntPtr pData, ref uint pcbSize);
   17.39 +
   17.40 +        [DllImport("user32.dll", SetLastError = true)]
   17.41 +        public static extern int GetRawInputDeviceList(
   17.42 +            [In, Out] RAWINPUTDEVICELIST[] InputdeviceList,
   17.43 +            [In, Out] ref uint puiNumDevices,
   17.44 +            [In] uint cbSize);
   17.45 +
   17.46 +    }
   17.47 +
   17.48 +
   17.49 +    static partial class Macro
   17.50 +    {
   17.51 +        /// <summary>
   17.52 +        /// Retrieves the input code from wParam in WM_INPUT.
   17.53 +        /// See RIM_INPUT and RIM_INPUTSINK.
   17.54 +        /// </summary>
   17.55 +        /// <param name="wParam"></param>
   17.56 +        /// <returns></returns>
   17.57 +        public static int GET_RAWINPUT_CODE_WPARAM(IntPtr wParam)
   17.58 +        {
   17.59 +            return (wParam.ToInt32() & 0xff);
   17.60 +        }
   17.61 +
   17.62 +        public static int GET_DEVICE_LPARAM(IntPtr lParam)
   17.63 +        {
   17.64 +            return ((ushort)(HIWORD(lParam.ToInt32()) & Const.FAPPCOMMAND_MASK));
   17.65 +        }
   17.66 +
   17.67 +        public static int HIWORD(int val)
   17.68 +        {
   17.69 +            return ((val >> 16) & 0xffff);
   17.70 +        }
   17.71 +
   17.72 +
   17.73 +        //#define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
   17.74 +        //#define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))        
   17.75 +        //#define LOBYTE(w)           ((BYTE)(((DWORD_PTR)(w)) & 0xff))
   17.76 +        //#define HIBYTE(w)           ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))
   17.77 +
   17.78 +        //#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
   17.79 +        //#define GET_DEVICE_LPARAM(lParam)     ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
   17.80 +        //#define GET_MOUSEORKEY_LPARAM         GET_DEVICE_LPARAM
   17.81 +        //#define GET_FLAGS_LPARAM(lParam)      (LOWORD(lParam))
   17.82 +        //#define GET_KEYSTATE_LPARAM(lParam)   GET_FLAGS_LPARAM(lParam)
   17.83 +
   17.84 +    }
   17.85 +
   17.86 +
   17.87 +
   17.88 +    static partial class Const
   17.89 +    {
   17.90 +        /// <summary>
   17.91 +        /// Windows Messages
   17.92 +        /// </summary>
   17.93 +        public const int WM_KEYDOWN = 0x0100;
   17.94 +        public const int WM_INPUT = 0x00FF;
   17.95 +
   17.96 +
   17.97 +        //
   17.98 +        public const int RID_INPUT = 0x10000003;
   17.99 +        public const int RID_HEADER = 0x10000005;
  17.100 +
  17.101 +        /// <summary>
  17.102 +        /// Possible value taken by wParam for WM_INPUT.
  17.103 +        /// <para />
  17.104 +        /// Input occurred while the application was in the foreground. The application must call DefWindowProc so the system can perform cleanup.
  17.105 +        /// </summary>
  17.106 +        public const int RIM_INPUT = 0;
  17.107 +        /// <summary>
  17.108 +        /// Possible value taken by wParam for WM_INPUT.
  17.109 +        /// <para />
  17.110 +        /// Input occurred while the application was not in the foreground. The application must call DefWindowProc so the system can perform the cleanup.
  17.111 +        /// </summary>
  17.112 +        public const int RIM_INPUTSINK = 1;
  17.113 +
  17.114 +        /// <summary>
  17.115 +        /// If set, the application command keys are handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a keyboard device.
  17.116 +        /// </summary>        
  17.117 +        public const uint RIDEV_APPKEYS = 0x00000400;
  17.118 +
  17.119 +        /// <summary>
  17.120 +        /// If set, the mouse button click does not activate the other window.
  17.121 +        /// </summary>
  17.122 +	    public const uint RIDEV_CAPTUREMOUSE = 0x00000200;
  17.123 +        
  17.124 +        /// <summary>
  17.125 +        /// If set, this enables the caller to receive WM_INPUT_DEVICE_CHANGE notifications for device arrival and device removal.
  17.126 +        /// Windows XP:  This flag is not supported until Windows Vista
  17.127 +        /// </summary>
  17.128 +	    public const uint RIDEV_DEVNOTIFY = 0x00002000;
  17.129 +
  17.130 +        /// <summary>
  17.131 +        /// If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC whose usage page is already specified with RIDEV_PAGEONLY.
  17.132 +        /// </summary>
  17.133 +        public const uint RIDEV_EXCLUDE = 0x00000010;
  17.134 +
  17.135 +        /// <summary>
  17.136 +        /// If set, this enables the caller to receive input in the background only if the foreground application does not process it. In other words, if the foreground application is not registered for raw input, then the background application that is registered will receive the input.
  17.137 +        /// Windows XP:  This flag is not supported until Windows Vista
  17.138 +        /// </summary>
  17.139 +	    public const uint RIDEV_EXINPUTSINK = 0x00001000;
  17.140 +
  17.141 +        /// <summary>
  17.142 +        /// If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that hwndTarget must be specified.
  17.143 +        /// </summary>
  17.144 +	    public const uint RIDEV_INPUTSINK = 0x00000100;
  17.145 +
  17.146 +	    /// <summary>
  17.147 +	    /// If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. RIDEV_NOHOTKEYS can be specified even if RIDEV_NOLEGACY is not specified and hwndTarget is NULL.
  17.148 +	    /// </summary>
  17.149 +        public const uint RIDEV_NOHOTKEYS = 0x00000200;
  17.150 +
  17.151 +        /// <summary>
  17.152 +        /// If set, this prevents any devices specified by usUsagePage or usUsage from generating legacy messages. This is only for the mouse and keyboard. See Remarks.
  17.153 +        /// </summary>
  17.154 +        public const uint RIDEV_NOLEGACY = 0x00000030;
  17.155 +        
  17.156 +        /// <summary>
  17.157 +        /// If set, this specifies all devices whose top level collection is from the specified usUsagePage. Note that usUsage must be zero. To exclude a particular top level collection, use RIDEV_EXCLUDE.
  17.158 +        /// </summary>
  17.159 +        public const uint RIDEV_PAGEONLY = 0x00000020;
  17.160 +
  17.161 +	    /// <summary>
  17.162 +        /// If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a device which matches the top level collection.
  17.163 +	    /// </summary>
  17.164 +        public const uint RIDEV_REMOVE = 0x00000001;
  17.165 +
  17.166 +        public const int APPCOMMAND_BROWSER_BACKWARD = 1;
  17.167 +        public const int APPCOMMAND_VOLUME_MUTE = 8;
  17.168 +        public const int APPCOMMAND_VOLUME_DOWN = 9;
  17.169 +        public const int APPCOMMAND_VOLUME_UP = 10;
  17.170 +        public const int APPCOMMAND_MEDIA_NEXTTRACK = 11;
  17.171 +        public const int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
  17.172 +        public const int APPCOMMAND_MEDIA_STOP = 13;
  17.173 +        public const int APPCOMMAND_MEDIA_PLAY_PAUSE = 14;
  17.174 +        public const int APPCOMMAND_MEDIA_PLAY = 46;
  17.175 +        public const int APPCOMMAND_MEDIA_PAUSE = 47;
  17.176 +        public const int APPCOMMAND_MEDIA_RECORD = 48;
  17.177 +        public const int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
  17.178 +        public const int APPCOMMAND_MEDIA_REWIND = 50;
  17.179 +        public const int APPCOMMAND_MEDIA_CHANNEL_UP = 51;
  17.180 +        public const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
  17.181 +
  17.182 +        public const int FAPPCOMMAND_MASK = 0xF000;
  17.183 +        public const int FAPPCOMMAND_MOUSE = 0x8000;
  17.184 +        public const int FAPPCOMMAND_KEY = 0;
  17.185 +		public const int FAPPCOMMAND_OEM = 0x1000;
  17.186 +    }
  17.187 +
  17.188 +    /// <summary>
  17.189 +    /// Introduced this enum for consistency and easy of use.
  17.190 +    /// Naming of the Win32 constants were preserved.
  17.191 +    /// </summary>
  17.192 +    public enum RawInputDeviceType : uint
  17.193 +    {
  17.194 +        /// <summary>
  17.195 +        /// Data comes from a mouse.
  17.196 +        /// </summary>
  17.197 +        RIM_TYPEMOUSE = 0,
  17.198 +        /// <summary>
  17.199 +        /// Data comes from a keyboard.
  17.200 +        /// </summary>
  17.201 +        RIM_TYPEKEYBOARD = 1,
  17.202 +        /// <summary>
  17.203 +        /// Data comes from an HID that is not a keyboard or a mouse.
  17.204 +        /// </summary>
  17.205 +        RIM_TYPEHID = 2
  17.206 +    }
  17.207 +
  17.208 +    /// <summary>
  17.209 +    /// Introduced this enum for consistency and easy of use.
  17.210 +    /// Naming of the Win32 constants were preserved.
  17.211 +    /// </summary>
  17.212 +    public enum RawInputDeviceInfoType : uint
  17.213 +    {
  17.214 +         /// <summary>
  17.215 +        /// GetRawInputDeviceInfo pData points to a string that contains the device name.
  17.216 +        /// </summary>
  17.217 +        RIDI_DEVICENAME = 0x20000007,
  17.218 +        /// <summary>
  17.219 +        /// GetRawInputDeviceInfo For this uiCommand only, the value in pcbSize is the character count (not the byte count).
  17.220 +        /// </summary>
  17.221 +        RIDI_DEVICEINFO = 0x2000000b,
  17.222 +        /// <summary>
  17.223 +        /// GetRawInputDeviceInfo pData points to an RID_DEVICE_INFO structure.
  17.224 +        /// </summary>
  17.225 +        RIDI_PREPARSEDDATA = 0x20000005
  17.226 +    }
  17.227 +
  17.228 +
  17.229 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.230 +    public struct RAWINPUTDEVICELIST
  17.231 +    {
  17.232 +        public IntPtr hDevice;
  17.233 +        public RawInputDeviceType dwType;
  17.234 +    }
  17.235 +
  17.236 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.237 +    public struct RAWINPUTDEVICE
  17.238 +    {
  17.239 +        [MarshalAs(UnmanagedType.U2)]
  17.240 +        public ushort usUsagePage;
  17.241 +        [MarshalAs(UnmanagedType.U2)]
  17.242 +        public ushort usUsage;
  17.243 +        [MarshalAs(UnmanagedType.U4)]
  17.244 +        public uint dwFlags;
  17.245 +        public IntPtr hwndTarget;
  17.246 +    }
  17.247 +
  17.248 +
  17.249 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.250 +    public struct RAWINPUTHEADER
  17.251 +    {
  17.252 +        [MarshalAs(UnmanagedType.U4)]
  17.253 +        public RawInputDeviceType dwType;
  17.254 +        [MarshalAs(UnmanagedType.U4)]
  17.255 +        public int dwSize;
  17.256 +        public IntPtr hDevice;
  17.257 +        [MarshalAs(UnmanagedType.U4)]
  17.258 +        public int wParam;
  17.259 +    }
  17.260 +
  17.261 +
  17.262 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.263 +    public struct RAWHID
  17.264 +    {
  17.265 +        [MarshalAs(UnmanagedType.U4)]
  17.266 +        public uint dwSizeHid;
  17.267 +        [MarshalAs(UnmanagedType.U4)]
  17.268 +        public uint dwCount;
  17.269 +        //
  17.270 +        //BYTE  bRawData[1];
  17.271 +    }
  17.272 +
  17.273 +
  17.274 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.275 +    public struct BUTTONSSTR
  17.276 +    {
  17.277 +        [MarshalAs(UnmanagedType.U2)]
  17.278 +        public ushort usButtonFlags;
  17.279 +        [MarshalAs(UnmanagedType.U2)]
  17.280 +        public ushort usButtonData;
  17.281 +    }
  17.282 +
  17.283 +
  17.284 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  17.285 +    public struct RAWMOUSE
  17.286 +    {
  17.287 +        [MarshalAs(UnmanagedType.U2)]
  17.288 +        [FieldOffset(0)]
  17.289 +        public ushort usFlags;
  17.290 +        [MarshalAs(UnmanagedType.U4)]
  17.291 +        [FieldOffset(4)]
  17.292 +        public uint ulButtons;
  17.293 +        [FieldOffset(4)]
  17.294 +        public BUTTONSSTR buttonsStr;
  17.295 +        [MarshalAs(UnmanagedType.U4)]
  17.296 +        [FieldOffset(8)]
  17.297 +        public uint ulRawButtons;
  17.298 +        [MarshalAs(UnmanagedType.U4)]
  17.299 +        [FieldOffset(12)]
  17.300 +        public int lLastX;
  17.301 +        [MarshalAs(UnmanagedType.U4)]
  17.302 +        [FieldOffset(16)]
  17.303 +        public int lLastY;
  17.304 +        [MarshalAs(UnmanagedType.U4)]
  17.305 +        [FieldOffset(20)]
  17.306 +        public uint ulExtraInformation;
  17.307 +    }
  17.308 +
  17.309 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.310 +    public struct RAWKEYBOARD
  17.311 +    {
  17.312 +        [MarshalAs(UnmanagedType.U2)]
  17.313 +        public ushort MakeCode;
  17.314 +        [MarshalAs(UnmanagedType.U2)]
  17.315 +        public ushort Flags;
  17.316 +        [MarshalAs(UnmanagedType.U2)]
  17.317 +        public ushort Reserved;
  17.318 +        [MarshalAs(UnmanagedType.U2)]
  17.319 +        public ushort VKey;
  17.320 +        [MarshalAs(UnmanagedType.U4)]
  17.321 +        public uint Message;
  17.322 +        [MarshalAs(UnmanagedType.U4)]
  17.323 +        public uint ExtraInformation;
  17.324 +    }
  17.325 +
  17.326 +
  17.327 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  17.328 +    public struct RAWINPUT
  17.329 +    {
  17.330 +        [FieldOffset(0)]
  17.331 +        public RAWINPUTHEADER header;
  17.332 +        [FieldOffset(16)]
  17.333 +        public RAWMOUSE mouse;
  17.334 +        [FieldOffset(16)]
  17.335 +        public RAWKEYBOARD keyboard;
  17.336 +        [FieldOffset(16)]
  17.337 +        public RAWHID hid;
  17.338 +    }
  17.339 +
  17.340 +
  17.341 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.342 +    public struct RID_DEVICE_INFO_MOUSE
  17.343 +    {
  17.344 +        public uint dwId;
  17.345 +        public uint dwNumberOfButtons;
  17.346 +        public uint dwSampleRate;
  17.347 +        public bool fHasHorizontalWheel;
  17.348 +    }
  17.349 +
  17.350 +
  17.351 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.352 +    public struct RID_DEVICE_INFO_KEYBOARD
  17.353 +    {
  17.354 +        public uint dwType;
  17.355 +        public uint dwSubType;
  17.356 +        public uint dwKeyboardMode;
  17.357 +        public uint dwNumberOfFunctionKeys;
  17.358 +        public uint dwNumberOfIndicators;
  17.359 +        public uint dwNumberOfKeysTotal;
  17.360 +    }
  17.361 +
  17.362 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  17.363 +    public struct RID_DEVICE_INFO_HID
  17.364 +    {
  17.365 +        public uint dwVendorId;
  17.366 +        public uint dwProductId;
  17.367 +        public uint dwVersionNumber;
  17.368 +        public ushort usUsagePage;
  17.369 +        public ushort usUsage;
  17.370 +    }
  17.371 +
  17.372 +    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  17.373 +    public struct RID_DEVICE_INFO
  17.374 +    {
  17.375 +        [FieldOffset(0)]
  17.376 +        public uint cbSize;
  17.377 +        [FieldOffset(4)]
  17.378 +        [MarshalAs(UnmanagedType.U4)]
  17.379 +        public RawInputDeviceType dwType;
  17.380 +        [FieldOffset(8)]
  17.381 +        public RID_DEVICE_INFO_MOUSE mouse;
  17.382 +        [FieldOffset(8)]
  17.383 +        public RID_DEVICE_INFO_KEYBOARD keyboard;
  17.384 +        [FieldOffset(8)]
  17.385 +        public RID_DEVICE_INFO_HID hid;
  17.386 +    }
  17.387 +
  17.388 +
  17.389 +}
  17.390 \ No newline at end of file
    18.1 --- a/Win32AppCommand.cs	Sun Mar 15 16:56:31 2015 +0100
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,37 +0,0 @@
    18.4 -//
    18.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
    18.6 -//
    18.7 -// This file is part of SharpLibHid.
    18.8 -//
    18.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
   18.10 -// it under the terms of the GNU General Public License as published by
   18.11 -// the Free Software Foundation, either version 3 of the License, or
   18.12 -// (at your option) any later version.
   18.13 -//
   18.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
   18.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.17 -// GNU General Public License for more details.
   18.18 -//
   18.19 -// You should have received a copy of the GNU General Public License
   18.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   18.21 -//
   18.22 -
   18.23 -using System;
   18.24 -using System.Runtime.InteropServices;
   18.25 -
   18.26 -namespace SharpLib.Win32
   18.27 -{
   18.28 -    static public partial class Const
   18.29 -    {
   18.30 -        public const int WM_APPCOMMAND = 0x0319;
   18.31 -    }
   18.32 -
   18.33 -    static public partial class Macro
   18.34 -    {
   18.35 -        public static int GET_APPCOMMAND_LPARAM(IntPtr lParam)
   18.36 -        {
   18.37 -            return ((short)HIWORD(lParam.ToInt32()) & ~Const.FAPPCOMMAND_MASK);
   18.38 -        }
   18.39 -    }
   18.40 -}
   18.41 \ No newline at end of file
    19.1 --- a/Win32CreateFile.cs	Sun Mar 15 16:56:31 2015 +0100
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,228 +0,0 @@
    19.4 -//
    19.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
    19.6 -//
    19.7 -// This file is part of SharpLibHid.
    19.8 -//
    19.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
   19.10 -// it under the terms of the GNU General Public License as published by
   19.11 -// the Free Software Foundation, either version 3 of the License, or
   19.12 -// (at your option) any later version.
   19.13 -//
   19.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
   19.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.17 -// GNU General Public License for more details.
   19.18 -//
   19.19 -// You should have received a copy of the GNU General Public License
   19.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   19.21 -//
   19.22 -
   19.23 -using System;
   19.24 -using System.Runtime.InteropServices;
   19.25 -using Microsoft.Win32.SafeHandles;
   19.26 -
   19.27 -namespace SharpLib.Win32
   19.28 -{
   19.29 -
   19.30 -    static partial class Function
   19.31 -    {
   19.32 -        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
   19.33 -        public static extern SafeFileHandle CreateFile(
   19.34 -             [MarshalAs(UnmanagedType.LPTStr)] string lpFileName,
   19.35 -             [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
   19.36 -             [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
   19.37 -             IntPtr lpSecurityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
   19.38 -             [MarshalAs(UnmanagedType.U4)] CreationDisposition dwCreationDisposition,
   19.39 -             [MarshalAs(UnmanagedType.U4)] FileFlagsAttributes dwFlagsAndAttributes,
   19.40 -             IntPtr hTemplateFile);
   19.41 -
   19.42 -        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
   19.43 -        public static extern SafeFileHandle CreateFileA(
   19.44 -             [MarshalAs(UnmanagedType.LPStr)] string lpFileName,
   19.45 -             [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
   19.46 -             [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
   19.47 -             IntPtr lpSecurityAttributes,
   19.48 -             [MarshalAs(UnmanagedType.U4)] CreationDisposition dwCreationDisposition,
   19.49 -             [MarshalAs(UnmanagedType.U4)] FileFlagsAttributes dwFlagsAndAttributes,
   19.50 -             IntPtr hTemplateFile);
   19.51 -
   19.52 -        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
   19.53 -        public static extern SafeFileHandle CreateFileW(
   19.54 -             [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
   19.55 -             [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
   19.56 -             [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
   19.57 -             IntPtr lpSecurityAttributes,
   19.58 -             [MarshalAs(UnmanagedType.U4)] CreationDisposition dwCreationDisposition,
   19.59 -             [MarshalAs(UnmanagedType.U4)] FileFlagsAttributes dwFlagsAndAttributes,
   19.60 -             IntPtr hTemplateFile);
   19.61 -    }
   19.62 -
   19.63 -
   19.64 -    static partial class Macro
   19.65 -    {
   19.66 -
   19.67 -    }
   19.68 -
   19.69 -
   19.70 -
   19.71 -    static partial class Const
   19.72 -    {
   19.73 -
   19.74 -    }
   19.75 -
   19.76 -    [Flags]
   19.77 -    enum FileAccess : uint
   19.78 -    {
   19.79 -        NONE = 0,
   19.80 -
   19.81 -        GENERIC_ALL = 0x10000000,
   19.82 -        GENERIC_EXECUTE = 0x20000000,
   19.83 -        GENERIC_READ = 0x80000000,
   19.84 -        GENERIC_WRITE = 0x40000000,
   19.85 -
   19.86 -        FILE_READ_DATA = (0x0001),  // file & pipe
   19.87 -        FILE_LIST_DIRECTORY = (0x0001),  // directory
   19.88 -
   19.89 -        FILE_WRITE_DATA = (0x0002),   // file & pipe
   19.90 -        FILE_ADD_FILE = (0x0002),  // directory
   19.91 -
   19.92 -        FILE_APPEND_DATA = (0x0004), // file
   19.93 -        FILE_ADD_SUBDIRECTORY = (0x0004),  // directory
   19.94 -        FILE_CREATE_PIPE_INSTANCE = (0x0004),   // named pipe
   19.95 -
   19.96 -        FILE_READ_EA = (0x0008),  // file & directory
   19.97 -
   19.98 -        FILE_WRITE_EA = (0x0010),    // file & directory
   19.99 -
  19.100 -        FILE_EXECUTE = (0x0020),    // file
  19.101 -        FILE_TRAVERSE = (0x0020),    // directory
  19.102 -
  19.103 -        FILE_DELETE_CHILD = (0x0040),    // directory
  19.104 -
  19.105 -        FILE_READ_ATTRIBUTES = (0x0080),    // all
  19.106 -
  19.107 -        FILE_WRITE_ATTRIBUTES = (0x0100),    // all
  19.108 -
  19.109 -        FILE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF),
  19.110 -
  19.111 -        FILE_GENERIC_READ = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE),
  19.112 -        FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE),
  19.113 -        FILE_GENERIC_EXECUTE = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE),
  19.114 -
  19.115 -        DELETE = (0x00010000),
  19.116 -        READ_CONTROL = (0x00020000),
  19.117 -        WRITE_DAC = (0x00040000),
  19.118 -        WRITE_OWNER = (0x00080000),
  19.119 -        SYNCHRONIZE = (0x00100000),
  19.120 -
  19.121 -        STANDARD_RIGHTS_REQUIRED = (0x000F0000),
  19.122 -
  19.123 -        STANDARD_RIGHTS_READ = (READ_CONTROL),
  19.124 -        STANDARD_RIGHTS_WRITE = (READ_CONTROL),
  19.125 -        STANDARD_RIGHTS_EXECUTE = (READ_CONTROL),
  19.126 -
  19.127 -        STANDARD_RIGHTS_ALL = (0x001F0000),
  19.128 -
  19.129 -        SPECIFIC_RIGHTS_ALL = (0x0000FFFF),
  19.130 -
  19.131 -        ACCESS_SYSTEM_SECURITY = (0x01000000),
  19.132 -
  19.133 -        MAXIMUM_ALLOWED = (0x02000000)
  19.134 -    }
  19.135 -    
  19.136 -
  19.137 -
  19.138 -    [Flags]
  19.139 -    public enum FileShare : uint
  19.140 -    {
  19.141 -        /// <summary>
  19.142 -        /// Prevents other processes from opening a file or device if they request delete, read, or write access.
  19.143 -        /// </summary>
  19.144 -        FILE_SHARE_NONE = 0x00000000,
  19.145 -        /// <summary>
  19.146 -        /// Enables subsequent open operations on an object to request read access.
  19.147 -        /// Otherwise, other processes cannot open the object if they request read access.
  19.148 -        /// If this flag is not specified, but the object has been opened for read access, the function fails.
  19.149 -        /// </summary>
  19.150 -        FILE_SHARE_READ = 0x00000001,
  19.151 -        /// <summary>
  19.152 -        /// Enables subsequent open operations on an object to request write access.
  19.153 -        /// Otherwise, other processes cannot open the object if they request write access.
  19.154 -        /// If this flag is not specified, but the object has been opened for write access, the function fails.
  19.155 -        /// </summary>
  19.156 -        FILE_SHARE_WRITE = 0x00000002,
  19.157 -        /// <summary>
  19.158 -        /// Enables subsequent open operations on an object to request delete access.
  19.159 -        /// Otherwise, other processes cannot open the object if they request delete access.
  19.160 -        /// If this flag is not specified, but the object has been opened for delete access, the function fails.
  19.161 -        /// </summary>
  19.162 -        FILE_SHARE_DELETE = 0x00000004
  19.163 -    }
  19.164 -
  19.165 -    public enum CreationDisposition : uint
  19.166 -    {
  19.167 -        /// <summary>
  19.168 -        /// Creates a new file. The function fails if a specified file exists.
  19.169 -        /// </summary>
  19.170 -        CREATE_NEW = 1,
  19.171 -        /// <summary>
  19.172 -        /// Creates a new file, always.
  19.173 -        /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
  19.174 -        /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
  19.175 -        /// </summary>
  19.176 -        CREATE_ALWAYS = 2,
  19.177 -        /// <summary>
  19.178 -        /// Opens a file. The function fails if the file does not exist.
  19.179 -        /// </summary>
  19.180 -        OPEN_EXISTING = 3,
  19.181 -        /// <summary>
  19.182 -        /// Opens a file, always.
  19.183 -        /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
  19.184 -        /// </summary>
  19.185 -        OPEN_ALWAYS = 4,
  19.186 -        /// <summary>
  19.187 -        /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
  19.188 -        /// The calling process must open the file with the GENERIC_WRITE access right.
  19.189 -        /// </summary>
  19.190 -        TRUNCATE_EXISTING = 5
  19.191 -    }
  19.192 -
  19.193 -    [Flags]
  19.194 -    public enum FileFlagsAttributes : uint
  19.195 -    {
  19.196 -        FILE_ATTRIBUTE_READONLY = 0x00000001,
  19.197 -        FILE_ATTRIBUTE_HIDDEN = 0x00000002,
  19.198 -        FILE_ATTRIBUTE_SYSTEM = 0x00000004,
  19.199 -        FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
  19.200 -        FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
  19.201 -        FILE_ATTRIBUTE_DEVICE = 0x00000040,
  19.202 -        FILE_ATTRIBUTE_NORMAL = 0x00000080,
  19.203 -        FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
  19.204 -        FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
  19.205 -        FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
  19.206 -        FILE_ATTRIBUTE_COMPRESSED = 0x00000800,
  19.207 -        FILE_ATTRIBUTE_OFFLINE = 0x00001000,
  19.208 -        FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
  19.209 -        FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
  19.210 -        FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000,
  19.211 -        FILE_ATTRIBUTE_VIRTUAL = 0x00010000,
  19.212 -        FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000,
  19.213 -        //  These are flags supported through CreateFile (W7) and CreateFile2 (W8 and beyond)
  19.214 -        FILE_FLAG_WRITE_THROUGH = 0x80000000,
  19.215 -        FILE_FLAG_OVERLAPPED = 0x40000000,
  19.216 -        FILE_FLAG_NO_BUFFERING = 0x20000000,
  19.217 -        FILE_FLAG_RANDOM_ACCESS = 0x10000000,
  19.218 -        FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000,
  19.219 -        FILE_FLAG_DELETE_ON_CLOSE = 0x04000000,
  19.220 -        FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
  19.221 -        FILE_FLAG_POSIX_SEMANTICS = 0x01000000,
  19.222 -        FILE_FLAG_SESSION_AWARE = 0x00800000,
  19.223 -        FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,
  19.224 -        FILE_FLAG_OPEN_NO_RECALL = 0x00100000,
  19.225 -        FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000
  19.226 -    }
  19.227 -
  19.228 -
  19.229 -
  19.230 -
  19.231 -}
  19.232 \ No newline at end of file
    20.1 --- a/Win32Hid.cs	Sun Mar 15 16:56:31 2015 +0100
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,515 +0,0 @@
    20.4 -//
    20.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
    20.6 -//
    20.7 -// This file is part of SharpLibHid.
    20.8 -//
    20.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
   20.10 -// it under the terms of the GNU General Public License as published by
   20.11 -// the Free Software Foundation, either version 3 of the License, or
   20.12 -// (at your option) any later version.
   20.13 -//
   20.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
   20.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.17 -// GNU General Public License for more details.
   20.18 -//
   20.19 -// You should have received a copy of the GNU General Public License
   20.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   20.21 -//
   20.22 -
   20.23 -using System;
   20.24 -using System.Runtime.InteropServices;
   20.25 -using Microsoft.Win32.SafeHandles;
   20.26 -using System.Text;
   20.27 -
   20.28 -namespace SharpLib.Win32
   20.29 -{
   20.30 -
   20.31 -    static partial class Function
   20.32 -    {
   20.33 -        [DllImport("hid.dll", CharSet = CharSet.Unicode)]
   20.34 -        public static extern HidStatus HidP_GetUsagesEx(HIDP_REPORT_TYPE ReportType, ushort LinkCollection, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] USAGE_AND_PAGE[] ButtonList, ref uint UsageLength, IntPtr PreparsedData, [MarshalAs(UnmanagedType.LPArray)] byte[] Report, uint ReportLength);
   20.35 -
   20.36 -        [DllImport("hid.dll", CharSet = CharSet.Auto, SetLastError = true)]
   20.37 -        public static extern Boolean HidD_GetManufacturerString(SafeFileHandle HidDeviceObject, StringBuilder Buffer, Int32 BufferLength);
   20.38 -
   20.39 -        [DllImport("hid.dll", CharSet = CharSet.Auto, SetLastError = true)]
   20.40 -        public static extern Boolean HidD_GetProductString(SafeFileHandle HidDeviceObject, StringBuilder Buffer, Int32 BufferLength);
   20.41 -
   20.42 -        [DllImport("hid.dll", CharSet = CharSet.Auto, SetLastError = true)]
   20.43 -        public static extern Boolean HidD_GetAttributes(SafeFileHandle HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
   20.44 -
   20.45 -        /// Return Type: NTSTATUS->LONG->int
   20.46 -        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   20.47 -        ///Capabilities: PHIDP_CAPS->_HIDP_CAPS*
   20.48 -        [DllImport("hid.dll", EntryPoint = "HidP_GetCaps", CallingConvention = CallingConvention.StdCall)]
   20.49 -        public static extern HidStatus HidP_GetCaps(System.IntPtr PreparsedData, ref HIDP_CAPS Capabilities);
   20.50 -
   20.51 -        /// Return Type: NTSTATUS->LONG->int
   20.52 -        ///ReportType: HIDP_REPORT_TYPE->_HIDP_REPORT_TYPE
   20.53 -        ///ButtonCaps: PHIDP_BUTTON_CAPS->_HIDP_BUTTON_CAPS*
   20.54 -        ///ButtonCapsLength: PUSHORT->USHORT*
   20.55 -        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   20.56 -        [DllImport("hid.dll", EntryPoint = "HidP_GetButtonCaps", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
   20.57 -        public static extern HidStatus HidP_GetButtonCaps(HIDP_REPORT_TYPE ReportType, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] HIDP_BUTTON_CAPS[] ButtonCaps, ref ushort ButtonCapsLength, System.IntPtr PreparsedData);
   20.58 -
   20.59 -        /// Return Type: NTSTATUS->LONG->int
   20.60 -        ///ReportType: HIDP_REPORT_TYPE->_HIDP_REPORT_TYPE
   20.61 -        ///ValueCaps: PHIDP_VALUE_CAPS->_HIDP_VALUE_CAPS*
   20.62 -        ///ValueCapsLength: PUSHORT->USHORT*
   20.63 -        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   20.64 -        [DllImport("hid.dll", EntryPoint = "HidP_GetValueCaps", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
   20.65 -        public static extern HidStatus HidP_GetValueCaps(HIDP_REPORT_TYPE ReportType, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] HIDP_VALUE_CAPS[] ValueCaps, ref ushort ValueCapsLength, System.IntPtr PreparsedData);
   20.66 -
   20.67 -        /// Return Type: NTSTATUS->LONG->int
   20.68 -        ///ReportType: HIDP_REPORT_TYPE->_HIDP_REPORT_TYPE
   20.69 -        ///UsagePage: USAGE->USHORT->unsigned short
   20.70 -        ///LinkCollection: USHORT->unsigned short
   20.71 -        ///Usage: USAGE->USHORT->unsigned short
   20.72 -        ///UsageValue: PULONG->ULONG*
   20.73 -        ///PreparsedData: PHIDP_PREPARSED_DATA->_HIDP_PREPARSED_DATA*
   20.74 -        ///Report: PCHAR->CHAR*
   20.75 -        ///ReportLength: ULONG->unsigned int
   20.76 -        [DllImport("hid.dll", EntryPoint = "HidP_GetUsageValue", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
   20.77 -        public static extern HidStatus HidP_GetUsageValue(HIDP_REPORT_TYPE ReportType, ushort UsagePage, ushort LinkCollection, ushort Usage, ref uint UsageValue, System.IntPtr PreparsedData, [MarshalAs(UnmanagedType.LPArray)] byte[] Report, uint ReportLength);
   20.78 -
   20.79 -
   20.80 -
   20.81 -    }
   20.82 -
   20.83 -
   20.84 -    static partial class Macro
   20.85 -    {
   20.86 -
   20.87 -
   20.88 -    }
   20.89 -
   20.90 -
   20.91 -    static partial class Const
   20.92 -    {
   20.93 -
   20.94 -
   20.95 -    }
   20.96 -
   20.97 -
   20.98 -    public enum HIDP_REPORT_TYPE : ushort
   20.99 -    {
  20.100 -        HidP_Input = 0,
  20.101 -        HidP_Output,
  20.102 -        HidP_Feature
  20.103 -    }
  20.104 -
  20.105 -
  20.106 -    public enum HidStatus : uint
  20.107 -    {
  20.108 -        HIDP_STATUS_SUCCESS = 0x110000,
  20.109 -        HIDP_STATUS_NULL = 0x80110001,
  20.110 -        HIDP_STATUS_INVALID_PREPARSED_DATA = 0xc0110001,
  20.111 -        HIDP_STATUS_INVALID_REPORT_TYPE = 0xc0110002,
  20.112 -        HIDP_STATUS_INVALID_REPORT_LENGTH = 0xc0110003,
  20.113 -        HIDP_STATUS_USAGE_NOT_FOUND = 0xc0110004,
  20.114 -        HIDP_STATUS_VALUE_OUT_OF_RANGE = 0xc0110005,
  20.115 -        HIDP_STATUS_BAD_LOG_PHY_VALUES = 0xc0110006,
  20.116 -        HIDP_STATUS_BUFFER_TOO_SMALL = 0xc0110007,
  20.117 -        HIDP_STATUS_INTERNAL_ERROR = 0xc0110008,
  20.118 -        HIDP_STATUS_I8042_TRANS_UNKNOWN = 0xc0110009,
  20.119 -        HIDP_STATUS_INCOMPATIBLE_REPORT_ID = 0xc011000a,
  20.120 -        HIDP_STATUS_NOT_VALUE_ARRAY = 0xc011000b,
  20.121 -        HIDP_STATUS_IS_VALUE_ARRAY = 0xc011000c,
  20.122 -        HIDP_STATUS_DATA_INDEX_NOT_FOUND = 0xc011000d,
  20.123 -        HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE = 0xc011000e,
  20.124 -        HIDP_STATUS_BUTTON_NOT_PRESSED = 0xc011000f,
  20.125 -        HIDP_STATUS_REPORT_DOES_NOT_EXIST = 0xc0110010,
  20.126 -        HIDP_STATUS_NOT_IMPLEMENTED = 0xc0110020,
  20.127 -        HIDP_STATUS_I8242_TRANS_UNKNOWN = 0xc0110009
  20.128 -    }
  20.129 -
  20.130 -
  20.131 -    [StructLayout(LayoutKind.Sequential)]
  20.132 -    public struct USAGE_AND_PAGE
  20.133 -    {
  20.134 -        public ushort Usage;
  20.135 -        public ushort UsagePage;
  20.136 -    };
  20.137 -
  20.138 -    [StructLayout(LayoutKind.Sequential)]
  20.139 -    public struct HIDD_ATTRIBUTES
  20.140 -    {
  20.141 -        public uint Size;
  20.142 -        public ushort VendorID;
  20.143 -        public ushort ProductID;
  20.144 -        public ushort VersionNumber;
  20.145 -    }
  20.146 -
  20.147 -
  20.148 -    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  20.149 -    public struct HIDP_CAPS
  20.150 -    {
  20.151 -        /// USAGE->USHORT->unsigned short
  20.152 -        public ushort Usage;
  20.153 -
  20.154 -        /// USAGE->USHORT->unsigned short
  20.155 -        public ushort UsagePage;
  20.156 -
  20.157 -        /// USHORT->unsigned short
  20.158 -        public ushort InputReportByteLength;
  20.159 -
  20.160 -        /// USHORT->unsigned short
  20.161 -        public ushort OutputReportByteLength;
  20.162 -
  20.163 -        /// USHORT->unsigned short
  20.164 -        public ushort FeatureReportByteLength;
  20.165 -
  20.166 -        /// USHORT[17]
  20.167 -        [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 17, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U2)]
  20.168 -        public ushort[] Reserved;
  20.169 -
  20.170 -        /// USHORT->unsigned short
  20.171 -        public ushort NumberLinkCollectionNodes;
  20.172 -
  20.173 -        /// USHORT->unsigned short
  20.174 -        public ushort NumberInputButtonCaps;
  20.175 -
  20.176 -        /// USHORT->unsigned short
  20.177 -        public ushort NumberInputValueCaps;
  20.178 -
  20.179 -        /// USHORT->unsigned short
  20.180 -        public ushort NumberInputDataIndices;
  20.181 -
  20.182 -        /// USHORT->unsigned short
  20.183 -        public ushort NumberOutputButtonCaps;
  20.184 -
  20.185 -        /// USHORT->unsigned short
  20.186 -        public ushort NumberOutputValueCaps;
  20.187 -
  20.188 -        /// USHORT->unsigned short
  20.189 -        public ushort NumberOutputDataIndices;
  20.190 -
  20.191 -        /// USHORT->unsigned short
  20.192 -        public ushort NumberFeatureButtonCaps;
  20.193 -
  20.194 -        /// USHORT->unsigned short
  20.195 -        public ushort NumberFeatureValueCaps;
  20.196 -
  20.197 -        /// USHORT->unsigned short
  20.198 -        public ushort NumberFeatureDataIndices;
  20.199 -    }
  20.200 -
  20.201 -    /// <summary>
  20.202 -    /// Type created in place of an anonymous struct
  20.203 -    /// </summary>
  20.204 -    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  20.205 -    public struct HIDP_BUTTON_CAPS_RANGE
  20.206 -    {
  20.207 -
  20.208 -        /// USAGE->USHORT->unsigned short
  20.209 -        public ushort UsageMin;
  20.210 -
  20.211 -        /// USAGE->USHORT->unsigned short
  20.212 -        public ushort UsageMax;
  20.213 -
  20.214 -        /// USHORT->unsigned short
  20.215 -        public ushort StringMin;
  20.216 -
  20.217 -        /// USHORT->unsigned short
  20.218 -        public ushort StringMax;
  20.219 -
  20.220 -        /// USHORT->unsigned short
  20.221 -        public ushort DesignatorMin;
  20.222 -
  20.223 -        /// USHORT->unsigned short
  20.224 -        public ushort DesignatorMax;
  20.225 -
  20.226 -        /// USHORT->unsigned short
  20.227 -        public ushort DataIndexMin;
  20.228 -
  20.229 -        /// USHORT->unsigned short
  20.230 -        public ushort DataIndexMax;
  20.231 -    }
  20.232 -
  20.233 -    /// <summary>
  20.234 -    /// Type created in place of an anonymous struct
  20.235 -    /// </summary>
  20.236 -    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  20.237 -    public struct HIDP_BUTTON_CAPS_NOT_RANGE
  20.238 -    {
  20.239 -
  20.240 -        /// USAGE->USHORT->unsigned short
  20.241 -        public ushort Usage;
  20.242 -
  20.243 -        /// USAGE->USHORT->unsigned short
  20.244 -        public ushort Reserved1;
  20.245 -
  20.246 -        /// USHORT->unsigned short
  20.247 -        public ushort StringIndex;
  20.248 -
  20.249 -        /// USHORT->unsigned short
  20.250 -        public ushort Reserved2;
  20.251 -
  20.252 -        /// USHORT->unsigned short
  20.253 -        public ushort DesignatorIndex;
  20.254 -
  20.255 -        /// USHORT->unsigned short
  20.256 -        public ushort Reserved3;
  20.257 -
  20.258 -        /// USHORT->unsigned short
  20.259 -        public ushort DataIndex;
  20.260 -
  20.261 -        /// USHORT->unsigned short
  20.262 -        public ushort Reserved4;
  20.263 -    }
  20.264 -
  20.265 -    /// <summary>
  20.266 -    /// 
  20.267 -    /// </summary>
  20.268 -    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  20.269 -    public struct HIDP_BUTTON_CAPS
  20.270 -    {
  20.271 -        /// USAGE->USHORT->unsigned short
  20.272 -        [FieldOffset(0)]
  20.273 -        public ushort UsagePage;
  20.274 -
  20.275 -        /// UCHAR->unsigned char
  20.276 -        [FieldOffset(2)]
  20.277 -        public byte ReportID;
  20.278 -
  20.279 -        /// BOOLEAN->BYTE->unsigned char
  20.280 -        [FieldOffset(3)]
  20.281 -        [MarshalAs(UnmanagedType.U1)]
  20.282 -        public bool IsAlias;
  20.283 -
  20.284 -        /// USHORT->unsigned short
  20.285 -        [FieldOffset(4)]
  20.286 -        public ushort BitField;
  20.287 -
  20.288 -        /// USHORT->unsigned short
  20.289 -        [FieldOffset(6)]
  20.290 -        public ushort LinkCollection;
  20.291 -
  20.292 -        /// USAGE->USHORT->unsigned short
  20.293 -        [FieldOffset(8)]
  20.294 -        public ushort LinkUsage;
  20.295 -
  20.296 -        /// USAGE->USHORT->unsigned short
  20.297 -        [FieldOffset(10)]
  20.298 -        public ushort LinkUsagePage;
  20.299 -
  20.300 -        /// BOOLEAN->BYTE->unsigned char
  20.301 -        [FieldOffset(12)]
  20.302 -        [MarshalAs(UnmanagedType.U1)]
  20.303 -        public bool IsRange;
  20.304 -
  20.305 -        /// BOOLEAN->BYTE->unsigned char
  20.306 -        [FieldOffset(13)]
  20.307 -        [MarshalAs(UnmanagedType.U1)]
  20.308 -        public bool IsStringRange;
  20.309 -
  20.310 -        /// BOOLEAN->BYTE->unsigned char
  20.311 -        [FieldOffset(14)]
  20.312 -        [MarshalAs(UnmanagedType.U1)]
  20.313 -        public bool IsDesignatorRange;
  20.314 -
  20.315 -        /// BOOLEAN->BYTE->unsigned char
  20.316 -        [FieldOffset(15)]
  20.317 -        [MarshalAs(UnmanagedType.U1)]
  20.318 -        public bool IsAbsolute;
  20.319 -
  20.320 -        /// ULONG[10]
  20.321 -        [FieldOffset(16)]
  20.322 -        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10, ArraySubType = UnmanagedType.U4)]
  20.323 -        public uint[] Reserved;
  20.324 -
  20.325 -        /// Union Range/NotRange
  20.326 -        [FieldOffset(56)]
  20.327 -        public HIDP_BUTTON_CAPS_RANGE Range;
  20.328 -
  20.329 -        [FieldOffset(56)]
  20.330 -        public HIDP_BUTTON_CAPS_NOT_RANGE NotRange;       
  20.331 -    }
  20.332 -
  20.333 -    /// <summary>
  20.334 -    /// Type created in place of an anonymous struct
  20.335 -    /// </summary>
  20.336 -    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  20.337 -    public struct HIDP_VALUE_CAPS_RANGE
  20.338 -    {
  20.339 -
  20.340 -        /// USAGE->USHORT->unsigned short
  20.341 -        public ushort UsageMin;
  20.342 -
  20.343 -        /// USAGE->USHORT->unsigned short
  20.344 -        public ushort UsageMax;
  20.345 -
  20.346 -        /// USHORT->unsigned short
  20.347 -        public ushort StringMin;
  20.348 -
  20.349 -        /// USHORT->unsigned short
  20.350 -        public ushort StringMax;
  20.351 -
  20.352 -        /// USHORT->unsigned short
  20.353 -        public ushort DesignatorMin;
  20.354 -
  20.355 -        /// USHORT->unsigned short
  20.356 -        public ushort DesignatorMax;
  20.357 -
  20.358 -        /// USHORT->unsigned short
  20.359 -        public ushort DataIndexMin;
  20.360 -
  20.361 -        /// USHORT->unsigned short
  20.362 -        public ushort DataIndexMax;
  20.363 -    }
  20.364 -
  20.365 -    /// <summary>
  20.366 -    /// Type created in place of an anonymous struct
  20.367 -    /// </summary>
  20.368 -    [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
  20.369 -    public struct HIDP_VALUE_CAPS_NOT_RANGE
  20.370 -    {
  20.371 -
  20.372 -        /// USAGE->USHORT->unsigned short
  20.373 -        public ushort Usage;
  20.374 -
  20.375 -        /// USAGE->USHORT->unsigned short
  20.376 -        public ushort Reserved1;
  20.377 -
  20.378 -        /// USHORT->unsigned short
  20.379 -        public ushort StringIndex;
  20.380 -
  20.381 -        /// USHORT->unsigned short
  20.382 -        public ushort Reserved2;
  20.383 -
  20.384 -        /// USHORT->unsigned short
  20.385 -        public ushort DesignatorIndex;
  20.386 -
  20.387 -        /// USHORT->unsigned short
  20.388 -        public ushort Reserved3;
  20.389 -
  20.390 -        /// USHORT->unsigned short
  20.391 -        public ushort DataIndex;
  20.392 -
  20.393 -        /// USHORT->unsigned short
  20.394 -        public ushort Reserved4;
  20.395 -    }
  20.396 -
  20.397 -
  20.398 -    /// <summary>
  20.399 -    /// 
  20.400 -    /// </summary>
  20.401 -    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  20.402 -    public struct HIDP_VALUE_CAPS
  20.403 -    {
  20.404 -
  20.405 -        /// USAGE->USHORT->unsigned short
  20.406 -        [FieldOffset(0)]
  20.407 -        public ushort UsagePage;
  20.408 -
  20.409 -        /// UCHAR->unsigned char
  20.410 -        [FieldOffset(2)]
  20.411 -        public byte ReportID;
  20.412 -
  20.413 -        /// BOOLEAN->BYTE->unsigned char
  20.414 -        [FieldOffset(3)]
  20.415 -        [MarshalAs(UnmanagedType.U1)]
  20.416 -        public bool IsAlias;
  20.417 -
  20.418 -        /// USHORT->unsigned short
  20.419 -        [FieldOffset(4)]
  20.420 -        public ushort BitField;
  20.421 -
  20.422 -        /// USHORT->unsigned short
  20.423 -        [FieldOffset(6)]
  20.424 -        public ushort LinkCollection;
  20.425 -
  20.426 -        /// USAGE->USHORT->unsigned short
  20.427 -        [FieldOffset(8)]
  20.428 -        public ushort LinkUsage;
  20.429 -
  20.430 -        /// USAGE->USHORT->unsigned short
  20.431 -        [FieldOffset(10)]
  20.432 -        public ushort LinkUsagePage;
  20.433 -
  20.434 -        /// BOOLEAN->BYTE->unsigned char
  20.435 -        [FieldOffset(12)]
  20.436 -        [MarshalAs(UnmanagedType.U1)]
  20.437 -        public bool IsRange;
  20.438 -
  20.439 -        /// BOOLEAN->BYTE->unsigned char
  20.440 -        [FieldOffset(13)]
  20.441 -        [MarshalAs(UnmanagedType.U1)]
  20.442 -        public bool IsStringRange;
  20.443 -
  20.444 -        /// BOOLEAN->BYTE->unsigned char
  20.445 -        [FieldOffset(14)]
  20.446 -        [MarshalAs(UnmanagedType.U1)]
  20.447 -        public bool IsDesignatorRange;
  20.448 -
  20.449 -        /// BOOLEAN->BYTE->unsigned char
  20.450 -        [FieldOffset(15)]
  20.451 -        [MarshalAs(UnmanagedType.U1)]
  20.452 -        public bool IsAbsolute;
  20.453 -
  20.454 -        /// BOOLEAN->BYTE->unsigned char
  20.455 -        [FieldOffset(16)]
  20.456 -        [MarshalAs(UnmanagedType.U1)]
  20.457 -        public bool HasNull;
  20.458 -
  20.459 -        /// UCHAR->unsigned char
  20.460 -        [FieldOffset(17)]
  20.461 -        public byte Reserved;
  20.462 -
  20.463 -        /// USHORT->unsigned short
  20.464 -        [FieldOffset(18)]
  20.465 -        public ushort BitSize;
  20.466 -
  20.467 -        /// USHORT->unsigned short
  20.468 -        [FieldOffset(20)]
  20.469 -        public ushort ReportCount;
  20.470 -
  20.471 -        /// USHORT[5]
  20.472 -        /// We had to use 5 ushorts instead of an array to avoid alignment exception issues.
  20.473 -        [FieldOffset(22)]
  20.474 -        public ushort Reserved21;
  20.475 -        [FieldOffset(24)]
  20.476 -        public ushort Reserved22;
  20.477 -        [FieldOffset(26)]
  20.478 -        public ushort Reserved23;
  20.479 -        [FieldOffset(28)]
  20.480 -        public ushort Reserved24;
  20.481 -        [FieldOffset(30)]
  20.482 -        public ushort Reserved25;
  20.483 -
  20.484 -        /// ULONG->unsigned int
  20.485 -        [FieldOffset(32)]
  20.486 -        public uint UnitsExp;
  20.487 -
  20.488 -        /// ULONG->unsigned int
  20.489 -        [FieldOffset(36)]
  20.490 -        public uint Units;
  20.491 -
  20.492 -        /// LONG->int
  20.493 -        [FieldOffset(40)]
  20.494 -        public int LogicalMin;
  20.495 -
  20.496 -        /// LONG->int
  20.497 -        [FieldOffset(44)]
  20.498 -        public int LogicalMax;
  20.499 -
  20.500 -        /// LONG->int
  20.501 -        [FieldOffset(48)]
  20.502 -        public int PhysicalMin;
  20.503 -
  20.504 -        /// LONG->int
  20.505 -        [FieldOffset(52)]
  20.506 -        public int PhysicalMax;
  20.507 -
  20.508 -        /// Union Range/NotRange
  20.509 -        [FieldOffset(56)]
  20.510 -        public HIDP_VALUE_CAPS_RANGE Range;
  20.511 -
  20.512 -        [FieldOffset(56)]
  20.513 -        public HIDP_VALUE_CAPS_NOT_RANGE NotRange;
  20.514 -    }
  20.515 -    
  20.516 -}
  20.517 -
  20.518 -
    21.1 --- a/Win32RawInput.cs	Sun Mar 15 16:56:31 2015 +0100
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,386 +0,0 @@
    21.4 -//
    21.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
    21.6 -//
    21.7 -// This file is part of SharpLibHid.
    21.8 -//
    21.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
   21.10 -// it under the terms of the GNU General Public License as published by
   21.11 -// the Free Software Foundation, either version 3 of the License, or
   21.12 -// (at your option) any later version.
   21.13 -//
   21.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
   21.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.17 -// GNU General Public License for more details.
   21.18 -//
   21.19 -// You should have received a copy of the GNU General Public License
   21.20 -// along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
   21.21 -//
   21.22 -
   21.23 -using System;
   21.24 -using System.Runtime.InteropServices;
   21.25 -
   21.26 -namespace SharpLib.Win32
   21.27 -{
   21.28 -
   21.29 -    static partial class Function
   21.30 -    {
   21.31 -        [DllImport("User32.dll", SetLastError = true)]
   21.32 -		public extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
   21.33 -
   21.34 -        [DllImport("User32.dll", SetLastError = true)]
   21.35 -		public extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
   21.36 -
   21.37 -   		[DllImport("User32.dll", SetLastError=true)]
   21.38 -        public extern static int GetRawInputDeviceInfo(IntPtr hDevice, RawInputDeviceInfoType uiCommand, IntPtr pData, ref uint pcbSize);
   21.39 -
   21.40 -        [DllImport("user32.dll", SetLastError = true)]
   21.41 -        public static extern int GetRawInputDeviceList(
   21.42 -            [In, Out] RAWINPUTDEVICELIST[] InputdeviceList,
   21.43 -            [In, Out] ref uint puiNumDevices,
   21.44 -            [In] uint cbSize);
   21.45 -
   21.46 -    }
   21.47 -
   21.48 -
   21.49 -    static partial class Macro
   21.50 -    {
   21.51 -        /// <summary>
   21.52 -        /// Retrieves the input code from wParam in WM_INPUT.
   21.53 -        /// See RIM_INPUT and RIM_INPUTSINK.
   21.54 -        /// </summary>
   21.55 -        /// <param name="wParam"></param>
   21.56 -        /// <returns></returns>
   21.57 -        public static int GET_RAWINPUT_CODE_WPARAM(IntPtr wParam)
   21.58 -        {
   21.59 -            return (wParam.ToInt32() & 0xff);
   21.60 -        }
   21.61 -
   21.62 -        public static int GET_DEVICE_LPARAM(IntPtr lParam)
   21.63 -        {
   21.64 -            return ((ushort)(HIWORD(lParam.ToInt32()) & Const.FAPPCOMMAND_MASK));
   21.65 -        }
   21.66 -
   21.67 -        public static int HIWORD(int val)
   21.68 -        {
   21.69 -            return ((val >> 16) & 0xffff);
   21.70 -        }
   21.71 -
   21.72 -
   21.73 -        //#define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
   21.74 -        //#define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))        
   21.75 -        //#define LOBYTE(w)           ((BYTE)(((DWORD_PTR)(w)) & 0xff))
   21.76 -        //#define HIBYTE(w)           ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))
   21.77 -
   21.78 -        //#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
   21.79 -        //#define GET_DEVICE_LPARAM(lParam)     ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
   21.80 -        //#define GET_MOUSEORKEY_LPARAM         GET_DEVICE_LPARAM
   21.81 -        //#define GET_FLAGS_LPARAM(lParam)      (LOWORD(lParam))
   21.82 -        //#define GET_KEYSTATE_LPARAM(lParam)   GET_FLAGS_LPARAM(lParam)
   21.83 -
   21.84 -    }
   21.85 -
   21.86 -
   21.87 -
   21.88 -    static partial class Const
   21.89 -    {
   21.90 -        /// <summary>
   21.91 -        /// Windows Messages
   21.92 -        /// </summary>
   21.93 -        public const int WM_KEYDOWN = 0x0100;
   21.94 -        public const int WM_INPUT = 0x00FF;
   21.95 -
   21.96 -
   21.97 -        //
   21.98 -        public const int RID_INPUT = 0x10000003;
   21.99 -        public const int RID_HEADER = 0x10000005;
  21.100 -
  21.101 -        /// <summary>
  21.102 -        /// Possible value taken by wParam for WM_INPUT.
  21.103 -        /// <para />
  21.104 -        /// Input occurred while the application was in the foreground. The application must call DefWindowProc so the system can perform cleanup.
  21.105 -        /// </summary>
  21.106 -        public const int RIM_INPUT = 0;
  21.107 -        /// <summary>
  21.108 -        /// Possible value taken by wParam for WM_INPUT.
  21.109 -        /// <para />
  21.110 -        /// Input occurred while the application was not in the foreground. The application must call DefWindowProc so the system can perform the cleanup.
  21.111 -        /// </summary>
  21.112 -        public const int RIM_INPUTSINK = 1;
  21.113 -
  21.114 -        /// <summary>
  21.115 -        /// If set, the application command keys are handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a keyboard device.
  21.116 -        /// </summary>        
  21.117 -        public const uint RIDEV_APPKEYS = 0x00000400;
  21.118 -
  21.119 -        /// <summary>
  21.120 -        /// If set, the mouse button click does not activate the other window.
  21.121 -        /// </summary>
  21.122 -	    public const uint RIDEV_CAPTUREMOUSE = 0x00000200;
  21.123 -        
  21.124 -        /// <summary>
  21.125 -        /// If set, this enables the caller to receive WM_INPUT_DEVICE_CHANGE notifications for device arrival and device removal.
  21.126 -        /// Windows XP:  This flag is not supported until Windows Vista
  21.127 -        /// </summary>
  21.128 -	    public const uint RIDEV_DEVNOTIFY = 0x00002000;
  21.129 -
  21.130 -        /// <summary>
  21.131 -        /// If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC whose usage page is already specified with RIDEV_PAGEONLY.
  21.132 -        /// </summary>
  21.133 -        public const uint RIDEV_EXCLUDE = 0x00000010;
  21.134 -
  21.135 -        /// <summary>
  21.136 -        /// If set, this enables the caller to receive input in the background only if the foreground application does not process it. In other words, if the foreground application is not registered for raw input, then the background application that is registered will receive the input.
  21.137 -        /// Windows XP:  This flag is not supported until Windows Vista
  21.138 -        /// </summary>
  21.139 -	    public const uint RIDEV_EXINPUTSINK = 0x00001000;
  21.140 -
  21.141 -        /// <summary>
  21.142 -        /// If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that hwndTarget must be specified.
  21.143 -        /// </summary>
  21.144 -	    public const uint RIDEV_INPUTSINK = 0x00000100;
  21.145 -
  21.146 -	    /// <summary>
  21.147 -	    /// If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. RIDEV_NOHOTKEYS can be specified even if RIDEV_NOLEGACY is not specified and hwndTarget is NULL.
  21.148 -	    /// </summary>
  21.149 -        public const uint RIDEV_NOHOTKEYS = 0x00000200;
  21.150 -
  21.151 -        /// <summary>
  21.152 -        /// If set, this prevents any devices specified by usUsagePage or usUsage from generating legacy messages. This is only for the mouse and keyboard. See Remarks.
  21.153 -        /// </summary>
  21.154 -        public const uint RIDEV_NOLEGACY = 0x00000030;
  21.155 -        
  21.156 -        /// <summary>
  21.157 -        /// If set, this specifies all devices whose top level collection is from the specified usUsagePage. Note that usUsage must be zero. To exclude a particular top level collection, use RIDEV_EXCLUDE.
  21.158 -        /// </summary>
  21.159 -        public const uint RIDEV_PAGEONLY = 0x00000020;
  21.160 -
  21.161 -	    /// <summary>
  21.162 -        /// If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a device which matches the top level collection.
  21.163 -	    /// </summary>
  21.164 -        public const uint RIDEV_REMOVE = 0x00000001;
  21.165 -
  21.166 -        public const int APPCOMMAND_BROWSER_BACKWARD = 1;
  21.167 -        public const int APPCOMMAND_VOLUME_MUTE = 8;
  21.168 -        public const int APPCOMMAND_VOLUME_DOWN = 9;
  21.169 -        public const int APPCOMMAND_VOLUME_UP = 10;
  21.170 -        public const int APPCOMMAND_MEDIA_NEXTTRACK = 11;
  21.171 -        public const int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
  21.172 -        public const int APPCOMMAND_MEDIA_STOP = 13;
  21.173 -        public const int APPCOMMAND_MEDIA_PLAY_PAUSE = 14;
  21.174 -        public const int APPCOMMAND_MEDIA_PLAY = 46;
  21.175 -        public const int APPCOMMAND_MEDIA_PAUSE = 47;
  21.176 -        public const int APPCOMMAND_MEDIA_RECORD = 48;
  21.177 -        public const int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
  21.178 -        public const int APPCOMMAND_MEDIA_REWIND = 50;
  21.179 -        public const int APPCOMMAND_MEDIA_CHANNEL_UP = 51;
  21.180 -        public const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
  21.181 -
  21.182 -        public const int FAPPCOMMAND_MASK = 0xF000;
  21.183 -        public const int FAPPCOMMAND_MOUSE = 0x8000;
  21.184 -        public const int FAPPCOMMAND_KEY = 0;
  21.185 -		public const int FAPPCOMMAND_OEM = 0x1000;
  21.186 -    }
  21.187 -
  21.188 -    /// <summary>
  21.189 -    /// Introduced this enum for consistency and easy of use.
  21.190 -    /// Naming of the Win32 constants were preserved.
  21.191 -    /// </summary>
  21.192 -    public enum RawInputDeviceType : uint
  21.193 -    {
  21.194 -        /// <summary>
  21.195 -        /// Data comes from a mouse.
  21.196 -        /// </summary>
  21.197 -        RIM_TYPEMOUSE = 0,
  21.198 -        /// <summary>
  21.199 -        /// Data comes from a keyboard.
  21.200 -        /// </summary>
  21.201 -        RIM_TYPEKEYBOARD = 1,
  21.202 -        /// <summary>
  21.203 -        /// Data comes from an HID that is not a keyboard or a mouse.
  21.204 -        /// </summary>
  21.205 -        RIM_TYPEHID = 2
  21.206 -    }
  21.207 -
  21.208 -    /// <summary>
  21.209 -    /// Introduced this enum for consistency and easy of use.
  21.210 -    /// Naming of the Win32 constants were preserved.
  21.211 -    /// </summary>
  21.212 -    public enum RawInputDeviceInfoType : uint
  21.213 -    {
  21.214 -         /// <summary>
  21.215 -        /// GetRawInputDeviceInfo pData points to a string that contains the device name.
  21.216 -        /// </summary>
  21.217 -        RIDI_DEVICENAME = 0x20000007,
  21.218 -        /// <summary>
  21.219 -        /// GetRawInputDeviceInfo For this uiCommand only, the value in pcbSize is the character count (not the byte count).
  21.220 -        /// </summary>
  21.221 -        RIDI_DEVICEINFO = 0x2000000b,
  21.222 -        /// <summary>
  21.223 -        /// GetRawInputDeviceInfo pData points to an RID_DEVICE_INFO structure.
  21.224 -        /// </summary>
  21.225 -        RIDI_PREPARSEDDATA = 0x20000005
  21.226 -    }
  21.227 -
  21.228 -
  21.229 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.230 -    public struct RAWINPUTDEVICELIST
  21.231 -    {
  21.232 -        public IntPtr hDevice;
  21.233 -        public RawInputDeviceType dwType;
  21.234 -    }
  21.235 -
  21.236 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.237 -    public struct RAWINPUTDEVICE
  21.238 -    {
  21.239 -        [MarshalAs(UnmanagedType.U2)]
  21.240 -        public ushort usUsagePage;
  21.241 -        [MarshalAs(UnmanagedType.U2)]
  21.242 -        public ushort usUsage;
  21.243 -        [MarshalAs(UnmanagedType.U4)]
  21.244 -        public uint dwFlags;
  21.245 -        public IntPtr hwndTarget;
  21.246 -    }
  21.247 -
  21.248 -
  21.249 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.250 -    public struct RAWINPUTHEADER
  21.251 -    {
  21.252 -        [MarshalAs(UnmanagedType.U4)]
  21.253 -        public RawInputDeviceType dwType;
  21.254 -        [MarshalAs(UnmanagedType.U4)]
  21.255 -        public int dwSize;
  21.256 -        public IntPtr hDevice;
  21.257 -        [MarshalAs(UnmanagedType.U4)]
  21.258 -        public int wParam;
  21.259 -    }
  21.260 -
  21.261 -
  21.262 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.263 -    public struct RAWHID
  21.264 -    {
  21.265 -        [MarshalAs(UnmanagedType.U4)]
  21.266 -        public uint dwSizeHid;
  21.267 -        [MarshalAs(UnmanagedType.U4)]
  21.268 -        public uint dwCount;
  21.269 -        //
  21.270 -        //BYTE  bRawData[1];
  21.271 -    }
  21.272 -
  21.273 -
  21.274 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.275 -    public struct BUTTONSSTR
  21.276 -    {
  21.277 -        [MarshalAs(UnmanagedType.U2)]
  21.278 -        public ushort usButtonFlags;
  21.279 -        [MarshalAs(UnmanagedType.U2)]
  21.280 -        public ushort usButtonData;
  21.281 -    }
  21.282 -
  21.283 -
  21.284 -    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  21.285 -    public struct RAWMOUSE
  21.286 -    {
  21.287 -        [MarshalAs(UnmanagedType.U2)]
  21.288 -        [FieldOffset(0)]
  21.289 -        public ushort usFlags;
  21.290 -        [MarshalAs(UnmanagedType.U4)]
  21.291 -        [FieldOffset(4)]
  21.292 -        public uint ulButtons;
  21.293 -        [FieldOffset(4)]
  21.294 -        public BUTTONSSTR buttonsStr;
  21.295 -        [MarshalAs(UnmanagedType.U4)]
  21.296 -        [FieldOffset(8)]
  21.297 -        public uint ulRawButtons;
  21.298 -        [MarshalAs(UnmanagedType.U4)]
  21.299 -        [FieldOffset(12)]
  21.300 -        public int lLastX;
  21.301 -        [MarshalAs(UnmanagedType.U4)]
  21.302 -        [FieldOffset(16)]
  21.303 -        public int lLastY;
  21.304 -        [MarshalAs(UnmanagedType.U4)]
  21.305 -        [FieldOffset(20)]
  21.306 -        public uint ulExtraInformation;
  21.307 -    }
  21.308 -
  21.309 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.310 -    public struct RAWKEYBOARD
  21.311 -    {
  21.312 -        [MarshalAs(UnmanagedType.U2)]
  21.313 -        public ushort MakeCode;
  21.314 -        [MarshalAs(UnmanagedType.U2)]
  21.315 -        public ushort Flags;
  21.316 -        [MarshalAs(UnmanagedType.U2)]
  21.317 -        public ushort Reserved;
  21.318 -        [MarshalAs(UnmanagedType.U2)]
  21.319 -        public ushort VKey;
  21.320 -        [MarshalAs(UnmanagedType.U4)]
  21.321 -        public uint Message;
  21.322 -        [MarshalAs(UnmanagedType.U4)]
  21.323 -        public uint ExtraInformation;
  21.324 -    }
  21.325 -
  21.326 -
  21.327 -    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  21.328 -    public struct RAWINPUT
  21.329 -    {
  21.330 -        [FieldOffset(0)]
  21.331 -        public RAWINPUTHEADER header;
  21.332 -        [FieldOffset(16)]
  21.333 -        public RAWMOUSE mouse;
  21.334 -        [FieldOffset(16)]
  21.335 -        public RAWKEYBOARD keyboard;
  21.336 -        [FieldOffset(16)]
  21.337 -        public RAWHID hid;
  21.338 -    }
  21.339 -
  21.340 -
  21.341 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.342 -    public struct RID_DEVICE_INFO_MOUSE
  21.343 -    {
  21.344 -        public uint dwId;
  21.345 -        public uint dwNumberOfButtons;
  21.346 -        public uint dwSampleRate;
  21.347 -        public bool fHasHorizontalWheel;
  21.348 -    }
  21.349 -
  21.350 -
  21.351 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.352 -    public struct RID_DEVICE_INFO_KEYBOARD
  21.353 -    {
  21.354 -        public uint dwType;
  21.355 -        public uint dwSubType;
  21.356 -        public uint dwKeyboardMode;
  21.357 -        public uint dwNumberOfFunctionKeys;
  21.358 -        public uint dwNumberOfIndicators;
  21.359 -        public uint dwNumberOfKeysTotal;
  21.360 -    }
  21.361 -
  21.362 -    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  21.363 -    public struct RID_DEVICE_INFO_HID
  21.364 -    {
  21.365 -        public uint dwVendorId;
  21.366 -        public uint dwProductId;
  21.367 -        public uint dwVersionNumber;
  21.368 -        public ushort usUsagePage;
  21.369 -        public ushort usUsage;
  21.370 -    }
  21.371 -
  21.372 -    [StructLayout(LayoutKind.Explicit, Pack = 1)]
  21.373 -    public struct RID_DEVICE_INFO
  21.374 -    {
  21.375 -        [FieldOffset(0)]
  21.376 -        public uint cbSize;
  21.377 -        [FieldOffset(4)]
  21.378 -        [MarshalAs(UnmanagedType.U4)]
  21.379 -        public RawInputDeviceType dwType;
  21.380 -        [FieldOffset(8)]
  21.381 -        public RID_DEVICE_INFO_MOUSE mouse;
  21.382 -        [FieldOffset(8)]
  21.383 -        public RID_DEVICE_INFO_KEYBOARD keyboard;
  21.384 -        [FieldOffset(8)]
  21.385 -        public RID_DEVICE_INFO_HID hid;
  21.386 -    }
  21.387 -
  21.388 -
  21.389 -}
  21.390 \ No newline at end of file