We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 319

Summary: RFC: prototype implementation of physical key codes
Product: SDL Reporter: Christian Walther <cwalther>
Component: eventsAssignee: Christian Walther <cwalther>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: API change    
Priority: P2    
Version: 2.0.0   
Hardware: All   
OS: All   
Attachments: Patch against /branches/SDL-1.2 rev. 2741
Demonstrates use of physical keycodes in a game.

Description Christian Walther 2006-09-03 06:54:25 UTC
So, attached is the thing I've been talking about for a while: a prototype implementation (for Mac OS X (Quartz) and X11) of a keyboard handling feature that in my opinion could replace both the "sym" field of the SDL_keysym structure (SDL_Event.key.keysym) with the associated SDLK_* constants and its "scancode" field. However, since I've gotten the impression that some people are of different opinion, I'm proposing it as an addition rather than a replacement.

It is implemented as a patch against SDL 1.2 (rev. 2741 from today, but none of the affected files has changed after rev. 2549) because at the time I started it, SDL 1.3 wasn't functional enough for it, but the intention is to get it into SDL 1.3 if people agree.

It adds three things to the SDL API:

- A new field in the SDL_keysym (SDL_Event.key.keysym) structure: SDLPKey pkey.

- An enumerated type SDLPKey in SDL_keysym.h with a set of constants for this field: e.g. SDL_PK_A, SDL_PK_RETURN, SDL_PK_LSHIFT.

- A new function: const char * SDL_PKeyName(SDLPKey pkey), explained below.

Unlike the SDL_Event.key.keysym.sym field with its SDLK_* constants, which refers to a key with a particular label, the SDL_Event.key.keysym.pkey field with its SDL_PK_* constants refers to a key at a specific physical position on the keyboard (hence the name "physical key code"). E.g. SDL_PK_A means "the leftmost letter key in the middle alphabetic row" (which is labeled "A" on a US keyboard).

The SDL_PKeyName function takes a physical key code and returns a human-readable description for that key that ideally matches what's printed on the key cap on the user's keyboard, i.e. it takes into account the OS' current key mapping settings.

One case where the usefulness of such a system should be obvious is emulators (of devices with PC-like keyboards, e.g. Basilisk or Qemu or PearPC) - what they usually did up to now was to work with the platform-dependent "scancode" field and translate it to the emulated scancodes they need using platform-specific lookup tables. Now SDL takes the work of compiling these tables off them.

However, even in the case of games I think this system has its advantages. First, when the keyboard is used as some sort of gamepad, it seems much more natural to map the keys by their position than by their label. E.g. SDL_PK_Z will always be below SDL_PK_A, while SDLK_z is only below SDLK_a on a US keyboard, not on a French or German one. Second, I find that SDL_PKeyName() works much better for presenting key names to the user than SDL_KeyName() - e.g. when I press the "
Comment 1 Christian Walther 2006-09-03 06:56:18 UTC
Created attachment 160 [details]
Patch against /branches/SDL-1.2 rev. 2741
Comment 2 Christian Walther 2006-09-03 06:57:09 UTC
Created attachment 161 [details]
Demonstrates use of physical keycodes in a game.
Comment 3 Christian Walther 2006-09-03 07:12:20 UTC
Discussion thread on the mailing list here: <http://thread.gmane.org/gmane.comp.lib.sdl/29599>
Comment 4 Sam Lantinga 2006-09-23 21:08:47 UTC
I have mixed feelings on this.  I'll definitely review it for inclusion in SDL 1.3 though.  A Win32 implementation is crucial, BTW.
Comment 5 Christian Walther 2006-09-25 14:42:26 UTC
(In reply to comment #4)
> I have mixed feelings on this.  I'll definitely review it for inclusion in SDL
> 1.3 though.

Thanks. I don't mind if you end up rejecting it (though I'd be interested in the reasons) - I mainly wrote this for two reasons: to prove to myself that it can be done, and to have something to show to the people who seemed to misunderstand my explanations about how I imagine this to work and why I think it's useful.

> A Win32 implementation is crucial, BTW.

I absolutely agree. It's just that Windows is not my home platform and so I postponed the work of finding out how to do this there until I know more about its chances of making it into SDL.
Comment 6 Sam Lantinga 2007-07-05 23:13:23 UTC
I chatted with Christian for a while today, and I agree with the need to provide positional key information. 

This is what we came up with for SDL 1.3:
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X) used to map the sym into an array
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
  non-printable characters and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
  converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)

This is subject to change, but he's going to take a crack at prototyping this in SDL 1.3.
Comment 7 Sam Lantinga 2009-02-16 20:46:28 UTC
Physical keycodes are in SDL 1.3, see include/SDL_scancode.h for details.