Server/FormMain.Hid.cs
author StephaneLenclud
Sun, 21 Aug 2016 16:30:58 +0200
changeset 248 0220cb84df58
parent 246 30a221eecc06
child 249 cadc4e4302c6
permissions -rw-r--r--
Fixing EAR event edition.
EAR HID event now displays 'Press a key' if not valid.
StephaneLenclud@125
     1
using System;
StephaneLenclud@126
     2
using System.IO;
StephaneLenclud@125
     3
using System.Collections.Generic;
StephaneLenclud@125
     4
using System.Linq;
StephaneLenclud@125
     5
using System.Text;
StephaneLenclud@125
     6
using System.Threading.Tasks;
StephaneLenclud@125
     7
using System.Diagnostics;
StephaneLenclud@125
     8
using System.Runtime.InteropServices;
StephaneLenclud@125
     9
using System.Windows.Forms;
StephaneLenclud@150
    10
using Microsoft.Win32.SafeHandles;
StephaneLenclud@155
    11
using System.ComponentModel;
StephaneLenclud@125
    12
//
StephaneLenclud@125
    13
using Hid = SharpLib.Hid;
StephaneLenclud@125
    14
using SharpLib.Win32;
StephaneLenclud@125
    15
StephaneLenclud@125
    16
namespace SharpDisplayManager
StephaneLenclud@125
    17
{
StephaneLenclud@138
    18
    /// <summary>
StephaneLenclud@138
    19
    /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes.
StephaneLenclud@138
    20
    /// </summary>
StephaneLenclud@131
    21
    [System.ComponentModel.DesignerCategory("Code")]
StephaneLenclud@226
    22
    public class FormMainHid : Form
StephaneLenclud@131
    23
    {
StephaneLenclud@131
    24
        //
StephaneLenclud@131
    25
        public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
StephaneLenclud@126
    26
StephaneLenclud@126
    27
StephaneLenclud@131
    28
        /// <summary>
StephaneLenclud@131
    29
        /// Register HID devices so that we receive corresponding WM_INPUT messages.
StephaneLenclud@131
    30
        /// </summary>
StephaneLenclud@131
    31
        protected void RegisterHidDevices()
StephaneLenclud@131
    32
        {
StephaneLenclud@131
    33
            // Register the input device to receive the commands from the
StephaneLenclud@131
    34
            // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
StephaneLenclud@131
    35
            // for the vendor defined usage page.
StephaneLenclud@128
    36
StephaneLenclud@241
    37
            RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[6];
StephaneLenclud@128
    38
StephaneLenclud@131
    39
            int i = 0;
StephaneLenclud@131
    40
            rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl;
StephaneLenclud@131
    41
            rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl;
StephaneLenclud@233
    42
            rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131
    43
            rid[i].hwndTarget = Handle;
StephaneLenclud@128
    44
StephaneLenclud@131
    45
            i++;
StephaneLenclud@131
    46
            rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
StephaneLenclud@131
    47
            rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl;
StephaneLenclud@233
    48
            rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131
    49
            rid[i].hwndTarget = Handle;
StephaneLenclud@126
    50
StephaneLenclud@131
    51
            i++;
StephaneLenclud@131
    52
            rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
StephaneLenclud@131
    53
            rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection;
StephaneLenclud@233
    54
            rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131
    55
            rid[i].hwndTarget = Handle;
StephaneLenclud@125
    56
StephaneLenclud@131
    57
            i++;
StephaneLenclud@131
    58
            rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131
    59
            rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl;
StephaneLenclud@233
    60
            rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131
    61
            rid[i].hwndTarget = Handle;
StephaneLenclud@125
    62
StephaneLenclud@131
    63
            i++;
StephaneLenclud@131
    64
            rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131
    65
            rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad;
StephaneLenclud@233
    66
            rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@131
    67
            rid[i].hwndTarget = Handle;
StephaneLenclud@125
    68
StephaneLenclud@241
    69
            i++;
StephaneLenclud@241
    70
            rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@241
    71
            rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
StephaneLenclud@241
    72
            rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
StephaneLenclud@241
    73
            rid[i].hwndTarget = Handle;
StephaneLenclud@241
    74
StephaneLenclud@131
    75
            //i++;
StephaneLenclud@131
    76
            //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131
    77
            //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
StephaneLenclud@131
    78
            //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
StephaneLenclud@131
    79
            //rid[i].hwndTarget = Handle;
StephaneLenclud@125
    80
StephaneLenclud@131
    81
            //i++;
StephaneLenclud@131
    82
            //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
StephaneLenclud@131
    83
            //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse;
StephaneLenclud@131
    84
            //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
StephaneLenclud@131
    85
            //rid[i].hwndTarget = aHWND;
StephaneLenclud@125
    86
StephaneLenclud@125
    87
StephaneLenclud@246
    88
            Program.HidHandler = new SharpLib.Hid.Handler(rid);
StephaneLenclud@246
    89
            if (!Program.HidHandler.IsRegistered)
StephaneLenclud@131
    90
            {
StephaneLenclud@131
    91
                Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
StephaneLenclud@131
    92
            }
StephaneLenclud@246
    93
            Program.HidHandler.OnHidEvent += HandleHidEventThreadSafe;
StephaneLenclud@159
    94
StephaneLenclud@131
    95
        }
StephaneLenclud@125
    96
StephaneLenclud@159
    97
StephaneLenclud@159
    98
StephaneLenclud@159
    99
StephaneLenclud@131
   100
        /// <summary>
StephaneLenclud@131
   101
        /// Here we receive HID events from our HID library.
StephaneLenclud@131
   102
        /// </summary>
StephaneLenclud@131
   103
        /// <param name="aSender"></param>
StephaneLenclud@131
   104
        /// <param name="aHidEvent"></param>
StephaneLenclud@131
   105
        public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
StephaneLenclud@131
   106
        {
StephaneLenclud@241
   107
            if (aHidEvent.IsStray || !aHidEvent.IsValid)
StephaneLenclud@131
   108
            {
StephaneLenclud@131
   109
                //Stray event just ignore it
StephaneLenclud@131
   110
                return;
StephaneLenclud@131
   111
            }
StephaneLenclud@125
   112
StephaneLenclud@131
   113
            if (this.InvokeRequired)
StephaneLenclud@131
   114
            {
StephaneLenclud@131
   115
                //Not in the proper thread, invoke ourselves
StephaneLenclud@131
   116
                OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe);
StephaneLenclud@131
   117
                this.Invoke(d, new object[] { aSender, aHidEvent });
StephaneLenclud@131
   118
            }
StephaneLenclud@131
   119
            else
StephaneLenclud@131
   120
            {
StephaneLenclud@247
   121
                //Trigger corresponding EAR event if any
StephaneLenclud@247
   122
                {
StephaneLenclud@247
   123
                    EventHid e = new EventHid();
StephaneLenclud@247
   124
                    e.Copy(aHidEvent);
StephaneLenclud@247
   125
                    Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@247
   126
                }
StephaneLenclud@247
   127
StephaneLenclud@241
   128
                if (aHidEvent.IsGeneric)
StephaneLenclud@150
   129
                {
StephaneLenclud@241
   130
                    if (aHidEvent.Usages.Count == 0)
StephaneLenclud@241
   131
                    {
StephaneLenclud@241
   132
                        //No usage, nothing to do then
StephaneLenclud@241
   133
                        return;
StephaneLenclud@241
   134
                    }
StephaneLenclud@150
   135
StephaneLenclud@241
   136
                    //We are in the proper thread
StephaneLenclud@241
   137
                    if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl)
StephaneLenclud@241
   138
                    {
StephaneLenclud@241
   139
                        //Trigger events as needed
StephaneLenclud@241
   140
                        EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter
StephaneLenclud@241
   141
                        {
StephaneLenclud@241
   142
                            Usage = (Hid.Usage.WindowsMediaCenterRemoteControl) aHidEvent.Usages[0]
StephaneLenclud@241
   143
                        };
StephaneLenclud@241
   144
                        Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@241
   145
                    }
StephaneLenclud@241
   146
                    else if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.Consumer)
StephaneLenclud@131
   147
                    {
StephaneLenclud@241
   148
                        //Trigger matching events if any
StephaneLenclud@241
   149
                        EventHidConsumerControl e = new EventHidConsumerControl
StephaneLenclud@241
   150
                        {
StephaneLenclud@241
   151
                            Usage = (Hid.Usage.ConsumerControl) aHidEvent.Usages[0]
StephaneLenclud@241
   152
                        };
StephaneLenclud@241
   153
                        Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@131
   154
                    }
StephaneLenclud@131
   155
                }
StephaneLenclud@241
   156
                else if (aHidEvent.IsKeyboard)
StephaneLenclud@237
   157
                {
StephaneLenclud@241
   158
                    //Trigger matching events if any
StephaneLenclud@241
   159
                    EventHidKeyboard e = new EventHidKeyboard
StephaneLenclud@241
   160
                    {
StephaneLenclud@241
   161
                        Key = aHidEvent.VirtualKey,
StephaneLenclud@241
   162
                        IsKeyUp = aHidEvent.IsButtonUp,
StephaneLenclud@241
   163
                        HasModifierAlt = aHidEvent.HasModifierAlt,
StephaneLenclud@241
   164
                        HasModifierControl = aHidEvent.HasModifierControl,
StephaneLenclud@241
   165
                        HasModifierShift = aHidEvent.HasModifierShift,
StephaneLenclud@241
   166
                        HasModifierWindows = aHidEvent.HasModifierWindows,
StephaneLenclud@241
   167
                    };
StephaneLenclud@238
   168
                    Properties.Settings.Default.EarManager.TriggerEvent(e);
StephaneLenclud@241
   169
                }                
StephaneLenclud@152
   170
StephaneLenclud@131
   171
            }
StephaneLenclud@131
   172
        }
StephaneLenclud@125
   173
StephaneLenclud@245
   174
    
StephaneLenclud@155
   175
StephaneLenclud@245
   176
    
StephaneLenclud@167
   177
StephaneLenclud@167
   178
StephaneLenclud@131
   179
        /// <summary>
StephaneLenclud@131
   180
        /// We need to handle WM_INPUT.
StephaneLenclud@131
   181
        /// </summary>
StephaneLenclud@131
   182
        /// <param name="message"></param>
StephaneLenclud@131
   183
        protected override void WndProc(ref Message message)
StephaneLenclud@131
   184
        {
StephaneLenclud@131
   185
            switch (message.Msg)
StephaneLenclud@131
   186
            {
StephaneLenclud@131
   187
                case Const.WM_INPUT:
StephaneLenclud@131
   188
                    //Returning zero means we processed that message.
StephaneLenclud@131
   189
                    message.Result = new IntPtr(0);
StephaneLenclud@246
   190
                    Program.HidHandler.ProcessInput(ref message);
StephaneLenclud@131
   191
                    break;
StephaneLenclud@131
   192
            }
StephaneLenclud@159
   193
StephaneLenclud@167
   194
            //Pass this on to base class.
StephaneLenclud@131
   195
            base.WndProc(ref message);
StephaneLenclud@131
   196
        }
StephaneLenclud@131
   197
    }
StephaneLenclud@125
   198
}