mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Disabled themes, fixed nonclient area rendering and caret deadlock
Disabled visual styles and added WM_NCPAINT handling (as a simple BitBlt copy from the original DC) to reduce glitches in rendering of common controls and windows, such as the GetSaveFileName dialog window in StarCraft. Fixed a deadlock in the caret emulation code caused by locking the GDI critical section prior to calling beginGdiRendering, which is locking both the DirectDraw and GDI critical sections. Another thread that only calls beginGdiRendering without entering the GDI critical section first could thus run into a deadlock as both threads were waiting on each other's critical sections. Now the global caret data has it its own critical section instead of sharing the GDI critical section.
This commit is contained in:
parent
2a23cf5636
commit
acbc183d00
@ -22,6 +22,21 @@ namespace
|
||||
};
|
||||
|
||||
CaretData g_caret = {};
|
||||
CRITICAL_SECTION g_caretCriticalSection;
|
||||
|
||||
class CaretScopedThreadLock
|
||||
{
|
||||
public:
|
||||
CaretScopedThreadLock()
|
||||
{
|
||||
EnterCriticalSection(&g_caretCriticalSection);
|
||||
}
|
||||
|
||||
~CaretScopedThreadLock()
|
||||
{
|
||||
LeaveCriticalSection(&g_caretCriticalSection);
|
||||
}
|
||||
};
|
||||
|
||||
void drawCaret()
|
||||
{
|
||||
@ -55,7 +70,7 @@ namespace
|
||||
DWORD /*dwEventThread*/,
|
||||
DWORD /*dwmsEventTime*/)
|
||||
{
|
||||
CompatGdi::GdiScopedThreadLock gdiLock;
|
||||
CaretScopedThreadLock caretLock;
|
||||
if (OBJID_CARET != idObject || !g_caret.isDrawn || g_caret.hwnd != hwnd)
|
||||
{
|
||||
return;
|
||||
@ -80,7 +95,7 @@ namespace
|
||||
BOOL result = CALL_ORIG_GDI(CreateCaret)(hWnd, hBitmap, nWidth, nHeight);
|
||||
if (result)
|
||||
{
|
||||
CompatGdi::GdiScopedThreadLock gdiLock;
|
||||
CaretScopedThreadLock caretLock;
|
||||
if (g_caret.isDrawn)
|
||||
{
|
||||
drawCaret();
|
||||
@ -99,7 +114,7 @@ namespace
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CompatGdi::GdiScopedThreadLock gdiLock;
|
||||
CaretScopedThreadLock caretLock;
|
||||
if (!g_caret.isDrawn)
|
||||
{
|
||||
IAccessible* accessible = nullptr;
|
||||
@ -129,7 +144,7 @@ namespace
|
||||
BOOL result = CALL_ORIG_GDI(HideCaret)(hWnd);
|
||||
if (result)
|
||||
{
|
||||
CompatGdi::GdiScopedThreadLock gdiLock;
|
||||
CaretScopedThreadLock caretLock;
|
||||
if (g_caret.isDrawn)
|
||||
{
|
||||
drawCaret();
|
||||
@ -147,6 +162,8 @@ namespace CompatGdiCaret
|
||||
{
|
||||
void installHooks()
|
||||
{
|
||||
InitializeCriticalSection(&g_caretCriticalSection);
|
||||
|
||||
DetourTransactionBegin();
|
||||
HOOK_GDI_FUNCTION(user32, CreateCaret, createCaret);
|
||||
HOOK_GDI_FUNCTION(user32, ShowCaret, showCaret);
|
||||
|
@ -99,10 +99,8 @@ namespace
|
||||
if (hwnd)
|
||||
{
|
||||
ExcludeClipRectsData excludeClipRectsData = { compatDc, origin, GetAncestor(hwnd, GA_ROOT) };
|
||||
EnumThreadWindows(GetCurrentThreadId(), &excludeClipRectsForOverlappingWindows,
|
||||
EnumWindows(&excludeClipRectsForOverlappingWindows,
|
||||
reinterpret_cast<LPARAM>(&excludeClipRectsData));
|
||||
RECT windowRect = {};
|
||||
GetWindowRect(hwnd, &windowRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
namespace
|
||||
{
|
||||
void eraseBackground(HWND hwnd, HDC dc);
|
||||
void ncPaint(HWND wnd);
|
||||
|
||||
LRESULT CALLBACK callWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@ -23,6 +24,13 @@ namespace
|
||||
eraseBackground(ret->hwnd, reinterpret_cast<HDC>(ret->wParam));
|
||||
}
|
||||
}
|
||||
else if (WM_NCPAINT == ret->message)
|
||||
{
|
||||
if (0 == ret->lResult)
|
||||
{
|
||||
ncPaint(ret->hwnd);
|
||||
}
|
||||
}
|
||||
else if (WM_WINDOWPOSCHANGED == ret->message)
|
||||
{
|
||||
CompatGdi::invalidate();
|
||||
@ -49,6 +57,37 @@ namespace
|
||||
CompatGdi::endGdiRendering();
|
||||
}
|
||||
}
|
||||
|
||||
void ncPaint(HWND hwnd)
|
||||
{
|
||||
if (!CompatGdi::beginGdiRendering())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HDC windowDc = GetWindowDC(hwnd);
|
||||
HDC compatDc = CompatGdiDc::getDc(windowDc);
|
||||
|
||||
if (compatDc)
|
||||
{
|
||||
RECT windowRect = {};
|
||||
GetWindowRect(hwnd, &windowRect);
|
||||
RECT clientRect = {};
|
||||
GetClientRect(hwnd, &clientRect);
|
||||
POINT clientOrigin = {};
|
||||
ClientToScreen(hwnd, &clientOrigin);
|
||||
|
||||
OffsetRect(&clientRect, clientOrigin.x - windowRect.left, clientOrigin.y - windowRect.top);
|
||||
ExcludeClipRect(compatDc, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom);
|
||||
CALL_ORIG_GDI(BitBlt)(compatDc, 0, 0,
|
||||
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, windowDc, 0, 0, SRCCOPY);
|
||||
|
||||
CompatGdiDc::releaseDc(windowDc);
|
||||
}
|
||||
|
||||
ReleaseDC(hwnd, windowDc);
|
||||
CompatGdi::endGdiRendering();
|
||||
}
|
||||
}
|
||||
|
||||
namespace CompatGdiWinProc
|
||||
|
@ -94,7 +94,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>DDrawCompat.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@ -121,7 +121,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>DDrawCompat.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>No</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
@ -1,5 +1,10 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Uxtheme.h>
|
||||
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
@ -163,6 +168,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID /*lpvReserved*/)
|
||||
Compat::origProcs.DirectInputCreateA = GetProcAddress(g_origDInputModule, "DirectInputCreateA");
|
||||
|
||||
SetProcessAffinityMask(GetCurrentProcess(), 1);
|
||||
SetThemeAppProperties(0);
|
||||
|
||||
if (Compat::origProcs.SetAppCompatData)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user