Sebastian Lackner : dinput: Ensure X11 input events are forwarded to wineserver even without message loop.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Nov 5 10:14:55 CST 2015


Module: wine
Branch: master
Commit: bfb845f9fccb2ff5bff0b0ba3238fec7f9f7b710
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bfb845f9fccb2ff5bff0b0ba3238fec7f9f7b710

Author: Sebastian Lackner <sebastian at 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 at fds-team.de>
Signed-off-by: Michael Müller <michael at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at 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);




More information about the wine-cvs mailing list