From 1b791fb2cbe395f60e1c58294aba5a3b83b24351 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 20 Sep 2022 08:59:36 +0200 Subject: [PATCH] only lock cursor in borderless if game window is the foreground window --- inc/dd.h | 1 - inc/mouse.h | 1 + src/dd.c | 5 +++-- src/directinput.c | 7 ++++--- src/mouse.c | 11 ++++++----- src/winapi_hooks.c | 10 +++++----- src/wndproc.c | 16 ++++++++-------- 7 files changed, 27 insertions(+), 24 deletions(-) diff --git a/inc/dd.h b/inc/dd.h index b04fac0..dee20a9 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -117,7 +117,6 @@ typedef struct CNCDDRAW HWND hwnd; WNDPROC wndproc; struct { DWORD x; DWORD y; } cursor; - BOOL locked; BOOL adjmouse; BOOL devmode; BOOL vsync; diff --git a/inc/mouse.h b/inc/mouse.h index 4457c08..1181ac2 100644 --- a/inc/mouse.h +++ b/inc/mouse.h @@ -5,6 +5,7 @@ void mouse_lock(); void mouse_unlock(); LRESULT CALLBACK mouse_hook_proc(int Code, WPARAM wParam, LPARAM lParam); +extern BOOL g_mouse_locked; extern HHOOK g_mouse_hook; extern HOOKPROC g_mouse_proc; diff --git a/src/dd.c b/src/dd.c index ff43bf5..b6d8d40 100644 --- a/src/dd.c +++ b/src/dd.c @@ -502,7 +502,8 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl g_ddraw->render.run = TRUE; - BOOL lock_mouse = (g_ddraw->locked || g_ddraw->fullscreen) && !(dwFlags & SDM_LEAVE_FULLSCREEN); + BOOL lock_mouse = g_mouse_locked; + mouse_unlock(); memset(&g_ddraw->render.mode, 0, sizeof(DEVMODE)); @@ -722,7 +723,7 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl } } - if (lock_mouse) + if (lock_mouse || (g_ddraw->fullscreen && GetForegroundWindow() == g_ddraw->hwnd)) mouse_lock(); } else diff --git a/src/directinput.c b/src/directinput.c index d433c1c..e320828 100644 --- a/src/directinput.c +++ b/src/directinput.c @@ -5,6 +5,7 @@ #include "debug.h" #include "hook.h" #include "dd.h" +#include "mouse.h" DIRECTINPUTCREATEAPROC real_DirectInputCreateA; @@ -41,7 +42,7 @@ static HRESULT WINAPI fake_did_SetCooperativeLevel(IDirectInputDeviceA* This, HW if (This == g_mouse_device && g_ddraw && (dwFlags & DISCL_EXCLUSIVE)) { - if (g_ddraw->locked || g_ddraw->devmode) + if (g_mouse_locked || g_ddraw->devmode) { while (real_ShowCursor(FALSE) >= 0); } @@ -63,7 +64,7 @@ static HRESULT WINAPI fake_did_GetDeviceData( HRESULT result = real_did_GetDeviceData(This, cbObjectData, rgdod, pdwInOut, dwFlags); - if (SUCCEEDED(result) && g_ddraw && !g_ddraw->locked) + if (SUCCEEDED(result) && g_ddraw && !g_mouse_locked) { if (pdwInOut) { @@ -85,7 +86,7 @@ static HRESULT WINAPI fake_did_GetDeviceState(IDirectInputDeviceA* This, DWORD c HRESULT result = real_did_GetDeviceState(This, cbData, lpvData); - if (SUCCEEDED(result) && g_ddraw && !g_ddraw->locked) + if (SUCCEEDED(result) && g_ddraw && !g_mouse_locked) { if (cbData > 0 && lpvData) { diff --git a/src/mouse.c b/src/mouse.c index 9b43aa7..d2ead61 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -5,6 +5,7 @@ #include "hook.h" +BOOL g_mouse_locked; HHOOK g_mouse_hook; HOOKPROC g_mouse_proc; @@ -13,7 +14,7 @@ void mouse_lock() if (g_ddraw->devmode || g_ddraw->bnet_active) return; - if (g_hook_active && !g_ddraw->locked && !IsIconic(g_ddraw->hwnd)) + if (g_hook_active && !g_mouse_locked && !IsIconic(g_ddraw->hwnd)) { int game_count = InterlockedExchangeAdd((LONG*)&g_ddraw->show_cursor_count, 0); int cur_count = real_ShowCursor(TRUE) - 1; @@ -46,7 +47,7 @@ void mouse_lock() real_MapWindowPoints(g_ddraw->hwnd, HWND_DESKTOP, (LPPOINT)&rc, 2); real_ClipCursor(&rc); - g_ddraw->locked = TRUE; + g_mouse_locked = TRUE; } } @@ -55,9 +56,9 @@ void mouse_unlock() if (g_ddraw->devmode || !g_hook_active) return; - if (g_ddraw->locked) + if (g_mouse_locked) { - g_ddraw->locked = FALSE; + g_mouse_locked = FALSE; real_ClipCursor(NULL); @@ -82,7 +83,7 @@ LRESULT CALLBACK mouse_hook_proc(int Code, WPARAM wParam, LPARAM lParam) if (!g_ddraw) return g_mouse_proc(Code, wParam, lParam); - if (Code < 0 || (!g_ddraw->devmode && !g_ddraw->locked)) + if (Code < 0 || (!g_ddraw->devmode && !g_mouse_locked)) return CallNextHookEx(g_mouse_hook, Code, wParam, lParam); fake_GetCursorPos(&((MOUSEHOOKSTRUCT*)lParam)->pt); diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index a0821b9..1d2ec5e 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -23,7 +23,7 @@ BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint) realpt.x = pt.x; realpt.y = pt.y; - if (g_ddraw->locked && (!g_ddraw->windowed || real_ScreenToClient(g_ddraw->hwnd, &pt))) + if (g_mouse_locked && (!g_ddraw->windowed || real_ScreenToClient(g_ddraw->hwnd, &pt))) { /* fallback solution for possible ClipCursor failure */ int diffx = 0, diffy = 0; @@ -152,7 +152,7 @@ BOOL WINAPI fake_ClipCursor(const RECT* lpRect) CopyRect(&g_ddraw->mouse.rc, &dst_rc); - if (g_ddraw->locked) + if (g_mouse_locked) { real_MapWindowPoints(g_ddraw->hwnd, HWND_DESKTOP, (LPPOINT)&dst_rc, 2); @@ -167,7 +167,7 @@ int WINAPI fake_ShowCursor(BOOL bShow) { if (g_ddraw) { - if (g_ddraw->locked || g_ddraw->devmode) + if (g_mouse_locked || g_ddraw->devmode) { int count = real_ShowCursor(bShow); InterlockedExchange((LONG*)&g_ddraw->show_cursor_count, count); @@ -190,7 +190,7 @@ HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor) { HCURSOR cursor = (HCURSOR)InterlockedExchange((LONG*)&g_ddraw->old_cursor, (LONG)hCursor); - if (!g_ddraw->locked && !g_ddraw->devmode) + if (!g_mouse_locked && !g_ddraw->devmode) return cursor; } @@ -265,7 +265,7 @@ BOOL WINAPI fake_ScreenToClient(HWND hWnd, LPPOINT lpPoint) BOOL WINAPI fake_SetCursorPos(int X, int Y) { - if (g_ddraw && !g_ddraw->locked && !g_ddraw->devmode) + if (g_ddraw && !g_mouse_locked && !g_ddraw->devmode) return TRUE; POINT pt = { X, Y }; diff --git a/src/wndproc.c b/src/wndproc.c index eee7eff..b16fcd5 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -105,7 +105,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case HTTOPRIGHT: return DefWindowProc(hWnd, uMsg, wParam, lParam); case HTCLIENT: - if (!g_ddraw->locked && !g_ddraw->devmode) + if (!g_mouse_locked && !g_ddraw->devmode) { real_SetCursor(LoadCursor(NULL, IDC_ARROW)); return TRUE; @@ -476,7 +476,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_WINDOWPOSCHANGING: { /* workaround for a bug where sometimes a background window steals the focus */ - if (g_ddraw->locked) + if (g_mouse_locked) { WINDOWPOS* pos = (WINDOWPOS*)lParam; @@ -486,8 +486,8 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam if (GetForegroundWindow() == g_ddraw->hwnd) mouse_lock(); + } } - } break; } case WM_MOUSELEAVE: @@ -523,14 +523,14 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam mouse_lock(); } } - else if (g_ddraw->fullscreen) + else if (g_ddraw->fullscreen && GetForegroundWindow() == g_ddraw->hwnd) { mouse_lock(); } } else { - if (!g_ddraw->windowed && !g_ddraw->locked && g_ddraw->noactivateapp && !g_ddraw->devmode) + if (!g_ddraw->windowed && !g_mouse_locked && g_ddraw->noactivateapp && !g_ddraw->devmode) return 0; mouse_unlock(); @@ -677,7 +677,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_RBUTTONUP: case WM_MBUTTONUP: { - if (!g_ddraw->devmode && !g_ddraw->locked) + if (!g_ddraw->devmode && !g_mouse_locked) { int x = GET_X_LPARAM(lParam); int y = GET_Y_LPARAM(lParam); @@ -718,7 +718,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_MBUTTONDOWN: case WM_MOUSEMOVE: { - if (!g_ddraw->devmode && !g_ddraw->locked) + if (!g_ddraw->devmode && !g_mouse_locked) { return 0; } @@ -765,7 +765,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_RBUTTONDOWN: case WM_XBUTTONDOWN: { - if (!g_ddraw->devmode && !g_ddraw->locked) + if (!g_ddraw->devmode && !g_mouse_locked) { int x = (DWORD)((GET_X_LPARAM(lParam) - g_ddraw->render.viewport.x) * g_ddraw->render.unscale_w); int y = (DWORD)((GET_Y_LPARAM(lParam) - g_ddraw->render.viewport.y) * g_ddraw->render.unscale_h);