Adding support for HID Keyboard events.
authorStephaneLenclud
Thu, 18 Aug 2016 18:49:03 +0200
changeset 2413b5a94f31400
parent 240 5c4f1e2bf29a
child 242 0a956121c273
Adding support for HID Keyboard events.
Server/Events/EventHidKeyboard.cs
Server/FormMain.Hid.cs
Server/SharpDisplayManager.csproj
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Server/Events/EventHidKeyboard.cs	Thu Aug 18 18:49:03 2016 +0200
     1.3 @@ -0,0 +1,138 @@
     1.4 +´╗┐using System;
     1.5 +using System.Collections.Generic;
     1.6 +using System.Linq;
     1.7 +using System.Text;
     1.8 +using System.Threading.Tasks;
     1.9 +using System.Runtime.Serialization;
    1.10 +using System.Windows.Forms;
    1.11 +using Ear = SharpLib.Ear;
    1.12 +using Hid = SharpLib.Hid;
    1.13 +
    1.14 +namespace SharpDisplayManager
    1.15 +{
    1.16 +    [DataContract]
    1.17 +    [Ear.AttributeObject(Id = "Event.Hid.Keyboard", Name = "HID Keyboard", Description = "Corresponding HID message received.")]
    1.18 +    public class EventHidKeyboard : Ear.Event
    1.19 +    {
    1.20 +        public EventHidKeyboard()
    1.21 +        {
    1.22 +        }
    1.23 +
    1.24 +        [DataMember]
    1.25 +        [Ear.AttributeObjectProperty
    1.26 +            (
    1.27 +            Id = "HID.Keyboard.Key",
    1.28 +            Name = "Key",
    1.29 +            Description = "The virtual key code."
    1.30 +            )]
    1.31 +        public Keys Key { get; set; }
    1.32 +
    1.33 +        [DataMember]
    1.34 +        [Ear.AttributeObjectProperty
    1.35 +            (
    1.36 +            Id = "HID.Keyboard.IsKeyUp",
    1.37 +            Name = "Key Up",
    1.38 +            Description = "Key up if set, key down otherwise."
    1.39 +            )]
    1.40 +        public bool IsKeyUp { get; set; } = true;
    1.41 +
    1.42 +        [DataMember]
    1.43 +        [Ear.AttributeObjectProperty
    1.44 +            (
    1.45 +            Id = "HID.Keyboard.HasModifierShift",
    1.46 +            Name = "Shift",
    1.47 +            Description = "Shift modifier applied."
    1.48 +            )]
    1.49 +        public bool HasModifierShift { get; set; } = false;
    1.50 +
    1.51 +        [DataMember]
    1.52 +        [Ear.AttributeObjectProperty
    1.53 +            (
    1.54 +            Id = "HID.Keyboard.HasModifierControl",
    1.55 +            Name = "Control",
    1.56 +            Description = "Control modifier applied."
    1.57 +            )]
    1.58 +        public bool HasModifierControl { get; set; } = false;
    1.59 +
    1.60 +        [DataMember]
    1.61 +        [Ear.AttributeObjectProperty
    1.62 +            (
    1.63 +            Id = "HID.Keyboard.HasModifierAlt",
    1.64 +            Name = "Alt",
    1.65 +            Description = "Alt modifier applied."
    1.66 +            )]
    1.67 +        public bool HasModifierAlt { get; set; } = false;
    1.68 +
    1.69 +        [DataMember]
    1.70 +        [Ear.AttributeObjectProperty
    1.71 +            (
    1.72 +            Id = "HID.Keyboard.HasModifierWindows",
    1.73 +            Name = "Windows",
    1.74 +            Description = "Windows modifier applied."
    1.75 +            )]
    1.76 +        public bool HasModifierWindows { get; set; } = false;
    1.77 +
    1.78 +
    1.79 +
    1.80 +        /// <summary>
    1.81 +        /// Make sure we distinguish between various configuration of this event 
    1.82 +        /// </summary>
    1.83 +        /// <returns></returns>
    1.84 +        public override string Brief()
    1.85 +        {
    1.86 +            string brief = Name + ": " + Key.ToString();
    1.87 +
    1.88 +            if (IsKeyUp)
    1.89 +            {
    1.90 +                brief += " (UP)";
    1.91 +            }
    1.92 +            else
    1.93 +            {
    1.94 +                brief += " (DOWN)";
    1.95 +            }
    1.96 +
    1.97 +            if (HasModifierAlt)
    1.98 +            {
    1.99 +                brief += " + ALT";
   1.100 +            }
   1.101 +
   1.102 +            if (HasModifierControl)
   1.103 +            {
   1.104 +                brief += " + CTRL";
   1.105 +            }
   1.106 +
   1.107 +            if (HasModifierShift)
   1.108 +            {
   1.109 +                brief += " + SHIFT";
   1.110 +            }
   1.111 +
   1.112 +            if (HasModifierWindows)
   1.113 +            {
   1.114 +                brief += " + WIN";
   1.115 +            }
   1.116 +
   1.117 +            return brief;
   1.118 +        }
   1.119 +
   1.120 +        /// <summary>
   1.121 +        ///
   1.122 +        /// </summary>
   1.123 +        /// <param name="obj"></param>
   1.124 +        /// <returns></returns>
   1.125 +        public override bool Equals(object obj)
   1.126 +        {
   1.127 +            if (obj is EventHidKeyboard)
   1.128 +            {
   1.129 +                EventHidKeyboard e = (EventHidKeyboard)obj;
   1.130 +                return  e.Key == Key
   1.131 +                        && e.IsKeyUp == IsKeyUp
   1.132 +                        && e.HasModifierAlt == HasModifierAlt
   1.133 +                        && e.HasModifierControl == HasModifierControl
   1.134 +                        && e.HasModifierShift == HasModifierShift
   1.135 +                        && e.HasModifierWindows == HasModifierWindows;
   1.136 +            }
   1.137 +
   1.138 +            return false;
   1.139 +        }
   1.140 +    }
   1.141 +}
     2.1 --- a/Server/FormMain.Hid.cs	Thu Aug 18 17:43:03 2016 +0200
     2.2 +++ b/Server/FormMain.Hid.cs	Thu Aug 18 18:49:03 2016 +0200
     2.3 @@ -40,7 +40,7 @@
     2.4              // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
     2.5              // for the vendor defined usage page.
     2.6  
     2.7 -            RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[5];
     2.8 +            RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[6];
     2.9  
    2.10              int i = 0;
    2.11              rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl;
    2.12 @@ -72,6 +72,12 @@
    2.13              rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    2.14              rid[i].hwndTarget = Handle;
    2.15  
    2.16 +            i++;
    2.17 +            rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
    2.18 +            rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
    2.19 +            rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    2.20 +            rid[i].hwndTarget = Handle;
    2.21 +
    2.22              //i++;
    2.23              //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
    2.24              //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
    2.25 @@ -104,7 +110,7 @@
    2.26          /// <param name="aHidEvent"></param>
    2.27          public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
    2.28          {
    2.29 -            if (aHidEvent.IsStray)
    2.30 +            if (aHidEvent.IsStray || !aHidEvent.IsValid)
    2.31              {
    2.32                  //Stray event just ignore it
    2.33                  return;
    2.34 @@ -118,43 +124,67 @@
    2.35              }
    2.36              else
    2.37              {
    2.38 -                if (aHidEvent.Usages.Count == 0)
    2.39 +                if (aHidEvent.IsGeneric)
    2.40                  {
    2.41 -                    //No usage, nothing to do then
    2.42 -                    return;
    2.43 -                }
    2.44 +                    if (aHidEvent.Usages.Count == 0)
    2.45 +                    {
    2.46 +                        //No usage, nothing to do then
    2.47 +                        return;
    2.48 +                    }
    2.49  
    2.50 -                //We are in the proper thread
    2.51 -                if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl)
    2.52 -                {
    2.53 -                    //Trigger events as needed
    2.54 -                    EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter { Usage = (Hid.Usage.WindowsMediaCenterRemoteControl)aHidEvent.Usages[0] };
    2.55 -                    Properties.Settings.Default.EarManager.TriggerEvent(e);
    2.56 +                    //We are in the proper thread
    2.57 +                    if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl)
    2.58 +                    {
    2.59 +                        //Trigger events as needed
    2.60 +                        EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter
    2.61 +                        {
    2.62 +                            Usage = (Hid.Usage.WindowsMediaCenterRemoteControl) aHidEvent.Usages[0]
    2.63 +                        };
    2.64 +                        Properties.Settings.Default.EarManager.TriggerEvent(e);
    2.65  
    2.66 -                    //Old legacy hard coded stuff
    2.67 -                    //TODO: remove it
    2.68 -                    switch (aHidEvent.Usages[0])
    2.69 +                        //Old legacy hard coded stuff
    2.70 +                        //TODO: remove it
    2.71 +                        switch (aHidEvent.Usages[0])
    2.72 +                        {
    2.73 +                            case (ushort) Hid.Usage.WindowsMediaCenterRemoteControl.GreenStart:
    2.74 +                                HandleGreenStart();
    2.75 +                                break;
    2.76 +                            case (ushort) Hid.Usage.WindowsMediaCenterRemoteControl.Eject:
    2.77 +                            case (ushort) Hid.Usage.WindowsMediaCenterRemoteControl.Ext2:
    2.78 +                                HandleEject();
    2.79 +                                break;
    2.80 +                        }
    2.81 +                    }
    2.82 +                    else if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.Consumer)
    2.83                      {
    2.84 -                        case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.GreenStart:
    2.85 -                            HandleGreenStart();
    2.86 -                            break;
    2.87 -                        case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.Eject:
    2.88 -                        case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.Ext2:
    2.89 -                            HandleEject();
    2.90 -                            break;
    2.91 +                        //Trigger matching events if any
    2.92 +                        EventHidConsumerControl e = new EventHidConsumerControl
    2.93 +                        {
    2.94 +                            Usage = (Hid.Usage.ConsumerControl) aHidEvent.Usages[0]
    2.95 +                        };
    2.96 +                        Properties.Settings.Default.EarManager.TriggerEvent(e);
    2.97 +
    2.98 +                        //Keep this for debug when only ThinkPad keyboard is available
    2.99 +                        //if (aHidEvent.Usages[0] == (ushort)Hid.Usage.ConsumerControl.ThinkPadFullscreenMagnifier)
   2.100 +                        //{
   2.101 +                        //    HandleEject();
   2.102 +                        //}
   2.103                      }
   2.104                  }
   2.105 -                else if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer)
   2.106 +                else if (aHidEvent.IsKeyboard)
   2.107                  {
   2.108 -                    EventHidConsumerControl e = new EventHidConsumerControl { Usage = (Hid.Usage.ConsumerControl)aHidEvent.Usages[0] };
   2.109 +                    //Trigger matching events if any
   2.110 +                    EventHidKeyboard e = new EventHidKeyboard
   2.111 +                    {
   2.112 +                        Key = aHidEvent.VirtualKey,
   2.113 +                        IsKeyUp = aHidEvent.IsButtonUp,
   2.114 +                        HasModifierAlt = aHidEvent.HasModifierAlt,
   2.115 +                        HasModifierControl = aHidEvent.HasModifierControl,
   2.116 +                        HasModifierShift = aHidEvent.HasModifierShift,
   2.117 +                        HasModifierWindows = aHidEvent.HasModifierWindows,
   2.118 +                    };
   2.119                      Properties.Settings.Default.EarManager.TriggerEvent(e);
   2.120 -
   2.121 -                    //Keep this for debug when only ThinkPad keyboard is available
   2.122 -                    //if (aHidEvent.Usages[0] == (ushort)Hid.Usage.ConsumerControl.ThinkPadFullscreenMagnifier)
   2.123 -                    //{
   2.124 -                    //    HandleEject();
   2.125 -                    //}
   2.126 -                }
   2.127 +                }                
   2.128  
   2.129              }
   2.130          }
     3.1 --- a/Server/SharpDisplayManager.csproj	Thu Aug 18 17:43:03 2016 +0200
     3.2 +++ b/Server/SharpDisplayManager.csproj	Thu Aug 18 18:49:03 2016 +0200
     3.3 @@ -180,6 +180,7 @@
     3.4      <Compile Include="ClientData.cs" />
     3.5      <Compile Include="EarManager.cs" />
     3.6      <Compile Include="Events\EventHidConsumerControl.cs" />
     3.7 +    <Compile Include="Events\EventHidKeyboard.cs" />
     3.8      <Compile Include="Events\EventHidWindowsMediaCenter.cs" />
     3.9      <Compile Include="FormEditObject.cs">
    3.10        <SubType>Form</SubType>