http://bugs.winehq.org/show_bug.cgi?id=2981
------- Additional Comments From allefant@gmail.com 2005-28-05 06:04 ------- Ok, that would have been too simple. Attaching a new patch, which really works. Of course, this is merely a work-around rather than a fix. But, it can safely be applied as far as I can see, and will fix all problems related to this.
Now, how to explain what is going on. Basically, the bug is in HOOK_CallHooks. It does not call global hooks, but only hooks for the current thread. This sounds like a quite serious flaw, so I probably am missing something.
But well, the bug seems to suggest I'm right. The workaround in the patch works, because when the hook is installed the second time, it is in the window thread, and that's the thread which calls HOOK_CallHooks. So from now on, the hook is seen, since now it's installed in the right thread. That the first hook still is installed in the other thread doesn't matter, since it never will be called anyway.
Now, a proper fix of course would be to fix HOOK_CallHooks. Basically, instead of just checking the hooks of the thread which calls HOOK_CallHooks, it should additionally check global (and only global) hooks of all other threads in the current process.
So, if you give me a way to iterate through all the threads of the current process, I can write a patch.
Thinking a bit further, I believe that using the KEYBOARD_LL hook is the wrong way to implement the dinput keyboard (unless real Windows does it that way as well). So a completely alternate solution would be to not install any KEYBOARD_LL hook for the keyboard dinput device, but instead directly call the KeyboardCallback function inside dlls/dinput/keyboard.c from dlls/x11drv/keyboard.c. I can make a patch for that instead as well, if you give me a way to loop over all currently acquired dinput devices.
I think best is to just apply the attached patch for now, add fixing of HOOK_CallHooks to some sort of TODO list (and then removed the workaround again once that's done), and also discuss somewhere if dinput shouldn't be implemented without a message hook really.