From 5af1d683d8d4becb3e5cdc7bd3a43ad0af8cf0ae Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 10 Sep 2024 15:42:14 +0200 Subject: [PATCH] Revert "add experimental WH_GETMESSAGE hook" This reverts commit dcc76a154dec7dd35e4299c0e77a58efdfbf3d8a. --- inc/mouse.h | 5 +- src/dd.c | 3 - src/dllmain.c | 2 - src/mouse.c | 171 ++------------------------------------------- src/winapi_hooks.c | 168 +++++++++++++++++++++++++++++++++++++++++++- src/wndproc.c | 94 ++++++++++++++++++++++++- 6 files changed, 264 insertions(+), 179 deletions(-) diff --git a/inc/mouse.h b/inc/mouse.h index 65ef0da..1181ac2 100644 --- a/inc/mouse.h +++ b/inc/mouse.h @@ -1,12 +1,9 @@ #ifndef MOUSE_H #define MOUSE_H -void mouse_hook_init(); -void mouse_hook_exit(); void mouse_lock(); void mouse_unlock(); -LRESULT CALLBACK mouse_gm_hook_proc(int code, WPARAM wParam, LPARAM lParam); -LRESULT CALLBACK mouse_hook_proc(int code, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK mouse_hook_proc(int Code, WPARAM wParam, LPARAM lParam); extern BOOL g_mouse_locked; extern HHOOK g_mouse_hook; diff --git a/src/dd.c b/src/dd.c index fee3a21..e9ae3d7 100644 --- a/src/dd.c +++ b/src/dd.c @@ -993,8 +993,6 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl g_ddraw.mouse.unscale_y = ((float)(g_ddraw.height - 1) / (g_ddraw.render.viewport.height - 1)); } - TRACE("sdm unscale_x %.6f, y=%.6f\n", g_ddraw.mouse.unscale_x, g_ddraw.mouse.unscale_y); - g_ddraw.mouse.x_adjust = g_ddraw.render.viewport.x; g_ddraw.mouse.y_adjust = g_ddraw.render.viewport.y; @@ -1372,7 +1370,6 @@ HRESULT dd_SetCooperativeLevel(HWND hwnd, DWORD dwFlags) g_ddraw.gui_thread_id = GetWindowThreadProcessId(g_ddraw.hwnd, NULL); keyboard_hook_init(); - mouse_hook_init(); if (!g_ddraw.render.hdc) { diff --git a/src/dllmain.c b/src/dllmain.c index fa8e2d1..76090f9 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -13,7 +13,6 @@ #include "utils.h" #include "versionhelpers.h" #include "keyboard.h" -#include "mouse.h" /* export for cncnet cnc games */ @@ -141,7 +140,6 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) indeo_disable(); timeEndPeriod(1); keyboard_hook_exit(); - mouse_hook_exit(); dinput_hook_exit(); hook_exit(); break; diff --git a/src/mouse.c b/src/mouse.c index cbb976b..46aca13 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,45 +1,15 @@ #include -#include -#include #include "debug.h" #include "winapi_hooks.h" #include "dd.h" #include "hook.h" #include "utils.h" #include "config.h" -#include "mouse.h" BOOL g_mouse_locked; HHOOK g_mouse_hook; HOOKPROC g_mouse_proc; -static HHOOK g_mouse_gm_hook; - -void mouse_hook_init() -{ - if (g_mouse_gm_hook && UnhookWindowsHookEx(g_mouse_gm_hook)) - { - g_mouse_gm_hook = NULL; - } - - if (!g_ddraw.gui_thread_id) - return; - - g_mouse_gm_hook = - real_SetWindowsHookExA( - WH_GETMESSAGE, - mouse_gm_hook_proc, - NULL, - g_ddraw.gui_thread_id); -} - -void mouse_hook_exit() -{ - if (g_mouse_gm_hook) - { - UnhookWindowsHookEx(g_mouse_gm_hook); - } -} void mouse_lock() { @@ -113,146 +83,15 @@ void mouse_unlock() } } -LRESULT CALLBACK mouse_gm_hook_proc(int code, WPARAM wParam, LPARAM lParam) -{ - if (code < 0 || !lParam || !g_ddraw.width) - return CallNextHookEx(g_mouse_gm_hook, code, wParam, lParam); - - MSG* msg = (MSG*)lParam; - - if (!g_config.windowed || real_ScreenToClient(g_ddraw.hwnd, &msg->pt)) - { - int x = max(msg->pt.x - g_ddraw.mouse.x_adjust, 0); - int y = max(msg->pt.y - g_ddraw.mouse.y_adjust, 0); - - if (g_config.adjmouse) - { - x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); - y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); - } - - msg->pt.x = min(x, g_ddraw.width - 1); - msg->pt.y = min(y, g_ddraw.height - 1); - } - else - { - msg->pt.x = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.x, 0); - msg->pt.y = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.y, 0); - } - - if (msg->hwnd != g_ddraw.hwnd) - return CallNextHookEx(g_mouse_gm_hook, code, wParam, lParam); - - switch (LOWORD(msg->message)) - { - /* button up messages reactivate cursor lock */ - case WM_LBUTTONUP: - case WM_RBUTTONUP: - case WM_MBUTTONUP: - { - if (!g_config.devmode && !g_mouse_locked) - { - int x = GET_X_LPARAM(msg->lParam); - int y = GET_Y_LPARAM(msg->lParam); - - if (x > g_ddraw.render.viewport.x + g_ddraw.render.viewport.width || - x < g_ddraw.render.viewport.x || - y > g_ddraw.render.viewport.y + g_ddraw.render.viewport.height || - y < g_ddraw.render.viewport.y) - { - x = g_ddraw.width / 2; - y = g_ddraw.height / 2; - } - else - { - x = (DWORD)((x - g_ddraw.render.viewport.x) * g_ddraw.mouse.unscale_x); - y = (DWORD)((y - g_ddraw.render.viewport.y) * g_ddraw.mouse.unscale_y); - } - - x = min(x, g_ddraw.width - 1); - y = min(y, g_ddraw.height - 1); - - InterlockedExchange((LONG*)&g_ddraw.cursor.x, x); - InterlockedExchange((LONG*)&g_ddraw.cursor.y, y); - - mouse_lock(); - - msg->message = MAKELONG(WM_NULL, HIWORD(msg->message)); - return 0; - } - /* fall through for lParam */ - } - /* down messages are ignored if we have no cursor lock */ - case WM_XBUTTONDBLCLK: - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: - case WM_MOUSEWHEEL: - case WM_MOUSEHOVER: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_MOUSEMOVE: - { - if (!g_config.devmode && !g_mouse_locked) - { - msg->message = MAKELONG(WM_NULL, HIWORD(msg->message)); - return 0; - } - - if (LOWORD(msg->message) == WM_MOUSEWHEEL) - { - POINT pt = { GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam) }; - real_ScreenToClient(g_ddraw.hwnd, &pt); - msg->lParam = MAKELPARAM(pt.x, pt.y); - } - - int x = max(GET_X_LPARAM(msg->lParam) - g_ddraw.mouse.x_adjust, 0); - int y = max(GET_Y_LPARAM(msg->lParam) - g_ddraw.mouse.y_adjust, 0); - - if (g_config.adjmouse) - { - if (g_config.vhack && !g_config.devmode) - { - POINT pt = { 0, 0 }; - fake_GetCursorPos(&pt); - - x = pt.x; - y = pt.y; - } - else - { - x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); - y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); - } - } - - x = min(x, g_ddraw.width - 1); - y = min(y, g_ddraw.height - 1); - - InterlockedExchange((LONG*)&g_ddraw.cursor.x, x); - InterlockedExchange((LONG*)&g_ddraw.cursor.y, y); - - msg->lParam = MAKELPARAM(x, y); - - break; - } - } - - return CallNextHookEx(g_mouse_gm_hook, code, wParam, lParam); -} - -LRESULT CALLBACK mouse_hook_proc(int code, WPARAM wParam, LPARAM lParam) +LRESULT CALLBACK mouse_hook_proc(int Code, WPARAM wParam, LPARAM lParam) { if (!g_ddraw.ref) - return g_mouse_proc(code, wParam, lParam); + return g_mouse_proc(Code, wParam, lParam); - if (code < 0 || (!g_config.devmode && !g_mouse_locked)) - return CallNextHookEx(g_mouse_hook, code, wParam, lParam); + if (Code < 0 || (!g_config.devmode && !g_mouse_locked)) + return CallNextHookEx(g_mouse_hook, Code, wParam, lParam); fake_GetCursorPos(&((MOUSEHOOKSTRUCT*)lParam)->pt); - return g_mouse_proc(code, wParam, lParam); + return g_mouse_proc(Code, wParam, lParam); } diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index b51731b..68dc9dd 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -612,12 +612,146 @@ HHOOK WINAPI fake_SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, D return result; } +BOOL HandleMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) +{ + if (g_ddraw.ref && g_ddraw.width) + { + switch (lpMsg->message) + { + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + { + if (!g_config.devmode && !g_mouse_locked) + { + int x = GET_X_LPARAM(lpMsg->lParam); + int y = GET_Y_LPARAM(lpMsg->lParam); + + if (x > g_ddraw.render.viewport.x + g_ddraw.render.viewport.width || + x < g_ddraw.render.viewport.x || + y > g_ddraw.render.viewport.y + g_ddraw.render.viewport.height || + y < g_ddraw.render.viewport.y) + { + x = g_ddraw.width / 2; + y = g_ddraw.height / 2; + } + else + { + x = (DWORD)((x - g_ddraw.render.viewport.x) * g_ddraw.mouse.unscale_x); + y = (DWORD)((y - g_ddraw.render.viewport.y) * g_ddraw.mouse.unscale_y); + } + + InterlockedExchange((LONG*)&g_ddraw.cursor.x, x); + InterlockedExchange((LONG*)&g_ddraw.cursor.y, y); + + mouse_lock(); + //return FALSE; + } + /* fall through for lParam */ + } + /* down messages are ignored if we have no cursor lock */ + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + case WM_MOUSEWHEEL: + case WM_MOUSEHOVER: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_MOUSEMOVE: + { + if (!g_config.devmode && !g_mouse_locked) + { + // Does not work with 'New Robinson' + //return FALSE; + } + + if (lpMsg->message == WM_MOUSEWHEEL) + { + POINT pt = { GET_X_LPARAM(lpMsg->lParam), GET_Y_LPARAM(lpMsg->lParam) }; + real_ScreenToClient(g_ddraw.hwnd, &pt); + lpMsg->lParam = MAKELPARAM(pt.x, pt.y); + } + + int x = max(GET_X_LPARAM(lpMsg->lParam) - g_ddraw.mouse.x_adjust, 0); + int y = max(GET_Y_LPARAM(lpMsg->lParam) - g_ddraw.mouse.y_adjust, 0); + + if (g_config.adjmouse) + { + if (g_config.vhack && !g_config.devmode) + { + POINT pt = { 0, 0 }; + fake_GetCursorPos(&pt); + + x = pt.x; + y = pt.y; + } + else + { + x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); + y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); + } + } + + x = min(x, g_ddraw.width - 1); + y = min(y, g_ddraw.height - 1); + + InterlockedExchange((LONG*)&g_ddraw.cursor.x, x); + InterlockedExchange((LONG*)&g_ddraw.cursor.y, y); + + lpMsg->lParam = MAKELPARAM(x, y); + + lpMsg->pt.x = x; + lpMsg->pt.y = y; + + break; + } + + } + } + + return TRUE; +} + BOOL WINAPI fake_GetMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) { if (g_ddraw.ref && (!hWnd || hWnd == g_ddraw.hwnd)) g_ddraw.last_msg_pull_tick = timeGetTime(); - return real_GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + BOOL result = real_GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + + if (result && lpMsg && g_ddraw.ref && g_ddraw.hwnd && g_ddraw.width && !g_config.fixmousehook) + { + if (!g_config.windowed || real_ScreenToClient(g_ddraw.hwnd, &lpMsg->pt)) + { + int x = max(lpMsg->pt.x - g_ddraw.mouse.x_adjust, 0); + int y = max(lpMsg->pt.y - g_ddraw.mouse.y_adjust, 0); + + if (g_config.adjmouse) + { + x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); + y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); + } + + lpMsg->pt.x = min(x, g_ddraw.width - 1); + lpMsg->pt.y = min(y, g_ddraw.height - 1); + } + else + { + lpMsg->pt.x = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.x, 0); + lpMsg->pt.y = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.y, 0); + } + + if (g_config.hook_getmessage) + { + HandleMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + } + } + + return result; } BOOL WINAPI fake_PeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) @@ -625,7 +759,37 @@ BOOL WINAPI fake_PeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT w if (g_ddraw.ref && (!hWnd || hWnd == g_ddraw.hwnd)) g_ddraw.last_msg_pull_tick = timeGetTime(); - return real_PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + BOOL result = real_PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + + if (result && lpMsg && g_ddraw.ref && g_ddraw.hwnd && g_ddraw.width && !g_config.fixmousehook) + { + if (!g_config.windowed || real_ScreenToClient(g_ddraw.hwnd, &lpMsg->pt)) + { + int x = max(lpMsg->pt.x - g_ddraw.mouse.x_adjust, 0); + int y = max(lpMsg->pt.y - g_ddraw.mouse.y_adjust, 0); + + if (g_config.adjmouse) + { + x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); + y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); + } + + lpMsg->pt.x = min(x, g_ddraw.width - 1); + lpMsg->pt.y = min(y, g_ddraw.height - 1); + } + else + { + lpMsg->pt.x = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.x, 0); + lpMsg->pt.y = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.y, 0); + } + + if (g_config.hook_peekmessage) + { + HandleMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + } + } + + return result; } BOOL WINAPI fake_GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT* lpwndpl) diff --git a/src/wndproc.c b/src/wndproc.c index 030751e..0d65fce 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -22,7 +22,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam if (uMsg != WM_MOUSEMOVE && uMsg != WM_NCMOUSEMOVE && uMsg != WM_NCHITTEST && uMsg != WM_SETCURSOR && uMsg != WM_KEYUP && uMsg != WM_KEYDOWN && uMsg != WM_CHAR && uMsg != WM_DEADCHAR && uMsg != WM_INPUT && uMsg != WM_UNICHAR && uMsg != WM_IME_CHAR && uMsg != WM_IME_KEYDOWN && uMsg != WM_IME_KEYUP && uMsg != WM_TIMER && - uMsg != WM_D3D9DEVICELOST && uMsg != WM_NULL) + uMsg != WM_D3D9DEVICELOST) { TRACE( " uMsg = %s (%d), wParam = %08X (%d), lParam = %08X (%d, LO=%d HI=%d)\n", @@ -42,7 +42,6 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam switch (uMsg) { - case WM_NULL: case WM_MOVING: case WM_NCLBUTTONDOWN: case WM_NCLBUTTONUP: @@ -781,6 +780,97 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam { break; } + /* button up messages reactivate cursor lock */ + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + { + if (!g_config.devmode && !g_mouse_locked) + { + int x = GET_X_LPARAM(lParam); + int y = GET_Y_LPARAM(lParam); + + if (x > g_ddraw.render.viewport.x + g_ddraw.render.viewport.width || + x < g_ddraw.render.viewport.x || + y > g_ddraw.render.viewport.y + g_ddraw.render.viewport.height || + y < g_ddraw.render.viewport.y) + { + x = g_ddraw.width / 2; + y = g_ddraw.height / 2; + } + else + { + x = (DWORD)((x - g_ddraw.render.viewport.x) * g_ddraw.mouse.unscale_x); + y = (DWORD)((y - g_ddraw.render.viewport.y) * g_ddraw.mouse.unscale_y); + } + + x = min(x, g_ddraw.width - 1); + y = min(y, g_ddraw.height - 1); + + InterlockedExchange((LONG*)&g_ddraw.cursor.x, x); + InterlockedExchange((LONG*)&g_ddraw.cursor.y, y); + + mouse_lock(); + return 0; + } + /* fall through for lParam */ + } + /* down messages are ignored if we have no cursor lock */ + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + case WM_MOUSEWHEEL: + case WM_MOUSEHOVER: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_MOUSEMOVE: + { + if (!g_config.devmode && !g_mouse_locked) + { + return 0; + } + + if (uMsg == WM_MOUSEWHEEL) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + real_ScreenToClient(g_ddraw.hwnd, &pt); + lParam = MAKELPARAM(pt.x, pt.y); + } + + int x = max(GET_X_LPARAM(lParam) - g_ddraw.mouse.x_adjust, 0); + int y = max(GET_Y_LPARAM(lParam) - g_ddraw.mouse.y_adjust, 0); + + if (g_config.adjmouse) + { + if (g_config.vhack && !g_config.devmode) + { + POINT pt = { 0, 0 }; + fake_GetCursorPos(&pt); + + x = pt.x; + y = pt.y; + } + else + { + x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); + y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); + } + } + + x = min(x, g_ddraw.width - 1); + y = min(y, g_ddraw.height - 1); + + InterlockedExchange((LONG*)&g_ddraw.cursor.x, x); + InterlockedExchange((LONG*)&g_ddraw.cursor.y, y); + + lParam = MAKELPARAM(x, y); + + break; + } case WM_PARENTNOTIFY: { switch (LOWORD(wParam))