# HG changeset patch
# User sl
# Date 1415444479 -3600
# Node ID 2ff6dbe0d356d50f6554b012434c0c553ffeb9df
# Parent 17f8421146ba193c8c0484f4ea6adb82cbcc59e1
More code consoludation. Supporting multiple HID input per message.
diff -r 17f8421146ba -r 2ff6dbe0d356 HumanInterfaceDevice.cs
--- a/HumanInterfaceDevice.cs Fri Nov 07 22:12:22 2014 +0100
+++ b/HumanInterfaceDevice.cs Sat Nov 08 12:01:19 2014 +0100
@@ -64,7 +64,7 @@
///
///
///
- public enum MceButton
+ public enum MceButton: ushort
{
///
/// Not defined by the Microsoft specs.
@@ -188,6 +188,9 @@
VideoSelection = 0x61
}
+ ///
+ /// Those codes come from experimenting with HP remotes.
+ ///
public enum HpMceButton: ushort
{
///
diff -r 17f8421146ba -r 2ff6dbe0d356 RemoteControlDevice.cs
--- a/RemoteControlDevice.cs Fri Nov 07 22:12:22 2014 +0100
+++ b/RemoteControlDevice.cs Sat Nov 08 12:01:19 2014 +0100
@@ -353,94 +353,101 @@
try
{
//Fetch raw input
- RAWINPUT raw = new RAWINPUT();
- if (!RawInput.GetRawInputData(message.LParam, ref raw, ref rawInputBuffer))
+ RAWINPUT rawInput = new RAWINPUT();
+ if (!RawInput.GetRawInputData(message.LParam, ref rawInput, ref rawInputBuffer))
{
return;
}
//Fetch device info
RID_DEVICE_INFO deviceInfo = new RID_DEVICE_INFO();
- if (!RawInput.GetDeviceInfo(raw.header.hDevice, ref deviceInfo))
+ if (!RawInput.GetDeviceInfo(rawInput.header.hDevice, ref deviceInfo))
{
return;
}
+
- //Check type of input device and quite if we don't like it
- switch (deviceInfo.dwType)
+ if (rawInput.header.dwType == Const.RIM_TYPEHID) //Check that our raw input is HID
{
- case Const.RIM_TYPEHID:
- Debug.WriteLine("WM_INPUT source device is HID.");
- break;
- case Const.RIM_TYPEMOUSE:
- Debug.WriteLine("WM_INPUT source device is Mouse.");
- return;
- case Const.RIM_TYPEKEYBOARD:
- Debug.WriteLine("WM_INPUT source device is Keyboard.");
- return;
- default:
- Debug.WriteLine("WM_INPUT source device is Unknown.");
- return;
- }
-
- //Get Usage Page and Usage
- Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
-
-
- if (raw.header.dwType == Const.RIM_TYPEHID //Check that our raw input is HID
- && raw.hid.dwSizeHid > 1 //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now
- && raw.hid.dwCount > 0) //Check that we have at least one HID msg
- {
- //TODO: for each HID message
-
- //Allocate a buffer for one HID message
- byte[] bRawData = new byte[raw.hid.dwSizeHid];
-
- //Compute the address from which to copy our HID message
- int pRawData = 0;
- unsafe
- {
- byte* source = (byte*)rawInputBuffer;
- source += sizeof(RAWINPUTHEADER) + sizeof(RAWHID);
- pRawData = (int)source;
- }
-
- //Copy HID message into our buffer
- Marshal.Copy(new IntPtr(pRawData), bRawData, 0, raw.hid.dwSizeHid);
- //bRawData[0] //Not sure what's the meaning of the code at offset 0
- //TODO: check size before access
- int rawData = bRawData[1]; //Get button code
- //Print HID codes in our debug output
- string hidDump = "HID " + raw.hid.dwCount + "/" + raw.hid.dwSizeHid + ":";
- foreach (byte b in bRawData)
- {
- hidDump += b.ToString("X2");
- }
- Debug.WriteLine(hidDump);
-
+ Debug.WriteLine("WM_INPUT source device is HID.");
+ //Get Usage Page and Usage
+ Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
//Make sure both usage page and usage are matching MCE remote
+ //TODO: handle more that just MCE usage page.
if (deviceInfo.hid.usUsagePage != (ushort)Hid.UsagePage.MceRemote || deviceInfo.hid.usUsage != (ushort)Hid.UsageId.MceRemoteUsage)
{
Debug.WriteLine("Not MCE remote page and usage.");
return;
}
- if (Enum.IsDefined(typeof(MceButton), rawData) && rawData != 0) //Our button is a known MCE button
+ 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
{
- if (this.ButtonPressed != null) //What's that?
+ return;
+ }
+
+
+ //Allocate a buffer for one HID input
+ byte[] hidInput = new byte[rawInput.hid.dwSizeHid];
+
+ //For each HID input in our raw input
+ for (int i = 0; i < rawInput.hid.dwCount; i++)
+ {
+ //Compute the address from which to copy our HID input
+ int hidInputOffset = 0;
+ unsafe
{
- this.ButtonPressed(this, new RemoteControlEventArgs((MceButton)rawData, GetDevice(message.LParam.ToInt32())));
+ byte* 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), hidInput, 0, rawInput.hid.dwSizeHid);
+
+ //Print HID raw input in our debug output
+ string hidDump = "HID " + rawInput.hid.dwCount + "/" + rawInput.hid.dwSizeHid + ":";
+ foreach (byte b in hidInput)
+ {
+ hidDump += b.ToString("X2");
+ }
+ Debug.WriteLine(hidDump);
+
+ ushort usage = 0;
+ //hidInput[0] //Not sure what's the meaning of the code at offset 0
+ if (hidInput.Length == 2)
+ {
+ //Single byte code
+ usage = hidInput[1]; //Get button code
+ }
+ else if (hidInput.Length > 2) //Defensive
+ {
+ //Assuming double bytes code
+ usage = (ushort)((hidInput[1] << 2) + hidInput[2]);
+ }
+
+ //
+ if (Enum.IsDefined(typeof(MceButton), usage) && usage != 0) //Our button is a known MCE button
+ {
+ if (this.ButtonPressed != null) //What's that?
+ {
+ this.ButtonPressed(this, new RemoteControlEventArgs((MceButton)usage, InputDevice.OEM));
+ }
}
}
+
}
- else if (raw.header.dwType == Const.RIM_TYPEMOUSE)
+ else if (rawInput.header.dwType == Const.RIM_TYPEMOUSE)
{
+ Debug.WriteLine("WM_INPUT source device is Mouse.");
// do mouse handling...
}
- else if (raw.header.dwType == Const.RIM_TYPEKEYBOARD)
+ else if (rawInput.header.dwType == Const.RIM_TYPEKEYBOARD)
{
+ Debug.WriteLine("WM_INPUT source device is Keyboard.");
// do keyboard handling...
+
}
}
finally