How is SDL 1.3 keyboard input supposed to work?

Can you explain how the new input system is supposed to work? I thought
I understood it, but now I am pretty sure I don’t.

There is a new textinput event. My guess is that this is used to return
the utf-8 for a key when a text key such as “a” or “(” are pressed. Is
this correct? Are these events always sent or only when unicode input is
enabled?

There are a number of new functions for looking up the names of
characters and converting them … can you give me a complete list of
these and how they are supposed to work? Also, what are they for?

Another thing that bothers me is that the table in SDL_keynames.h
doesn’t actually contain the SDLK_* names of the keys. Why is that?

It makes sense to me that the key up/down events return only physical
key codes and textinput events return the utf-8 unicode when it is
available. But most of the rest seems like overkill to me.

I’m sending this to the whole list for clarification.

Bob Pendleton

Bob Pendleton wrote:

There is a new textinput event. My guess is that this is used to return
the utf-8 for a key when a text key such as “a” or “(” are pressed. Is
this correct?

I think so. The important thing to remember about text input events is
that they’re not intrinsically correlated with key events. With input
methods, a sequence of key presses can generate a single text input
event, and with things like handwriting recognition, text input events
could occur without any key events at all (theoretically, I don’t think
this is currently implemented anywhere).

Are these events always sent or only when unicode input is enabled?

I’m not sure. I haven’t concerned myself with text input events so far.
Sam? The Cocoa backend currently sends them whenever
SDL_EventState(SDL_TEXTINPUT, SDL_QUERY) is set. Does the “enabling
unicode input” thing even still exist?

There are a number of new functions for looking up the names of
characters and converting them … can you give me a complete list of
these and how they are supposed to work? Also, what are they for?

These things are explained in the documentation of SDL_keyboard.h and
SDL_keysym.h (extractable using Doxygen, there’s a doxyfile in
SDL/include). From the point of view of the library user, there are only
two such functions, SDL_GetLayoutKey() and SDL_GetKeyName(). Here’s what
I have written about them in the documentation (just for reference - do
read it in the HTML version that has links and stuff). If there’s
anything unclear about it, please ask.

SDLKey SDL_GetLayoutKey (SDLKey physicalKey)

Get the layout key code corresponding to the given physical key code
according to the current keyboard layout.

See SDLKey for details.

If physicalKey is not a physical key code, it is returned unchanged.

See also:
SDL_GetKeyName()

const char * SDL_GetKeyName(SDLKey layoutKey)

Get a human-readable name for a key.

Parameters:
layoutKey An SDL layout key code.

If what you have is a physical key code, e.g. from the key.keysym.sym
field of the SDL_Event structure, convert it to a layout key code using
SDL_GetLayoutKey() first. Doing this ensures that the returned name
matches what users see on their keyboards. Calling this function
directly on a physical key code (that is not also a layout key code) is
possible, but is not recommended except for debugging purposes. The name
returned in that case is the name of the SDLK_* constant and is not
suitable for display to users.

Returns:
A pointer to a UTF-8 string that stays valid at least until the
next call to this function. If you need it around any longer, you must
copy it. Always non-NULL.

See also:
SDLKey

From the point of view of the backend implementor, there is one more
provided function (SDL_SetKeyName()), and one function, or in special
cases two, to implement (SDL_VideoDevice.GetLayoutKey(),
SDL_VideoDevice.GetSpecialKeyName()) (apart from the generation of the
physical key codes in SDL_VideoDevice.PumpEvents()). Again, most of what
follows is copied from the comments in SDL_keyboard_c.h and
SDL_sysvideo.h (this is not contained in the Doxygen output because it’s
not part of the public API), and I’m open for clarification requests.

void SDL_SetKeyName(SDLKey physicalKey, const char *name)

Set a platform-dependent key name, overriding the default
platform-agnostic name. Encoded as UTF-8. The string is not copied, thus
the pointer given to this function must stay valid forever (or at least
until the call to VideoQuit()).

Example: the SDLK_*META keys are called “command” on Mac OS, while the
default names in SDL_keynames.h say “meta”. Therefore the Cocoa backend
calls SDL_SetKeyName(SDLK_LMETA, “left command”); in Cocoa_InitKeyboard().

SDLKey (*GetLayoutKey)(_THIS, SDLKey physicalKey)

Get the layout key code corresponding to the given physical key code
according to the OS’ current keyboard layout.

  • For character keys, this should return the Unicode code point of
    the character that is generated when the key is pressed without shift or
    any other modifiers.
  • For non-character keys, this should return one of the SDLK_*
    constants (usually the argument itself since these keys are typically
    layout-independent). Make sure that all of these values returned by this
    function have a suitable name defined, either the default from
    SDL_keynames.h, or one set using SDL_SetKeyName() in VideoInit(). In
    particular, if this function can return any of the codes whose default
    names start with “SDLK_” (usually, it shouldn’t, since these are
    layout-dependent character keys), these names should be replaced by
    proper user-readable names.
  • If there are keys that cannot be adequately described by either a
    single Unicode character or an SDLK_* constant, this function may return
    a code with SDL_KEY_LAYOUT_SPECIAL_BIT set in the most significant byte
    and an arbitrary value in the less significant 3 bytes. The
    GetSpecialKeyName() function must then be implemented to take this code
    and return a human-readable key name for it.
    If the argument is not a physical key code or if translation of the
    key code by the OS’ keyboard layout fails for any reason, the argument
    must be returned unchanged.
    On platforms that don’t have the notion of a user-configurable
    keyboard layout, this may be left unimplemented. The default
    implementation of SDL_GetLayoutKey() then acts as the identity. The note
    about defining key names above particularly applies in this case.

const char * (*GetSpecialKeyName)(_THIS, SDLKey layoutKey)

Get a human-readable name for a special layout key code. This only
needs to be implemented if this driver’s implementation of
GetLayoutKey() generates such codes (with SDL_KEY_LAYOUT_SPECIAL_BIT
set) - see above.

Another thing that bothers me is that the table in SDL_keynames.h
doesn’t actually contain the SDLK_* names of the keys. Why is that?

Because these are names to be displayed to the user. When I press the
tab key in the key configuration dialog of a game, it should say “tab”,
not “SDLK_TAB”. (Some entries in that table do have the SDLK_* names.
That’s not a violation of the rule I just stated because these SDLK_*
constants are physical-only - they don’t occur as layout key codes, and
therefore the game user will never see these names.) See the SDLKey
documentation and the comments in SDL_keynames.h.

It makes sense to me that the key up/down events return only physical
key codes and textinput events return the utf-8 unicode when it is
available. But most of the rest seems like overkill to me.

That’s what I used to think too, until Sam convinced me that “layout key
codes” (as opposed to “physical key codes”), equivalent to the SDLK_*
codes of SDL 1.2 or to the KeySyms of X11, can be useful as well.

They are useful for games whose input works along the lines of “press I
to open the inventory”: the inventory should be opened by the key that’s
labeled “I”, no matter where it is located on the keyboard.

I’m sending this to the whole list for clarification.

(I’m sending this to the list only, in the hope that Gmane’s recent
posting slowness has been fixed. Personal copy may follow if not.)

-Christian

Hey, thanks.

I had found about half of this information in the code.

The names in the table make sense to me now. The only problem I still
have is that they are all in English.

OK, I can stop obsessing over those parts and go back to what I was
doing.

Bob PendletonOn Thu, 2007-12-27 at 11:34 +0100, Christian Walther wrote:

Bob Pendleton wrote:

There is a new textinput event. My guess is that this is used to return
the utf-8 for a key when a text key such as “a” or “(” are pressed. Is
this correct?

I think so. The important thing to remember about text input events is
that they’re not intrinsically correlated with key events. With input
methods, a sequence of key presses can generate a single text input
event, and with things like handwriting recognition, text input events
could occur without any key events at all (theoretically, I don’t think
this is currently implemented anywhere).

Are these events always sent or only when unicode input is enabled?

I’m not sure. I haven’t concerned myself with text input events so far.
Sam? The Cocoa backend currently sends them whenever
SDL_EventState(SDL_TEXTINPUT, SDL_QUERY) is set. Does the “enabling
unicode input” thing even still exist?

There are a number of new functions for looking up the names of
characters and converting them … can you give me a complete list of
these and how they are supposed to work? Also, what are they for?

These things are explained in the documentation of SDL_keyboard.h and
SDL_keysym.h (extractable using Doxygen, there’s a doxyfile in
SDL/include). From the point of view of the library user, there are only
two such functions, SDL_GetLayoutKey() and SDL_GetKeyName(). Here’s what
I have written about them in the documentation (just for reference - do
read it in the HTML version that has links and stuff). If there’s
anything unclear about it, please ask.

SDLKey SDL_GetLayoutKey (SDLKey physicalKey)

Get the layout key code corresponding to the given physical key code
according to the current keyboard layout.

See SDLKey for details.

If physicalKey is not a physical key code, it is returned unchanged.

See also:
SDL_GetKeyName()

const char * SDL_GetKeyName(SDLKey layoutKey)

Get a human-readable name for a key.

Parameters:
layoutKey An SDL layout key code.

If what you have is a physical key code, e.g. from the key.keysym.sym
field of the SDL_Event structure, convert it to a layout key code using
SDL_GetLayoutKey() first. Doing this ensures that the returned name
matches what users see on their keyboards. Calling this function
directly on a physical key code (that is not also a layout key code) is
possible, but is not recommended except for debugging purposes. The name
returned in that case is the name of the SDLK_* constant and is not
suitable for display to users.

Returns:
A pointer to a UTF-8 string that stays valid at least until the
next call to this function. If you need it around any longer, you must
copy it. Always non-NULL.

See also:
SDLKey

From the point of view of the backend implementor, there is one more
provided function (SDL_SetKeyName()), and one function, or in special
cases two, to implement (SDL_VideoDevice.GetLayoutKey(),
SDL_VideoDevice.GetSpecialKeyName()) (apart from the generation of the
physical key codes in SDL_VideoDevice.PumpEvents()). Again, most of what
follows is copied from the comments in SDL_keyboard_c.h and
SDL_sysvideo.h (this is not contained in the Doxygen output because it’s
not part of the public API), and I’m open for clarification requests.

void SDL_SetKeyName(SDLKey physicalKey, const char *name)

Set a platform-dependent key name, overriding the default
platform-agnostic name. Encoded as UTF-8. The string is not copied, thus
the pointer given to this function must stay valid forever (or at least
until the call to VideoQuit()).

Example: the SDLK_*META keys are called “command” on Mac OS, while the
default names in SDL_keynames.h say “meta”. Therefore the Cocoa backend
calls SDL_SetKeyName(SDLK_LMETA, “left command”); in Cocoa_InitKeyboard().

SDLKey (*GetLayoutKey)(_THIS, SDLKey physicalKey)

Get the layout key code corresponding to the given physical key code
according to the OS’ current keyboard layout.

  • For character keys, this should return the Unicode code point of
    the character that is generated when the key is pressed without shift or
    any other modifiers.
  • For non-character keys, this should return one of the SDLK_*
    constants (usually the argument itself since these keys are typically
    layout-independent). Make sure that all of these values returned by this
    function have a suitable name defined, either the default from
    SDL_keynames.h, or one set using SDL_SetKeyName() in VideoInit(). In
    particular, if this function can return any of the codes whose default
    names start with “SDLK_” (usually, it shouldn’t, since these are
    layout-dependent character keys), these names should be replaced by
    proper user-readable names.
  • If there are keys that cannot be adequately described by either a
    single Unicode character or an SDLK_* constant, this function may return
    a code with SDL_KEY_LAYOUT_SPECIAL_BIT set in the most significant byte
    and an arbitrary value in the less significant 3 bytes. The
    GetSpecialKeyName() function must then be implemented to take this code
    and return a human-readable key name for it.
    If the argument is not a physical key code or if translation of the
    key code by the OS’ keyboard layout fails for any reason, the argument
    must be returned unchanged.
    On platforms that don’t have the notion of a user-configurable
    keyboard layout, this may be left unimplemented. The default
    implementation of SDL_GetLayoutKey() then acts as the identity. The note
    about defining key names above particularly applies in this case.

const char * (*GetSpecialKeyName)(_THIS, SDLKey layoutKey)

Get a human-readable name for a special layout key code. This only
needs to be implemented if this driver’s implementation of
GetLayoutKey() generates such codes (with SDL_KEY_LAYOUT_SPECIAL_BIT
set) - see above.

Another thing that bothers me is that the table in SDL_keynames.h
doesn’t actually contain the SDLK_* names of the keys. Why is that?

Because these are names to be displayed to the user. When I press the
tab key in the key configuration dialog of a game, it should say “tab”,
not “SDLK_TAB”. (Some entries in that table do have the SDLK_* names.
That’s not a violation of the rule I just stated because these SDLK_*
constants are physical-only - they don’t occur as layout key codes, and
therefore the game user will never see these names.) See the SDLKey
documentation and the comments in SDL_keynames.h.

It makes sense to me that the key up/down events return only physical
key codes and textinput events return the utf-8 unicode when it is
available. But most of the rest seems like overkill to me.

That’s what I used to think too, until Sam convinced me that “layout key
codes” (as opposed to “physical key codes”), equivalent to the SDLK_*
codes of SDL 1.2 or to the KeySyms of X11, can be useful as well.

They are useful for games whose input works along the lines of “press I
to open the inventory”: the inventory should be opened by the key that’s
labeled “I”, no matter where it is located on the keyboard.

I’m sending this to the whole list for clarification.

(I’m sending this to the list only, in the hope that Gmane’s recent
posting slowness has been fixed. Personal copy may follow if not.)

-Christian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±-------------------------------------+

Bob Pendleton wrote:

The names in the table make sense to me now. The only problem I still
have is that they are all in English.

Yes, that is a problem. So far I haven’t been able to think of a better
solution than leaving their localization to the application, since the
internationalization APIs are so different between platforms (perhaps
this is something that could be abstracted in SDL too…). Improvements
are welcome.

OK, I can stop obsessing over those parts and go back to what I was
doing.

By the way, I’m currently investigating the use of the existing
KeySym-to-Unicode tables you pointed me to for the GetLayoutKey()
implementation. I’ll post to bugzilla if and when I have something to show.

-Christian

Bob Pendleton wrote:

The names in the table make sense to me now. The only problem I still
have is that they are all in English.

Yes, that is a problem. So far I haven’t been able to think of a better
solution than leaving their localization to the application, since the
internationalization APIs are so different between platforms (perhaps
this is something that could be abstracted in SDL too…). Improvements
are welcome.

OK, I can stop obsessing over those parts and go back to what I was
doing.

By the way, I’m currently investigating the use of the existing
KeySym-to-Unicode tables you pointed me to for the GetLayoutKey()
implementation. I’ll post to bugzilla if and when I have something to show.

Great! post a note so I don’t miss it.

Bob PendletonOn Fri, 2007-12-28 at 10:14 +0100, Christian Walther wrote:

-Christian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±-------------------------------------+