RemoteControlDevice.cs
author sl
Mon, 24 Nov 2014 16:46:26 +0100
changeset 14 0d9f479cbbf7
parent 13 6e4d62a4fed3
child 15 2044181ade12
permissions -rw-r--r--
Fixing HID page and usage test.
sl@0
     1
using System;
sl@0
     2
using System.Windows.Forms;
sl@0
     3
using System.Runtime.InteropServices;
sl@0
     4
using System.Diagnostics;
sl@8
     5
using Hid.UsageTables;
sl@9
     6
using Win32;
sl@0
     7
sl@6
     8
namespace Devices.RemoteControl
sl@0
     9
{
sl@6
    10
sl@0
    11
	public enum InputDevice
sl@0
    12
	{
sl@0
    13
		Key,
sl@0
    14
		Mouse,
sl@0
    15
		OEM
sl@0
    16
	}
sl@0
    17
sl@0
    18
sl@0
    19
	public enum RemoteControlButton
sl@0
    20
	{
sl@0
    21
		Clear,
sl@0
    22
		Down,
sl@0
    23
		Left,
sl@0
    24
		Digit0,
sl@0
    25
		Digit1,
sl@0
    26
		Digit2,
sl@0
    27
		Digit3,
sl@0
    28
		Digit4,
sl@0
    29
		Digit5,
sl@0
    30
		Digit6,
sl@0
    31
		Digit7,
sl@0
    32
		Digit8,
sl@0
    33
		Digit9,
sl@0
    34
		Enter,
sl@0
    35
		Right,
sl@0
    36
		Up,
sl@0
    37
sl@0
    38
		Back,
sl@0
    39
		ChannelDown,
sl@0
    40
		ChannelUp,
sl@0
    41
		FastForward,
sl@0
    42
		VolumeMute,
sl@0
    43
		Pause,
sl@0
    44
		Play,
sl@0
    45
        PlayPause,
sl@0
    46
		Record,
sl@0
    47
		PreviousTrack,
sl@0
    48
		Rewind,
sl@0
    49
		NextTrack,
sl@0
    50
		Stop,
sl@0
    51
		VolumeDown,
sl@0
    52
		VolumeUp,
sl@0
    53
sl@0
    54
		RecordedTV,
sl@0
    55
		Guide,
sl@0
    56
		LiveTV,
sl@12
    57
		MoreInfo,
sl@12
    58
        Print,
sl@0
    59
		DVDMenu,
sl@0
    60
		DVDAngle,
sl@0
    61
		DVDAudio,
sl@0
    62
		DVDSubtitle,
sl@0
    63
		MyMusic,
sl@0
    64
		MyPictures,
sl@0
    65
		MyVideos,
sl@0
    66
		MyTV,
sl@0
    67
		OEM1,
sl@0
    68
		OEM2,
sl@0
    69
		StandBy,
sl@0
    70
		TVJump,
sl@0
    71
sl@0
    72
		Unknown
sl@0
    73
	}
sl@0
    74
sl@0
    75
sl@0
    76
	#region RemoteControlEventArgs
sl@0
    77
sl@0
    78
	public class RemoteControlEventArgs : EventArgs
sl@0
    79
	{
sl@3
    80
        RemoteControlButton _rcb;
sl@0
    81
		InputDevice _device;
sl@3
    82
        MceButton iMceButton;
sl@0
    83
sl@3
    84
        public RemoteControlEventArgs(RemoteControlButton rcb, InputDevice device)
sl@0
    85
		{
sl@3
    86
            iMceButton = MceButton.Null;
sl@0
    87
			_rcb = rcb;
sl@0
    88
			_device = device;
sl@0
    89
		}
sl@0
    90
sl@3
    91
        public RemoteControlEventArgs(MceButton mce, InputDevice device)
sl@3
    92
        {
sl@3
    93
            iMceButton = mce;
sl@3
    94
            _rcb = RemoteControlButton.Unknown;
sl@3
    95
            _device = device;
sl@3
    96
        }
sl@0
    97
sl@0
    98
		public RemoteControlEventArgs()
sl@0
    99
		{
sl@3
   100
            iMceButton = MceButton.Null;
sl@0
   101
			_rcb = RemoteControlButton.Unknown;
sl@0
   102
			_device = InputDevice.Key;
sl@0
   103
		}
sl@0
   104
sl@0
   105
		public RemoteControlButton Button
sl@0
   106
		{
sl@0
   107
			get { return _rcb;  }
sl@0
   108
			set { _rcb = value; }
sl@0
   109
		}
sl@0
   110
sl@3
   111
        public MceButton MceButton
sl@3
   112
        {
sl@3
   113
            get { return iMceButton; }
sl@3
   114
            set { iMceButton = value; }
sl@3
   115
        }
sl@3
   116
sl@0
   117
		public InputDevice Device
sl@0
   118
		{
sl@0
   119
			get { return _device;  }
sl@0
   120
			set { _device = value; }
sl@0
   121
		}
sl@0
   122
	}
sl@0
   123
sl@0
   124
	#endregion RemoteControlEventArgs
sl@0
   125
sl@0
   126
sl@0
   127
	public sealed class RemoteControlDevice
sl@0
   128
	{
sl@0
   129
		private const int WM_KEYDOWN	= 0x0100;
sl@0
   130
		private const int WM_APPCOMMAND	= 0x0319;
sl@0
   131
		private const int WM_INPUT		= 0x00FF;
sl@0
   132
sl@0
   133
		private const int APPCOMMAND_BROWSER_BACKWARD   = 1;
sl@0
   134
		private const int APPCOMMAND_VOLUME_MUTE        = 8;
sl@0
   135
		private const int APPCOMMAND_VOLUME_DOWN        = 9;
sl@0
   136
		private const int APPCOMMAND_VOLUME_UP          = 10;
sl@0
   137
		private const int APPCOMMAND_MEDIA_NEXTTRACK    = 11;
sl@0
   138
		private const int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
sl@0
   139
		private const int APPCOMMAND_MEDIA_STOP         = 13;
sl@0
   140
		private const int APPCOMMAND_MEDIA_PLAY_PAUSE   = 14;
sl@0
   141
		private const int APPCOMMAND_MEDIA_PLAY         = 46;
sl@0
   142
		private const int APPCOMMAND_MEDIA_PAUSE        = 47;
sl@0
   143
		private const int APPCOMMAND_MEDIA_RECORD       = 48;
sl@0
   144
		private const int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
sl@0
   145
		private const int APPCOMMAND_MEDIA_REWIND       = 50;
sl@0
   146
		private const int APPCOMMAND_MEDIA_CHANNEL_UP   = 51;
sl@0
   147
		private const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
sl@0
   148
sl@0
   149
		private const int FAPPCOMMAND_MASK				= 0xF000;
sl@0
   150
		private const int FAPPCOMMAND_MOUSE				= 0x8000;
sl@0
   151
		private const int FAPPCOMMAND_KEY				= 0;
sl@0
   152
		private const int FAPPCOMMAND_OEM				= 0x1000;
sl@0
   153
sl@6
   154
sl@6
   155
sl@0
   156
		public delegate void RemoteControlDeviceEventHandler(object sender, RemoteControlEventArgs e);
sl@0
   157
		public event RemoteControlDeviceEventHandler ButtonPressed;
sl@0
   158
sl@12
   159
        public delegate void HidUsageHandler(ushort aUsage);
sl@12
   160
        
sl@12
   161
sl@0
   162
sl@0
   163
		//-------------------------------------------------------------
sl@0
   164
		// constructors
sl@0
   165
		//-------------------------------------------------------------
sl@0
   166
sl@0
   167
		public RemoteControlDevice()
sl@0
   168
		{
sl@0
   169
			// Register the input device to receive the commands from the
sl@0
   170
			// remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
sl@0
   171
			// for the vendor defined usage page.
sl@0
   172
sl@0
   173
			RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[3];
sl@0
   174
sl@0
   175
			rid[0].usUsagePage = 0xFFBC;
sl@0
   176
			rid[0].usUsage = 0x88;
sl@0
   177
			rid[0].dwFlags = 0;
sl@0
   178
sl@0
   179
			rid[1].usUsagePage = 0x0C;
sl@0
   180
			rid[1].usUsage = 0x01;
sl@0
   181
			rid[1].dwFlags = 0;
sl@0
   182
sl@0
   183
			rid[2].usUsagePage = 0x0C;
sl@0
   184
			rid[2].usUsage = 0x80;
sl@0
   185
			rid[2].dwFlags = 0;
sl@0
   186
sl@9
   187
			if (!Function.RegisterRawInputDevices(rid,
sl@0
   188
				(uint) rid.Length,
sl@0
   189
				(uint) Marshal.SizeOf(rid[0]))
sl@0
   190
				)
sl@0
   191
			{
sl@0
   192
				throw new ApplicationException("Failed to register raw input devices.");
sl@0
   193
			}
sl@0
   194
		}
sl@0
   195
sl@0
   196
sl@0
   197
		//-------------------------------------------------------------
sl@0
   198
		// methods
sl@0
   199
		//-------------------------------------------------------------
sl@0
   200
sl@0
   201
		public void ProcessMessage(Message message)
sl@0
   202
		{
sl@12
   203
		int param;
sl@0
   204
sl@0
   205
			switch (message.Msg)
sl@0
   206
			{
sl@0
   207
				case WM_KEYDOWN:
sl@0
   208
					param = message.WParam.ToInt32();
sl@0
   209
					ProcessKeyDown(param);
sl@0
   210
					break;
sl@0
   211
				case WM_APPCOMMAND:
sl@0
   212
					param = message.LParam.ToInt32();
sl@0
   213
					ProcessAppCommand(param);
sl@0
   214
					break;
sl@0
   215
				case WM_INPUT:
sl@0
   216
					ProcessInputCommand(ref message);
sl@0
   217
                    message.Result = new IntPtr(0);
sl@0
   218
					break;
sl@0
   219
			}
sl@0
   220
sl@0
   221
		}
sl@0
   222
sl@0
   223
sl@0
   224
		//-------------------------------------------------------------
sl@0
   225
		// methods (helpers)
sl@0
   226
		//-------------------------------------------------------------
sl@0
   227
sl@0
   228
		private void ProcessKeyDown(int param)
sl@0
   229
		{
sl@0
   230
			RemoteControlButton rcb = RemoteControlButton.Unknown;
sl@0
   231
sl@0
   232
			switch (param)
sl@0
   233
			{
sl@0
   234
				case (int) Keys.Escape:
sl@0
   235
					rcb = RemoteControlButton.Clear;
sl@0
   236
					break;
sl@0
   237
				case (int) Keys.Down:
sl@0
   238
					rcb = RemoteControlButton.Down;
sl@0
   239
					break;
sl@0
   240
				case (int) Keys.Left:
sl@0
   241
					rcb = RemoteControlButton.Left;
sl@0
   242
					break;
sl@0
   243
				case (int) Keys.D0:
sl@0
   244
					rcb = RemoteControlButton.Digit0;
sl@0
   245
					break;
sl@0
   246
				case (int) Keys.D1:
sl@0
   247
					rcb = RemoteControlButton.Digit1;
sl@0
   248
					break;
sl@0
   249
				case (int) Keys.D2:
sl@0
   250
					rcb = RemoteControlButton.Digit2;
sl@0
   251
					break;
sl@0
   252
				case (int) Keys.D3:
sl@0
   253
					rcb = RemoteControlButton.Digit3;
sl@0
   254
					break;
sl@0
   255
				case (int) Keys.D4:
sl@0
   256
					rcb = RemoteControlButton.Digit4;
sl@0
   257
					break;
sl@0
   258
				case (int) Keys.D5:
sl@0
   259
					rcb = RemoteControlButton.Digit5;
sl@0
   260
					break;
sl@0
   261
				case (int) Keys.D6:
sl@0
   262
					rcb = RemoteControlButton.Digit6;
sl@0
   263
					break;
sl@0
   264
				case (int) Keys.D7:
sl@0
   265
					rcb = RemoteControlButton.Digit7;
sl@0
   266
					break;
sl@0
   267
				case (int) Keys.D8:
sl@0
   268
					rcb = RemoteControlButton.Digit8;
sl@0
   269
					break;
sl@0
   270
				case (int) Keys.D9:
sl@0
   271
					rcb = RemoteControlButton.Digit9;
sl@0
   272
					break;
sl@0
   273
				case (int) Keys.Enter:
sl@0
   274
					rcb = RemoteControlButton.Enter;
sl@0
   275
					break;
sl@0
   276
				case (int) Keys.Right:
sl@0
   277
					rcb = RemoteControlButton.Right;
sl@0
   278
					break;
sl@0
   279
				case (int) Keys.Up:
sl@0
   280
					rcb = RemoteControlButton.Up;
sl@0
   281
					break;
sl@0
   282
			}
sl@0
   283
sl@0
   284
			if (this.ButtonPressed != null && rcb != RemoteControlButton.Unknown)
sl@0
   285
				this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(param)));
sl@0
   286
		}
sl@0
   287
sl@0
   288
sl@0
   289
		private void ProcessAppCommand(int param)
sl@0
   290
		{
sl@0
   291
			RemoteControlButton rcb = RemoteControlButton.Unknown;
sl@0
   292
sl@0
   293
			int cmd	= (int) (((ushort) (param >> 16)) & ~FAPPCOMMAND_MASK);
sl@0
   294
sl@0
   295
			switch (cmd)
sl@0
   296
			{
sl@0
   297
				case APPCOMMAND_BROWSER_BACKWARD:
sl@0
   298
					rcb = RemoteControlButton.Back;
sl@0
   299
					break;
sl@0
   300
				case APPCOMMAND_MEDIA_CHANNEL_DOWN:
sl@0
   301
					rcb = RemoteControlButton.ChannelDown;
sl@0
   302
					break;
sl@0
   303
				case APPCOMMAND_MEDIA_CHANNEL_UP:
sl@0
   304
					rcb = RemoteControlButton.ChannelUp;
sl@0
   305
					break;
sl@0
   306
				case APPCOMMAND_MEDIA_FAST_FORWARD:
sl@0
   307
					rcb = RemoteControlButton.FastForward;
sl@0
   308
					break;
sl@0
   309
				case APPCOMMAND_VOLUME_MUTE:
sl@0
   310
					rcb = RemoteControlButton.VolumeMute;
sl@0
   311
					break;
sl@0
   312
				case APPCOMMAND_MEDIA_PAUSE:
sl@0
   313
					rcb = RemoteControlButton.Pause;
sl@0
   314
					break;
sl@0
   315
				case APPCOMMAND_MEDIA_PLAY:
sl@0
   316
					rcb = RemoteControlButton.Play;
sl@0
   317
					break;
sl@0
   318
                case APPCOMMAND_MEDIA_PLAY_PAUSE:
sl@0
   319
                    rcb = RemoteControlButton.PlayPause;
sl@0
   320
                    break;
sl@0
   321
				case APPCOMMAND_MEDIA_RECORD:
sl@0
   322
					rcb = RemoteControlButton.Record;
sl@0
   323
					break;
sl@0
   324
				case APPCOMMAND_MEDIA_PREVIOUSTRACK:
sl@0
   325
					rcb = RemoteControlButton.PreviousTrack;
sl@0
   326
					break;
sl@0
   327
				case APPCOMMAND_MEDIA_REWIND:
sl@0
   328
					rcb = RemoteControlButton.Rewind;
sl@0
   329
					break;
sl@0
   330
				case APPCOMMAND_MEDIA_NEXTTRACK:
sl@0
   331
					rcb = RemoteControlButton.NextTrack;
sl@0
   332
					break;
sl@0
   333
				case APPCOMMAND_MEDIA_STOP:
sl@0
   334
					rcb = RemoteControlButton.Stop;
sl@0
   335
					break;
sl@0
   336
				case APPCOMMAND_VOLUME_DOWN:
sl@0
   337
					rcb = RemoteControlButton.VolumeDown;
sl@0
   338
					break;
sl@0
   339
				case APPCOMMAND_VOLUME_UP:
sl@0
   340
					rcb = RemoteControlButton.VolumeUp;
sl@0
   341
					break;
sl@0
   342
			}
sl@0
   343
sl@0
   344
			if (this.ButtonPressed != null && rcb != RemoteControlButton.Unknown)
sl@0
   345
				this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(param)));
sl@0
   346
		}
sl@0
   347
sl@12
   348
        /// <summary>
sl@12
   349
        /// 
sl@12
   350
        /// </summary>
sl@12
   351
        /// <param name="aUsage"></param>
sl@12
   352
        private void HidConsumerDeviceHandler(ushort aUsage)
sl@12
   353
        {
sl@12
   354
            if (aUsage == 0)
sl@12
   355
            {
sl@12
   356
                //Just skip those
sl@12
   357
                return;
sl@12
   358
            }
sl@12
   359
sl@12
   360
            if (Enum.IsDefined(typeof(ConsumerControl), aUsage) && aUsage != 0) //Our button is a known consumer control
sl@12
   361
            {
sl@12
   362
                if (this.ButtonPressed != null)
sl@12
   363
                {
sl@12
   364
                    RemoteControlButton button=RemoteControlButton.Unknown;
sl@12
   365
                    if (aUsage== (ushort)ConsumerControl.AppCtrlProperties)
sl@12
   366
                    {
sl@12
   367
                        button = RemoteControlButton.MoreInfo;
sl@12
   368
                    }
sl@12
   369
                    else if (aUsage==(ushort)ConsumerControl.AppCtrlPrint)
sl@12
   370
                    {
sl@12
   371
                        button = RemoteControlButton.Print;
sl@12
   372
                    }
sl@12
   373
                    else if (aUsage==(ushort)ConsumerControl.MediaSelectProgramGuide)
sl@12
   374
                    {
sl@12
   375
                        button = RemoteControlButton.Guide;
sl@12
   376
                    }
sl@12
   377
                    this.ButtonPressed(this, new RemoteControlEventArgs(button, InputDevice.OEM));
sl@12
   378
                }
sl@12
   379
            }
sl@12
   380
            else
sl@12
   381
            {
sl@12
   382
                Debug.WriteLine("Unknown Consumer Control!");
sl@12
   383
            }
sl@12
   384
        }
sl@12
   385
sl@12
   386
        /// <summary>
sl@12
   387
        /// 
sl@12
   388
        /// </summary>
sl@12
   389
        /// <param name="aUsage"></param>
sl@12
   390
        private void HidMceRemoteHandler(ushort aUsage)
sl@12
   391
        {
sl@12
   392
            if (aUsage == 0)
sl@12
   393
            {
sl@12
   394
                //Just skip those
sl@12
   395
                return;
sl@12
   396
            }
sl@12
   397
sl@12
   398
sl@12
   399
            if (Enum.IsDefined(typeof(MceButton), aUsage) && aUsage != 0) //Our button is a known MCE button
sl@12
   400
            {
sl@12
   401
                if (this.ButtonPressed != null)
sl@12
   402
                {
sl@12
   403
                    this.ButtonPressed(this, new RemoteControlEventArgs((MceButton)aUsage, InputDevice.OEM));
sl@12
   404
                }
sl@12
   405
            }
sl@12
   406
            else
sl@12
   407
            {
sl@12
   408
                Debug.WriteLine("Unknown MCE button!");
sl@12
   409
            }
sl@12
   410
sl@12
   411
        }
sl@12
   412
sl@0
   413
sl@0
   414
		private void ProcessInputCommand(ref Message message)
sl@0
   415
		{
sl@7
   416
            Debug.WriteLine("================WM_INPUT================");
sl@6
   417
sl@0
   418
sl@10
   419
            //Declare a pointer
sl@10
   420
            IntPtr rawInputBuffer = IntPtr.Zero;
sl@0
   421
sl@10
   422
            try
sl@10
   423
            {
sl@10
   424
                //Fetch raw input
sl@11
   425
                RAWINPUT rawInput = new RAWINPUT();
sl@11
   426
                if (!RawInput.GetRawInputData(message.LParam, ref rawInput, ref rawInputBuffer))
sl@6
   427
                {
sl@6
   428
                    return;
sl@6
   429
                }
sl@6
   430
sl@10
   431
                //Fetch device info
sl@10
   432
                RID_DEVICE_INFO deviceInfo = new RID_DEVICE_INFO();
sl@11
   433
                if (!RawInput.GetDeviceInfo(rawInput.header.hDevice, ref deviceInfo))
sl@10
   434
                {
sl@10
   435
                    return;
sl@10
   436
                }
sl@11
   437
               
sl@6
   438
sl@11
   439
                if (rawInput.header.dwType == Const.RIM_TYPEHID)  //Check that our raw input is HID                        
sl@6
   440
                {
sl@11
   441
                    Debug.WriteLine("WM_INPUT source device is HID.");
sl@11
   442
                    //Get Usage Page and Usage
sl@13
   443
                    Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage ID: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
sl@10
   444
sl@12
   445
                    //
sl@13
   446
                    HidUsageHandler usagePageHandler=null;
sl@12
   447
sl@14
   448
                    //Check if this an MCE remote HID message
sl@14
   449
                    if (deviceInfo.hid.usUsagePage == (ushort)Hid.UsagePage.MceRemote && deviceInfo.hid.usUsage == (ushort)Hid.UsageId.MceRemoteUsage)
sl@12
   450
                    {                        
sl@13
   451
                        usagePageHandler = HidMceRemoteHandler;
sl@12
   452
                    }
sl@14
   453
                    //Check if this is a consumer control HID message
sl@14
   454
                    else if (deviceInfo.hid.usUsagePage == (ushort)Hid.UsagePage.Consumer && deviceInfo.hid.usUsage == (ushort)Hid.UsageId.ConsumerControl)
sl@12
   455
                    {
sl@13
   456
                        usagePageHandler = HidConsumerDeviceHandler;
sl@12
   457
                    }
sl@14
   458
                    //Unknown HID message
sl@12
   459
                    else
sl@6
   460
                    {
sl@14
   461
                        Debug.WriteLine("Unknown HID message.");
sl@6
   462
                        return;
sl@6
   463
                    }
sl@0
   464
sl@11
   465
                    if (!(rawInput.hid.dwSizeHid > 1     //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now
sl@11
   466
                        && rawInput.hid.dwCount > 0))    //Check that we have at least one HID msg
sl@3
   467
                    {
sl@11
   468
                        return;
sl@11
   469
                    }
sl@11
   470
sl@11
   471
sl@11
   472
                    //Allocate a buffer for one HID input
sl@11
   473
                    byte[] hidInput = new byte[rawInput.hid.dwSizeHid];
sl@11
   474
sl@11
   475
                    //For each HID input in our raw input
sl@11
   476
                    for (int i = 0; i < rawInput.hid.dwCount; i++)
sl@11
   477
                    {
sl@11
   478
                        //Compute the address from which to copy our HID input
sl@11
   479
                        int hidInputOffset = 0;
sl@11
   480
                        unsafe
sl@3
   481
                        {
sl@11
   482
                            byte* source = (byte*)rawInputBuffer;
sl@11
   483
                            source += sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + (rawInput.hid.dwSizeHid * i);
sl@11
   484
                            hidInputOffset = (int)source;
sl@11
   485
                        }
sl@11
   486
sl@11
   487
                        //Copy HID input into our buffer
sl@11
   488
                        Marshal.Copy(new IntPtr(hidInputOffset), hidInput, 0, rawInput.hid.dwSizeHid);
sl@11
   489
sl@11
   490
                        //Print HID raw input in our debug output
sl@11
   491
                        string hidDump = "HID " + rawInput.hid.dwCount + "/" + rawInput.hid.dwSizeHid + ":";
sl@11
   492
                        foreach (byte b in hidInput)
sl@11
   493
                        {
sl@11
   494
                            hidDump += b.ToString("X2");
sl@11
   495
                        }
sl@11
   496
                        Debug.WriteLine(hidDump);
sl@11
   497
                        
sl@11
   498
                        ushort usage = 0;
sl@11
   499
                        //hidInput[0] //Not sure what's the meaning of the code at offset 0
sl@11
   500
                        if (hidInput.Length == 2)
sl@11
   501
                        {
sl@11
   502
                            //Single byte code
sl@11
   503
                            usage = hidInput[1]; //Get button code
sl@11
   504
                        }
sl@11
   505
                        else if (hidInput.Length > 2) //Defensive
sl@11
   506
                        {
sl@11
   507
                            //Assuming double bytes code
sl@12
   508
                            usage = (ushort)((hidInput[2] << 8) + hidInput[1]);
sl@11
   509
                        }
sl@11
   510
sl@13
   511
                        Debug.WriteLine("Usage: 0x" + usage.ToString("X4"));
sl@13
   512
sl@13
   513
                        //Call on our Usage Page handler
sl@13
   514
                        usagePageHandler(usage);
sl@3
   515
                    }
sl@11
   516
sl@10
   517
                }
sl@11
   518
                else if (rawInput.header.dwType == Const.RIM_TYPEMOUSE)
sl@10
   519
                {
sl@11
   520
                    Debug.WriteLine("WM_INPUT source device is Mouse.");
sl@10
   521
                    // do mouse handling...
sl@10
   522
                }
sl@11
   523
                else if (rawInput.header.dwType == Const.RIM_TYPEKEYBOARD)
sl@10
   524
                {
sl@11
   525
                    Debug.WriteLine("WM_INPUT source device is Keyboard.");
sl@10
   526
                    // do keyboard handling...
sl@11
   527
sl@10
   528
                }
sl@10
   529
            }
sl@10
   530
            finally
sl@10
   531
            {
sl@10
   532
                //Always executed when leaving our try block
sl@10
   533
                Marshal.FreeHGlobal(rawInputBuffer);
sl@10
   534
            }
sl@0
   535
		}
sl@0
   536
sl@0
   537
sl@0
   538
		private InputDevice GetDevice(int param)
sl@0
   539
		{
sl@0
   540
			InputDevice inputDevice;
sl@0
   541
sl@0
   542
			switch ((int) (((ushort) (param >> 16)) & FAPPCOMMAND_MASK))
sl@0
   543
			{
sl@0
   544
				case FAPPCOMMAND_OEM:
sl@0
   545
					inputDevice = InputDevice.OEM;
sl@0
   546
					break;
sl@0
   547
				case FAPPCOMMAND_MOUSE:
sl@0
   548
					inputDevice = InputDevice.Mouse;
sl@0
   549
					break;
sl@0
   550
				default:
sl@0
   551
					inputDevice = InputDevice.Key;
sl@0
   552
					break;
sl@0
   553
			}
sl@0
   554
sl@0
   555
			return inputDevice;
sl@0
   556
		}
sl@0
   557
	}
sl@0
   558
}