diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index a3610573940..15727844f03 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -30,6 +30,7 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" +#include "winreg.h" #include "dinput.h" #include "dinput_private.h" @@ -50,6 +51,13 @@ static const IDirectInputDevice8WVtbl SysMouseWvt; typedef struct SysMouseImpl SysMouseImpl; +typedef enum +{ + WARP_DEFAULT, + WARP_DISABLE, + WARP_FORCE_ON +} WARP_MOUSE; + struct SysMouseImpl { struct IDirectInputDevice2AImpl base; @@ -66,6 +74,8 @@ struct SysMouseImpl /* This is for mouse reporting. */ DIMOUSESTATE2 m_state; + + WARP_MOUSE warp_override; }; static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam ); @@ -174,6 +184,8 @@ static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputIm SysMouseImpl* newDevice; LPDIDATAFORMAT df = NULL; unsigned i; + char buffer[20]; + HKEY hkey, appkey; newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseImpl)); if (!newDevice) return NULL; @@ -186,6 +198,17 @@ static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputIm newDevice->base.dinput = dinput; newDevice->base.event_proc = dinput_mouse_hook; + get_app_key(&hkey, &appkey); + if (!get_config_key(hkey, appkey, "MouseWarpOverride", buffer, sizeof(buffer))) + { + if (!strcasecmp(buffer, "disable")) + newDevice->warp_override = WARP_DISABLE; + else if (!strcasecmp(buffer, "force")) + newDevice->warp_override = WARP_FORCE_ON; + } + if (appkey) RegCloseKey(appkey); + if (hkey) RegCloseKey(hkey); + /* Create copy of default data format */ if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIMouse2.dwSize))) goto failed; memcpy(df, &c_dfDIMouse2, c_dfDIMouse2.dwSize); @@ -306,7 +329,9 @@ static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARA wdata = pt1.y; } - This->need_warp = (pt.x || pt.y) && dwCoop & DISCL_EXCLUSIVE; + This->need_warp = This->warp_override != WARP_DISABLE && + (pt.x || pt.y) && + (dwCoop & DISCL_EXCLUSIVE || This->warp_override == WARP_FORCE_ON); break; } case WM_MOUSEWHEEL: @@ -422,14 +447,18 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) else ERR("Failed to get RECT: %d\n", GetLastError()); } - + + /* Need a window to warp mouse in. */ + if (This->warp_override == WARP_FORCE_ON && !This->base.win) + This->base.win = GetDesktopWindow(); + /* Get the window dimension and find the center */ GetWindowRect(This->base.win, &rect); This->win_centerX = (rect.right - rect.left) / 2; This->win_centerY = (rect.bottom - rect.top ) / 2; - + /* Warp the mouse to the center of the window */ - if (This->base.dwCoopLevel & DISCL_EXCLUSIVE) + if (This->base.dwCoopLevel & DISCL_EXCLUSIVE || This->warp_override == WARP_FORCE_ON) { This->mapped_center.x = This->win_centerX; This->mapped_center.y = This->win_centerY; @@ -463,7 +492,7 @@ static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface) } /* And put the mouse cursor back where it was at acquire time */ - if (This->base.dwCoopLevel & DISCL_EXCLUSIVE) + if (This->base.dwCoopLevel & DISCL_EXCLUSIVE || This->warp_override == WARP_FORCE_ON) { TRACE(" warping mouse back to (%d , %d)\n", This->org_coords.x, This->org_coords.y); SetCursorPos(This->org_coords.x, This->org_coords.y);