public void ProcessRawInput(IntPtr hdevice)
        {
            if (DeviceList.Count == 0)
            {
                return;
            }

            int dwSize = 0;

            Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, IntPtr.Zero, ref dwSize, Marshal.SizeOf(typeof(RawInputHeader)));

            if (dwSize != Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, out rawBuffer, ref dwSize, Marshal.SizeOf(typeof(RawInputHeader))))
            {
                Debug.WriteLine("Error getting the rawinput buffer");
                return;
            }

            int virtualKey = rawBuffer.Data.Keyboard.VKey;
            int makeCode   = rawBuffer.Data.Keyboard.Makecode;
            int flags      = rawBuffer.Data.Keyboard.Flags;

            if (virtualKey == Win32.KEYBOARD_OVERRUN_MAKE_CODE)
            {
                return;
            }

            bool isE0BitSet = (flags & Win32.RI_KEY_E0) != 0;

            KeyPressEvent keyPressEvent;

            if (DeviceList.ContainsKey(rawBuffer.Header.Device))
            {
                lock (lockObject)
                {
                    keyPressEvent = DeviceList[rawBuffer.Header.Device];
                }
            }
            else
            {
                Debug.WriteLine("Handle: {0} was not in the device list.", rawBuffer.Header.Device);
                return;
            }

            keyPressEvent.IsKeyDown = rawBuffer.Data.Keyboard.Message == Win32.WM_KEYDOWN;
            keyPressEvent.VKeyName  = KeyMapper.GetKeyName(VirtualKeyCorrection(virtualKey, isE0BitSet, makeCode)).ToUpper();
            keyPressEvent.VKey      = virtualKey;

            KeyPressed?.Invoke(this, new RawInputEventArgs(keyPressEvent));
        }
    void Update()
    {
        foreach (var downKeys in downKeysByDeviceId)
        {
            downKeys.Value.Clear();
        }
        foreach (var upKeys in upKeysByDeviceId)
        {
            upKeys.Value.Clear();
        }

        // Poll the events and properly update whatever we need
        IntPtr data      = poll();
        int    numEvents = Marshal.ReadInt32(data);

        for (int i = 0; i < numEvents; ++i)
        {
            var  ev     = new RawInputEvent();
            long offset = data.ToInt64() + sizeof(int) + i * Marshal.SizeOf(ev);
            ev.devHandle        = Marshal.ReadInt32(new IntPtr(offset + 0));
            ev.x                = Marshal.ReadInt32(new IntPtr(offset + 4));
            ev.y                = Marshal.ReadInt32(new IntPtr(offset + 8));
            ev.wheel            = Marshal.ReadInt32(new IntPtr(offset + 12));
            ev.press            = Marshal.ReadByte(new IntPtr(offset + 16));
            ev.release          = Marshal.ReadByte(new IntPtr(offset + 17));
            ev.type             = Marshal.ReadByte(new IntPtr(offset + 18));
            ev.padding0         = Marshal.ReadByte(new IntPtr(offset + 19));
            ev.keyboardFlags    = (ushort)Marshal.ReadInt16(new IntPtr(offset + 20));
            ev.keyboardVkey     = (ushort)Marshal.ReadInt16(new IntPtr(offset + 22));
            ev.keyboardMakeCode = (ushort)Marshal.ReadInt16(new IntPtr(offset + 24));

            if (ev.type == RE_DEVICE_CONNECT)
            {
                if (verbose)
                {
                    Debug.LogFormat("Device connected: handle {0}", ev.devHandle);
                }
                SendMessageUpwards("OnInputDeviceConnect", ev.devHandle, SendMessageOptions.DontRequireReceiver);
            }
            else if (ev.type == RE_DEVICE_DISCONNECT)
            {
                if (verbose)
                {
                    Debug.LogFormat("Device disconnected: handle {0}", ev.devHandle);
                }
                SendMessageUpwards("OnInputDeviceDisconnect", ev.devHandle, SendMessageOptions.DontRequireReceiver);
            }
            else if (ev.type == RE_KEYBOARD)
            {
                var isBreakBitSet = ((ev.keyboardFlags & Win32.RI_KEY_BREAK) != 0);
                var isE0BitSet    = ((ev.keyboardFlags & Win32.RI_KEY_E0) != 0);

                var keyName = KeyMapper.GetKeyName(Win32.VirtualKeyCorrection(ev.keyboardVkey, isE0BitSet, ev.keyboardMakeCode)).ToUpper();

                if (verbose)
                {
                    Debug.LogFormat("{0} H:{1} Key:{2} Break:{3} Flags:{4} Vkey:{5}",
                                    getEventName(ev.type),
                                    ev.devHandle,
                                    keyName,
                                    isBreakBitSet,
                                    ev.keyboardFlags,
                                    ev.keyboardVkey);
                }

                // Pressed keys
                if (!keysByDeviceId.ContainsKey(ev.devHandle))
                {
                    keysByDeviceId[ev.devHandle] = new Dictionary <string, bool>();
                }
                var oldPressed = GetKey(ev.devHandle, keyName);
                var newPressed = (isBreakBitSet == false);
                keysByDeviceId[ev.devHandle][keyName] = newPressed;

                // Down keys
                if (!downKeysByDeviceId.ContainsKey(ev.devHandle))
                {
                    downKeysByDeviceId[ev.devHandle] = new Dictionary <string, bool>();
                }
                if (oldPressed == false && newPressed == true)
                {
                    downKeysByDeviceId[ev.devHandle][keyName] = true;
                }

                // Up keys
                if (!upKeysByDeviceId.ContainsKey(ev.devHandle))
                {
                    upKeysByDeviceId[ev.devHandle] = new Dictionary <string, bool>();
                }
                if (oldPressed == true && newPressed == false)
                {
                    upKeysByDeviceId[ev.devHandle][keyName] = true;
                }
            }
        }
        Marshal.FreeCoTaskMem(data);

        if (verbose)
        {
            foreach (var pk in downKeysByDeviceId)
            {
                foreach (var k in pk.Value)
                {
                    if (k.Value)
                    {
                        Debug.LogFormat("Dev Handle: {0} Key Down: {1}", pk.Key, k.Key);
                    }
                }
            }

            foreach (var pk in upKeysByDeviceId)
            {
                foreach (var k in pk.Value)
                {
                    if (k.Value)
                    {
                        Debug.LogFormat("Dev Handle: {0} Key Up: {1}", pk.Key, k.Key);
                    }
                }
            }
        }
    }