I test wine often with a game called Elastomania. Wine gets better over the years, but there is one problem that remains when playing that game: In the menus the cursor moves two positons on a key press. The biggest problem is that most of the menus have an odd number of items, so half of them are not reachable.
This happens with all the versions of wine I have tested on al the platforms I tested it on.
The game uses directx.
The problem is not in that both the keyup AND keydown events are being interpreted, because the cursor moves twice at keydown. The cursor does not repeat when a key is held down longer. My not so very usefull guess is that the program tries to shut down some sort of messaging, but that doesnt't work with wine, and the program still listens to those events, and recieves them.
Where do keyboard events go?
this is the output when ran with no cmdline options: Could not stat /mnt/fd0 (No such file or directory), ignoring drive A: fixme:ddraw:Main_DirectDraw_SetCooperativeLevel (0x40464254)->(00000000,00000008) fixme:ddraw:Main_DirectDraw_SetCooperativeLevel (0x40386af8)->(00010021,00000013) fixme:x11drv:X11DRV_DDHAL_CreatePalette stub fixme:x11drv:X11DRV_DDHAL_CreatePalette stub fixme:x11drv:X11DRV_DDHAL_CreatePalette stub err:dinput:SysKeyboardAImpl_Unacquire \ Unacquiring a not-acquired device !!!
here is a summary of the output when ran with: --debugmsg +key,+keyboard,+dinput
it starts with tons of: KEYBOARD_MapDeadKeysys no character for dead keysym 0x00XXXX and X11DRV_KEYBOARD_DetectLayout matches=47, mismatches=0, score=94 X11DRV_KEYBOARD_DetectLayout Attempting to match against "United Sta... blablabla...
then: X11DRV_InitKeyboard fixme:ddraw:Main_DirectDraw_SetCooperativeLevel DirectInputCreateA IDirectInputAImpl_CreateDevice keyboarddev_create_device Creating a Keyboard device (0x40464288)
then tons of: IDirectInputDevice2AImpl_SetDataFormat
then: IDirectInputDevice2AImpl_SetCooperativeLevel \ (this=0x40464288,0x00010021,0x00000006) DISCL_FOREGROUND DISCL_NONEXCLUSIVE
it then does very often: X11DRV_MapVirtualKey ... wMapType=1 and uses the return values in: GetAsyncKeyState () which is always: -> 0
and then (at line 25711)...
X11DRV_KeyEvent state = 0 X11DRV_KeyEvent KeyPress : keysym=20 (space), ascii chars=1 / 20 / ' ' X11DRV_KeyEvent keycode 0x41 converted to vkey 0x20 X11DRV_KeyEvent bScan = 0x39. queue_kbd_event wParam=0020, lParam=00390001, InputKeyState=81 TranslateMessage (WM_KEYDOWN, 0020, 00390001) TranslateMessage Translating key VK_SPACE (0020), scancode 39 X11DRV_ToUnicode (0020, 0039) : faked state = 0 X11DRV_ToUnicode Found keycode 65 (0x41) X11DRV_ToUnicode Translating char 0x20 from code page 28591 to unicode X11DRV_ToUnicode ToUnicode about to return 1 with char 20 TranslateMessage 1 -> PostMessage(WM_CHAR) TranslateMessage (WM_CHAR, 0020, 00390001)
I pressed the space bar!
among 'failing' GetAsyncKeyStates is now GetAsyncKeyState (20) -> 8001 GetAsyncKeyState (20) -> 8000 GetAsyncKeyState (20) -> 8000 GetAsyncKeyState (20) -> 8000 GetAsyncKeyState (20) -> 8000
and then: X11DRV_KeyEvent state = 0 X11DRV_KeyEvent KeyRelease : keysym=20 (space), ascii chars=1 / 20 / ' ' X11DRV_KeyEvent keycode 0x41 converted to vkey 0x20 X11DRV_KeyEvent bScan = 0x39. queue_kbd_event wParam=0020, lParam=c0390001, InputKeyState=1 TranslateMessage (WM_KEYUP, 0020, C0390001)
and yes: GetAsyncKeyState (20) -> 0
for the VK_UP that gets interpreted twice, the only diffrence is a call to X11DRV_ToUnicode that returns 0, so there is no: TranslateMessage (WM_CHAR...
so for every keypress you get:
... GetAsyncKeyState -> 0 GetAsyncKeyState -> 0
keydown: X11DRV_KeyEvent queue_kbd_event TranslateMessage (WM_KEYDOWN...
GetAsyncKeyState -> 8001 GetAsyncKeyState -> 8000 ... GetAsyncKeyState -> 8000
keyup: X11DRV_KeyEvent queue_kbd_event TranslateMessage (WM_KEYUP... GetAsyncKeyState -> 0 ...
A demo of the game can be downloaded at http://www.elastomania.com