[Scummvm-devel] FYI: Keyboard events: keycode vs. ascii

Max Horn max at quendi.de
Sat Jun 23 16:39:32 CEST 2007


Hi there,

this email is relevant to all porters and all engine maintainers.

As you may have noticed (there was a big bunch of related commits),  
we have changed the way keyboard events are represented a bit.

Specifically, we now provide constants for *all* keycodes backends  
may legally generate. These are taken straight from SDL, which is  
what we used as internal reference anyway, but so far without making  
it explicit. This used to cause quite some confusion for porters and  
engine authors (as was evident by looking through the current  
keyboard code in several engines and backends). In this process, the  
Common::Event::kbd struct was given a type of it's own  
(Common::KeyState, defined in common/keyboard.h), making it easier to  
write code which tracks the full keystate.

Let me explain how and when to use the "keycode", and when "ascii":  
The keycode is meant to be unique per-key. That is, if you press a  
given key, it should always generate the same keycode, no matter what  
modifiers are pressed. So, "v", "Shift-v" and "Alt-v" all should  
produce a keycode of "V" (or, rather: Common::KEYCODE_v), with the  
appropriate modifier flags set.

Contrast this with the value of the "ascii" field: In the first case  
it will contain 'v', in the second 'V', and what it contains in the  
third case is currently *not* defined and can very between backend  
(over here it is 'Ã').

As a consequence, if you need to check for keycombos, you should  
*always* use keycode+flags to detect them. On the other hand, use the  
"ascii" value if you want to let the user perform text input.  And  
*always* use the Common::KEYCODE_* constants for this purpose

Torbjšrn and me already converted most engines to use the new  
techniques. This allowed the removal of several hacks and workarounds  
which were there as a result of the old undocumented keyboard code  
behavior. Yay!



Some implementation details:
* Backends should only generate keycode values defined in common/ 
keyboard.h. If you think a key is "missing" there, do *not* just add  
it to the list! First, check the US-international keyboard layout and  
use the appropriate key label used there (see here <http:// 
en.wikipedia.org/wiki/Keyboard_layout#US-International> resp. here  
<http://en.wikipedia.org/wiki/Image:KB_US-International.svg>). If you  
really really think that you must add a keycode, *first* discuss this  
with the rest of the team (i.e. on this list, or contact me  
directly). All in all, I'd actually prefer if we *reduced* the list  
of defined KEYCODEs, rather than making it even longer.

* Backends should always populate the keycode field with something  
meaningful, so that engines can rely on this.

* As for the "ascii" field, the value is roughly defined like this:
   - if the event was generated by a real (or virtual) keyboard, then  
the "ascii" value should be the ascii code (or unicode in the  
future?) of the character this key press would generate in other  
applications. So "A" gives "a", "Shift-A" gives "A", and "Alt-A"  
gives whatever on your target OS is expected to come out of "Alt- 
A" (i.e. mostly undefined). On the other hand, most "special" keys  
give an undefined ascii code; in fact backends are allowed to set the  
ascii code to 0 for those.
  - There are some exceptions for that last rule right now: certain  
keys, most importantly the function keys, return, tab, esc, should  
still generate ASCII values, as defined in common/keyboard.h, e.g.  
Common::ASCII_F1.  The plan is to slowly phase those out, at least  
the function key constants; the few constants < 32 are pretty  
standard values and might be retained.

* In particular, engines should filter the "ascii" values and not  
just blindly accept them! It can contain values > 255, too, used for  
certain special/virtual keys right now, and possibly UTF-16 in the  
future. And it can also be zero even though keycode is non-zero!



Finally, note that this change might cause a few regressions, but I  
strongly believe that overall it will improve our code quality and  
make life a bit easier for engine authors and porters alike. If you  
have any questions or suggestions, as usual, fire away.


Cheers,
Max



More information about the Scummvm-devel mailing list