[SDL] how is SDL 1.3 keyboard input supposed to work?

Christian Walther cwalther at gmx.ch
Thu Dec 27 02:34:06 PST 2007


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



More information about the SDL mailing list