Hid/HidHandler.cs
author StephaneLenclud
Tue, 17 Mar 2015 15:35:58 +0100
changeset 83 2d5955694057
parent 81 baabcd5cdf8c
child 84 e13ea80016a1
permissions -rw-r--r--
Switch solution to 2013.
Event repeat now a Handler option.
Handler now deregisters devices when disposed.
Adding Thinkpad custom usages.
     1 //
     2 // Copyright (C) 2014-2015 Stéphane Lenclud.
     3 //
     4 // This file is part of SharpLibHid.
     5 //
     6 // SharpDisplayManager is free software: you can redistribute it and/or modify
     7 // it under the terms of the GNU General Public License as published by
     8 // the Free Software Foundation, either version 3 of the License, or
     9 // (at your option) any later version.
    10 //
    11 // SharpDisplayManager is distributed in the hope that it will be useful,
    12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 // GNU General Public License for more details.
    15 //
    16 // You should have received a copy of the GNU General Public License
    17 // along with SharpDisplayManager.  If not, see <http://www.gnu.org/licenses/>.
    18 //
    19 
    20 
    21 using System;
    22 using System.Windows.Forms;
    23 using System.Runtime.InteropServices;
    24 using System.Diagnostics;
    25 using System.Text;
    26 using Microsoft.Win32.SafeHandles;
    27 using SharpLib.Win32;
    28 using System.Collections.Generic;
    29 
    30 
    31 namespace SharpLib.Hid
    32 {
    33     /// <summary>
    34     /// Our HID handler manages raw input registrations, processes WM_INPUT messages and broadcasts HID events in return.
    35     /// </summary>
    36     public class Handler : IDisposable
    37     {
    38         public delegate void HidEventHandler(object aSender, Event aHidEvent);
    39         public event HidEventHandler OnHidEvent;
    40         List<Event> iHidEvents;
    41         RAWINPUTDEVICE[] iRawInputDevices;
    42 
    43 
    44         public bool IsRegistered { get; private set; }
    45         public bool ManageRepeats { get; private set; }
    46 
    47         public Handler(RAWINPUTDEVICE[] aRawInputDevices, bool aManageRepeats=false)
    48         {
    49             iRawInputDevices = aRawInputDevices;
    50             iHidEvents = new List<Event>();
    51             IsRegistered = Function.RegisterRawInputDevices(iRawInputDevices, (uint)iRawInputDevices.Length, (uint)Marshal.SizeOf(iRawInputDevices[0]));
    52             ManageRepeats = aManageRepeats;
    53         }
    54 
    55         /// <summary>
    56         /// Will de-register devices.
    57         /// </summary>
    58         public void Dispose()
    59         {
    60             //Setup device removal
    61             for (int i=0; i<iRawInputDevices.Length; i++)
    62             {
    63                 iRawInputDevices[i].dwFlags = Const.RIDEV_REMOVE;
    64                 iRawInputDevices[i].hwndTarget = IntPtr.Zero;
    65             }
    66 
    67             //De-register
    68             Function.RegisterRawInputDevices(iRawInputDevices, (uint)iRawInputDevices.Length, (uint)Marshal.SizeOf(iRawInputDevices[0]));
    69             IsRegistered = false;
    70         }
    71 
    72         /// <summary>
    73         /// Process a WM_INPUT message.
    74         /// </summary>
    75         /// <param name="aMessage"></param>
    76         public void ProcessInput(ref Message aMessage)
    77         {
    78             if (aMessage.Msg != Const.WM_INPUT)
    79             {
    80                 //We only process WM_INPUT messages
    81                 return;
    82             }
    83 
    84             Event hidEvent = new Event(aMessage, OnHidEventRepeat, ManageRepeats);
    85             hidEvent.DebugWrite();
    86 
    87             if (!hidEvent.IsValid || !hidEvent.IsGeneric)
    88             {
    89                 Debug.WriteLine("Skipping HID message.");
    90                 return;
    91             }
    92 
    93             //
    94             if (ManageRepeats)
    95             {
    96                 if (hidEvent.IsButtonUp)
    97                 {
    98                     //This is a key up event
    99                     //We need to discard any events belonging to the same page and collection
   100                     for (int i = (iHidEvents.Count - 1); i >= 0; i--)
   101                     {
   102                         if (iHidEvents[i].UsageId == hidEvent.UsageId)
   103                         {
   104                             iHidEvents[i].Dispose();
   105                             iHidEvents.RemoveAt(i);
   106                         }
   107                     }
   108                 }
   109                 else
   110                 {
   111                     //Keep that event until we get a key up message
   112                     iHidEvents.Add(hidEvent);
   113                 }
   114             }
   115 
   116             //Broadcast our events
   117             OnHidEvent(this, hidEvent);    
   118         }
   119 
   120         public void OnHidEventRepeat(Event aHidEvent)
   121         {
   122             //Broadcast our events
   123             OnHidEvent(this, aHidEvent);    
   124         }
   125 
   126     }
   127 
   128 }