Currently SDL does not provide portable physical keycodes (independant
of the keyboard layout). The current workaround is to recommend X11
FreeDinkEdit users to switch to a US keyboard layout (setxkbmap
us).

For FreeDink, I think DMods authors usually attached scripts to the
letters keys, so we could try something with the unicode field and get
compatibility for that part of the keyboard only.

This is currently implemented, with some work-arounds, in
FreeDinkedit.

-----

Date: Sat, 18 Aug 2007 21:22:04 +0200
From: Sylvain Beucler <beuc@beuc.net>
To: sdl@lists.libsdl.org
User-Agent: Mutt/1.5.13 (2006-08-11)
Subject: [SDL] Portable keycodes?

Hi,

I just ran some keycodes tests with 2 platforms (W2K and X11) and 2
keyboard layouts (US and French).

My question is: is there a way to get consistent keycodes across
platforms with SDL?  For example, what I'd like to use the 0-9 digits
(those in the top line of the keyboard) the same way, whatever the OS
and whatever the keyboard layout. E.g. in Duke Nukem 3D and most FPS
that's how you select weapons.


The main problem is that under X11, SDL_sim returns essentially the
same thing than the SDL unicode field.

I think the DirectX keycodes or the xev "keycode" field (see below)
are a good thing: they do not rely on the current keyboard mapping,
they always refer to the same physical location on the keyboard (from
what I can tell). For games, the physical location of the key is what
matters. If the application needs to get the actual letters, not the
keys, the unicode field is already perfect.

Any clue?

-----

Here are the tests:

Background: on a French keyboard:

- Q and A are swapped.

- Pressing 2 gives a E+accent (é), you need Shift+2 to get the
  digit. That's similar for 0-9.


Properly naming the keys:
- US-Q == "top-left letter" - Q for QWERTY
- US-2 == "first line, 3rd key with a '2' on it" - 2 for QWERTY


Now for the tests:

SDL - X11 - SDL_sim or Unicode:
EN
 US-Q -> 113 'q'
 US-2 -> 50 '2'
FR
 US-Q -> 97 'a'
 US-2 -> 233 'world 73'

-> What was typed as text, without caps
The only difference I see between SDL_sim and Unicode is when using
dead keys (such as ^+a).


SDL - W2K - SDL_sim (are those DirectX keycodes?):
EN
 US-Q -> 113 'q'
 US-2 -> 50 '2'
FR
 US-Q -> 113 'q'
 US-2 -> 50 '2'

-> Always US

SDL - W2K - Unicode:
EN
 US-Q -> 113 'q'
 US-2 -> 50 '2'
FR
 US-Q -> 97 'a'
 US-2 -> 233 'world 73'

-> What was typed as text, without caps


(W32API - GetAsyncKeyState - for reference)
EN
 US-Q -> 81 'Q'
 US-2 -> 50 '2'
FR
 US-Q -> 65 'A'
 US-2 -> 50 '2'

Digits -> Always US
Letters -> Locale, with caps
Rest -> Huge mess
-> Don't use


(xev - X11 - for reference)
US-Q - US
KeyPress event, serial 30, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051508871, (217,167), root:(232,263),
    state 0x0, keycode 24 (keysym 0x71, q), same_screen YES,
    XLookupString gives 1 bytes: (71) "q"
    XmbLookupString gives 1 bytes: (71) "q"
    XFilterEvent returns: False

KeyRelease event, serial 30, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051508955, (217,167), root:(232,263),
    state 0x0, keycode 24 (keysym 0x71, q), same_screen YES,
    XLookupString gives 1 bytes: (71) "q"

US-Q - FR
KeyPress event, serial 26, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051433631, (794,532), root:(809,628),
    state 0x0, keycode 24 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"
    XmbLookupString gives 1 bytes: (61) "a"
    XFilterEvent returns: False

KeyRelease event, serial 29, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051433692, (794,532), root:(809,628),
    state 0x0, keycode 24 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"


US-2 - US
KeyPress event, serial 30, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051576843, (72,33), root:(87,129),
    state 0x0, keycode 11 (keysym 0x32, 2), same_screen YES,
    XLookupString gives 1 bytes: (32) "2"
    XmbLookupString gives 1 bytes: (32) "2"
    XFilterEvent returns: False

KeyRelease event, serial 30, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051576896, (72,33), root:(87,129),
    state 0x0, keycode 11 (keysym 0x32, 2), same_screen YES,
    XLookupString gives 1 bytes: (32) "2"

US-2 - FR
KeyPress event, serial 31, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051594850, (284,365), root:(299,461),
    state 0x0, keycode 11 (keysym 0xe9, eacute), same_screen YES,
    XLookupString gives 2 bytes: (c3 a9) "é"
    XmbLookupString gives 2 bytes: (c3 a9) "é"
    XFilterEvent returns: False

KeyRelease event, serial 31, synthetic NO, window 0x3800001,
    root 0x47, subw 0x0, time 2051594934, (284,365), root:(299,461),
    state 0x0, keycode 11 (keysym 0xe9, eacute), same_screen YES,
    XLookupString gives 2 bytes: (c3 a9) "é"


-> The "keycode" field is constant


-- 
Sylvain


To: sdl@libsdl.org
From: Christian Walther <cwalther@gmx.ch>
Date: Sat, 18 Aug 2007 22:52:56 +0200
User-Agent: Thunderbird 2.0.0.4 (Macintosh/20070604)
Subject: Re: [SDL] Portable keycodes?

Sylvain Beucler wrote:
> My question is: is there a way to get consistent keycodes across
> platforms with SDL?

We're working on this... expect the first bits to show up in SDL 1.3
shortly.

If you need it in SDL 1.2 (Mac OS X and X11 only though), have a look at
<http://thread.gmane.org/gmane.comp.lib.sdl/29599>.

  -Christian
