Azerty keyboard support

Hello
first pardon my english, i’m not too used to use it.

So i came accross a bug while coding (i use debian’ SDL2.0.5 on X11) this is related to azerty keyboards and may be to many others non-qwerty keyboards.

The bug is related to https://forums.libsdl.org/viewtopic.php?p=49166 which has been solved (more like work around) in SDL2.0.6 anyway this fix doesn’t fix everything.

I cannot use last SDL version for now but i doubt this problem has been fixed completely.

As before, some shifted key simply don’t give the correct SDL_Keycode.
In azerty keyboard 1234567890 are shifted key, the fix i speak above has somehow fixed theses key by linking scancode and keycode (if i understood correctly) but others keys are not fixed this include ¨£%µ?./§ https://en.wikipedia.org/wiki/AZERTY

The bug seems to be that there is no SDL_Keycode for theses keys…

I think there is a fix to do about general keyboard variations like a SDL_GetKeyboardLayout() so the application can handle the keyboard properly using scancodes for example. Another fix would be to properly design the keyboard variations using the OS functions ? I don’t know.

I understand this is quite a lot of work for a little problem that not many users are concerned about but… Well… What do you think about it ? Should i make at least a report on bugzilla ?

Again if this kind of “bug” has been solved excuse my post, i searched for a while and didn’t found anything.

SDL is a good library thanks for coding and maintaining it :wink:

As I understand it, the SDL_Keycodes are supposed to be Unicode values and should be the same on all operating systems (when using the same keyboard layout).
Because many (esp. older) games use Keycodes instead of Scancodes (and map SDL_Keycode to their own keycodes), this isn’t very helpful for all games. To make sure that at least the 123…90 keys can be used in a way that accommodates such old games, this hack was added that the number keys with the scancodes SDL_SCANCODE_1, SDL_SCANCODE_2, …, SDL_SCANCODE_9, SDL_SCANCODE_0 are always mapped to SDLK_1, SDLK_2, …, SDLK_9, SDLK_0.
See also https://bugzilla.libsdl.org/show_bug.cgi?id=3188 for discussion about it.

So if you want to use keys on the AZERTY-Keyboard that are not number-keys or other keys that already have a SDLK_* constant, you should be able to use the integer Unicode-value, see https://en.wikipedia.org/wiki/List_of_Unicode_characters (I guess that ù should be 249 then).
See also https://wiki.libsdl.org/SDLKeycodeLookup for a list of defined SDL_Keycodes, at least ?./% should be defined there.

However, I would suggest to use Scancodes internally (for your keybindings in the code and config), and translate them to Keycodes (and keycode names) only for display purposes (keybindings menu, “press key $name” hints, …), like:

SDL_Scancode sc = ...; // from event or config file or whatever
SDL_Keycode key = SDL_GetKeyFromScancode(sc);
const char* keyname = SDL_GetKeyName(key); // use this to display the name to the user

Furthermore, for text input, please use https://wiki.libsdl.org/SDL_TextInputEvent

Thanks for you answer.

The problem is that even keys with a SDKLK_* constant doesn’t works!

if (e.key.keysym.sym == SDLK_PLUS) { printf(“plus key\n”);}
tryed with +?./% but theses SDLK_* are not recognised on azerty keyboard!
may be i’m missing something but it’s quite weird if i have to make an internal remap of the keyboard …

anyways the problem comes only with keys that need to be shifted (or alt-gr) to access the symbol.
Is it possible a layer in the SDL lib is missing shift interpretation to access to the SDLK-* ?
I mean, on QWERTY keyboard it’s easy to pass from scancodes to keycodes but on others keyboard you would need to check whenever a mod key (alt-gr or shift) have been pressed to be sure of the result SDLK_* …

Couldn’t be something to try to work on (somewhere in times :wink: ) ?
I’m not good enought to seek the answer in the SDL source code but … would you say the actual behavior of SDL is a feature, a bug or something missing implementation… ?

Thanks for your patience

P.S.: by the way, keysym.unicode seems to not exists anymore on SDL2

The keycode is not meant to tell you the character that would be created by the current combination of keys.
It’s an identifier for the key, and usually it’s the (lowercase) Unicode of the character you’d get when pressing that key without any modifiers like Shift or Alt-Gr – or in case of non-character keys like F1, F2, …, Enter, Ctrl etc it’s scancode | 1<<30. (I think the only exception to this rule are the number-keys, see earlier discussion).

So on (French) AZERTY keyboards there is no SDLK_PLUS key - because that key is SDLK_EQUALS (with event.key.keysym.mod == KMOD_LSHIFT (or KMOD_RSHIFT)).

This is much more useful for game input events, because you’ll often have logic like “key $X means forward, and if you press Shift at the same time you run” - so the information that $X is pressed and Shift is pressed at the same time is much more interesting than “key $Y, that happens to be $X with Shift on this particular layout, is pressed”.

I think you only need the character you’d get with shift or Alt-Gr when the user is typing something, i.e. for Text-Input.
And for this SDL has TextInput Events that contain UTF-8 text. This also works with “dead keys”, where you can first press the ` key and then the e key and get a “è” character, so the first keypress doesn’t produce a character at all, and the second keypress produces a character that’s a “combination” of the first and second key.
It also works with more complicated input schemes as used for Asian languages, for example.

Even though the keycode paradigm makes sense, you still need to be able to turn an SDLK_* code into a actual character to display in a mapping UI for the user… e.g., F = attack, B = block, A = move left, etc. A function to do this under the new keycode scheme is missing in SDL2.x (SDL_GetCharFromKeycode() or such). So you have to implement this yourself if you need it.

It’s pretty clear to me that there is NOT an SDLK_XXXXX code for every labeled key on every keyboard in existence… so if you don’t have a mostly-English keyboard, you’re pretty much out of luck for true, SDLK -to- “character” mapping. Scancode mapping is even more abstract, so you won’t be able to turn a SCANCODE into an actual character to show the user either.

I appreciate the ability to do all the whizzy cool text input stuff to enter strings of special characters, etc., but it does nothing to help with the “map a key to a game function and display that key to the user” method like so many games use.

And don’t get me wrong… most of this has nothing to do with SDL specifically. Despite all the advances with nationalized characters and all, keyboards are still too dumb in the sense they provide no indication of what is printed on the keys.

Why does

SDL_Scancode sc = ...; // from event or config file or whatever
SDL_Keycode key = SDL_GetKeyFromScancode(sc);
const char* keyname = SDL_GetKeyName(key); // use this to display the name to the user

as described above not work for you?

Thanks a lot for your answers,
i understand a bit more how SDL is thought to work.

Thanks again

1 Like

It only really works for keys that correspond to ASCII characters.

As a side note, I see that tests/checkkeys.c uses the TEXTINPUT event to print out the actual character that the keypress produces. The event comes in right after the KEYDOWN event but before the KEYUP event. It would be nice if the KEYDOWN event would actually include the character (possibly multiple bytes) from the single keypress as well.

No?

I have the following code in my simple test:

SDL_Event ev;
// ...
switch(ev.type) {
  case SDL_KEYDOWN:
    printf("Keycode: %s (%d) Scancode: %s (%d)\n",
           SDL_GetKeyName(ev.key.keysym.sym), ev.key.keysym.sym,
           SDL_GetScancodeName(ev.key.keysym.scancode), ev.key.keysym.scancode);
    break;
  // ...
}

and I get output like
Keycode: ^ (94) Scancode: ` (53)
Keycode: Left Shift (1073742049) Scancode: Left Shift (225)
Keycode: ü (252) Scancode: [ (47)
Keycode: ä (228) Scancode: ’ (52)
Keycode: Backspace (8) Scancode: Backspace (42)
Keycode: Tab (9) Scancode: Tab (43)
Keycode: ß (223) Scancode: - (45)
Keycode: Escape (27) Scancode: Escape (41)

So this does not just work with ASCII keys.