RemoteControlDevice.cs
author sl
Tue, 04 Nov 2014 20:58:19 +0100
changeset 3 db8e6a25d6bc
parent 2 505a13a09336
child 4 eed66dfd9848
permissions -rw-r--r--
Proper support for all MCE buttons.
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@0
     5
sl@0
     6
sl@0
     7
namespace BruceThomas.Devices.RemoteControl
sl@0
     8
{
sl@0
     9
	public enum InputDevice
sl@0
    10
	{
sl@0
    11
		Key,
sl@0
    12
		Mouse,
sl@0
    13
		OEM
sl@0
    14
	}
sl@0
    15
sl@0
    16
sl@0
    17
	public enum RemoteControlButton
sl@0
    18
	{
sl@0
    19
		Clear,
sl@0
    20
		Down,
sl@0
    21
		Left,
sl@0
    22
		Digit0,
sl@0
    23
		Digit1,
sl@0
    24
		Digit2,
sl@0
    25
		Digit3,
sl@0
    26
		Digit4,
sl@0
    27
		Digit5,
sl@0
    28
		Digit6,
sl@0
    29
		Digit7,
sl@0
    30
		Digit8,
sl@0
    31
		Digit9,
sl@0
    32
		Enter,
sl@0
    33
		Right,
sl@0
    34
		Up,
sl@0
    35
sl@0
    36
		Back,
sl@0
    37
		ChannelDown,
sl@0
    38
		ChannelUp,
sl@0
    39
		FastForward,
sl@0
    40
		VolumeMute,
sl@0
    41
		Pause,
sl@0
    42
		Play,
sl@0
    43
        PlayPause,
sl@0
    44
		Record,
sl@0
    45
		PreviousTrack,
sl@0
    46
		Rewind,
sl@0
    47
		NextTrack,
sl@0
    48
		Stop,
sl@0
    49
		VolumeDown,
sl@0
    50
		VolumeUp,
sl@0
    51
sl@0
    52
		RecordedTV,
sl@0
    53
		Guide,
sl@0
    54
		LiveTV,
sl@0
    55
		Details,
sl@0
    56
		DVDMenu,
sl@0
    57
		DVDAngle,
sl@0
    58
		DVDAudio,
sl@0
    59
		DVDSubtitle,
sl@0
    60
		MyMusic,
sl@0
    61
		MyPictures,
sl@0
    62
		MyVideos,
sl@0
    63
		MyTV,
sl@0
    64
		OEM1,
sl@0
    65
		OEM2,
sl@0
    66
		StandBy,
sl@0
    67
		TVJump,
sl@0
    68
sl@0
    69
		Unknown
sl@0
    70
	}
sl@0
    71
sl@3
    72
    /// <summary>
sl@3
    73
    /// 
sl@3
    74
    /// </summary>
sl@3
    75
    public enum MceButton
sl@3
    76
    {
sl@3
    77
        Null                    =   0x00, //Not defined by the specs
sl@3
    78
        GreenStart              =   0x0D,
sl@3
    79
        ClosedCaptioning        =   0x2B,
sl@3
    80
        Teletext                =   0x5A,
sl@3
    81
        TeletextRed             =   0x5B,
sl@3
    82
        TeletextGreen           =   0x5C,
sl@3
    83
        TeletextYellow          =   0x5D,
sl@3
    84
        TeletextBlue            =   0x5E,
sl@3
    85
        LiveTv                  =   0x25,
sl@3
    86
        Music                   =   0x47,
sl@3
    87
        RecordedTv              =   0x48,
sl@3
    88
        Pictures                =   0x49,
sl@3
    89
        Videos                  =   0x4A,
sl@3
    90
        FmRadio                 =   0x50,
sl@3
    91
        Extras                  =   0x3C,
sl@3
    92
        ExtrasApp               =   0x3D,
sl@3
    93
        DvdMenu                 =   0x24,
sl@3
    94
        DvdAngle                =   0x4B,
sl@3
    95
        DvdAudio                =   0x4C,
sl@3
    96
        DvdSubtitle             =   0x4D,
sl@3
    97
        Eject                   =   0x28,
sl@3
    98
        DvdTopMenu              =   0x43,
sl@3
    99
        Ext0                    =   0x32,
sl@3
   100
        Ext1                    =   0x33,
sl@3
   101
        Ext2                    =   0x34,
sl@3
   102
        Ext3                    =   0x35,
sl@3
   103
        Ext4                    =   0x36,
sl@3
   104
        Ext5                    =   0x37,
sl@3
   105
        Ext6                    =   0x38,
sl@3
   106
        Ext7                    =   0x39,
sl@3
   107
        Ext8                    =   0x3A,
sl@3
   108
        Ext9                    =   0x80,
sl@3
   109
        Ext10                   =   0x81,
sl@3
   110
        Ext11                   =   0x6F,
sl@3
   111
        Zoom                    =   0x27,
sl@3
   112
        ChannelInput            =   0x42,
sl@3
   113
        SubAudio                =   0x2D,
sl@3
   114
        Channel10               =   0x3E,
sl@3
   115
        Channel11               =   0x3F,
sl@3
   116
        Channel12               =   0x40,
sl@3
   117
        Display                 =   0x4F,
sl@3
   118
        Kiosk                   =   0x6A,
sl@3
   119
        NetworkSelection        =   0x2C,
sl@3
   120
        BlueRayTool             =   0x78,
sl@3
   121
        ChannelInfo             =   0x41,
sl@3
   122
        VideoSelection          =   0x61                
sl@3
   123
    }
sl@3
   124
sl@0
   125
sl@0
   126
	#region RemoteControlEventArgs
sl@0
   127
sl@0
   128
	public class RemoteControlEventArgs : EventArgs
sl@0
   129
	{
sl@3
   130
        RemoteControlButton _rcb;
sl@0
   131
		InputDevice _device;
sl@3
   132
        MceButton iMceButton;
sl@0
   133
sl@3
   134
        public RemoteControlEventArgs(RemoteControlButton rcb, InputDevice device)
sl@0
   135
		{
sl@3
   136
            iMceButton = MceButton.Null;
sl@0
   137
			_rcb = rcb;
sl@0
   138
			_device = device;
sl@0
   139
		}
sl@0
   140
sl@3
   141
        public RemoteControlEventArgs(MceButton mce, InputDevice device)
sl@3
   142
        {
sl@3
   143
            iMceButton = mce;
sl@3
   144
            _rcb = RemoteControlButton.Unknown;
sl@3
   145
            _device = device;
sl@3
   146
        }
sl@0
   147
sl@0
   148
		public RemoteControlEventArgs()
sl@0
   149
		{
sl@3
   150
            iMceButton = MceButton.Null;
sl@0
   151
			_rcb = RemoteControlButton.Unknown;
sl@0
   152
			_device = InputDevice.Key;
sl@0
   153
		}
sl@0
   154
sl@0
   155
		public RemoteControlButton Button
sl@0
   156
		{
sl@0
   157
			get { return _rcb;  }
sl@0
   158
			set { _rcb = value; }
sl@0
   159
		}
sl@0
   160
sl@3
   161
        public MceButton MceButton
sl@3
   162
        {
sl@3
   163
            get { return iMceButton; }
sl@3
   164
            set { iMceButton = value; }
sl@3
   165
        }
sl@3
   166
sl@0
   167
		public InputDevice Device
sl@0
   168
		{
sl@0
   169
			get { return _device;  }
sl@0
   170
			set { _device = value; }
sl@0
   171
		}
sl@0
   172
	}
sl@0
   173
sl@0
   174
	#endregion RemoteControlEventArgs
sl@0
   175
sl@0
   176
sl@0
   177
	public sealed class RemoteControlDevice
sl@0
   178
	{
sl@0
   179
sl@0
   180
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@0
   181
		internal struct RAWINPUTDEVICE
sl@0
   182
		{
sl@0
   183
			[MarshalAs(UnmanagedType.U2)]
sl@0
   184
			public ushort usUsagePage;
sl@0
   185
			[MarshalAs(UnmanagedType.U2)]
sl@0
   186
			public ushort usUsage;
sl@0
   187
			[MarshalAs(UnmanagedType.U4)]
sl@0
   188
			public int	 dwFlags;
sl@0
   189
			public IntPtr hwndTarget;
sl@0
   190
		}
sl@0
   191
sl@0
   192
sl@0
   193
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@0
   194
		internal struct RAWINPUTHEADER
sl@0
   195
		{
sl@0
   196
			[MarshalAs(UnmanagedType.U4)]
sl@0
   197
			public int dwType;
sl@0
   198
			[MarshalAs(UnmanagedType.U4)]
sl@0
   199
			public int dwSize;
sl@0
   200
            public IntPtr hDevice;
sl@0
   201
			[MarshalAs(UnmanagedType.U4)]
sl@0
   202
			public int wParam;
sl@0
   203
		}
sl@0
   204
sl@0
   205
sl@0
   206
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@0
   207
		internal struct RAWHID
sl@0
   208
		{
sl@0
   209
			[MarshalAs(UnmanagedType.U4)]
sl@0
   210
			public int dwSizeHid;
sl@0
   211
			[MarshalAs(UnmanagedType.U4)]
sl@0
   212
			public int dwCount;
sl@0
   213
            //
sl@0
   214
            //BYTE  bRawData[1];
sl@0
   215
		}
sl@0
   216
sl@0
   217
sl@0
   218
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@0
   219
		internal struct BUTTONSSTR
sl@0
   220
		{
sl@0
   221
			[MarshalAs(UnmanagedType.U2)]
sl@0
   222
			public ushort usButtonFlags;
sl@0
   223
			[MarshalAs(UnmanagedType.U2)]
sl@0
   224
			public ushort usButtonData;
sl@0
   225
		}
sl@0
   226
sl@0
   227
sl@0
   228
        [StructLayout(LayoutKind.Explicit, Pack = 1)]
sl@0
   229
		internal struct RAWMOUSE
sl@0
   230
		{
sl@0
   231
			[MarshalAs(UnmanagedType.U2)]
sl@0
   232
			[FieldOffset (0)] public ushort usFlags;
sl@0
   233
			[MarshalAs(UnmanagedType.U4)]
sl@0
   234
			[FieldOffset (4)] public uint ulButtons;
sl@0
   235
			[FieldOffset (4)] public BUTTONSSTR buttonsStr;
sl@0
   236
			[MarshalAs(UnmanagedType.U4)]
sl@0
   237
			[FieldOffset (8)] public uint ulRawButtons;
sl@0
   238
            [MarshalAs(UnmanagedType.U4)]
sl@0
   239
            [FieldOffset (12)] public int lLastX;
sl@0
   240
            [MarshalAs(UnmanagedType.U4)]
sl@0
   241
            [FieldOffset (16)] public int lLastY;
sl@0
   242
			[MarshalAs(UnmanagedType.U4)]
sl@0
   243
			[FieldOffset (20)] public uint ulExtraInformation;
sl@0
   244
		}
sl@0
   245
sl@0
   246
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@0
   247
		internal struct RAWKEYBOARD
sl@0
   248
		{
sl@0
   249
			[MarshalAs(UnmanagedType.U2)]
sl@0
   250
			public ushort MakeCode;
sl@0
   251
			[MarshalAs(UnmanagedType.U2)]
sl@0
   252
			public ushort Flags;
sl@0
   253
			[MarshalAs(UnmanagedType.U2)]
sl@0
   254
			public ushort Reserved;
sl@0
   255
			[MarshalAs(UnmanagedType.U2)]
sl@0
   256
			public ushort VKey;
sl@0
   257
			[MarshalAs(UnmanagedType.U4)]
sl@0
   258
			public uint Message;
sl@0
   259
			[MarshalAs(UnmanagedType.U4)]
sl@0
   260
			public uint ExtraInformation;
sl@0
   261
		}
sl@0
   262
sl@0
   263
sl@0
   264
		[StructLayout(LayoutKind.Explicit, Pack=1)]
sl@0
   265
		internal struct RAWINPUT
sl@0
   266
		{
sl@0
   267
			[FieldOffset  (0)] public RAWINPUTHEADER header;
sl@0
   268
			[FieldOffset (16)] public RAWMOUSE mouse;
sl@0
   269
			[FieldOffset (16)] public RAWKEYBOARD keyboard;
sl@0
   270
			[FieldOffset (16)] public RAWHID hid;
sl@0
   271
		}
sl@0
   272
sl@0
   273
sl@0
   274
		[DllImport("User32.dll")]
sl@0
   275
		extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
sl@0
   276
sl@0
   277
		[DllImport("User32.dll")]
sl@0
   278
		extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
sl@0
   279
sl@0
   280
sl@0
   281
		private const int WM_KEYDOWN	= 0x0100;
sl@0
   282
		private const int WM_APPCOMMAND	= 0x0319;
sl@0
   283
		private const int WM_INPUT		= 0x00FF;
sl@0
   284
sl@0
   285
		private const int APPCOMMAND_BROWSER_BACKWARD   = 1;
sl@0
   286
		private const int APPCOMMAND_VOLUME_MUTE        = 8;
sl@0
   287
		private const int APPCOMMAND_VOLUME_DOWN        = 9;
sl@0
   288
		private const int APPCOMMAND_VOLUME_UP          = 10;
sl@0
   289
		private const int APPCOMMAND_MEDIA_NEXTTRACK    = 11;
sl@0
   290
		private const int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
sl@0
   291
		private const int APPCOMMAND_MEDIA_STOP         = 13;
sl@0
   292
		private const int APPCOMMAND_MEDIA_PLAY_PAUSE   = 14;
sl@0
   293
		private const int APPCOMMAND_MEDIA_PLAY         = 46;
sl@0
   294
		private const int APPCOMMAND_MEDIA_PAUSE        = 47;
sl@0
   295
		private const int APPCOMMAND_MEDIA_RECORD       = 48;
sl@0
   296
		private const int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
sl@0
   297
		private const int APPCOMMAND_MEDIA_REWIND       = 50;
sl@0
   298
		private const int APPCOMMAND_MEDIA_CHANNEL_UP   = 51;
sl@0
   299
		private const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
sl@0
   300
sl@0
   301
		private const int RIM_TYPEMOUSE					= 0;
sl@0
   302
		private const int RIM_TYPEKEYBOARD				= 1;
sl@0
   303
		private const int RIM_TYPEHID					= 2;
sl@0
   304
sl@0
   305
		private const int RID_INPUT						= 0x10000003;
sl@0
   306
		private const int RID_HEADER					= 0x10000005;
sl@0
   307
sl@0
   308
		private const int FAPPCOMMAND_MASK				= 0xF000;
sl@0
   309
		private const int FAPPCOMMAND_MOUSE				= 0x8000;
sl@0
   310
		private const int FAPPCOMMAND_KEY				= 0;
sl@0
   311
		private const int FAPPCOMMAND_OEM				= 0x1000;
sl@0
   312
sl@0
   313
		public delegate void RemoteControlDeviceEventHandler(object sender, RemoteControlEventArgs e);
sl@0
   314
		public event RemoteControlDeviceEventHandler ButtonPressed;
sl@0
   315
sl@0
   316
sl@0
   317
		//-------------------------------------------------------------
sl@0
   318
		// constructors
sl@0
   319
		//-------------------------------------------------------------
sl@0
   320
sl@0
   321
		public RemoteControlDevice()
sl@0
   322
		{
sl@0
   323
			// Register the input device to receive the commands from the
sl@0
   324
			// remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
sl@0
   325
			// for the vendor defined usage page.
sl@0
   326
sl@0
   327
			RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[3];
sl@0
   328
sl@0
   329
			rid[0].usUsagePage = 0xFFBC;
sl@0
   330
			rid[0].usUsage = 0x88;
sl@0
   331
			rid[0].dwFlags = 0;
sl@0
   332
sl@0
   333
			rid[1].usUsagePage = 0x0C;
sl@0
   334
			rid[1].usUsage = 0x01;
sl@0
   335
			rid[1].dwFlags = 0;
sl@0
   336
sl@0
   337
			rid[2].usUsagePage = 0x0C;
sl@0
   338
			rid[2].usUsage = 0x80;
sl@0
   339
			rid[2].dwFlags = 0;
sl@0
   340
sl@0
   341
			if (!RegisterRawInputDevices(rid,
sl@0
   342
				(uint) rid.Length,
sl@0
   343
				(uint) Marshal.SizeOf(rid[0]))
sl@0
   344
				)
sl@0
   345
			{
sl@0
   346
				throw new ApplicationException("Failed to register raw input devices.");
sl@0
   347
			}
sl@0
   348
		}
sl@0
   349
sl@0
   350
sl@0
   351
		//-------------------------------------------------------------
sl@0
   352
		// methods
sl@0
   353
		//-------------------------------------------------------------
sl@0
   354
sl@0
   355
		public void ProcessMessage(Message message)
sl@0
   356
		{
sl@0
   357
			int param;
sl@0
   358
sl@0
   359
			switch (message.Msg)
sl@0
   360
			{
sl@0
   361
				case WM_KEYDOWN:
sl@0
   362
					param = message.WParam.ToInt32();
sl@0
   363
					ProcessKeyDown(param);
sl@0
   364
					break;
sl@0
   365
				case WM_APPCOMMAND:
sl@0
   366
					param = message.LParam.ToInt32();
sl@0
   367
					ProcessAppCommand(param);
sl@0
   368
					break;
sl@0
   369
				case WM_INPUT:
sl@0
   370
					ProcessInputCommand(ref message);
sl@0
   371
                    message.Result = new IntPtr(0);
sl@0
   372
					break;
sl@0
   373
			}
sl@0
   374
sl@0
   375
		}
sl@0
   376
sl@0
   377
sl@0
   378
		//-------------------------------------------------------------
sl@0
   379
		// methods (helpers)
sl@0
   380
		//-------------------------------------------------------------
sl@0
   381
sl@0
   382
		private void ProcessKeyDown(int param)
sl@0
   383
		{
sl@0
   384
			RemoteControlButton rcb = RemoteControlButton.Unknown;
sl@0
   385
sl@0
   386
			switch (param)
sl@0
   387
			{
sl@0
   388
				case (int) Keys.Escape:
sl@0
   389
					rcb = RemoteControlButton.Clear;
sl@0
   390
					break;
sl@0
   391
				case (int) Keys.Down:
sl@0
   392
					rcb = RemoteControlButton.Down;
sl@0
   393
					break;
sl@0
   394
				case (int) Keys.Left:
sl@0
   395
					rcb = RemoteControlButton.Left;
sl@0
   396
					break;
sl@0
   397
				case (int) Keys.D0:
sl@0
   398
					rcb = RemoteControlButton.Digit0;
sl@0
   399
					break;
sl@0
   400
				case (int) Keys.D1:
sl@0
   401
					rcb = RemoteControlButton.Digit1;
sl@0
   402
					break;
sl@0
   403
				case (int) Keys.D2:
sl@0
   404
					rcb = RemoteControlButton.Digit2;
sl@0
   405
					break;
sl@0
   406
				case (int) Keys.D3:
sl@0
   407
					rcb = RemoteControlButton.Digit3;
sl@0
   408
					break;
sl@0
   409
				case (int) Keys.D4:
sl@0
   410
					rcb = RemoteControlButton.Digit4;
sl@0
   411
					break;
sl@0
   412
				case (int) Keys.D5:
sl@0
   413
					rcb = RemoteControlButton.Digit5;
sl@0
   414
					break;
sl@0
   415
				case (int) Keys.D6:
sl@0
   416
					rcb = RemoteControlButton.Digit6;
sl@0
   417
					break;
sl@0
   418
				case (int) Keys.D7:
sl@0
   419
					rcb = RemoteControlButton.Digit7;
sl@0
   420
					break;
sl@0
   421
				case (int) Keys.D8:
sl@0
   422
					rcb = RemoteControlButton.Digit8;
sl@0
   423
					break;
sl@0
   424
				case (int) Keys.D9:
sl@0
   425
					rcb = RemoteControlButton.Digit9;
sl@0
   426
					break;
sl@0
   427
				case (int) Keys.Enter:
sl@0
   428
					rcb = RemoteControlButton.Enter;
sl@0
   429
					break;
sl@0
   430
				case (int) Keys.Right:
sl@0
   431
					rcb = RemoteControlButton.Right;
sl@0
   432
					break;
sl@0
   433
				case (int) Keys.Up:
sl@0
   434
					rcb = RemoteControlButton.Up;
sl@0
   435
					break;
sl@0
   436
			}
sl@0
   437
sl@0
   438
			if (this.ButtonPressed != null && rcb != RemoteControlButton.Unknown)
sl@0
   439
				this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(param)));
sl@0
   440
		}
sl@0
   441
sl@0
   442
sl@0
   443
		private void ProcessAppCommand(int param)
sl@0
   444
		{
sl@0
   445
			RemoteControlButton rcb = RemoteControlButton.Unknown;
sl@0
   446
sl@0
   447
			int cmd	= (int) (((ushort) (param >> 16)) & ~FAPPCOMMAND_MASK);
sl@0
   448
sl@0
   449
			switch (cmd)
sl@0
   450
			{
sl@0
   451
				case APPCOMMAND_BROWSER_BACKWARD:
sl@0
   452
					rcb = RemoteControlButton.Back;
sl@0
   453
					break;
sl@0
   454
				case APPCOMMAND_MEDIA_CHANNEL_DOWN:
sl@0
   455
					rcb = RemoteControlButton.ChannelDown;
sl@0
   456
					break;
sl@0
   457
				case APPCOMMAND_MEDIA_CHANNEL_UP:
sl@0
   458
					rcb = RemoteControlButton.ChannelUp;
sl@0
   459
					break;
sl@0
   460
				case APPCOMMAND_MEDIA_FAST_FORWARD:
sl@0
   461
					rcb = RemoteControlButton.FastForward;
sl@0
   462
					break;
sl@0
   463
				case APPCOMMAND_VOLUME_MUTE:
sl@0
   464
					rcb = RemoteControlButton.VolumeMute;
sl@0
   465
					break;
sl@0
   466
				case APPCOMMAND_MEDIA_PAUSE:
sl@0
   467
					rcb = RemoteControlButton.Pause;
sl@0
   468
					break;
sl@0
   469
				case APPCOMMAND_MEDIA_PLAY:
sl@0
   470
					rcb = RemoteControlButton.Play;
sl@0
   471
					break;
sl@0
   472
                case APPCOMMAND_MEDIA_PLAY_PAUSE:
sl@0
   473
                    rcb = RemoteControlButton.PlayPause;
sl@0
   474
                    break;
sl@0
   475
				case APPCOMMAND_MEDIA_RECORD:
sl@0
   476
					rcb = RemoteControlButton.Record;
sl@0
   477
					break;
sl@0
   478
				case APPCOMMAND_MEDIA_PREVIOUSTRACK:
sl@0
   479
					rcb = RemoteControlButton.PreviousTrack;
sl@0
   480
					break;
sl@0
   481
				case APPCOMMAND_MEDIA_REWIND:
sl@0
   482
					rcb = RemoteControlButton.Rewind;
sl@0
   483
					break;
sl@0
   484
				case APPCOMMAND_MEDIA_NEXTTRACK:
sl@0
   485
					rcb = RemoteControlButton.NextTrack;
sl@0
   486
					break;
sl@0
   487
				case APPCOMMAND_MEDIA_STOP:
sl@0
   488
					rcb = RemoteControlButton.Stop;
sl@0
   489
					break;
sl@0
   490
				case APPCOMMAND_VOLUME_DOWN:
sl@0
   491
					rcb = RemoteControlButton.VolumeDown;
sl@0
   492
					break;
sl@0
   493
				case APPCOMMAND_VOLUME_UP:
sl@0
   494
					rcb = RemoteControlButton.VolumeUp;
sl@0
   495
					break;
sl@0
   496
			}
sl@0
   497
sl@0
   498
			if (this.ButtonPressed != null && rcb != RemoteControlButton.Unknown)
sl@0
   499
				this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(param)));
sl@0
   500
		}
sl@0
   501
sl@0
   502
sl@0
   503
		private void ProcessInputCommand(ref Message message)
sl@0
   504
		{
sl@0
   505
			RemoteControlButton rcb = RemoteControlButton.Unknown;
sl@0
   506
			uint dwSize = 0;
sl@0
   507
sl@0
   508
            uint sizeOfHeader=(uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
sl@0
   509
sl@0
   510
            //Get the size of our raw input data.
sl@0
   511
			GetRawInputData(message.LParam,	RID_INPUT, IntPtr.Zero,	ref dwSize,	sizeOfHeader);
sl@0
   512
sl@0
   513
            //Allocate a large enough buffer
sl@0
   514
			IntPtr buffer = Marshal.AllocHGlobal((int) dwSize);
sl@0
   515
			try
sl@0
   516
			{
sl@0
   517
				if(buffer == IntPtr.Zero)
sl@0
   518
					return;
sl@0
   519
sl@0
   520
                //Now read our RAWINPUT data
sl@0
   521
				if (GetRawInputData(message.LParam,	RID_INPUT, buffer, ref dwSize, (uint) Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
sl@0
   522
				{
sl@0
   523
					return;
sl@0
   524
				}
sl@0
   525
sl@0
   526
                //Cast our buffer
sl@0
   527
                RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT));
sl@0
   528
sl@0
   529
                //Check that our raw input is HID
sl@0
   530
                if (raw.header.dwType == RIM_TYPEHID && raw.hid.dwSizeHid>0)
sl@0
   531
				{
sl@0
   532
                    //Allocate a buffer for one HID message
sl@0
   533
					byte[] bRawData = new byte[raw.hid.dwSizeHid];
sl@0
   534
sl@0
   535
                    //Compute the address from which to copy our HID message
sl@0
   536
                    int pRawData = 0;
sl@0
   537
                    unsafe
sl@0
   538
                    {
sl@0
   539
                        byte* source = (byte*)buffer;
sl@0
   540
                        source += sizeof(RAWINPUTHEADER) + sizeof(RAWHID);
sl@0
   541
                        //source += 1;
sl@0
   542
                        pRawData = (int)source;
sl@0
   543
                    }
sl@0
   544
                    //int pRawData = buffer.ToUint32() + Marshal.SizeOf(typeof(RAWINPUT)) + 1;
sl@0
   545
sl@0
   546
					//Marshal.Copy(new IntPtr(pRawData), bRawData, 0, raw.hid.dwSizeHid - 1);
sl@0
   547
                    Marshal.Copy(new IntPtr(pRawData), bRawData, 0, raw.hid.dwSizeHid);
sl@0
   548
					//int rawData = bRawData[0] | bRawData[1] << 8;
sl@0
   549
                    int rawData = bRawData[1]; //Get button code
sl@2
   550
                    Debug.WriteLine("HID " + raw.hid.dwCount + "/" + raw.hid.dwSizeHid + ":" + bRawData[0].ToString("X2") + bRawData[1].ToString("X2"));
sl@0
   551
sl@3
   552
                    if (Enum.IsDefined(typeof(MceButton), rawData) && rawData!=0) //Our button is a known MCE button
sl@3
   553
                    {
sl@3
   554
                        if (this.ButtonPressed != null) //What's that?
sl@3
   555
                        {
sl@3
   556
                            this.ButtonPressed(this, new RemoteControlEventArgs((MceButton)rawData, GetDevice(message.LParam.ToInt32())));
sl@3
   557
                        }
sl@3
   558
                    }
sl@0
   559
				}
sl@0
   560
				else if(raw.header.dwType == RIM_TYPEMOUSE)
sl@0
   561
				{
sl@0
   562
					// do mouse handling...
sl@0
   563
				}
sl@0
   564
				else if(raw.header.dwType == RIM_TYPEKEYBOARD)
sl@0
   565
				{
sl@0
   566
					// do keyboard handling...
sl@0
   567
				}
sl@0
   568
			}
sl@0
   569
			finally
sl@0
   570
			{
sl@0
   571
				Marshal.FreeHGlobal(buffer);
sl@0
   572
			}
sl@0
   573
		}
sl@0
   574
sl@0
   575
sl@0
   576
		private InputDevice GetDevice(int param)
sl@0
   577
		{
sl@0
   578
			InputDevice inputDevice;
sl@0
   579
sl@0
   580
			switch ((int) (((ushort) (param >> 16)) & FAPPCOMMAND_MASK))
sl@0
   581
			{
sl@0
   582
				case FAPPCOMMAND_OEM:
sl@0
   583
					inputDevice = InputDevice.OEM;
sl@0
   584
					break;
sl@0
   585
				case FAPPCOMMAND_MOUSE:
sl@0
   586
					inputDevice = InputDevice.Mouse;
sl@0
   587
					break;
sl@0
   588
				default:
sl@0
   589
					inputDevice = InputDevice.Key;
sl@0
   590
					break;
sl@0
   591
			}
sl@0
   592
sl@0
   593
			return inputDevice;
sl@0
   594
		}
sl@0
   595
	}
sl@0
   596
}