Win32 keyhandling

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
tonic
Posts: 69
Joined: Mon Dec 10, 2007 6:18 pm
Contact:

Dead keys not working, Alt/AltGr modifiers not supported

Post by tonic »

Here's some things to fix with key event handling. I have only tested these on Win32 and have no idea if these problems are present on other platforms.

1)
Prevent usage of AltGr key not to be classified as key with control modifier. Because of this some chars can't be entered to GUI components. For example, on Finnish keyboard '@' is entered by pressing AltGr+2 (or alternatively Ctrl-Alt-2). EditBox UI code ignores it as it sees control modifier being held down. A hack to workaround this is to add the following code before posting key event in WndProc:

Code: Select all

if ((allKeys[VK_MENU] & 0x80) != 0)
    event.KeyInput.Control = 0;
Alternatively, proposal for a proper fix: Add alt key modifier to SKeyInput - "event.KeyInput.Alt" and fill it with the VK_MENU key state. Probably WM_SYSKEYDOWN and WM_SYSKEYUP need to be added as listened events in the WndProc. Additionally the UI code needs to be rewritten not to look at the modifiers as is to decide if key should be ignored or not.

2)
Fix for dead keys. Dead key is a key where pressing it doesn't first do anything, and then pressing next key produces a combination of characters. For example, on European keyboards pressing '¨' and 'u' lead to typing of character 'ü'.

For this to work, I think the character translation code in WndProc needs to be changed from usage of ToAscii to usage of ToUnicode. Additionally the "TranslateMessage(&msg);" call needs to be removed, as it translates the keys to char events and alters behavior of ToUnicode, and those events aren't used.

The code to use ToUnicode instead of ToAscii looks like this:

Code: Select all

WCHAR keyChars[2];
UINT scanCode = HIWORD(lParam);
int conversionResult = ToUnicode((UINT)wParam,scanCode,allKeys,keyChars,
            sizeof(keyChars)/sizeof(keyChars[0]),0);
if (conversionResult == 1)
    event.KeyInput.Char = keyChars[0];
else
    event.KeyInput.Char = 0;
// .. now just postEventFromUser -- or maybe first apply the hack mentioned in point 1) above.
Caveat: Switching to ToUnicode breaks compatibility with Windows 9x/ME (if Irrlicht was compatible with those in the first place?). When debugging this problem I compared implementation details with SDL (latest 1.2.x) and noticed it has a workaround for that issue, using a different way on older Windows. That code is more complex and involves detecting windows version, fetching code page using GetCodePage, listening WM_INPUTLANGCHANGE and re-fetching code page as needed, and finally using combination of ToAsciiEx and MultiByteToWideChar to get the character value.

3)
I noted that the Irrlicht SDL driver omits filling the modifier and Char fields of key events. That should be easily fixed by copying the data from the SDL event structures. Just remember to add call to SDL_EnableUNICODE(1); at the initialization phase and fill the irr event's Char field from the SDL keysym's unicode field.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I've added the necessary changes for the SDL device to latest SVN trunk. The Win32 needs still to be done.
CuteAlien
Admin
Posts: 9929
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Uh wait - so you drop win98/ME support now? So far Irrlicht worked with that and I was rather glad about it. While there is a unicode lib from Microsoft for those, it has such an unfortunate license that I couldn't use it in my last project.

Would it be possible to add another define for that maybe? So people who still want to support those systems can still do so with Irrlicht?
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

No, I added the stuff for proper SDL function. The win32 device was not changed as we have to think about a proper solution.
tonic
Posts: 69
Joined: Mon Dec 10, 2007 6:18 pm
Contact:

Post by tonic »

CuteAlien wrote:Uh wait - so you drop win98/ME support now?
As I noted, using "ToUnicode" doesn't work on win98/ME. But SDL has a workaround for that, so that it uses different way to accomplish the same thing when ran in older Windows. Something similar could be implemented for Irrlicht as well.
Post Reply