Meaning of SDLK_* - undocumented and inconsistent behavior

While hacking around in SDL’s mouse handling on Mac OS X (I’m not done
yet :slight_smile: ) I came across another issue that I’d like to discuss (actually,
I’ve come across it before, see
http://article.gmane.org/gmane.comp.lib.sdl/20860/, but now I’ve done
some more research):

What is the supposed meaning of the SDL_Event.key.keysym.sym field and
the corresponding SDLK_* constants? Is SDLK_z

  1. “the key that would be labeled ‘Z’ on a US keyboard”, i.e. a
    reference to a key at a specific hardware position, or

  2. “the key that’s labeled ‘Z’”, i.e. a reference to a key that
    generates a specific character?

The documentation is not clear about this, and neither are the
implementations.

I’d vote for 1, because 2 makes it impossible to do mapping-by-position
(which is essential e.g. for emulators) in a portable way. And if
mapping-by-generated-character is what you want, that’s what
SDL_Event.key.keysym.unicode is there for.

The current Quartz code implements 2 (interestingly, it does so by doing
extra work - changing it to 1 is a matter of removing code).
The current X11 code implements 2 (implementing 1 is not easy to do in
an elegant way - I have an idea, but it needs reviewing by some X11 guru).
The current windx5 code implements 1.
The current windib code implements 2 (I don’t know enough about Windows
to tell how feasible an implementation of 1 would be, but as dx5 is the
default backend on Windows, I’m not sure whether it would be worth the
effort).

Any opinions on this matter?
If I were to provide a patch that switches Quartz and X11 to 1, what
would be its chance of being accepted into SDL?

-Christian

What is the supposed meaning of the SDL_Event.key.keysym.sym field and
the corresponding SDLK_* constants? Is SDLK_z

  1. “the key that would be labeled ‘Z’ on a US keyboard”, i.e. a
    reference to a key at a specific hardware position, or

  2. “the key that’s labeled ‘Z’”, i.e. a reference to a key that
    generates a specific character?

I believe it was meant to be “the key that’s labeled ‘Z’ on Sam’s
keyboard”. :slight_smile:

Realistically, people actually wanting to know text input should be
using the Unicode field, but there’s probably a lot of code out there
that is counting on these to match up.

Does anyone have any opinions on this?

–ryan.

What is the supposed meaning of the SDL_Event.key.keysym.sym field and
the corresponding SDLK_* constants? Is SDLK_z

  1. “the key that would be labeled ‘Z’ on a US keyboard”, i.e. a
    reference to a key at a specific hardware position, or

  2. “the key that’s labeled ‘Z’”, i.e. a reference to a key that
    generates a specific character?

I believe it was meant to be “the key that’s labeled ‘Z’ on Sam’s
keyboard”. :slight_smile:

Realistically, people actually wanting to know text input should be
using the Unicode field, but there’s probably a lot of code out there
that is counting on these to match up.

Does anyone have any opinions on this?

After working with World of Warcraft’s code, I figured out how to do it
the way I had always intended, which is to map to the unshifted code for
the current keyboard. Unfortunately, this leaves SDL’s keysym set lacking,
and this can’t be addressed until a major API change (1.3)

To answer your question, it should generally be option 2, specifically
so those programs which make that assumption (almost all emulators) will
work correctly.

See ya,
-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment

Sam Lantinga wrote:

After working with World of Warcraft’s code, I figured out how to do it
the way I had always intended, which is to map to the unshifted code for
the current keyboard. Unfortunately, this leaves SDL’s keysym set lacking,
and this can’t be addressed until a major API change (1.3)

I’m not sure what you mean by “the unshifted code for the current
keyboard”. Is it what I called option 1 (a code that identifies a
specific position on the keyboard) or 2 (a code that identifies the
symbol printed on the key cap)?

If it is 1, how does that leave the keysym set lacking? It seems to have
codes for all keys of all keyboards I know. And even if some would have
to be added, why would that cause API incompatibility?

To answer your question, it should generally be option 2, specifically
so those programs which make that assumption (almost all emulators) will
work correctly.

Is that so that “almost all emulators” make that assumption? AFAIR,
Qemu, Basilisk II, and PearPC use event.key.keysym.scancode and map it
to a platform-independent position code using platform-specific look-up
tables. If we changed event.key.keysym.sym to be such a code everywhere,
they could stop doing that. As they aren’t using event.key.keysym.sym at
all in their current versions, there would be no backwards compatibility
issue for them.

Also, since the DirectX backend currently implements option 1,
applications that assume option 2 don’t work correctly there already.

I’m not sure if in “almost all emulators” you include those whose
emulated devices don’t have a PC-style keyboard, but for those it
doesn’t matter much IMHO as their PC-key-to-device-key mapping is
arbitrary and should be configurable anyway.

-Christian