Module: wine Branch: master Commit: bfb845f9fccb2ff5bff0b0ba3238fec7f9f7b710 URL: http://source.winehq.org/git/wine.git/?a=commit;h=bfb845f9fccb2ff5bff0b0ba32...
Author: Sebastian Lackner sebastian@fds-team.de Date: Thu Nov 5 15:57:29 2015 +0100
dinput: Ensure X11 input events are forwarded to wineserver even without message loop.
This commit basically reverts b22ff8018aca7c365e505f1db7732f7050ae259b.
Windows does not do that, but our current implementation of winex11 requires periodic event polling to forward events to the wineserver.
Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Michael Müller michael@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/dinput/device.c | 5 +++-- dlls/dinput/dinput_main.c | 14 ++++++++++++++ dlls/dinput/dinput_private.h | 1 + dlls/dinput/keyboard.c | 2 ++ dlls/dinput/mouse.c | 2 ++ dlls/dinput/tests/mouse.c | 3 +++ 6 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index ab43029..1ba6ffc 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1631,8 +1631,9 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Poll(LPDIRECTINPUTDEVICE8W iface) IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
if (!This->acquired) return DIERR_NOTACQUIRED; - /* Because wine devices do not need to be polled, just return DI_NOEFFECT */ - return DI_NOEFFECT; + + check_dinput_events(); + return DI_OK; }
HRESULT WINAPI IDirectInputDevice2AImpl_Poll(LPDIRECTINPUTDEVICE8A iface) diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 18840b2..aef9d10 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -1632,6 +1632,20 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface) LeaveCriticalSection(&dinput_hook_crit); }
+void check_dinput_events(void) +{ + /* Windows does not do that, but our current implementation of winex11 + * requires periodic event polling to forward events to the wineserver. + * + * We have to call this function from multiple places, because: + * - some games do not explicitly poll for mouse events + * (for example Culpa Innata) + * - some games only poll the device, and neither keyboard nor mouse + * (for example Civilization: Call to Power 2) + */ + MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, 0); +} + BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved) { switch(reason) diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index 022a7a9..176c0e0 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -63,6 +63,7 @@ extern const struct dinput_device joystick_linuxinput_device DECLSPEC_HIDDEN; extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN;
extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W) DECLSPEC_HIDDEN; +extern void check_dinput_events(void) DECLSPEC_HIDDEN; typedef int (*DI_EVENT_PROC)(LPDIRECTINPUTDEVICE8A, WPARAM, LPARAM);
extern void _copy_diactionformatAtoW(LPDIACTIONFORMATW, LPDIACTIONFORMATA) DECLSPEC_HIDDEN; diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index f3ac30e..4c3c38e 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -335,6 +335,8 @@ static HRESULT WINAPI SysKeyboardWImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W ifac if (len != This->base.data_format.user_df->dwDataSize ) return DIERR_INVALIDPARAM;
+ check_dinput_events(); + EnterCriticalSection(&This->base.crit);
if (TRACE_ON(dinput)) { diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 3e63a34..eaec6b1 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -553,6 +553,8 @@ static HRESULT WINAPI SysMouseWImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface,
if(This->base.acquired == 0) return DIERR_NOTACQUIRED;
+ check_dinput_events(); + EnterCriticalSection(&This->base.crit); _dump_mouse_state(&This->m_state);
diff --git a/dlls/dinput/tests/mouse.c b/dlls/dinput/tests/mouse.c index 1a5f4bc..34940e4 100644 --- a/dlls/dinput/tests/mouse.c +++ b/dlls/dinput/tests/mouse.c @@ -93,6 +93,7 @@ static void test_acquire(IDirectInputA *pDI, HWND hwnd) DIPROPDWORD di_op; DIDEVICEOBJECTDATA mouse_state; DWORD cnt; + MSG msg; int i;
if (! SetForegroundWindow(hwnd)) @@ -130,6 +131,8 @@ static void test_acquire(IDirectInputA *pDI, HWND hwnd) * loose mouse input */ hwnd2 = CreateWindowA("static", "Temporary", WS_VISIBLE, 10, 210, 200, 200, NULL, NULL, NULL, NULL); + ok(hwnd2 != NULL, "CreateWindowA failed with %u\n", GetLastError()); + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
hr = IDirectInputDevice_GetDeviceState(pMouse, sizeof(m_state), &m_state); ok(hr == DIERR_NOTACQUIRED, "GetDeviceState() should have failed: %08x\n", hr);