#pragma once struct InputKeyboardRawInput { Input& input; InputKeyboardRawInput(Input& input) : input(input) {} struct Key { uint16_t code; uint16_t flag; string name; bool value; }; vector keys; struct Keyboard { shared_pointer hid{new HID::Keyboard}; } kb; auto update(RAWINPUT* input) -> void { uint code = input->data.keyboard.MakeCode; uint flag = input->data.keyboard.Flags; for(auto& key : keys) { if(key.code != code) continue; key.value = (key.flag == flag); } } auto assign(uint inputID, bool value) -> void { auto& group = kb.hid->buttons(); if(group.input(inputID).value() == value) return; input.doChange(kb.hid, HID::Keyboard::GroupID::Button, inputID, group.input(inputID).value(), value); group.input(inputID).setValue(value); } auto poll(vector>& devices) -> void { for(auto n : range(keys.size())) assign(n, keys[n].value); devices.append(kb.hid); } auto initialize() -> bool { rawinput.updateKeyboard = {&InputKeyboardRawInput::update, this}; //Pause sends 0x001d,4 + 0x0045,0; NumLock sends only 0x0045,0 //pressing Pause will falsely trigger NumLock //further, pause sends its key release even while button is held down //because of this, we cannot map either reliably keys.append({0x0001, 0, "Escape"}); keys.append({0x003b, 0, "F1"}); keys.append({0x003c, 0, "F2"}); keys.append({0x003d, 0, "F3"}); keys.append({0x003e, 0, "F4"}); keys.append({0x003f, 0, "F5"}); keys.append({0x0040, 0, "F6"}); keys.append({0x0041, 0, "F7"}); keys.append({0x0042, 0, "F8"}); keys.append({0x0043, 0, "F9"}); keys.append({0x0044, 0, "F10"}); keys.append({0x0057, 0, "F11"}); keys.append({0x0058, 0, "F12"}); keys.append({0x0037, 2, "PrintScreen"}); keys.append({0x0046, 0, "ScrollLock"}); //keys.append({0x001d, 4, "Pause"}); keys.append({0x0029, 0, "Tilde"}); keys.append({0x0002, 0, "Num1"}); keys.append({0x0003, 0, "Num2"}); keys.append({0x0004, 0, "Num3"}); keys.append({0x0005, 0, "Num4"}); keys.append({0x0006, 0, "Num5"}); keys.append({0x0007, 0, "Num6"}); keys.append({0x0008, 0, "Num7"}); keys.append({0x0009, 0, "Num8"}); keys.append({0x000a, 0, "Num9"}); keys.append({0x000b, 0, "Num0"}); keys.append({0x000c, 0, "Dash"}); keys.append({0x000d, 0, "Equal"}); keys.append({0x000e, 0, "Backspace"}); keys.append({0x0052, 2, "Insert"}); keys.append({0x0053, 2, "Delete"}); keys.append({0x0047, 2, "Home"}); keys.append({0x004f, 2, "End"}); keys.append({0x0049, 2, "PageUp"}); keys.append({0x0051, 2, "PageDown"}); keys.append({0x001e, 0, "A"}); keys.append({0x0030, 0, "B"}); keys.append({0x002e, 0, "C"}); keys.append({0x0020, 0, "D"}); keys.append({0x0012, 0, "E"}); keys.append({0x0021, 0, "F"}); keys.append({0x0022, 0, "G"}); keys.append({0x0023, 0, "H"}); keys.append({0x0017, 0, "I"}); keys.append({0x0024, 0, "J"}); keys.append({0x0025, 0, "K"}); keys.append({0x0026, 0, "L"}); keys.append({0x0032, 0, "M"}); keys.append({0x0031, 0, "N"}); keys.append({0x0018, 0, "O"}); keys.append({0x0019, 0, "P"}); keys.append({0x0010, 0, "Q"}); keys.append({0x0013, 0, "R"}); keys.append({0x001f, 0, "S"}); keys.append({0x0014, 0, "T"}); keys.append({0x0016, 0, "U"}); keys.append({0x002f, 0, "V"}); keys.append({0x0011, 0, "W"}); keys.append({0x002d, 0, "X"}); keys.append({0x0015, 0, "Y"}); keys.append({0x002c, 0, "Z"}); keys.append({0x001a, 0, "LeftBracket"}); keys.append({0x001b, 0, "RightBracket"}); keys.append({0x002b, 0, "Backslash"}); keys.append({0x0027, 0, "Semicolon"}); keys.append({0x0028, 0, "Apostrophe"}); keys.append({0x0033, 0, "Comma"}); keys.append({0x0034, 0, "Period"}); keys.append({0x0035, 0, "Slash"}); keys.append({0x004f, 0, "Keypad1"}); keys.append({0x0050, 0, "Keypad2"}); keys.append({0x0051, 0, "Keypad3"}); keys.append({0x004b, 0, "Keypad4"}); keys.append({0x004c, 0, "Keypad5"}); keys.append({0x004d, 0, "Keypad6"}); keys.append({0x0047, 0, "Keypad7"}); keys.append({0x0048, 0, "Keypad8"}); keys.append({0x0049, 0, "Keypad9"}); keys.append({0x0052, 0, "Keypad0"}); keys.append({0x0053, 0, "Point"}); keys.append({0x001c, 2, "Enter"}); keys.append({0x004e, 0, "Add"}); keys.append({0x004a, 0, "Subtract"}); keys.append({0x0037, 0, "Multiply"}); keys.append({0x0035, 2, "Divide"}); //keys.append({0x0045, 0, "NumLock"}); keys.append({0x003a, 0, "CapsLock"}); keys.append({0x0048, 2, "Up"}); keys.append({0x0050, 2, "Down"}); keys.append({0x004b, 2, "Left"}); keys.append({0x004d, 2, "Right"}); keys.append({0x000f, 0, "Tab"}); keys.append({0x001c, 0, "Return"}); keys.append({0x0039, 0, "Spacebar"}); keys.append({0x002a, 0, "LeftShift"}); keys.append({0x0036, 0, "RightShift"}); keys.append({0x001d, 0, "LeftControl"}); keys.append({0x001d, 2, "RightControl"}); keys.append({0x0038, 0, "LeftAlt"}); keys.append({0x0038, 2, "RightAlt"}); keys.append({0x005b, 2, "LeftSuper"}); keys.append({0x005c, 2, "RightSuper"}); keys.append({0x005d, 2, "Menu"}); kb.hid->setVendorID(HID::Keyboard::GenericVendorID); kb.hid->setProductID(HID::Keyboard::GenericProductID); kb.hid->setPathID(0); for(auto& key : keys) kb.hid->buttons().append(key.name); return true; } auto terminate() -> void { rawinput.updateKeyboard.reset(); } };