Exemplo n.º 1
0
    /// <summary>
    /// </summary>
    /// <param name="aRawInputHandle"></param>
    /// <param name="aRawInput"></param>
    /// <param name="rawInputBuffer">Caller must free up memory on the pointer using Marshal.FreeHGlobal</param>
    /// <returns></returns>
    public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
    {
      var success = true;
      rawInputBuffer = IntPtr.Zero;

      try
      {
        uint dwSize = 0;
        var sizeOfHeader = (uint) Marshal.SizeOf(typeof (RAWINPUTHEADER));

        //Get the size of our raw input data.
        Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);

        //Allocate a large enough buffer
        rawInputBuffer = Marshal.AllocHGlobal((int) dwSize);

        //Now read our RAWINPUT data
        if (
          Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize,
            (uint) Marshal.SizeOf(typeof (RAWINPUTHEADER))) != dwSize)
        {
          return false;
        }

        //Cast our buffer
        aRawInput = (RAWINPUT) Marshal.PtrToStructure(rawInputBuffer, typeof (RAWINPUT));
      }
      catch
      {
        Debug.WriteLine("GetRawInputData failed!");
        success = false;
      }

      return success;
    }
Exemplo n.º 2
0
        /// <summary>
        /// </summary>
        /// <param name="aRawInputHandle"></param>
        /// <param name="aRawInput"></param>
        /// <param name="rawInputBuffer">Caller must free up memory on the pointer using Marshal.FreeHGlobal</param>
        /// <returns></returns>
        public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
        {
            var success = true;

            rawInputBuffer = IntPtr.Zero;

            try
            {
                uint dwSize       = 0;
                var  sizeOfHeader = (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));

                //Get the size of our raw input data.
                Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);

                //Allocate a large enough buffer
                rawInputBuffer = Marshal.AllocHGlobal((int)dwSize);

                //Now read our RAWINPUT data
                if (
                    Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize,
                                             (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
                {
                    return(false);
                }

                //Cast our buffer
                aRawInput = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
            }
            catch
            {
                Debug.WriteLine("GetRawInputData failed!");
                success = false;
            }

            return(success);
        }
Exemplo n.º 3
0
    /// <summary>
    ///   Initialize an HidEvent from a WM_INPUT message
    /// </summary>
    /// <param name="hRawInputDevice">
    ///   Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as
    ///   rawinput.header.hDevice
    /// </param>
    public HidEvent(Message aMessage, HidEventRepeatDelegate aRepeatDelegate)
    {
      RepeatCount = 0;
      IsValid = false;
      IsKeyboard = false;
      IsGeneric = false;


      Time = DateTime.Now;
      OriginalTime = DateTime.Now;
      Timer = new Timer();
      Timer.Elapsed += (sender, e) => OnRepeatTimerElapsed(sender, e, this);
      Usages = new List<ushort>();
      OnHidEventRepeat += aRepeatDelegate;

      if (aMessage.Msg != Const.WM_INPUT)
      {
        //Has to be a WM_INPUT message
        return;
      }

      if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUT)
      {
        IsForeground = true;
      }
      else if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUTSINK)
      {
        IsForeground = false;
      }

      //Declare some pointers
      var rawInputBuffer = IntPtr.Zero;
      //My understanding is that this is basically our HID descriptor 
      var preParsedData = IntPtr.Zero;

      try
      {
        //Fetch raw input
        var rawInput = new RAWINPUT();
        if (!RawInput.GetRawInputData(aMessage.LParam, ref rawInput, ref rawInputBuffer))
        {
          return;
        }

        //Fetch device info
        var deviceInfo = new RID_DEVICE_INFO();
        if (!RawInput.GetDeviceInfo(rawInput.header.hDevice, ref deviceInfo))
        {
          return;
        }

        //Get various information about this HID device
        Device = new HidDevice(rawInput.header.hDevice);

        if (rawInput.header.dwType == Const.RIM_TYPEHID) //Check that our raw input is HID                        
        {
          IsGeneric = true;

          Debug.WriteLine("WM_INPUT source device is HID.");
          //Get Usage Page and Usage
          //Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage ID: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
          UsagePage = deviceInfo.hid.usUsagePage;
          UsageCollection = deviceInfo.hid.usUsage;

          preParsedData = RawInput.GetPreParsedData(rawInput.header.hDevice);

          if (
            !(rawInput.hid.dwSizeHid > 1
              //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now
              && rawInput.hid.dwCount > 0)) //Check that we have at least one HID msg
          {
            return;
          }

          //Allocate a buffer for one HID input
          var hidInputReport = new byte[rawInput.hid.dwSizeHid];

          Debug.WriteLine("Raw input contains " + rawInput.hid.dwCount + " HID input report(s)");

          //For each HID input report in our raw input
          for (var i = 0; i < rawInput.hid.dwCount; i++)
          {
            //Compute the address from which to copy our HID input
            var hidInputOffset = 0;
            unsafe
            {
              var source = (byte*) rawInputBuffer;
              source += sizeof (RAWINPUTHEADER) + sizeof (RAWHID) + (rawInput.hid.dwSizeHid*i);
              hidInputOffset = (int) source;
            }

            //Copy HID input into our buffer
            Marshal.Copy(new IntPtr(hidInputOffset), hidInputReport, 0, (int) rawInput.hid.dwSizeHid);

            //Print HID input report in our debug output
            var hidDump = "HID input report: ";
            foreach (var b in hidInputReport)
            {
              hidDump += b.ToString("X2");
            }
            Debug.WriteLine(hidDump);

            //Proper parsing now
            uint usageCount = 1; //Assuming a single usage per input report. Is that correct?
            var usages = new USAGE_AND_PAGE[usageCount];
            var status = Function.HidP_GetUsagesEx(HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, preParsedData,
              hidInputReport, (uint) hidInputReport.Length);
            if (status != HidStatus.HIDP_STATUS_SUCCESS)
            {
              Log.Error("HID: Could not parse HID data!");
            }
            else
            {
              //Debug.WriteLine("UsagePage: 0x" + usages[0].UsagePage.ToString("X4"));
              //Debug.WriteLine("Usage: 0x" + usages[0].Usage.ToString("X4"));
              //Add this usage to our list
              Usages.Add(usages[0].Usage);
            }
          }
        }
        else if (rawInput.header.dwType == Const.RIM_TYPEMOUSE)
        {
          IsMouse = true;

          Debug.WriteLine("WM_INPUT source device is Mouse.");
          // do mouse handling...
        }
        else if (rawInput.header.dwType == Const.RIM_TYPEKEYBOARD)
        {
          IsKeyboard = true;

          Debug.WriteLine("WM_INPUT source device is Keyboard.");
          // do keyboard handling...
          Debug.WriteLine("Type: " + deviceInfo.keyboard.dwType);
          Debug.WriteLine("SubType: " + deviceInfo.keyboard.dwSubType);
          Debug.WriteLine("Mode: " + deviceInfo.keyboard.dwKeyboardMode);
          Debug.WriteLine("Number of function keys: " + deviceInfo.keyboard.dwNumberOfFunctionKeys);
          Debug.WriteLine("Number of indicators: " + deviceInfo.keyboard.dwNumberOfIndicators);
          Debug.WriteLine("Number of keys total: " + deviceInfo.keyboard.dwNumberOfKeysTotal);
        }
      }
      finally
      {
        //Always executed when leaving our try block
        Marshal.FreeHGlobal(rawInputBuffer);
        Marshal.FreeHGlobal(preParsedData);
      }

      //Start repeat timer if needed 
      if (IsButtonDown)
      {
        StartRepeatTimer(iRepeatDelay);
      }

      IsValid = true;
    }