public
Last active

Detect keyboard layouts (azerty, qwertz, others) using SDL2

  • Download Gist
layouts.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
#clone https://bitbucket.org/marcusva/py-sdl2
 
"""
Distinguish azerty/qwerty/qwertz
 
After experimenting, must SDL_INIT_VIDEO and use
SDL_GetKeyFromScancode or SDL_GetScancodeFromKey
 
The mapping is cached by SDL2;
enable the event loop or use SDL_Quit to detect again.
 
Alternatively, just use layout-independent
scancodes in your application.
"""
 
import sdl2
import sdl2.keyboard
import sdl2.keycode
from sdl2.keycode import *
 
# required, on Linux anyway
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
 
# unnecessary
#sdl2.SDL_Init(sdl2.SDL_INIT_EVERYTHING)
 
assert sdl2.keyboard.SDL_GetScancodeFromName(b'A') == sdl2.keycode.SDL_SCANCODE_A == 4
assert sdl2.keyboard.SDL_GetKeyFromName(b'A') == ord('a') == b'a'[0] == 97
assert sdl2.keyboard.SDL_GetScancodeName(4) == b'A'
assert sdl2.keyboard.SDL_GetKeyName(97) == b'A'
 
# Mapping keys to a scancode (position) allows to discriminate layouts
for keycode in b'aqwzy':
print('{}: {}'.format(chr(keycode), sdl2.keyboard.SDL_GetScancodeFromKey(keycode)))
 
# Using the reverse mapping makes more sense;
# map select scancodes of the top row to a layout
keys = bytes(sdl2.keyboard.SDL_GetKeyFromScancode(sc) for sc in (SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_Y))
if keys == b'qwy':
print('qwerty')
elif keys == b'azy':
print('azerty')
elif keys == b'qwz':
print('qwertz')
elif keys == b'qwj':
print('colemak')
elif keys == b'q,f':
print('dvorak')
elif keys == b'b\xe9y':
# SDL2 doesn't seem to map deadkey ^ and falls back to y
print('b├ępo')
else:
print('unknown', keys)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.