1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Fixed multi-threaded issues with emulated mouse cursor

Fixes invisible cursor after alt-tabbing in Beach Life.
This commit is contained in:
narzoul 2022-07-31 15:47:50 +02:00
parent 524f708a7f
commit 3d958e5ef2
3 changed files with 24 additions and 32 deletions

View File

@ -9,8 +9,10 @@
namespace namespace
{ {
const HCURSOR INVALID_CURSOR = static_cast<HCURSOR>(INVALID_HANDLE_VALUE);
RECT g_clipRect = {}; RECT g_clipRect = {};
HCURSOR g_cursor = nullptr; HCURSOR g_cursor = INVALID_CURSOR;
bool g_isEmulated = false; bool g_isEmulated = false;
RECT g_monitorClipRect = {}; RECT g_monitorClipRect = {};
HCURSOR g_nullCursor = nullptr; HCURSOR g_nullCursor = nullptr;
@ -52,7 +54,7 @@ namespace
{ {
LOG_FUNC("GetCursor"); LOG_FUNC("GetCursor");
Compat::ScopedCriticalSection lock(g_cs); Compat::ScopedCriticalSection lock(g_cs);
return LOG_RESULT(g_isEmulated ? g_cursor : CALL_ORIG_FUNC(GetCursor)()); return LOG_RESULT(g_cursor != INVALID_CURSOR ? g_cursor : CALL_ORIG_FUNC(GetCursor)());
} }
BOOL WINAPI getCursorInfo(PCURSORINFO pci) BOOL WINAPI getCursorInfo(PCURSORINFO pci)
@ -86,8 +88,7 @@ namespace
HCURSOR WINAPI setCursor(HCURSOR hCursor) HCURSOR WINAPI setCursor(HCURSOR hCursor)
{ {
LOG_FUNC("SetCursor", hCursor); return Gdi::Cursor::setCursor(hCursor);
return LOG_RESULT(Gdi::Cursor::setCursor(hCursor));
} }
void updateClipRect() void updateClipRect()
@ -163,19 +164,17 @@ namespace Gdi
HCURSOR setCursor(HCURSOR cursor) HCURSOR setCursor(HCURSOR cursor)
{ {
LOG_FUNC("SetCursor", cursor);
Compat::ScopedCriticalSection lock(g_cs); Compat::ScopedCriticalSection lock(g_cs);
if (!g_isEmulated) if (cursor == g_nullCursor)
{ {
return CALL_ORIG_FUNC(SetCursor)(cursor); return LOG_RESULT(g_cursor);
} }
HCURSOR prevCursor = g_cursor; HCURSOR prevCursor = g_cursor != INVALID_CURSOR ? g_cursor : CALL_ORIG_FUNC(GetCursor)();
if (cursor != g_nullCursor) g_cursor = cursor;
{ CALL_ORIG_FUNC(SetCursor)(g_isEmulated && cursor ? g_nullCursor : cursor);
g_cursor = cursor; return LOG_RESULT(prevCursor);
CALL_ORIG_FUNC(SetCursor)(cursor ? g_nullCursor : nullptr);
}
return prevCursor;
} }
void setEmulated(bool isEmulated) void setEmulated(bool isEmulated)
@ -190,15 +189,9 @@ namespace Gdi
g_isEmulated = isEmulated; g_isEmulated = isEmulated;
g_prevCursorInfo = {}; g_prevCursorInfo = {};
if (isEmulated) POINT pos = {};
{ GetCursorPos(&pos);
setCursor(CALL_ORIG_FUNC(GetCursor)()); SetCursorPos(pos.x, pos.y);
}
else
{
CALL_ORIG_FUNC(SetCursor)(g_cursor);
g_cursor = nullptr;
}
} }
void setMonitorClipRect(const RECT& rect) void setMonitorClipRect(const RECT& rect)

View File

@ -202,31 +202,26 @@ namespace
case WM_SETCURSOR: case WM_SETCURSOR:
{ {
if (!Gdi::Cursor::isEmulated())
{
return origDefWindowProc(hwnd, msg, wParam, lParam);
}
switch (LOWORD(lParam)) switch (LOWORD(lParam))
{ {
case HTLEFT: case HTLEFT:
case HTRIGHT: case HTRIGHT:
Gdi::Cursor::setCursor(LoadCursor(nullptr, IDC_SIZEWE)); SetCursor(LoadCursor(nullptr, IDC_SIZEWE));
return TRUE; return TRUE;
case HTTOP: case HTTOP:
case HTBOTTOM: case HTBOTTOM:
Gdi::Cursor::setCursor(LoadCursor(nullptr, IDC_SIZENS)); SetCursor(LoadCursor(nullptr, IDC_SIZENS));
return TRUE; return TRUE;
case HTTOPLEFT: case HTTOPLEFT:
case HTBOTTOMRIGHT: case HTBOTTOMRIGHT:
Gdi::Cursor::setCursor(LoadCursor(nullptr, IDC_SIZENWSE)); SetCursor(LoadCursor(nullptr, IDC_SIZENWSE));
return TRUE; return TRUE;
case HTBOTTOMLEFT: case HTBOTTOMLEFT:
case HTTOPRIGHT: case HTTOPRIGHT:
Gdi::Cursor::setCursor(LoadCursor(nullptr, IDC_SIZENESW)); SetCursor(LoadCursor(nullptr, IDC_SIZENESW));
return TRUE; return TRUE;
} }
@ -246,7 +241,7 @@ namespace
} }
else else
{ {
Gdi::Cursor::setCursor(LoadCursor(nullptr, IDC_ARROW)); SetCursor(LoadCursor(nullptr, IDC_ARROW));
} }
return FALSE; return FALSE;
} }

View File

@ -171,6 +171,10 @@ namespace
onDestroyWindow(hwnd); onDestroyWindow(hwnd);
break; break;
case WM_SETCURSOR:
SetCursor(CALL_ORIG_FUNC(GetCursor)());
break;
case WM_STYLECHANGED: case WM_STYLECHANGED:
if (Gdi::Window::isTopLevelWindow(hwnd)) if (Gdi::Window::isTopLevelWindow(hwnd))
{ {