Get integer representing label printed on keyboard layout

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!