diff options
Diffstat (limited to 'src/SFML/Window/OSX/HIDInputManager.mm')
-rw-r--r-- | src/SFML/Window/OSX/HIDInputManager.mm | 870 |
1 files changed, 870 insertions, 0 deletions
diff --git a/src/SFML/Window/OSX/HIDInputManager.mm b/src/SFML/Window/OSX/HIDInputManager.mm new file mode 100644 index 0000000..a332932 --- /dev/null +++ b/src/SFML/Window/OSX/HIDInputManager.mm @@ -0,0 +1,870 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2018 Marco Antognini (antognini.marco@gmail.com), +// Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Window/OSX/HIDInputManager.hpp> +#include <SFML/System/Err.hpp> +#include <AppKit/AppKit.h> + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +HIDInputManager& HIDInputManager::getInstance() +{ + static HIDInputManager instance; + return instance; +} + + +//////////////////////////////////////////////////////////// +bool HIDInputManager::isKeyPressed(Keyboard::Key key) +{ + return isPressed(m_keys[key]); +} + + +//////////////////////////////////////////////////////////// +long HIDInputManager::getLocationID(IOHIDDeviceRef device) +{ + long loc = 0; + + // Get a unique ID: its USB location ID + CFTypeRef typeRef = IOHIDDeviceGetProperty(device, + CFSTR(kIOHIDLocationIDKey)); + if (!typeRef || (CFGetTypeID(typeRef) != CFNumberGetTypeID())) + return 0; + + CFNumberRef locRef = (CFNumberRef)typeRef; + + if (!CFNumberGetValue(locRef, kCFNumberLongType, &loc)) + return 0; + + return loc; +} + + +//////////////////////////////////////////////////////////// +CFDictionaryRef HIDInputManager::copyDevicesMask(UInt32 page, UInt32 usage) +{ + // Create the dictionary. + CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + // Add the page value. + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); + CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), value); + CFRelease(value); + + // Add the usage value (which is only valid if page value exists). + value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); + CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), value); + CFRelease(value); + + return dict; +} + + +//////////////////////////////////////////////////////////// +HIDInputManager::HIDInputManager() : +m_isValid(true), +m_layoutData(0), +m_layout(0), +m_manager(0) +{ + // Get the current keyboard layout + TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource(); + m_layoutData = (CFDataRef)TISGetInputSourceProperty(tis, + kTISPropertyUnicodeKeyLayoutData); + + if (m_layoutData == 0) + { + sf::err() << "Cannot get the keyboard layout" << std::endl; + freeUp(); + return; + } + + // Keep a reference for ourself + CFRetain(m_layoutData); + m_layout = (UCKeyboardLayout *)CFDataGetBytePtr(m_layoutData); + + // The TIS is no more needed + CFRelease(tis); + + // Create an HID Manager reference + m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + + // Open the HID Manager reference + IOReturn openStatus = IOHIDManagerOpen(m_manager, kIOHIDOptionsTypeNone); + + if (openStatus != kIOReturnSuccess) + { + sf::err() << "Error when opening the HID manager" << std::endl; + freeUp(); + return; + } + + // Initialize the keyboard + initializeKeyboard(); +} + + +//////////////////////////////////////////////////////////// +HIDInputManager::~HIDInputManager() +{ + freeUp(); +} + + +void HIDInputManager::initializeKeyboard() +{ + //////////////////////////////////////////////////////////// + // The purpose of this function is to initialize m_keys so we can get + // the associate IOHIDElementRef with a sf::Keyboard::Key in ~constant~ time. + + // Get only keyboards + CFSetRef keyboards = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard); + if (keyboards == NULL) + { + sf::err() << "No keyboard detected by the HID manager!" << std::endl; + freeUp(); + return; + } + + CFIndex keyboardCount = CFSetGetCount(keyboards); // >= 1 (asserted by copyDevices) + + // Get an iterable array + CFTypeRef devicesArray[keyboardCount]; + CFSetGetValues(keyboards, devicesArray); + + for (CFIndex i = 0; i < keyboardCount; ++i) + { + IOHIDDeviceRef keyboard = (IOHIDDeviceRef)devicesArray[i]; + loadKeyboard(keyboard); + } + + // Release unused stuff + CFRelease(keyboards); + + //////////////////////////////////////////////////////////// + // At this point m_keys is filled with as many IOHIDElementRef as possible +} + + +//////////////////////////////////////////////////////////// +void HIDInputManager::loadKeyboard(IOHIDDeviceRef keyboard) +{ + CFArrayRef keys = IOHIDDeviceCopyMatchingElements(keyboard, + NULL, + kIOHIDOptionsTypeNone); + if (keys == NULL) + { + sf::err() << "We got a keyboard without any keys (1)" << std::endl; + return; + } + + // How many elements are there? + CFIndex keysCount = CFArrayGetCount(keys); + + if (keysCount == 0) + { + sf::err() << "We got a keyboard without any keys (2)" << std::endl; + CFRelease(keys); + return; + } + + // Go through all connected elements. + for (CFIndex i = 0; i < keysCount; ++i) + { + IOHIDElementRef aKey = (IOHIDElementRef) CFArrayGetValueAtIndex(keys, i); + + // Skip non-matching keys elements + if (IOHIDElementGetUsagePage(aKey) != kHIDPage_KeyboardOrKeypad) + continue; + + loadKey(aKey); + } + + // Release unused stuff + CFRelease(keys); +} + + +//////////////////////////////////////////////////////////// +void HIDInputManager::loadKey(IOHIDElementRef key) +{ + // Get its virtual code + UInt32 usageCode = IOHIDElementGetUsage(key); + UInt8 virtualCode = usageToVirtualCode(usageCode); + + if (virtualCode == 0xff) + return; // no corresponding virtual code -> skip + + // Now translate the virtual code to Unicode according to + // the current keyboard layout + + UInt32 deadKeyState = 0; + // Unicode string length is usually less or equal to 4 + UniCharCount maxStringLength = 4; + UniCharCount actualStringLength = 0; + UniChar unicodeString[maxStringLength]; + + OSStatus error; + + error = UCKeyTranslate(m_layout, // current layout + virtualCode, // our key + kUCKeyActionDown, // or kUCKeyActionUp ? + 0x100, // no modifiers + LMGetKbdType(), // keyboard's type + kUCKeyTranslateNoDeadKeysBit,// some sort of option + &deadKeyState, // unused stuff + maxStringLength, // our memory limit + &actualStringLength, // length of what we get + unicodeString); // what we get + + if (error == noErr) + { + // Translation went fine + + // The corresponding SFML key code + Keyboard::Key code = Keyboard::Unknown; // KeyCound means 'none' + + // First we look if the key down is from a list of characters + // that depend on keyboard localization + if (actualStringLength > 0) + code = localizedKeys(unicodeString[0]); + + // The key is not a localized one so we try to find a + // corresponding code through virtual key code + if (code == Keyboard::Unknown) + code = nonLocalizedKeys(virtualCode); + + // A code was found, wonderful! + if (code != Keyboard::Unknown) + { + // Ok, everything went fine. Now we have a unique + // corresponding sf::Keyboard::Key to one IOHIDElementRef + m_keys[code].push_back(key); + + // And don't forget to keep the reference alive for our usage + CFRetain(m_keys[code].back()); + } + + //////////////////////////////////////////////////////////// + // These are known to be unbound: + // Supposed Virtual | HID | Supposed Key + // =============================================== + // 0x1b | 0x2d | Hyphen + // 0x39 | 0x39 | CapsLock + // 0x47 | 0x53 | NumLock + // 0x6e | 0x65 | Application + // 0x4c | 0x77 | Select + + //if (code == Keyboard::Unknown) { // The key is unknown. + // sf::err() << "This is an unknown key. Virtual key code is 0x" + // << std::hex + // << (UInt32)virtualCode + // << " and HID usage code is 0x" + // << usageCode + // << std::dec + // << "." + // << std::endl; + //} + + } /* if (error == noErr) */ + else + { + sf::err() << "Cannot translate the virtual key code, error: " + << error + << std::endl; + } +} + + +//////////////////////////////////////////////////////////// +void HIDInputManager::freeUp() +{ + m_isValid = false; + + if (m_layoutData != 0) + CFRelease(m_layoutData); + m_layoutData = 0; + // Do not release m_layout! It is owned by m_layoutData. + if (m_manager != 0) + CFRelease(m_manager); + m_manager = 0; + + for (unsigned int i = 0; i < Keyboard::KeyCount; ++i) + { + for (IOHIDElements::iterator it = m_keys[i].begin(); it != m_keys[i].end(); ++it) + CFRelease(*it); + + m_keys[i].clear(); + } +} + + +//////////////////////////////////////////////////////////// +CFSetRef HIDInputManager::copyDevices(UInt32 page, UInt32 usage) +{ + // Filter and keep only the requested devices + CFDictionaryRef mask = copyDevicesMask(page, usage); + + IOHIDManagerSetDeviceMatching(m_manager, mask); + + CFRelease(mask); + mask = 0; + + CFSetRef devices = IOHIDManagerCopyDevices(m_manager); + if (devices == NULL) + return NULL; + + // Is there at least one device? + CFIndex deviceCount = CFSetGetCount(devices); + if (deviceCount < 1) + { + CFRelease(devices); + return NULL; + } + + return devices; +} + +bool HIDInputManager::isPressed(IOHIDElements& elements) +{ + if (!m_isValid) + return false; + + // state = true if at least one corresponding HID button is pressed + bool state = false; + + for (IOHIDElements::iterator it = elements.begin(); it != elements.end(); /* noop */) + { + IOHIDValueRef value = 0; + + IOHIDDeviceRef device = IOHIDElementGetDevice(*it); + IOHIDDeviceGetValue(device, *it, &value); + + if (!value) + { + // This means some kind of error / disconnection so we remove this + // element from our buttons + CFRelease(*it); + it = elements.erase(it); + } + else if (IOHIDValueGetIntegerValue(value) == 1) + { + // This means the button is pressed + state = true; + break; // Stop here + } + else + { + // This means the button is released + ++it; + } + } + + return state; +} + + +//////////////////////////////////////////////////////////// +UInt8 HIDInputManager::usageToVirtualCode(UInt32 usage) +{ + // Some usage key doesn't have any corresponding virtual + // code or it was not found (return 0xff). + switch (usage) + { + case kHIDUsage_KeyboardErrorRollOver: return 0xff; + case kHIDUsage_KeyboardPOSTFail: return 0xff; + case kHIDUsage_KeyboardErrorUndefined: return 0xff; + + case kHIDUsage_KeyboardA: return 0x00; + case kHIDUsage_KeyboardB: return 0x0b; + case kHIDUsage_KeyboardC: return 0x08; + case kHIDUsage_KeyboardD: return 0x02; + case kHIDUsage_KeyboardE: return 0x0e; + case kHIDUsage_KeyboardF: return 0x03; + case kHIDUsage_KeyboardG: return 0x05; + case kHIDUsage_KeyboardH: return 0x04; + case kHIDUsage_KeyboardI: return 0x22; + case kHIDUsage_KeyboardJ: return 0x26; + case kHIDUsage_KeyboardK: return 0x28; + case kHIDUsage_KeyboardL: return 0x25; + case kHIDUsage_KeyboardM: return 0x2e; + case kHIDUsage_KeyboardN: return 0x2d; + case kHIDUsage_KeyboardO: return 0x1f; + case kHIDUsage_KeyboardP: return 0x23; + case kHIDUsage_KeyboardQ: return 0x0c; + case kHIDUsage_KeyboardR: return 0x0f; + case kHIDUsage_KeyboardS: return 0x01; + case kHIDUsage_KeyboardT: return 0x11; + case kHIDUsage_KeyboardU: return 0x20; + case kHIDUsage_KeyboardV: return 0x09; + case kHIDUsage_KeyboardW: return 0x0d; + case kHIDUsage_KeyboardX: return 0x07; + case kHIDUsage_KeyboardY: return 0x10; + case kHIDUsage_KeyboardZ: return 0x06; + + case kHIDUsage_Keyboard1: return 0x12; + case kHIDUsage_Keyboard2: return 0x13; + case kHIDUsage_Keyboard3: return 0x14; + case kHIDUsage_Keyboard4: return 0x15; + case kHIDUsage_Keyboard5: return 0x17; + case kHIDUsage_Keyboard6: return 0x16; + case kHIDUsage_Keyboard7: return 0x1a; + case kHIDUsage_Keyboard8: return 0x1c; + case kHIDUsage_Keyboard9: return 0x19; + case kHIDUsage_Keyboard0: return 0x1d; + + case kHIDUsage_KeyboardReturnOrEnter: return 0x24; + case kHIDUsage_KeyboardEscape: return 0x35; + case kHIDUsage_KeyboardDeleteOrBackspace: return 0x33; + case kHIDUsage_KeyboardTab: return 0x30; + case kHIDUsage_KeyboardSpacebar: return 0x31; + case kHIDUsage_KeyboardHyphen: return 0x1b; + case kHIDUsage_KeyboardEqualSign: return 0x18; + case kHIDUsage_KeyboardOpenBracket: return 0x21; + case kHIDUsage_KeyboardCloseBracket: return 0x1e; + case kHIDUsage_KeyboardBackslash: return 0x2a; + case kHIDUsage_KeyboardNonUSPound: return 0xff; + case kHIDUsage_KeyboardSemicolon: return 0x29; + case kHIDUsage_KeyboardQuote: return 0x27; + case kHIDUsage_KeyboardGraveAccentAndTilde: return 0x32; + case kHIDUsage_KeyboardComma: return 0x2b; + case kHIDUsage_KeyboardPeriod: return 0x2F; + case kHIDUsage_KeyboardSlash: return 0x2c; + case kHIDUsage_KeyboardCapsLock: return 0x39; + + case kHIDUsage_KeyboardF1: return 0x7a; + case kHIDUsage_KeyboardF2: return 0x78; + case kHIDUsage_KeyboardF3: return 0x63; + case kHIDUsage_KeyboardF4: return 0x76; + case kHIDUsage_KeyboardF5: return 0x60; + case kHIDUsage_KeyboardF6: return 0x61; + case kHIDUsage_KeyboardF7: return 0x62; + case kHIDUsage_KeyboardF8: return 0x64; + case kHIDUsage_KeyboardF9: return 0x65; + case kHIDUsage_KeyboardF10: return 0x6d; + case kHIDUsage_KeyboardF11: return 0x67; + case kHIDUsage_KeyboardF12: return 0x6f; + + case kHIDUsage_KeyboardPrintScreen: return 0xff; + case kHIDUsage_KeyboardScrollLock: return 0xff; + case kHIDUsage_KeyboardPause: return 0xff; + case kHIDUsage_KeyboardInsert: return 0x72; + case kHIDUsage_KeyboardHome: return 0x73; + case kHIDUsage_KeyboardPageUp: return 0x74; + case kHIDUsage_KeyboardDeleteForward: return 0x75; + case kHIDUsage_KeyboardEnd: return 0x77; + case kHIDUsage_KeyboardPageDown: return 0x79; + + case kHIDUsage_KeyboardRightArrow: return 0x7c; + case kHIDUsage_KeyboardLeftArrow: return 0x7b; + case kHIDUsage_KeyboardDownArrow: return 0x7d; + case kHIDUsage_KeyboardUpArrow: return 0x7e; + + case kHIDUsage_KeypadNumLock: return 0x47; + case kHIDUsage_KeypadSlash: return 0x4b; + case kHIDUsage_KeypadAsterisk: return 0x43; + case kHIDUsage_KeypadHyphen: return 0x4e; + case kHIDUsage_KeypadPlus: return 0x45; + case kHIDUsage_KeypadEnter: return 0x4c; + + case kHIDUsage_Keypad1: return 0x53; + case kHIDUsage_Keypad2: return 0x54; + case kHIDUsage_Keypad3: return 0x55; + case kHIDUsage_Keypad4: return 0x56; + case kHIDUsage_Keypad5: return 0x57; + case kHIDUsage_Keypad6: return 0x58; + case kHIDUsage_Keypad7: return 0x59; + case kHIDUsage_Keypad8: return 0x5b; + case kHIDUsage_Keypad9: return 0x5c; + case kHIDUsage_Keypad0: return 0x52; + + case kHIDUsage_KeypadPeriod: return 0x41; + case kHIDUsage_KeyboardNonUSBackslash: return 0xff; + case kHIDUsage_KeyboardApplication: return 0x6e; + case kHIDUsage_KeyboardPower: return 0xff; + case kHIDUsage_KeypadEqualSign: return 0x51; + + case kHIDUsage_KeyboardF13: return 0x69; + case kHIDUsage_KeyboardF14: return 0x6b; + case kHIDUsage_KeyboardF15: return 0x71; + case kHIDUsage_KeyboardF16: return 0xff; + case kHIDUsage_KeyboardF17: return 0xff; + case kHIDUsage_KeyboardF18: return 0xff; + case kHIDUsage_KeyboardF19: return 0xff; + case kHIDUsage_KeyboardF20: return 0xff; + case kHIDUsage_KeyboardF21: return 0xff; + case kHIDUsage_KeyboardF22: return 0xff; + case kHIDUsage_KeyboardF23: return 0xff; + case kHIDUsage_KeyboardF24: return 0xff; + + case kHIDUsage_KeyboardExecute: return 0xff; + case kHIDUsage_KeyboardHelp: return 0xff; + case kHIDUsage_KeyboardMenu: return 0x7F; + case kHIDUsage_KeyboardSelect: return 0x4c; + case kHIDUsage_KeyboardStop: return 0xff; + case kHIDUsage_KeyboardAgain: return 0xff; + case kHIDUsage_KeyboardUndo: return 0xff; + case kHIDUsage_KeyboardCut: return 0xff; + case kHIDUsage_KeyboardCopy: return 0xff; + case kHIDUsage_KeyboardPaste: return 0xff; + case kHIDUsage_KeyboardFind: return 0xff; + + case kHIDUsage_KeyboardMute: return 0xff; + case kHIDUsage_KeyboardVolumeUp: return 0xff; + case kHIDUsage_KeyboardVolumeDown: return 0xff; + + case kHIDUsage_KeyboardLockingCapsLock: return 0xff; + case kHIDUsage_KeyboardLockingNumLock: return 0xff; + case kHIDUsage_KeyboardLockingScrollLock: return 0xff; + + case kHIDUsage_KeypadComma: return 0xff; + case kHIDUsage_KeypadEqualSignAS400: return 0xff; + case kHIDUsage_KeyboardInternational1: return 0xff; + case kHIDUsage_KeyboardInternational2: return 0xff; + case kHIDUsage_KeyboardInternational3: return 0xff; + case kHIDUsage_KeyboardInternational4: return 0xff; + case kHIDUsage_KeyboardInternational5: return 0xff; + case kHIDUsage_KeyboardInternational6: return 0xff; + case kHIDUsage_KeyboardInternational7: return 0xff; + case kHIDUsage_KeyboardInternational8: return 0xff; + case kHIDUsage_KeyboardInternational9: return 0xff; + + case kHIDUsage_KeyboardLANG1: return 0xff; + case kHIDUsage_KeyboardLANG2: return 0xff; + case kHIDUsage_KeyboardLANG3: return 0xff; + case kHIDUsage_KeyboardLANG4: return 0xff; + case kHIDUsage_KeyboardLANG5: return 0xff; + case kHIDUsage_KeyboardLANG6: return 0xff; + case kHIDUsage_KeyboardLANG7: return 0xff; + case kHIDUsage_KeyboardLANG8: return 0xff; + case kHIDUsage_KeyboardLANG9: return 0xff; + + case kHIDUsage_KeyboardAlternateErase: return 0xff; + case kHIDUsage_KeyboardSysReqOrAttention: return 0xff; + case kHIDUsage_KeyboardCancel: return 0xff; + case kHIDUsage_KeyboardClear: return 0xff; + case kHIDUsage_KeyboardPrior: return 0xff; + case kHIDUsage_KeyboardReturn: return 0xff; + case kHIDUsage_KeyboardSeparator: return 0xff; + case kHIDUsage_KeyboardOut: return 0xff; + case kHIDUsage_KeyboardOper: return 0xff; + case kHIDUsage_KeyboardClearOrAgain: return 0xff; + case kHIDUsage_KeyboardCrSelOrProps: return 0xff; + case kHIDUsage_KeyboardExSel: return 0xff; + + /* 0xa5-0xdf Reserved */ + + case kHIDUsage_KeyboardLeftControl: return 0x3b; + case kHIDUsage_KeyboardLeftShift: return 0x38; + case kHIDUsage_KeyboardLeftAlt: return 0x3a; + case kHIDUsage_KeyboardLeftGUI: return 0x37; + case kHIDUsage_KeyboardRightControl: return 0x3e; + case kHIDUsage_KeyboardRightShift: return 0x3c; + case kHIDUsage_KeyboardRightAlt: return 0x3d; + case kHIDUsage_KeyboardRightGUI: return 0x36; + + /* 0xe8-0xffff Reserved */ + + case kHIDUsage_Keyboard_Reserved: return 0xff; + default: return 0xff; + } +} + + +//////////////////////////////////////////////////////// +Keyboard::Key HIDInputManager::localizedKeys(UniChar ch) +{ + switch (ch) + { + case 'a': + case 'A': return sf::Keyboard::A; + + case 'b': + case 'B': return sf::Keyboard::B; + + case 'c': + case 'C': return sf::Keyboard::C; + + case 'd': + case 'D': return sf::Keyboard::D; + + case 'e': + case 'E': return sf::Keyboard::E; + + case 'f': + case 'F': return sf::Keyboard::F; + + case 'g': + case 'G': return sf::Keyboard::G; + + case 'h': + case 'H': return sf::Keyboard::H; + + case 'i': + case 'I': return sf::Keyboard::I; + + case 'j': + case 'J': return sf::Keyboard::J; + + case 'k': + case 'K': return sf::Keyboard::K; + + case 'l': + case 'L': return sf::Keyboard::L; + + case 'm': + case 'M': return sf::Keyboard::M; + + case 'n': + case 'N': return sf::Keyboard::N; + + case 'o': + case 'O': return sf::Keyboard::O; + + case 'p': + case 'P': return sf::Keyboard::P; + + case 'q': + case 'Q': return sf::Keyboard::Q; + + case 'r': + case 'R': return sf::Keyboard::R; + + case 's': + case 'S': return sf::Keyboard::S; + + case 't': + case 'T': return sf::Keyboard::T; + + case 'u': + case 'U': return sf::Keyboard::U; + + case 'v': + case 'V': return sf::Keyboard::V; + + case 'w': + case 'W': return sf::Keyboard::W; + + case 'x': + case 'X': return sf::Keyboard::X; + + case 'y': + case 'Y': return sf::Keyboard::Y; + + case 'z': + case 'Z': return sf::Keyboard::Z; + + // The key is not 'localized'. + default: return sf::Keyboard::Unknown; + } +} + + +//////////////////////////////////////////////////////// +Keyboard::Key HIDInputManager::nonLocalizedKeys(UniChar virtualKeycode) +{ + // (Some) 0x code based on https://forums.macrumors.com/showthread.php?t=780577 + // Some sf::Keyboard::Key are present twice. + switch (virtualKeycode) + { + // These cases should not be used but anyway... + case 0x00: return sf::Keyboard::A; + case 0x0b: return sf::Keyboard::B; + case 0x08: return sf::Keyboard::C; + case 0x02: return sf::Keyboard::D; + case 0x0e: return sf::Keyboard::E; + case 0x03: return sf::Keyboard::F; + case 0x05: return sf::Keyboard::G; + case 0x04: return sf::Keyboard::H; + case 0x22: return sf::Keyboard::I; + case 0x26: return sf::Keyboard::J; + case 0x28: return sf::Keyboard::K; + case 0x25: return sf::Keyboard::L; + case 0x2e: return sf::Keyboard::M; + case 0x2d: return sf::Keyboard::N; + case 0x1f: return sf::Keyboard::O; + case 0x23: return sf::Keyboard::P; + case 0x0c: return sf::Keyboard::Q; + case 0x0f: return sf::Keyboard::R; + case 0x01: return sf::Keyboard::S; + case 0x11: return sf::Keyboard::T; + case 0x20: return sf::Keyboard::U; + case 0x09: return sf::Keyboard::V; + case 0x0d: return sf::Keyboard::W; + case 0x07: return sf::Keyboard::X; + case 0x10: return sf::Keyboard::Y; + case 0x06: return sf::Keyboard::Z; + + // These cases should not be used but anyway... + case 0x1d: return sf::Keyboard::Num0; + case 0x12: return sf::Keyboard::Num1; + case 0x13: return sf::Keyboard::Num2; + case 0x14: return sf::Keyboard::Num3; + case 0x15: return sf::Keyboard::Num4; + case 0x17: return sf::Keyboard::Num5; + case 0x16: return sf::Keyboard::Num6; + case 0x1a: return sf::Keyboard::Num7; + case 0x1c: return sf::Keyboard::Num8; + case 0x19: return sf::Keyboard::Num9; + + case 0x35: return sf::Keyboard::Escape; + + // Modifier keys : never happen with keyDown/keyUp methods (?) + case 0x3b: return sf::Keyboard::LControl; + case 0x38: return sf::Keyboard::LShift; + case 0x3a: return sf::Keyboard::LAlt; + case 0x37: return sf::Keyboard::LSystem; + case 0x3e: return sf::Keyboard::RControl; + case 0x3c: return sf::Keyboard::RShift; + case 0x3d: return sf::Keyboard::RAlt; + case 0x36: return sf::Keyboard::RSystem; + + case 0x7f: return sf::Keyboard::Menu; + case NSMenuFunctionKey: return sf::Keyboard::Menu; + + case 0x21: return sf::Keyboard::LBracket; + case 0x1e: return sf::Keyboard::RBracket; + case 0x29: return sf::Keyboard::Semicolon; + case 0x2b: return sf::Keyboard::Comma; + case 0x41: /* keypad */ return sf::Keyboard::Period; + case 0x2f: /* keyboard */ return sf::Keyboard::Period; + case 0x27: return sf::Keyboard::Quote; + case 0x2c: return sf::Keyboard::Slash; + case 0x2a: return sf::Keyboard::Backslash; + + // sf::Keyboard::Tilde might be in conflict with some other key. + // 0x0a is for "Non-US Backslash" according to HID Calibrator, + // a sample provided by Apple. + case 0x0a: return sf::Keyboard::Tilde; + + case 0x51: /* keypad */ return sf::Keyboard::Equal; + case 0x18: /* keyboard */ return sf::Keyboard::Equal; + case 0x32: return sf::Keyboard::Hyphen; + case 0x31: return sf::Keyboard::Space; + case 0x4c: /* keypad */ return sf::Keyboard::Enter; + case 0x24: /* keyboard */ return sf::Keyboard::Enter; + case 0x33: return sf::Keyboard::Backspace; + case 0x30: return sf::Keyboard::Tab; + + // Duplicates (see next section). + case 0x74: return sf::Keyboard::PageUp; + case 0x79: return sf::Keyboard::PageDown; + case 0x77: return sf::Keyboard::End; + case 0x73: return sf::Keyboard::Home; + + case NSPageUpFunctionKey: return sf::Keyboard::PageUp; + case NSPageDownFunctionKey: return sf::Keyboard::PageDown; + case NSEndFunctionKey: return sf::Keyboard::End; + case NSHomeFunctionKey: return sf::Keyboard::Home; + + case 0x72: return sf::Keyboard::Insert; + case NSInsertFunctionKey: return sf::Keyboard::Insert; + case 0x75: return sf::Keyboard::Delete; + case NSDeleteFunctionKey: return sf::Keyboard::Delete; + + case 0x45: return sf::Keyboard::Add; + case 0x4e: return sf::Keyboard::Subtract; + case 0x43: return sf::Keyboard::Multiply; + case 0x4b: return sf::Keyboard::Divide; + + // Duplicates (see next section). + case 0x7b: return sf::Keyboard::Left; + case 0x7c: return sf::Keyboard::Right; + case 0x7e: return sf::Keyboard::Up; + case 0x7d: return sf::Keyboard::Down; + + case NSLeftArrowFunctionKey: return sf::Keyboard::Left; + case NSRightArrowFunctionKey: return sf::Keyboard::Right; + case NSUpArrowFunctionKey: return sf::Keyboard::Up; + case NSDownArrowFunctionKey: return sf::Keyboard::Down; + + case 0x52: return sf::Keyboard::Numpad0; + case 0x53: return sf::Keyboard::Numpad1; + case 0x54: return sf::Keyboard::Numpad2; + case 0x55: return sf::Keyboard::Numpad3; + case 0x56: return sf::Keyboard::Numpad4; + case 0x57: return sf::Keyboard::Numpad5; + case 0x58: return sf::Keyboard::Numpad6; + case 0x59: return sf::Keyboard::Numpad7; + case 0x5b: return sf::Keyboard::Numpad8; + case 0x5c: return sf::Keyboard::Numpad9; + + // Duplicates (see next section). + case 0x7a: return sf::Keyboard::F1; + case 0x78: return sf::Keyboard::F2; + case 0x63: return sf::Keyboard::F3; + case 0x76: return sf::Keyboard::F4; + case 0x60: return sf::Keyboard::F5; + case 0x61: return sf::Keyboard::F6; + case 0x62: return sf::Keyboard::F7; + case 0x64: return sf::Keyboard::F8; + case 0x65: return sf::Keyboard::F9; + case 0x6d: return sf::Keyboard::F10; + case 0x67: return sf::Keyboard::F11; + case 0x6f: return sf::Keyboard::F12; + case 0x69: return sf::Keyboard::F13; + case 0x6b: return sf::Keyboard::F14; + case 0x71: return sf::Keyboard::F15; + + case NSF1FunctionKey: return sf::Keyboard::F1; + case NSF2FunctionKey: return sf::Keyboard::F2; + case NSF3FunctionKey: return sf::Keyboard::F3; + case NSF4FunctionKey: return sf::Keyboard::F4; + case NSF5FunctionKey: return sf::Keyboard::F5; + case NSF6FunctionKey: return sf::Keyboard::F6; + case NSF7FunctionKey: return sf::Keyboard::F7; + case NSF8FunctionKey: return sf::Keyboard::F8; + case NSF9FunctionKey: return sf::Keyboard::F9; + case NSF10FunctionKey: return sf::Keyboard::F10; + case NSF11FunctionKey: return sf::Keyboard::F11; + case NSF12FunctionKey: return sf::Keyboard::F12; + case NSF13FunctionKey: return sf::Keyboard::F13; + case NSF14FunctionKey: return sf::Keyboard::F14; + case NSF15FunctionKey: return sf::Keyboard::F15; + + case NSPauseFunctionKey: return sf::Keyboard::Pause; + + // keycode 0x1b is not bound to any key. + // This key is ' on CH-FR, ) on FR and - on US layouts. + + // An unknown key. + default: return sf::Keyboard::Unknown; + } +} + + +} // namespace priv + +} // namespace sf + |