Let me expand a bit on what I've discovered so far in my journey through SDL hell. As they say in the classics, "let me tell ye my tale of woe".
Whenever a key is pressed in Oolite, it triggers a "keydown" event, followed by a "keyup" event. For the keydown event, certain properties are available:
1. A keyboard scancode, which is a unique number corresponding to a key in a specific and constant location on the keyboard. This code is the same no matter what keyboard layout you are using (with caveats).
2. A unicode value that translates into the key character from whatever keyboard layout you are using.
3. A SDLKey property, which is an SDL code for the key. This value is unique and constant, staying the same no matter what keyboard layout you are using. Most of the time, on a US QWERTY keyboard, this will equivalent to the unicode value (with caveats).
Now, Oolite is reading our keyconfig file and translating the key characters into unicode values. And we're getting the unicode value passed to us during the keydown event, which allows for an easy match up.
And if you're just pressing straight keys (ie, with no modifiers), everything is fine. International keys are no problem.
But problems arise if you press Ctrl. First, when pressing Ctrl and an alpha character (a-z), instead of the normal unicode values for a-z (which are 97-122 for lowercase letters, 65-90 for uppercase), you'll get values from 1-26. The reason for this is...well it's complicated. Essentially, Ctrl codes were operations a user could perform to do special functions (like add a CR/LF). The upshot of this is that, suddenly the unicode representation of the key character being pressed is lost.
The SDLKey value is still available. But it remains constant no matter what keyboard layout you're using, I suspect because of what I noted in my previous post, that the values are tied to the system language, not the keyboard layout in use). Which means there is no way to easily translate the data back to the expected key character you entered on the config screen.
As an example, here are some results of some keypresses.
For a US QWERTY keyboard
Code: Select all
Press "z": Scancode = 44, unicode = 122, SDLKey = 122
Press "Ctrl-z": Scancode = 44, unicode = 26, SDLKey = 122
For a German QWERTZ keyboard
Code: Select all
Press "z": Scancode = 21, unicode = 122, SDLKey = 121
Press "Ctrl-z": Scancode = 21, unicode = 26, SDLKey = 121
The scancode is different because the location of the "z" key has moved, but the unicode values have stayed the same.
So, for basic Ctrl-a to Ctrl-z I can translate the unicode value into the actual key. But things get a little more murky when dealing with Ctrl and international character. For instance, here are the results from pressing ß on a German keyboard (which is a "-" on a US keyboard):
Code: Select all
Without ctrl: Scancode = 12, Unicode = 223, SDLKey = 45
With ctrl: Scancode = 12, Unicode = 0, SDLKey = 45
Now, when pressing Ctrl, the unicode value is gone completely. Based on this data, I have no way of knowing what the actual key character is. I know the position on the keyboard, and I could look up the SDLKey reference to learn that this is called SDLK_MINUS, but that doesn't help me determine what international character has been mapped to the minus key.
What I need to find is a way to translate the scancode into a virtual keyboard key. The SDL function "SDL_GetKeyName" stubbornly refuses to give any answer other than "-", regardless of the keyboard layout in play (again, because of aforementioned limitation).
This is certainly a challenging project!