Esempio n. 1
0
        /// <summary>
        /// Function to retrieve the device name.
        /// </summary>
        /// <param name="device">Raw input device to gather information from.</param>
        /// <returns>A device name structure.</returns>
        private T GetDeviceInfo <T>(ref RAWINPUTDEVICELIST device)
            where T : class, IGorgonRawInputDeviceInfo
        {
            RID_DEVICE_INFO deviceInfo = RawInputApi.GetDeviceInfo(ref device);

            string deviceName = RawInputApi.GetDeviceName(ref device);

            if (string.IsNullOrWhiteSpace(deviceName))
            {
                return(null);
            }

            string className         = RawInputDeviceRegistryInfo.GetDeviceClass(deviceName, _log);
            string deviceDescription = RawInputDeviceRegistryInfo.GetDeviceDescription(deviceName, _log);

            switch (deviceInfo.dwType)
            {
            case RawInputType.Keyboard:
                return(new RawKeyboardInfo(device.Device, deviceName, className, deviceDescription, deviceInfo.keyboard) as T);

            case RawInputType.Mouse:
                return(new RawMouseInfo(device.Device, deviceName, className, deviceDescription, deviceInfo.mouse) as T);

            case RawInputType.HID:
                return(new GorgonRawHIDInfo(device.Device, deviceName, className, deviceDescription, deviceInfo.hid) as T);

            default:
                return(null);
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Function to unhook raw input from the application.
 /// </summary>
 private void UnhookRawInput()
 {
     foreach (HIDUsage type in _devices.Values.Select(item => item.DeviceUsage).Distinct())
     {
         RawInputApi.UnregisterRawInputDevice(type);
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Function to unregister the device from the raw input provider.
        /// </summary>
        /// <param name="device">The device to unregister from the raw input provider.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="device"/> parameter is <b>null</b>.</exception>
        /// <remarks>
        /// This will unregister a previously registered <see cref="IGorgonRawInputDevice"/>. When the last device of a specific type (e.g. a mouse, keyboard, etc...) is unregistered, then the
        /// Raw Input messages for that device type will also be unregistered and the application will no longer receive messages from that type of device.
        /// </remarks>
        public void UnregisterDevice(IGorgonRawInputDevice device)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            lock (_syncLock)
            {
                var key = new DeviceKey
                {
                    DeviceType   = device.DeviceType,
                    DeviceHandle = device.Handle
                };

                switch (device.DeviceType)
                {
                case RawInputType.Keyboard:
                    _keyboardDevices.Remove(key);
                    break;

                case RawInputType.Mouse:
                    _mouseDevices.Remove(key);
                    break;

                case RawInputType.HID:
                    _hids.Remove(key);
                    break;

                default:
                    throw new ArgumentException(string.Format(Resources.GORINP_RAW_ERR_UNKNOWN_DEVICE_TYPE, device.DeviceType), nameof(device));
                }

                if (!_devices.ContainsKey(key))
                {
                    return;
                }

                _devices.Remove(key);

                // If all devices of this type have been unregistered, unregister with raw input as well.
                if ((_devices.Count(item => item.Value.DeviceType == device.DeviceType) == 0) &&
                    (RawInputApi.GetDeviceRegistration(device.DeviceUsage) != null))
                {
                    RawInputApi.UnregisterRawInputDevice(device.DeviceUsage);
                }

                // If we have no more registered devices, then uninstall the filter.
                if (_devices.Count != 0)
                {
                    return;
                }

                _filter?.Dispose();
                _filter = null;
            }
        }
Esempio n. 4
0
        public void Test_RawInput_AllDevices()
        {
            bool foundOneDevice = false;

            foreach (var rawInputDeviceInfo in RawInputApi.GetAllDevices().OrderBy(information => information.DeviceInfo.Type).ThenBy(information => information.DisplayName))
            {
                Log.Info().WriteLine("RawInput Device {0} with name {1}", rawInputDeviceInfo.DeviceInfo.Type, rawInputDeviceInfo.DisplayName);
                switch (rawInputDeviceInfo.DeviceInfo.Type)
                {
                case RawInputDeviceTypes.Keyboard:
                    var keyboardInfo = rawInputDeviceInfo.DeviceInfo.Keyboard;
                    Log.Info().WriteLine("Keyboard is of type {0} and subtype {1} and in mode {2}.", keyboardInfo.Type, keyboardInfo.SubType, keyboardInfo.KeyboardMode);
                    Log.Info().WriteLine("Keyboard with {0} key, of which {1} function keys and it has {2} LEDs.", keyboardInfo.NumberOfKeysTotal, keyboardInfo.NumberOfFunctionKeys, keyboardInfo.NumberOfIndicators);
                    break;
                }

                foundOneDevice = true;
            }
            Assert.True(foundOneDevice);
        }
Esempio n. 5
0
        /// <summary>
        /// Function to retrieve a list of human interface devices (HID).
        /// </summary>
        /// <returns>A read only list containing information about each human interface device.</returns>
        public IReadOnlyList <GorgonRawHIDInfo> EnumerateHumanInterfaceDevices()
        {
            RAWINPUTDEVICELIST[] devices = RawInputApi.EnumerateRawInputDevices(RawInputType.HID);
            var result = new List <GorgonRawHIDInfo>();

            for (int i = 0; i < devices.Length; i++)
            {
                GorgonRawHIDInfo info = GetDeviceInfo <GorgonRawHIDInfo>(ref devices[i]);

                if (info == null)
                {
                    _log.Print("WARNING: Could not retrieve the class and device name.  Skipping this device.", LoggingLevel.Verbose);
                    continue;
                }

                _log.Print("Found human interface device: '{0}' on HID path {1}, class {2}.", LoggingLevel.Verbose, info.Description, info.HIDPath, info.DeviceClass);

                result.Add(info);
            }

            return(result);
        }
Esempio n. 6
0
        /// <summary>
        /// Function to register the device with the raw input provider.
        /// </summary>
        /// <param name="device">The device to register with the raw input provider.</param>
        /// <param name="settings">[Optional] Settings for the device type.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="device"/> parameter is <b>null</b>.</exception>
        /// <remarks>
        /// <para>
        /// This will register the <see cref="IGorgonRawInputDevice"/> with the application. For the very first device of a specific type (e.g. a mouse, keyboard, etc...) the Raw Input object will set up
        /// the device type registration for the device. This enables an application to start receiving Raw Input messages from a device type.
        /// </para>
        /// <para>
        /// The optional <paramref name="settings"/> parameter allows an application change how raw input handles the device being registered. It can be used to set up background input monitoring, or a
        /// target window for raw input messages (which must be set if the background option is turned on). By default, there is no background message processing and no target window (messages go to
        /// whichever window has focus).
        /// </para>
        /// <para>
        /// Every call to this method should be paired with a call to <see cref="UnregisterDevice"/> when the device(s) are no longer needed.
        /// </para>
        /// </remarks>
        public void RegisterDevice(IGorgonRawInputDevice device, GorgonRawInputSettings?settings = null)
        {
            IntPtr targetHandle = IntPtr.Zero;

            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            if (settings == null)
            {
                settings = new GorgonRawInputSettings();
            }

            lock (_syncLock)
            {
                // If we've not set up the filter yet, then add it to the window now.
                if (_filter == null)
                {
                    _filter = new RawInputMessageFilter(_keyboardDevices, _mouseDevices, _hids, _applicationWindow, _useNativeHook);
                }

                var key = new DeviceKey
                {
                    DeviceType   = device.DeviceType,
                    DeviceHandle = device.Handle
                };

                if (_devices.ContainsKey(key))
                {
                    return;
                }

                switch (device.DeviceType)
                {
                case RawInputType.Keyboard:
                    _keyboardDevices.Add(key, (IRawInputDeviceData <GorgonRawKeyboardData>)device);
                    break;

                case RawInputType.Mouse:
                    _mouseDevices.Add(key, (IRawInputDeviceData <GorgonRawMouseData>)device);
                    break;

                case RawInputType.HID:
                    _hids.Add(key, (IRawInputDeviceData <GorgonRawHIDData>)device);
                    break;

                default:
                    throw new ArgumentException(string.Format(Resources.GORINP_RAW_ERR_UNKNOWN_DEVICE_TYPE, device.DeviceType), nameof(device));
                }

                _devices.Add(key, device);

                // Get the current device registration properties.
                RAWINPUTDEVICE?deviceReg = RawInputApi.GetDeviceRegistration(device.DeviceUsage);
                if (deviceReg != null)
                {
                    // Remove the device before updating it.
                    UnregisterDevice(device);
                }

                // If we omit the target window, and specify background messages, we'll use the application window instead.
                // This is because Raw Input requires that background devices have a window target.
                if ((settings.Value.TargetWindow.IsNull) && (settings.Value.AllowBackground))
                {
                    unsafe
                    {
                        settings = new GorgonRawInputSettings
                        {
                            TargetWindow    = new GorgonReadOnlyPointer((void *)_applicationWindow, IntPtr.Size),
                            AllowBackground = true
                        };
                    }
                }

                RawInputDeviceFlags flags = RawInputDeviceFlags.None;

                if (settings.Value.AllowBackground)
                {
                    flags |= RawInputDeviceFlags.InputSink;
                }

                RawInputApi.RegisterRawInputDevice(device.DeviceUsage, targetHandle, flags);
            }
        }