///////////////////////////////////////////////////////
| 455 | |
| 456 | //////////////////////////////////////////////////////////// |
| 457 | void ensureMapping() |
| 458 | { |
| 459 | static bool isMappingInitialized = false; |
| 460 | |
| 461 | if (isMappingInitialized) |
| 462 | return; |
| 463 | |
| 464 | // Phase 1: Initialize mappings with default values |
| 465 | scancodeToKeycode.fill(nullKeyCode); |
| 466 | keycodeToScancode.fill(sf::Keyboard::Scan::Unknown); |
| 467 | |
| 468 | // Phase 2: Get XKB names with key code |
| 469 | const auto display = sf::priv::openDisplay(); |
| 470 | |
| 471 | std::array<char, XkbKeyNameLength + 1> name{}; |
| 472 | XkbDescPtr descriptor = XkbGetMap(display.get(), 0, XkbUseCoreKbd); |
| 473 | XkbGetNames(display.get(), XkbKeyNamesMask, descriptor); |
| 474 | |
| 475 | std::unordered_map<std::string, sf::Keyboard::Scancode> nameScancodeMap = getNameScancodeMap(); |
| 476 | |
| 477 | for (int keycode = descriptor->min_key_code; keycode <= descriptor->max_key_code; ++keycode) |
| 478 | { |
| 479 | if (!isValidKeycode(static_cast<KeyCode>(keycode))) |
| 480 | { |
| 481 | continue; |
| 482 | } |
| 483 | |
| 484 | std::memcpy(name.data(), descriptor->names->keys[keycode].name, XkbKeyNameLength); |
| 485 | name[XkbKeyNameLength] = '\0'; |
| 486 | |
| 487 | const auto mappedScancode = nameScancodeMap.find(std::string(name.data())); |
| 488 | auto scancode = sf::Keyboard::Scan::Unknown; |
| 489 | |
| 490 | if (mappedScancode != nameScancodeMap.end()) |
| 491 | scancode = mappedScancode->second; |
| 492 | |
| 493 | if (scancode != sf::Keyboard::Scan::Unknown) |
| 494 | scancodeToKeycode[scancode] = static_cast<KeyCode>(keycode); |
| 495 | |
| 496 | keycodeToScancode[static_cast<KeyCode>(keycode)] = scancode; |
| 497 | } |
| 498 | |
| 499 | XkbFreeNames(descriptor, XkbKeyNamesMask, True); |
| 500 | XkbFreeKeyboard(descriptor, 0, True); |
| 501 | |
| 502 | // Phase 3: Translate un-translated keycodes using traditional X11 KeySym lookups |
| 503 | for (int keycode = 8; keycode < maxKeyCode; ++keycode) |
| 504 | { |
| 505 | if (keycodeToScancode[static_cast<KeyCode>(keycode)] == sf::Keyboard::Scan::Unknown) |
| 506 | { |
| 507 | const auto scancode = translateKeyCode(display.get(), static_cast<KeyCode>(keycode)); |
| 508 | |
| 509 | if (scancode != sf::Keyboard::Scan::Unknown && scancodeToKeycode[scancode] == nullKeyCode) |
| 510 | scancodeToKeycode[scancode] = static_cast<KeyCode>(keycode); |
| 511 | |
| 512 | keycodeToScancode[static_cast<KeyCode>(keycode)] = scancode; |
| 513 | } |
| 514 | } |
no test coverage detected