Skip to content

Instantly share code, notes, and snippets.

@g2p
Last active January 4, 2016 08:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save g2p/8597984 to your computer and use it in GitHub Desktop.
Save g2p/8597984 to your computer and use it in GitHub Desktop.
Detect keyboard layouts (azerty, qwertz, others) using SDL2
#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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment