http://bugs.winehq.org/show_bug.cgi?id=7909
------- Additional Comments From focht@gmx.net 2007-12-04 10:05 ------- Hello again,
some update and possible solution :)
Seems i misinterpreted returned X11DRV_GetAsyncKeyState() flag field.
First call to X11DRV_GetAsyncKeyState() returns "rbutton down seen" (key is pressed + key got pressed since last time). All consecutive calls to X11DRV_GetAsyncKeyState() return "rbutton down seen" (key is pressed). No up state is reached/seen.
After putting additional debugging code and trace messages it became obvious.
--- trace --- trace:event:process_events ButtonPress for hwnd/window 0x10024/3a00001 trace:cursor:X11DRV_send_mouse_input before: (2) -> 0 trace:cursor:X11DRV_send_mouse_input after: (2) -> ffff8001 trace:event:process_events MotionNotify for hwnd/window 0x10024/3a00001 trace:cursor:X11DRV_MotionNotify hwnd 0x10024, event->is_hint 0 trace:cursor:X11DRV_send_mouse_input before: (2) -> ffff8001 trace:cursor:X11DRV_send_mouse_input after: (2) -> ffff8001 trace:event:process_events processed 2 events ... trace:key:X11DRV_GetAsyncKeyState before: (2) -> ffff8001 trace:key:X11DRV_GetAsyncKeyState after: (2) -> ffff8001 .... trace:key:X11DRV_GetAsyncKeyState before: (2) -> ffff8000 trace:key:X11DRV_GetAsyncKeyState after: (2) -> ffff8000 ... --- trace ---
The problematic code is X11DRV_GetAsyncKeyState().
--- snip dlls/winex11.drv/keyboard.c --- SHORT X11DRV_GetAsyncKeyState(INT key) { SHORT retval; X11DRV_MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_KEY, 0 );
retval = ((key_state_table[key] & 0x40) ? 0x0001 : 0) | ((key_state_table[key] & 0x80) ? 0x8000 : 0); key_state_table[key] &= ~0x40; TRACE_(key)("(%x) -> %x\n", key, retval); return retval; } --- snip dlls/winex11.drv/keyboard.c ---
Looking at the pseudo code from my posting earlier and you will know. The application basically "busy loops" using GetAsyncKeyState(). That means GetAsyncKeyState() has to handle not only keyboard but mouse button events too! In short: X11DRV_MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_KEY ...) is not enough, it filters out mouse button state messages (button down/up).
Modify the filter to "QS_KEY | QS_MOUSEBUTTON" (dont use QS_ALLINPUT!)
--- snip dlls/winex11.drv/keyboard.c --- SHORT X11DRV_GetAsyncKeyState(INT key) { SHORT retval; X11DRV_MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_KEY | QS_MOUSEBUTTON, 0 );
retval = ((key_state_table[key] & 0x40) ? 0x0001 : 0) | ((key_state_table[key] & 0x80) ? 0x8000 : 0); key_state_table[key] &= ~0x40; TRACE_(key)("(%x) -> %x\n", key, retval); return retval; } --- snip dlls/winex11.drv/keyboard.c ---
Now it handles mouse button input too - which updates the key_state_table used by X11DRV_GetAsyncKeyState(). I tested with photoshop 5.5 tril and it worked like a charm, lockup gone, context menu shows up on right mouse click :) If any other applications/versions suffer from this one, please retest it using this workaround.
Regards.