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