Is there a function that maps either a key or scancode integer to a GLFW_KEY_*
integer that represents the label printed on the keyboard layout? In other words, if I press the letter “q” on QWERTY, AZERTY, or Dvorak, is there a function f
so that f(e.scancode) == GLFW_KEY_Q
?
It looks like glfwGetKeyName(GLFW_KEY_UNKNOWN, scancode)
works for all of the above keyboard layouts, but it returns a const char*
so I have to do a string comparison on “q”. Also it doesn’t work with nonprintable keys such as Enter, Tab, F1-12, etc.
There is no function to translate a key or scancode to an integer, glfwGetKeyName
is the solution here: For the keys you’re interested in a simple test should suffice:
const char* keyName = glfwGetKeyName(key, 0);
if( 'q' == keyName[0] && 0 == keyName[1] )
{
// have key q
}
It’s possible that you can dispense with the 0 == keyName[1] since the current implementation appears to be single characters encoded as UTF8, so longer encodings the first byte won’t match ascii a-z - however my original implementation had strings for “SPACE” etc. and I can’t guarantee that the key names will remain single characters.
1 Like
Okay, I guess that’s fine. I wrap GLFW’s events into my own classes, so I’ll add keyName
to the key class if that’s the best that can be done. No allocations are made because it’s a pointer to GLFW-lifetime storage, so the whole process is as “clean” as an integer compare anyway.
One last question: What do the scancode
integers represent anyway? For example, if I press “q” on my keyboard, key
will be 81 which is GLFW_KEY_Q
. But scancode
is 24, which doesn’t seem to correspond to anything I can use. Are the scancode values unspecified and platform dependent? Or does the number 24 mean “Q” in some reliable way?
From the Keyboard input documentation:
The scancode is unique for every key, regardless of whether it has a key token. Scancodes are platform-specific but consistent over time, so keys will have different scancodes depending on the platform but they are safe to save to disk.
Could I theoretically hard-code three maps std::map<int, int> scancodeToKeyWindows, scancodeToKeyMac, scancodeToKeyLinux
and they would be well-defined on all versions of those OS’s? Do the maps depend on the keyboard layout at all, i.e. if I unplug my QWERTY keyboard and plug in an AZERTY keyboard, or if I change to Dvorak with software, will scancodeToKeyWindows[scancode]
always return the key label, for both printable and nonprintable keys?
The scancodes match physical keys and may be different on different keyboards on the same OS, so I wouldn’t do this.
Okay, I’ll stick with your first approach then!