StephaneLenclud@125: using System;
StephaneLenclud@126: using System.IO;
StephaneLenclud@125: using System.Collections.Generic;
StephaneLenclud@125: using System.Linq;
StephaneLenclud@125: using System.Text;
StephaneLenclud@125: using System.Threading.Tasks;
StephaneLenclud@125: using System.Diagnostics;
StephaneLenclud@125: using System.Runtime.InteropServices;
StephaneLenclud@125: using System.Windows.Forms;
StephaneLenclud@150: using Microsoft.Win32.SafeHandles;
StephaneLenclud@155: using System.ComponentModel;
StephaneLenclud@125: //
StephaneLenclud@125: using Hid = SharpLib.Hid;
StephaneLenclud@125: using SharpLib.Win32;
StephaneLenclud@125:
StephaneLenclud@125: namespace SharpDisplayManager
StephaneLenclud@125: {
StephaneLenclud@138: ///
StephaneLenclud@138: /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes.
StephaneLenclud@138: ///
StephaneLenclud@131: [System.ComponentModel.DesignerCategory("Code")]
StephaneLenclud@226: public class FormMainHid : Form
StephaneLenclud@131: {
StephaneLenclud@131: //
StephaneLenclud@131: public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
StephaneLenclud@126:
StephaneLenclud@126:
StephaneLenclud@131: ///
StephaneLenclud@131: /// Register HID devices so that we receive corresponding WM_INPUT messages.
StephaneLenclud@131: ///
StephaneLenclud@131: protected void RegisterHidDevices()
StephaneLenclud@131: {
StephaneLenclud@131: // Register the input device to receive the commands from the
StephaneLenclud@131: // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
StephaneLenclud@131: // for the vendor defined usage page.
StephaneLenclud@128:
StephaneLenclud@241: RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[6];
StephaneLenclud@128:
StephaneLenclud@131: int i = 0;
StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl;
StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl;
StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131: rid[i].hwndTarget = Handle;
StephaneLenclud@128:
StephaneLenclud@131: i++;
StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl;
StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131: rid[i].hwndTarget = Handle;
StephaneLenclud@126:
StephaneLenclud@131: i++;
StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection;
StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131: rid[i].hwndTarget = Handle;
StephaneLenclud@125:
StephaneLenclud@131: i++;
StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl;
StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131: rid[i].hwndTarget = Handle;
StephaneLenclud@125:
StephaneLenclud@131: i++;
StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad;
StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131: rid[i].hwndTarget = Handle;
StephaneLenclud@125:
StephaneLenclud@241: i++;
StephaneLenclud@241: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@241: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
StephaneLenclud@241: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@241: rid[i].hwndTarget = Handle;
StephaneLenclud@241:
StephaneLenclud@131: //i++;
StephaneLenclud@131: //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131: //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
StephaneLenclud@131: //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
StephaneLenclud@131: //rid[i].hwndTarget = Handle;
StephaneLenclud@125:
StephaneLenclud@131: //i++;
StephaneLenclud@131: //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131: //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse;
StephaneLenclud@131: //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
StephaneLenclud@131: //rid[i].hwndTarget = aHWND;
StephaneLenclud@125:
StephaneLenclud@125:
StephaneLenclud@246: Program.HidHandler = new SharpLib.Hid.Handler(rid);
StephaneLenclud@246: if (!Program.HidHandler.IsRegistered)
StephaneLenclud@131: {
StephaneLenclud@131: Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
StephaneLenclud@131: }
StephaneLenclud@246: Program.HidHandler.OnHidEvent += HandleHidEventThreadSafe;
StephaneLenclud@159:
StephaneLenclud@131: }
StephaneLenclud@125:
StephaneLenclud@159:
StephaneLenclud@159:
StephaneLenclud@159:
StephaneLenclud@131: ///
StephaneLenclud@131: /// Here we receive HID events from our HID library.
StephaneLenclud@131: ///
StephaneLenclud@131: ///
StephaneLenclud@131: ///
StephaneLenclud@131: public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
StephaneLenclud@131: {
StephaneLenclud@241: if (aHidEvent.IsStray || !aHidEvent.IsValid)
StephaneLenclud@131: {
StephaneLenclud@131: //Stray event just ignore it
StephaneLenclud@131: return;
StephaneLenclud@131: }
StephaneLenclud@125:
StephaneLenclud@131: if (this.InvokeRequired)
StephaneLenclud@131: {
StephaneLenclud@131: //Not in the proper thread, invoke ourselves
StephaneLenclud@131: OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe);
StephaneLenclud@131: this.Invoke(d, new object[] { aSender, aHidEvent });
StephaneLenclud@131: }
StephaneLenclud@131: else
StephaneLenclud@131: {
StephaneLenclud@247: //Trigger corresponding EAR event if any
StephaneLenclud@247: {
StephaneLenclud@247: EventHid e = new EventHid();
StephaneLenclud@247: e.Copy(aHidEvent);
StephaneLenclud@247: Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@247: }
StephaneLenclud@247:
StephaneLenclud@241: if (aHidEvent.IsGeneric)
StephaneLenclud@150: {
StephaneLenclud@241: if (aHidEvent.Usages.Count == 0)
StephaneLenclud@241: {
StephaneLenclud@241: //No usage, nothing to do then
StephaneLenclud@241: return;
StephaneLenclud@241: }
StephaneLenclud@150:
StephaneLenclud@241: //We are in the proper thread
StephaneLenclud@241: if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl)
StephaneLenclud@241: {
StephaneLenclud@241: //Trigger events as needed
StephaneLenclud@241: EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter
StephaneLenclud@241: {
StephaneLenclud@241: Usage = (Hid.Usage.WindowsMediaCenterRemoteControl) aHidEvent.Usages[0]
StephaneLenclud@241: };
StephaneLenclud@241: Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@241: }
StephaneLenclud@241: else if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.Consumer)
StephaneLenclud@131: {
StephaneLenclud@241: //Trigger matching events if any
StephaneLenclud@241: EventHidConsumerControl e = new EventHidConsumerControl
StephaneLenclud@241: {
StephaneLenclud@241: Usage = (Hid.Usage.ConsumerControl) aHidEvent.Usages[0]
StephaneLenclud@241: };
StephaneLenclud@241: Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@131: }
StephaneLenclud@131: }
StephaneLenclud@241: else if (aHidEvent.IsKeyboard)
StephaneLenclud@237: {
StephaneLenclud@241: //Trigger matching events if any
StephaneLenclud@241: EventHidKeyboard e = new EventHidKeyboard
StephaneLenclud@241: {
StephaneLenclud@241: Key = aHidEvent.VirtualKey,
StephaneLenclud@241: IsKeyUp = aHidEvent.IsButtonUp,
StephaneLenclud@241: HasModifierAlt = aHidEvent.HasModifierAlt,
StephaneLenclud@241: HasModifierControl = aHidEvent.HasModifierControl,
StephaneLenclud@241: HasModifierShift = aHidEvent.HasModifierShift,
StephaneLenclud@241: HasModifierWindows = aHidEvent.HasModifierWindows,
StephaneLenclud@241: };
StephaneLenclud@238: Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@241: }
StephaneLenclud@152:
StephaneLenclud@131: }
StephaneLenclud@131: }
StephaneLenclud@125:
StephaneLenclud@245:
StephaneLenclud@155:
StephaneLenclud@245:
StephaneLenclud@167:
StephaneLenclud@167:
StephaneLenclud@131: ///
StephaneLenclud@131: /// We need to handle WM_INPUT.
StephaneLenclud@131: ///
StephaneLenclud@131: ///
StephaneLenclud@131: protected override void WndProc(ref Message message)
StephaneLenclud@131: {
StephaneLenclud@131: switch (message.Msg)
StephaneLenclud@131: {
StephaneLenclud@131: case Const.WM_INPUT:
StephaneLenclud@131: //Returning zero means we processed that message.
StephaneLenclud@131: message.Result = new IntPtr(0);
StephaneLenclud@246: Program.HidHandler.ProcessInput(ref message);
StephaneLenclud@131: break;
StephaneLenclud@131: }
StephaneLenclud@159:
StephaneLenclud@167: //Pass this on to base class.
StephaneLenclud@131: base.WndProc(ref message);
StephaneLenclud@131: }
StephaneLenclud@131: }
StephaneLenclud@125: }