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

This commit basically reverts b22ff8018a.

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>
This commit is contained in:
Sebastian Lackner 2015-11-05 15:57:29 +01:00 committed by Alexandre Julliard
parent eca5ee9a49
commit bfb845f9fc
6 changed files with 25 additions and 2 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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)) {

View File

@ -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);

View File

@ -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);