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

Moved GDI parts to Gdi namespace and subdirectory

This commit is contained in:
narzoul 2016-08-27 20:35:10 +02:00
parent a078ea4be0
commit b65f98f0e3
33 changed files with 601 additions and 549 deletions

View File

@ -3,11 +3,11 @@
#include "CompatDirectDrawSurface.h"
#include "CompatDisplayMode.h"
#include "CompatFontSmoothing.h"
#include "CompatGdi.h"
#include "CompatPrimarySurface.h"
#include "CompatPtr.h"
#include "CompatRef.h"
#include "DDrawLog.h"
#include "Gdi/Gdi.h"
extern HWND g_mainWindow;
@ -42,7 +42,7 @@ namespace
if (primary && SUCCEEDED(primary->Restore(primary)))
{
CompatDirectDrawSurface<IDirectDrawSurface7>::fixSurfacePtrs(*primary);
CompatGdi::invalidate(nullptr);
Gdi::invalidate(nullptr);
}
CompatFontSmoothing::setSystemSettings(g_fontSmoothingSettings);
@ -90,7 +90,7 @@ namespace
if (!isActivated)
{
CompatGdi::disableEmulation();
Gdi::disableEmulation();
}
if (g_fullScreenDirectDraw)
@ -108,7 +108,7 @@ namespace
if (isActivated)
{
CompatGdi::enableEmulation();
Gdi::enableEmulation();
}
Compat::LogLeave("handleActivateApp", isActivated);

View File

@ -4,11 +4,11 @@
#include "CompatDirectDrawPalette.h"
#include "CompatDirectDrawSurface.h"
#include "CompatDisplayMode.h"
#include "CompatGdi.h"
#include "CompatPrimarySurface.h"
#include "CompatPtr.h"
#include "DDrawProcs.h"
#include "DDrawRepository.h"
#include "Gdi/Gdi.h"
#include "IReleaseNotifier.h"
#include "RealPrimarySurface.h"
@ -465,7 +465,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Restore(TSurface* T
result = RealPrimarySurface::restore();
if (wasLost)
{
CompatGdi::invalidate(nullptr);
Gdi::invalidate(nullptr);
}
}
}

View File

@ -1,7 +0,0 @@
#pragma once
namespace CompatGdiCaret
{
void installHooks();
void uninstallHooks();
}

View File

@ -1,12 +0,0 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
namespace CompatGdiDc
{
HDC getDc(HDC origDc, bool isMenuPaintDc = false);
HDC getOrigDc(HDC dc);
void releaseDc(HDC origDc);
}

View File

@ -1,27 +0,0 @@
#pragma once
#define CINTERFACE
#define WIN32_LEAN_AND_MEAN
#include <ddraw.h>
#include <Windows.h>
#include "CompatWeakPtr.h"
namespace CompatGdiDcCache
{
struct CachedDc
{
CompatWeakPtr<IDirectDrawSurface7> surface;
HDC dc;
DWORD cacheId;
};
void clear();
CachedDc getDc();
bool init();
void releaseDc(const CachedDc& cachedDc);
void setDdLockThreadId(DWORD ddLockThreadId);
void setSurfaceMemory(void* surfaceMemory, LONG pitch);
void updatePalette(DWORD startingEntry, DWORD count);
}

View File

@ -1,6 +0,0 @@
#pragma once
namespace CompatGdiDcFunctions
{
void installHooks();
};

View File

@ -1,7 +0,0 @@
#pragma once
namespace CompatGdiPaintHandlers
{
void installHooks();
void uninstallHooks();
}

View File

@ -1,7 +0,0 @@
#pragma once
namespace CompatGdiScrollFunctions
{
void installHooks();
void updateScrolledWindow(HWND hwnd);
};

View File

@ -1,7 +0,0 @@
#pragma once
namespace CompatGdiWinProc
{
void installHooks();
void uninstallHooks();
}

View File

@ -70,7 +70,7 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>ddraw</TargetName>
<IncludePath>C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\include;$(IncludePath)</IncludePath>
<IncludePath>$(ProjectDir);C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\lib.X86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -78,7 +78,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>ddraw</TargetName>
<IncludePath>C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\include;$(IncludePath)</IncludePath>
<IncludePath>$(ProjectDir);C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\lib.X86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -158,16 +158,6 @@
<ClInclude Include="CompatDirectDrawPalette.h" />
<ClInclude Include="CompatDisplayMode.h" />
<ClInclude Include="CompatFontSmoothing.h" />
<ClInclude Include="CompatGdi.h" />
<ClInclude Include="CompatGdiCaret.h" />
<ClInclude Include="CompatGdiDc.h" />
<ClInclude Include="CompatGdiDcCache.h" />
<ClInclude Include="CompatGdiDcFunctions.h" />
<ClInclude Include="CompatGdiPaintHandlers.h" />
<ClInclude Include="CompatGdiScrollBar.h" />
<ClInclude Include="CompatGdiScrollFunctions.h" />
<ClInclude Include="CompatGdiTitleBar.h" />
<ClInclude Include="CompatGdiWinProc.h" />
<ClInclude Include="CompatHooks.h" />
<ClInclude Include="CompatPaletteConverter.h" />
<ClInclude Include="CompatPtr.h" />
@ -198,6 +188,16 @@
<ClInclude Include="DirectDrawSurfaceVtblVisitor.h" />
<ClInclude Include="DirectDrawVtblVisitor.h" />
<ClInclude Include="DDrawLog.h" />
<ClInclude Include="Gdi\Gdi.h" />
<ClInclude Include="Gdi\Caret.h" />
<ClInclude Include="Gdi\Dc.h" />
<ClInclude Include="Gdi\DcCache.h" />
<ClInclude Include="Gdi\DcFunctions.h" />
<ClInclude Include="Gdi\PaintHandlers.h" />
<ClInclude Include="Gdi\ScrollBar.h" />
<ClInclude Include="Gdi\ScrollFunctions.h" />
<ClInclude Include="Gdi\TitleBar.h" />
<ClInclude Include="Gdi\WinProc.h" />
<ClInclude Include="Hook.h" />
<ClInclude Include="IReleaseNotifier.h" />
<ClInclude Include="RealPrimarySurface.h" />
@ -218,15 +218,6 @@
<ClCompile Include="CompatDirectDrawSurface.cpp" />
<ClCompile Include="CompatDisplayMode.cpp" />
<ClCompile Include="CompatFontSmoothing.cpp" />
<ClCompile Include="CompatGdi.cpp" />
<ClCompile Include="CompatGdiCaret.cpp" />
<ClCompile Include="CompatGdiDcCache.cpp" />
<ClCompile Include="CompatGdiDcFunctions.cpp" />
<ClCompile Include="CompatGdiPaintHandlers.cpp" />
<ClCompile Include="CompatGdiScrollBar.cpp" />
<ClCompile Include="CompatGdiScrollFunctions.cpp" />
<ClCompile Include="CompatGdiTitleBar.cpp" />
<ClCompile Include="CompatGdiWinProc.cpp" />
<ClCompile Include="CompatHooks.cpp" />
<ClCompile Include="CompatPaletteConverter.cpp" />
<ClCompile Include="CompatRegistry.cpp" />
@ -236,10 +227,19 @@
<ClCompile Include="DllMain.cpp" />
<ClCompile Include="CompatPrimarySurface.cpp" />
<ClCompile Include="DDrawProcs.cpp" />
<ClCompile Include="Gdi\Gdi.cpp" />
<ClCompile Include="Gdi\Caret.cpp" />
<ClCompile Include="Gdi\Dc.cpp" />
<ClCompile Include="Gdi\DcCache.cpp" />
<ClCompile Include="Gdi\DcFunctions.cpp" />
<ClCompile Include="Gdi\PaintHandlers.cpp" />
<ClCompile Include="Gdi\ScrollBar.cpp" />
<ClCompile Include="Gdi\ScrollFunctions.cpp" />
<ClCompile Include="Gdi\TitleBar.cpp" />
<ClCompile Include="Gdi\WinProc.cpp" />
<ClCompile Include="Hook.cpp" />
<ClCompile Include="IReleaseNotifier.cpp" />
<ClCompile Include="RealPrimarySurface.cpp" />
<ClCompile Include="CompatGdiDc.cpp" />
<ClCompile Include="DDrawRepository.cpp" />
<ClCompile Include="Time.cpp" />
<ClCompile Include="UnmodifiedDDrawProcs.cpp" />

View File

@ -13,6 +13,12 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Header Files\Gdi">
<UniqueIdentifier>{ed9adcfd-bf6f-4b69-b425-7a9252072e4d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Gdi">
<UniqueIdentifier>{a8e1437a-7bec-4492-830a-9a0d844aa06b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="DDrawProcs.h">
@ -63,36 +69,6 @@
<ClInclude Include="DDrawScopedThreadLock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiDcCache.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiDc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdi.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiWinProc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiCaret.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiTitleBar.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiScrollBar.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiDcFunctions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiScrollFunctions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatGdiPaintHandlers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Hook.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -183,6 +159,36 @@
<ClInclude Include="D3dDdiHooks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Gdi\Gdi.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\Caret.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\Dc.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\DcCache.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\DcFunctions.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\PaintHandlers.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\ScrollBar.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\ScrollFunctions.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\TitleBar.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\WinProc.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="DllMain.cpp">
@ -215,36 +221,6 @@
<ClCompile Include="CompatDirectDrawPalette.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiDcCache.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiDc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiWinProc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiCaret.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiTitleBar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiScrollBar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiDcFunctions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiScrollFunctions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatGdiPaintHandlers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Hook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -299,6 +275,36 @@
<ClCompile Include="D3dDdiHooks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Gdi\Gdi.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\Caret.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\Dc.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\DcCache.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\DcFunctions.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\PaintHandlers.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\ScrollBar.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\ScrollFunctions.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\TitleBar.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\WinProc.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="DDrawCompat.def">

View File

@ -7,12 +7,12 @@
#include "CompatDisplayMode.h"
#include "CompatFontSmoothing.h"
#include "CompatGdi.h"
#include "CompatHooks.h"
#include "CompatRegistry.h"
#include "D3dDdiHooks.h"
#include "DDrawHooks.h"
#include "DDrawProcs.h"
#include "Gdi/Gdi.h"
#include "Time.h"
struct IDirectInput;
@ -32,7 +32,7 @@ namespace
Compat::Log() << "Installing DirectDraw hooks";
DDrawHooks::installHooks();
Compat::Log() << "Installing GDI hooks";
CompatGdi::installHooks();
Gdi::installHooks();
Compat::Log() << "Installing registry hooks";
CompatRegistry::installHooks();
Compat::Log() << "Finished installing hooks";
@ -137,7 +137,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID /*lpvReserved*/)
Compat::Log() << "Detaching DDrawCompat";
DDrawHooks::uninstallHooks();
D3dDdiHooks::uninstallHooks();
CompatGdi::uninstallHooks();
Gdi::uninstallHooks();
Compat::unhookAllFunctions();
FreeLibrary(g_origDInputModule);
FreeLibrary(g_origDDrawModule);

View File

@ -2,9 +2,9 @@
#include <Windows.h>
#include "CompatGdi.h"
#include "CompatGdiCaret.h"
#include "CompatGdiDc.h"
#include "Gdi/Caret.h"
#include "Gdi/Dc.h"
#include "Gdi/Gdi.h"
#include "Hook.h"
#include "ScopedCriticalSection.h"
@ -63,10 +63,10 @@ namespace
if (caret.isVisible)
{
HDC dc = GetDC(caret.hwnd);
HDC compatDc = CompatGdiDc::getDc(dc);
HDC compatDc = Gdi::Dc::getDc(dc);
CALL_ORIG_FUNC(PatBlt)(
compatDc, caret.left, caret.top, caret.width, caret.height, PATINVERT);
CompatGdiDc::releaseDc(dc);
Gdi::Dc::releaseDc(dc);
ReleaseDC(caret.hwnd, dc);
}
}
@ -103,11 +103,11 @@ namespace
return;
}
if ((g_caret.isVisible || newCaret.isVisible) && CompatGdi::beginGdiRendering())
if ((g_caret.isVisible || newCaret.isVisible) && Gdi::beginGdiRendering())
{
drawCaret(g_caret);
drawCaret(newCaret);
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
}
g_caret = newCaret;
@ -118,29 +118,32 @@ namespace
Compat::hookFunction<decltype(&func), &func>( \
#module, #func, getCompatGdiCaretFuncPtr<decltype(&func), &func>(&func));
namespace CompatGdiCaret
namespace Gdi
{
void installHooks()
namespace Caret
{
InitializeCriticalSection(&g_caretCriticalSection);
void installHooks()
{
InitializeCriticalSection(&g_caretCriticalSection);
HOOK_GDI_CARET_FUNCTION(user32, CreateCaret);
HOOK_GDI_CARET_FUNCTION(user32, DestroyCaret);
HOOK_GDI_CARET_FUNCTION(user32, HideCaret);
HOOK_GDI_CARET_FUNCTION(user32, SetCaretPos);
HOOK_GDI_CARET_FUNCTION(user32, ShowCaret);
HOOK_GDI_CARET_FUNCTION(user32, CreateCaret);
HOOK_GDI_CARET_FUNCTION(user32, DestroyCaret);
HOOK_GDI_CARET_FUNCTION(user32, HideCaret);
HOOK_GDI_CARET_FUNCTION(user32, SetCaretPos);
HOOK_GDI_CARET_FUNCTION(user32, ShowCaret);
const DWORD threadId = GetCurrentThreadId();
g_compatGdiCaretGeneralEventHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_HIDE,
nullptr, &compatGdiCaretEvent, 0, threadId, WINEVENT_OUTOFCONTEXT);
g_compatGdiCaretLocationChangeEventHook = SetWinEventHook(
EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, nullptr, &compatGdiCaretEvent,
0, threadId, WINEVENT_OUTOFCONTEXT);
}
const DWORD threadId = GetCurrentThreadId();
g_compatGdiCaretGeneralEventHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_HIDE,
nullptr, &compatGdiCaretEvent, 0, threadId, WINEVENT_OUTOFCONTEXT);
g_compatGdiCaretLocationChangeEventHook = SetWinEventHook(
EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, nullptr, &compatGdiCaretEvent,
0, threadId, WINEVENT_OUTOFCONTEXT);
}
void uninstallHooks()
{
UnhookWinEvent(g_compatGdiCaretLocationChangeEventHook);
UnhookWinEvent(g_compatGdiCaretGeneralEventHook);
void uninstallHooks()
{
UnhookWinEvent(g_compatGdiCaretLocationChangeEventHook);
UnhookWinEvent(g_compatGdiCaretGeneralEventHook);
}
}
}

10
DDrawCompat/Gdi/Caret.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
namespace Gdi
{
namespace Caret
{
void installHooks();
void uninstallHooks();
}
}

View File

@ -1,16 +1,16 @@
#include <algorithm>
#include <unordered_map>
#include "CompatGdi.h"
#include "CompatGdiDc.h"
#include "CompatGdiDcCache.h"
#include "DDrawLog.h"
#include "Gdi/Dc.h"
#include "Gdi/DcCache.h"
#include "Gdi/Gdi.h"
#include "Hook.h"
#include "ScopedCriticalSection.h"
namespace
{
using CompatGdiDcCache::CachedDc;
using Gdi::DcCache::CachedDc;
struct CompatDc : CachedDc
{
@ -154,75 +154,78 @@ namespace
}
}
namespace CompatGdiDc
namespace Gdi
{
HDC getDc(HDC origDc, bool isMenuPaintDc)
namespace Dc
{
if (!origDc || OBJ_DC != GetObjectType(origDc) || DT_RASDISPLAY != GetDeviceCaps(origDc, TECHNOLOGY))
HDC getDc(HDC origDc, bool isMenuPaintDc)
{
return nullptr;
if (!origDc || OBJ_DC != GetObjectType(origDc) || DT_RASDISPLAY != GetDeviceCaps(origDc, TECHNOLOGY))
{
return nullptr;
}
Compat::ScopedCriticalSection gdiLock(Gdi::g_gdiCriticalSection);
auto it = g_origDcToCompatDc.find(origDc);
if (it != g_origDcToCompatDc.end())
{
++it->second.refCount;
return it->second.dc;
}
const HWND hwnd = CALL_ORIG_FUNC(WindowFromDC)(origDc);
const bool isMenuWindow = hwnd && 0x8000 == GetClassLongPtr(hwnd, GCW_ATOM);
if (isMenuWindow && !isMenuPaintDc)
{
return nullptr;
}
CompatDc compatDc(Gdi::DcCache::getDc());
if (!compatDc.dc)
{
return nullptr;
}
POINT origin = {};
GetDCOrgEx(origDc, &origin);
compatDc.savedState = SaveDC(compatDc.dc);
copyDcAttributes(compatDc, origDc, origin);
setClippingRegion(compatDc.dc, origDc, hwnd, isMenuWindow, origin);
compatDc.refCount = 1;
compatDc.origDc = origDc;
g_origDcToCompatDc.insert(CompatDcMap::value_type(origDc, compatDc));
return compatDc.dc;
}
Compat::ScopedCriticalSection gdiLock(CompatGdi::g_gdiCriticalSection);
auto it = g_origDcToCompatDc.find(origDc);
if (it != g_origDcToCompatDc.end())
HDC getOrigDc(HDC dc)
{
++it->second.refCount;
return it->second.dc;
const auto it = std::find_if(g_origDcToCompatDc.begin(), g_origDcToCompatDc.end(),
[dc](const CompatDcMap::value_type& compatDc) { return compatDc.second.dc == dc; });
return it != g_origDcToCompatDc.end() ? it->first : dc;
}
const HWND hwnd = CALL_ORIG_FUNC(WindowFromDC)(origDc);
const bool isMenuWindow = hwnd && 0x8000 == GetClassLongPtr(hwnd, GCW_ATOM);
if (isMenuWindow && !isMenuPaintDc)
void releaseDc(HDC origDc)
{
return nullptr;
}
Compat::ScopedCriticalSection gdiLock(Gdi::g_gdiCriticalSection);
CompatDc compatDc(CompatGdiDcCache::getDc());
if (!compatDc.dc)
{
return nullptr;
}
auto it = g_origDcToCompatDc.find(origDc);
if (it == g_origDcToCompatDc.end())
{
return;
}
POINT origin = {};
GetDCOrgEx(origDc, &origin);
compatDc.savedState = SaveDC(compatDc.dc);
copyDcAttributes(compatDc, origDc, origin);
setClippingRegion(compatDc.dc, origDc, hwnd, isMenuWindow, origin);
compatDc.refCount = 1;
compatDc.origDc = origDc;
g_origDcToCompatDc.insert(CompatDcMap::value_type(origDc, compatDc));
return compatDc.dc;
}
HDC getOrigDc(HDC dc)
{
const auto it = std::find_if(g_origDcToCompatDc.begin(), g_origDcToCompatDc.end(),
[dc](const CompatDcMap::value_type& compatDc) { return compatDc.second.dc == dc; });
return it != g_origDcToCompatDc.end() ? it->first : dc;
}
void releaseDc(HDC origDc)
{
Compat::ScopedCriticalSection gdiLock(CompatGdi::g_gdiCriticalSection);
auto it = g_origDcToCompatDc.find(origDc);
if (it == g_origDcToCompatDc.end())
{
return;
}
CompatDc& compatDc = it->second;
--compatDc.refCount;
if (0 == compatDc.refCount)
{
RestoreDC(compatDc.dc, compatDc.savedState);
CompatGdiDcCache::releaseDc(compatDc);
g_origDcToCompatDc.erase(origDc);
CompatDc& compatDc = it->second;
--compatDc.refCount;
if (0 == compatDc.refCount)
{
RestoreDC(compatDc.dc, compatDc.savedState);
Gdi::DcCache::releaseDc(compatDc);
g_origDcToCompatDc.erase(origDc);
}
}
}
}

15
DDrawCompat/Gdi/Dc.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
namespace Gdi
{
namespace Dc
{
HDC getDc(HDC origDc, bool isMenuPaintDc = false);
HDC getOrigDc(HDC dc);
void releaseDc(HDC origDc);
}
}

View File

@ -1,17 +1,17 @@
#include <cstring>
#include <vector>
#include "CompatGdiDcCache.h"
#include "CompatPrimarySurface.h"
#include "CompatPtr.h"
#include "Config.h"
#include "DDrawLog.h"
#include "DDrawProcs.h"
#include "DDrawRepository.h"
#include "Gdi/DcCache.h"
namespace
{
using CompatGdiDcCache::CachedDc;
using Gdi::DcCache::CachedDc;
std::vector<CachedDc> g_cache;
DWORD g_cacheSize = 0;
@ -117,108 +117,111 @@ namespace
}
}
namespace CompatGdiDcCache
namespace Gdi
{
void clear()
namespace DcCache
{
for (auto& cachedDc : g_cache)
void clear()
{
releaseCachedDc(cachedDc);
for (auto& cachedDc : g_cache)
{
releaseCachedDc(cachedDc);
}
g_cache.clear();
g_cacheSize = 0;
++g_cacheId;
}
g_cache.clear();
g_cacheSize = 0;
++g_cacheId;
}
CachedDc getDc()
{
CachedDc cachedDc = {};
if (!g_surfaceMemory)
CachedDc getDc()
{
CachedDc cachedDc = {};
if (!g_surfaceMemory)
{
return cachedDc;
}
if (g_cache.empty())
{
extendCache();
}
if (!g_cache.empty())
{
cachedDc = g_cache.back();
g_cache.pop_back();
const DWORD usedCacheSize = g_cacheSize - g_cache.size();
if (usedCacheSize > g_maxUsedCacheSize)
{
g_maxUsedCacheSize = usedCacheSize;
Compat::Log() << "GDI used DC cache size: " << g_maxUsedCacheSize;
}
}
return cachedDc;
}
if (g_cache.empty())
bool init()
{
extendCache();
auto dd(DDrawRepository::getDirectDraw());
dd->CreatePalette(dd,
DDPCAPS_8BIT | DDPCAPS_ALLOW256, g_paletteEntries, &g_palette.getRef(), nullptr);
return nullptr != g_palette;
}
if (!g_cache.empty())
void releaseDc(const CachedDc& cachedDc)
{
cachedDc = g_cache.back();
g_cache.pop_back();
const DWORD usedCacheSize = g_cacheSize - g_cache.size();
if (usedCacheSize > g_maxUsedCacheSize)
if (cachedDc.cacheId == g_cacheId)
{
g_maxUsedCacheSize = usedCacheSize;
Compat::Log() << "GDI used DC cache size: " << g_maxUsedCacheSize;
g_cache.push_back(cachedDc);
}
else
{
releaseCachedDc(cachedDc);
}
}
return cachedDc;
}
bool init()
{
auto dd(DDrawRepository::getDirectDraw());
dd->CreatePalette(dd,
DDPCAPS_8BIT | DDPCAPS_ALLOW256, g_paletteEntries, &g_palette.getRef(), nullptr);
return nullptr != g_palette;
}
void releaseDc(const CachedDc& cachedDc)
{
if (cachedDc.cacheId == g_cacheId)
void setDdLockThreadId(DWORD ddLockThreadId)
{
g_cache.push_back(cachedDc);
}
else
{
releaseCachedDc(cachedDc);
}
}
void setDdLockThreadId(DWORD ddLockThreadId)
{
g_ddLockThreadId = ddLockThreadId;
}
void setSurfaceMemory(void* surfaceMemory, LONG pitch)
{
if (g_surfaceMemory == surfaceMemory && g_pitch == pitch)
{
return;
g_ddLockThreadId = ddLockThreadId;
}
g_surfaceMemory = surfaceMemory;
g_pitch = pitch;
clear();
}
void updatePalette(DWORD startingEntry, DWORD count)
{
PALETTEENTRY entries[256] = {};
std::memcpy(&entries[startingEntry],
&CompatPrimarySurface::g_paletteEntries[startingEntry],
count * sizeof(PALETTEENTRY));
for (DWORD i = startingEntry; i < startingEntry + count; ++i)
void setSurfaceMemory(void* surfaceMemory, LONG pitch)
{
if (entries[i].peFlags & PC_RESERVED)
if (g_surfaceMemory == surfaceMemory && g_pitch == pitch)
{
entries[i] = CompatPrimarySurface::g_paletteEntries[0];
entries[i].peFlags = CompatPrimarySurface::g_paletteEntries[i].peFlags;
return;
}
}
if (0 != std::memcmp(&g_paletteEntries[startingEntry], &entries[startingEntry],
count * sizeof(PALETTEENTRY)))
{
std::memcpy(&g_paletteEntries[startingEntry], &entries[startingEntry],
count * sizeof(PALETTEENTRY));
g_palette->SetEntries(g_palette, 0, startingEntry, count, g_paletteEntries);
g_surfaceMemory = surfaceMemory;
g_pitch = pitch;
clear();
}
void updatePalette(DWORD startingEntry, DWORD count)
{
PALETTEENTRY entries[256] = {};
std::memcpy(&entries[startingEntry],
&CompatPrimarySurface::g_paletteEntries[startingEntry],
count * sizeof(PALETTEENTRY));
for (DWORD i = startingEntry; i < startingEntry + count; ++i)
{
if (entries[i].peFlags & PC_RESERVED)
{
entries[i] = CompatPrimarySurface::g_paletteEntries[0];
entries[i].peFlags = CompatPrimarySurface::g_paletteEntries[i].peFlags;
}
}
if (0 != std::memcmp(&g_paletteEntries[startingEntry], &entries[startingEntry],
count * sizeof(PALETTEENTRY)))
{
std::memcpy(&g_paletteEntries[startingEntry], &entries[startingEntry],
count * sizeof(PALETTEENTRY));
g_palette->SetEntries(g_palette, 0, startingEntry, count, g_paletteEntries);
clear();
}
}
}
}

30
DDrawCompat/Gdi/DcCache.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#define CINTERFACE
#define WIN32_LEAN_AND_MEAN
#include <ddraw.h>
#include <Windows.h>
#include "CompatWeakPtr.h"
namespace Gdi
{
namespace DcCache
{
struct CachedDc
{
CompatWeakPtr<IDirectDrawSurface7> surface;
HDC dc;
DWORD cacheId;
};
void clear();
CachedDc getDc();
bool init();
void releaseDc(const CachedDc& cachedDc);
void setDdLockThreadId(DWORD ddLockThreadId);
void setSurfaceMemory(void* surfaceMemory, LONG pitch);
void updatePalette(DWORD startingEntry, DWORD count);
}
}

View File

@ -1,10 +1,10 @@
#include <unordered_map>
#include "CompatDisplayMode.h"
#include "CompatGdi.h"
#include "CompatGdiDc.h"
#include "CompatGdiDcFunctions.h"
#include "DDrawLog.h"
#include "Gdi/Dc.h"
#include "Gdi/DcFunctions.h"
#include "Gdi/Gdi.h"
#include "Hook.h"
namespace
@ -45,7 +45,7 @@ namespace
HDC replaceDc(HDC dc)
{
HDC compatDc = CompatGdiDc::getDc(dc);
HDC compatDc = Gdi::Dc::getDc(dc);
return compatDc ? compatDc : dc;
}
@ -54,7 +54,7 @@ namespace
void releaseDc(HDC dc)
{
CompatGdiDc::releaseDc(dc);
Gdi::Dc::releaseDc(dc);
}
template <typename T, typename... Params>
@ -72,7 +72,7 @@ namespace
#endif
if (!hasDisplayDcArg(params...) ||
!CompatGdi::beginGdiRendering(getDdLockFlags<OrigFuncPtr, origFunc>(params...)))
!Gdi::beginGdiRendering(getDdLockFlags<OrigFuncPtr, origFunc>(params...)))
{
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...);
@ -81,7 +81,7 @@ namespace
{
Compat::Log() << "Skipping redirection since there is no display DC argument";
}
else if (!CompatGdi::isEmulationEnabled())
else if (!Gdi::isEmulationEnabled())
{
Compat::Log() << "Skipping redirection since GDI emulation is disabled";
}
@ -97,7 +97,7 @@ namespace
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(replaceDc(params)...);
releaseDc(params...);
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
#ifdef _DEBUG
Compat::LogLeave(g_funcNames[origFunc], params...) << result;
@ -205,7 +205,7 @@ namespace
HWND WINAPI windowFromDc(HDC dc)
{
return CALL_ORIG_FUNC(WindowFromDC)(CompatGdiDc::getOrigDc(dc));
return CALL_ORIG_FUNC(WindowFromDC)(Gdi::Dc::getOrigDc(dc));
}
}
@ -216,96 +216,99 @@ namespace
HOOK_GDI_DC_FUNCTION(module, func##A); \
HOOK_GDI_DC_FUNCTION(module, func##W)
namespace CompatGdiDcFunctions
namespace Gdi
{
void installHooks()
namespace DcFunctions
{
// Bitmap functions
HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend);
HOOK_GDI_DC_FUNCTION(gdi32, BitBlt);
HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, CompatDisplayMode::createCompatibleBitmap);
HOOK_FUNCTION(gdi32, CreateDIBitmap, CompatDisplayMode::createDIBitmap);
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, CompatDisplayMode::createDiscardableBitmap);
HOOK_GDI_DC_FUNCTION(gdi32, ExtFloodFill);
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
HOOK_GDI_DC_FUNCTION(gdi32, GdiTransparentBlt);
HOOK_GDI_DC_FUNCTION(gdi32, GetDIBits);
HOOK_GDI_DC_FUNCTION(gdi32, GetPixel);
HOOK_GDI_DC_FUNCTION(msimg32, GradientFill);
HOOK_GDI_DC_FUNCTION(gdi32, MaskBlt);
HOOK_GDI_DC_FUNCTION(gdi32, PlgBlt);
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBits);
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBitsToDevice);
HOOK_GDI_DC_FUNCTION(gdi32, SetPixel);
HOOK_GDI_DC_FUNCTION(gdi32, SetPixelV);
HOOK_GDI_DC_FUNCTION(gdi32, StretchBlt);
HOOK_GDI_DC_FUNCTION(gdi32, StretchDIBits);
HOOK_GDI_DC_FUNCTION(msimg32, TransparentBlt);
void installHooks()
{
// Bitmap functions
HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend);
HOOK_GDI_DC_FUNCTION(gdi32, BitBlt);
HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, CompatDisplayMode::createCompatibleBitmap);
HOOK_FUNCTION(gdi32, CreateDIBitmap, CompatDisplayMode::createDIBitmap);
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, CompatDisplayMode::createDiscardableBitmap);
HOOK_GDI_DC_FUNCTION(gdi32, ExtFloodFill);
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
HOOK_GDI_DC_FUNCTION(gdi32, GdiTransparentBlt);
HOOK_GDI_DC_FUNCTION(gdi32, GetDIBits);
HOOK_GDI_DC_FUNCTION(gdi32, GetPixel);
HOOK_GDI_DC_FUNCTION(msimg32, GradientFill);
HOOK_GDI_DC_FUNCTION(gdi32, MaskBlt);
HOOK_GDI_DC_FUNCTION(gdi32, PlgBlt);
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBits);
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBitsToDevice);
HOOK_GDI_DC_FUNCTION(gdi32, SetPixel);
HOOK_GDI_DC_FUNCTION(gdi32, SetPixelV);
HOOK_GDI_DC_FUNCTION(gdi32, StretchBlt);
HOOK_GDI_DC_FUNCTION(gdi32, StretchDIBits);
HOOK_GDI_DC_FUNCTION(msimg32, TransparentBlt);
// Brush functions
HOOK_GDI_DC_FUNCTION(gdi32, PatBlt);
// Brush functions
HOOK_GDI_DC_FUNCTION(gdi32, PatBlt);
// Device context functions
HOOK_GDI_DC_FUNCTION(gdi32, DrawEscape);
HOOK_FUNCTION(user32, WindowFromDC, windowFromDc);
// Device context functions
HOOK_GDI_DC_FUNCTION(gdi32, DrawEscape);
HOOK_FUNCTION(user32, WindowFromDC, windowFromDc);
// Filled shape functions
HOOK_GDI_DC_FUNCTION(gdi32, Chord);
HOOK_GDI_DC_FUNCTION(gdi32, Ellipse);
HOOK_GDI_DC_FUNCTION(user32, FillRect);
HOOK_GDI_DC_FUNCTION(user32, FrameRect);
HOOK_GDI_DC_FUNCTION(user32, InvertRect);
HOOK_GDI_DC_FUNCTION(gdi32, Pie);
HOOK_GDI_DC_FUNCTION(gdi32, Polygon);
HOOK_GDI_DC_FUNCTION(gdi32, PolyPolygon);
HOOK_GDI_DC_FUNCTION(gdi32, Rectangle);
HOOK_GDI_DC_FUNCTION(gdi32, RoundRect);
// Filled shape functions
HOOK_GDI_DC_FUNCTION(gdi32, Chord);
HOOK_GDI_DC_FUNCTION(gdi32, Ellipse);
HOOK_GDI_DC_FUNCTION(user32, FillRect);
HOOK_GDI_DC_FUNCTION(user32, FrameRect);
HOOK_GDI_DC_FUNCTION(user32, InvertRect);
HOOK_GDI_DC_FUNCTION(gdi32, Pie);
HOOK_GDI_DC_FUNCTION(gdi32, Polygon);
HOOK_GDI_DC_FUNCTION(gdi32, PolyPolygon);
HOOK_GDI_DC_FUNCTION(gdi32, Rectangle);
HOOK_GDI_DC_FUNCTION(gdi32, RoundRect);
// Font and text functions
HOOK_GDI_TEXT_DC_FUNCTION(user32, DrawText);
HOOK_GDI_TEXT_DC_FUNCTION(user32, DrawTextEx);
HOOK_GDI_TEXT_DC_FUNCTION(gdi32, ExtTextOut);
HOOK_GDI_TEXT_DC_FUNCTION(gdi32, PolyTextOut);
HOOK_GDI_TEXT_DC_FUNCTION(user32, TabbedTextOut);
HOOK_GDI_TEXT_DC_FUNCTION(gdi32, TextOut);
// Font and text functions
HOOK_GDI_TEXT_DC_FUNCTION(user32, DrawText);
HOOK_GDI_TEXT_DC_FUNCTION(user32, DrawTextEx);
HOOK_GDI_TEXT_DC_FUNCTION(gdi32, ExtTextOut);
HOOK_GDI_TEXT_DC_FUNCTION(gdi32, PolyTextOut);
HOOK_GDI_TEXT_DC_FUNCTION(user32, TabbedTextOut);
HOOK_GDI_TEXT_DC_FUNCTION(gdi32, TextOut);
// Icon functions
HOOK_GDI_DC_FUNCTION(user32, DrawIcon);
HOOK_GDI_DC_FUNCTION(user32, DrawIconEx);
// Icon functions
HOOK_GDI_DC_FUNCTION(user32, DrawIcon);
HOOK_GDI_DC_FUNCTION(user32, DrawIconEx);
// Line and curve functions
HOOK_GDI_DC_FUNCTION(gdi32, AngleArc);
HOOK_GDI_DC_FUNCTION(gdi32, Arc);
HOOK_GDI_DC_FUNCTION(gdi32, ArcTo);
HOOK_GDI_DC_FUNCTION(gdi32, LineTo);
HOOK_GDI_DC_FUNCTION(gdi32, PolyBezier);
HOOK_GDI_DC_FUNCTION(gdi32, PolyBezierTo);
HOOK_GDI_DC_FUNCTION(gdi32, PolyDraw);
HOOK_GDI_DC_FUNCTION(gdi32, Polyline);
HOOK_GDI_DC_FUNCTION(gdi32, PolylineTo);
HOOK_GDI_DC_FUNCTION(gdi32, PolyPolyline);
// Line and curve functions
HOOK_GDI_DC_FUNCTION(gdi32, AngleArc);
HOOK_GDI_DC_FUNCTION(gdi32, Arc);
HOOK_GDI_DC_FUNCTION(gdi32, ArcTo);
HOOK_GDI_DC_FUNCTION(gdi32, LineTo);
HOOK_GDI_DC_FUNCTION(gdi32, PolyBezier);
HOOK_GDI_DC_FUNCTION(gdi32, PolyBezierTo);
HOOK_GDI_DC_FUNCTION(gdi32, PolyDraw);
HOOK_GDI_DC_FUNCTION(gdi32, Polyline);
HOOK_GDI_DC_FUNCTION(gdi32, PolylineTo);
HOOK_GDI_DC_FUNCTION(gdi32, PolyPolyline);
// Painting and drawing functions
HOOK_GDI_DC_FUNCTION(user32, DrawCaption);
HOOK_GDI_DC_FUNCTION(user32, DrawEdge);
HOOK_GDI_DC_FUNCTION(user32, DrawFocusRect);
HOOK_GDI_DC_FUNCTION(user32, DrawFrameControl);
HOOK_GDI_TEXT_DC_FUNCTION(user32, DrawState);
HOOK_GDI_TEXT_DC_FUNCTION(user32, GrayString);
HOOK_GDI_DC_FUNCTION(user32, PaintDesktop);
// Painting and drawing functions
HOOK_GDI_DC_FUNCTION(user32, DrawCaption);
HOOK_GDI_DC_FUNCTION(user32, DrawEdge);
HOOK_GDI_DC_FUNCTION(user32, DrawFocusRect);
HOOK_GDI_DC_FUNCTION(user32, DrawFrameControl);
HOOK_GDI_TEXT_DC_FUNCTION(user32, DrawState);
HOOK_GDI_TEXT_DC_FUNCTION(user32, GrayString);
HOOK_GDI_DC_FUNCTION(user32, PaintDesktop);
// Region functions
HOOK_GDI_DC_FUNCTION(gdi32, FillRgn);
HOOK_GDI_DC_FUNCTION(gdi32, FrameRgn);
HOOK_GDI_DC_FUNCTION(gdi32, InvertRgn);
HOOK_GDI_DC_FUNCTION(gdi32, PaintRgn);
// Region functions
HOOK_GDI_DC_FUNCTION(gdi32, FillRgn);
HOOK_GDI_DC_FUNCTION(gdi32, FrameRgn);
HOOK_GDI_DC_FUNCTION(gdi32, InvertRgn);
HOOK_GDI_DC_FUNCTION(gdi32, PaintRgn);
// Scroll bar functions
HOOK_GDI_DC_FUNCTION(user32, ScrollDC);
// Scroll bar functions
HOOK_GDI_DC_FUNCTION(user32, ScrollDC);
// Undocumented functions
HOOK_GDI_DC_FUNCTION(gdi32, GdiDrawStream);
HOOK_GDI_DC_FUNCTION(gdi32, PolyPatBlt);
// Undocumented functions
HOOK_GDI_DC_FUNCTION(gdi32, GdiDrawStream);
HOOK_GDI_DC_FUNCTION(gdi32, PolyPatBlt);
}
}
}

View File

@ -0,0 +1,9 @@
#pragma once
namespace Gdi
{
namespace DcFunctions
{
void installHooks();
}
}

View File

@ -1,15 +1,15 @@
#include <atomic>
#include "CompatGdi.h"
#include "CompatGdiCaret.h"
#include "CompatGdiDcCache.h"
#include "CompatGdiDcFunctions.h"
#include "CompatGdiPaintHandlers.h"
#include "CompatGdiScrollFunctions.h"
#include "CompatGdiWinProc.h"
#include "CompatPaletteConverter.h"
#include "CompatPrimarySurface.h"
#include "DDrawProcs.h"
#include "Gdi/Caret.h"
#include "Gdi/DcCache.h"
#include "Gdi/DcFunctions.h"
#include "Gdi/Gdi.h"
#include "Gdi/PaintHandlers.h"
#include "Gdi/ScrollFunctions.h"
#include "Gdi/WinProc.h"
#include "RealPrimarySurface.h"
#include "ScopedCriticalSection.h"
@ -67,12 +67,12 @@ namespace
g_ddLockFlags = lockFlags;
if (0 != lockFlags)
{
EnterCriticalSection(&CompatGdi::g_gdiCriticalSection);
EnterCriticalSection(&Gdi::g_gdiCriticalSection);
}
g_ddLockThreadId = GetCurrentThreadId();
CompatGdiDcCache::setDdLockThreadId(g_ddLockThreadId);
CompatGdiDcCache::setSurfaceMemory(desc.lpSurface, desc.lPitch);
Gdi::DcCache::setDdLockThreadId(g_ddLockThreadId);
Gdi::DcCache::setSurfaceMemory(desc.lpSurface, desc.lPitch);
return true;
}
@ -89,7 +89,7 @@ namespace
if (0 != g_ddLockFlags)
{
LeaveCriticalSection(&CompatGdi::g_gdiCriticalSection);
LeaveCriticalSection(&Gdi::g_gdiCriticalSection);
}
g_ddLockFlags = 0;
@ -97,7 +97,7 @@ namespace
}
}
namespace CompatGdi
namespace Gdi
{
CRITICAL_SECTION g_gdiCriticalSection;
@ -192,7 +192,7 @@ namespace CompatGdi
void installHooks()
{
InitializeCriticalSection(&g_gdiCriticalSection);
if (CompatGdiDcCache::init())
if (Gdi::DcCache::init())
{
g_ddUnlockBeginEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
g_ddUnlockEndEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
@ -202,11 +202,11 @@ namespace CompatGdi
return;
}
CompatGdiDcFunctions::installHooks();
CompatGdiPaintHandlers::installHooks();
CompatGdiScrollFunctions::installHooks();
CompatGdiWinProc::installHooks();
CompatGdiCaret::installHooks();
Gdi::DcFunctions::installHooks();
Gdi::PaintHandlers::installHooks();
Gdi::ScrollFunctions::installHooks();
Gdi::WinProc::installHooks();
Gdi::Caret::installHooks();
}
}
@ -232,16 +232,16 @@ namespace CompatGdi
void uninstallHooks()
{
CompatGdiCaret::uninstallHooks();
CompatGdiWinProc::uninstallHooks();
CompatGdiPaintHandlers::uninstallHooks();
Gdi::Caret::uninstallHooks();
Gdi::WinProc::uninstallHooks();
Gdi::PaintHandlers::uninstallHooks();
}
void updatePalette(DWORD startingEntry, DWORD count)
{
if (isEmulationEnabled() && CompatPrimarySurface::g_palette)
{
CompatGdiDcCache::updatePalette(startingEntry, count);
Gdi::DcCache::updatePalette(startingEntry, count);
}
}
}

View File

@ -4,7 +4,7 @@
#include <Windows.h>
namespace CompatGdi
namespace Gdi
{
bool beginGdiRendering(DWORD lockFlags = 0);
void endGdiRendering();

View File

@ -1,12 +1,12 @@
#include "CompatGdi.h"
#include "CompatGdiDc.h"
#include "CompatGdiPaintHandlers.h"
#include "CompatGdiScrollBar.h"
#include "CompatGdiScrollFunctions.h"
#include "CompatGdiTitleBar.h"
#include "CompatPrimarySurface.h"
#include "CompatRegistry.h"
#include "DDrawLog.h"
#include "Gdi/Dc.h"
#include "Gdi/Gdi.h"
#include "Gdi/PaintHandlers.h"
#include "Gdi/ScrollBar.h"
#include "Gdi/ScrollFunctions.h"
#include "Gdi/TitleBar.h"
#include "Hook.h"
#include "RealPrimarySurface.h"
@ -117,7 +117,7 @@ namespace
LRESULT result = defPaintProc(hwnd, msg, wParam, lParam, g_origEditWndProc, "editWndProc");
if (0 == result && (WM_HSCROLL == msg || WM_VSCROLL == msg))
{
CompatGdiScrollFunctions::updateScrolledWindow(hwnd);
Gdi::ScrollFunctions::updateScrolledWindow(hwnd);
}
return result;
}
@ -157,17 +157,17 @@ namespace
LRESULT onEraseBackground(HWND hwnd, HDC dc, WNDPROC origWndProc)
{
if (!hwnd || !CompatGdi::beginGdiRendering())
if (!hwnd || !Gdi::beginGdiRendering())
{
return origWndProc(hwnd, WM_ERASEBKGND, reinterpret_cast<WPARAM>(dc), 0);
}
LRESULT result = 0;
HDC compatDc = CompatGdiDc::getDc(dc);
HDC compatDc = Gdi::Dc::getDc(dc);
if (compatDc)
{
result = origWndProc(hwnd, WM_ERASEBKGND, reinterpret_cast<WPARAM>(compatDc), 0);
CompatGdiDc::releaseDc(dc);
Gdi::Dc::releaseDc(dc);
if (result)
{
RealPrimarySurface::disableUpdates();
@ -178,7 +178,7 @@ namespace
result = origWndProc(hwnd, WM_ERASEBKGND, reinterpret_cast<WPARAM>(dc), 0);
}
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
if (result && compatDc)
{
@ -191,20 +191,20 @@ namespace
LRESULT onMenuPaint(HWND hwnd, WNDPROC origWndProc)
{
if (!hwnd || !CompatGdi::beginGdiRendering())
if (!hwnd || !Gdi::beginGdiRendering())
{
return origWndProc(hwnd, WM_PAINT, 0, 0);
}
HDC dc = GetWindowDC(hwnd);
const bool isMenuPaintDc = true;
HDC compatDc = CompatGdiDc::getDc(dc, isMenuPaintDc);
HDC compatDc = Gdi::Dc::getDc(dc, isMenuPaintDc);
if (compatDc)
{
origWndProc(hwnd, WM_PRINT, reinterpret_cast<WPARAM>(compatDc),
PRF_NONCLIENT | PRF_ERASEBKGND | PRF_CLIENT);
ValidateRect(hwnd, nullptr);
CompatGdiDc::releaseDc(dc);
Gdi::Dc::releaseDc(dc);
}
else
{
@ -212,55 +212,55 @@ namespace
}
ReleaseDC(hwnd, dc);
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
return 0;
}
LRESULT onNcPaint(HWND hwnd, WPARAM wParam, WNDPROC origWndProc)
{
if (!hwnd || !CompatGdi::beginGdiRendering())
if (!hwnd || !Gdi::beginGdiRendering())
{
return origWndProc(hwnd, WM_NCPAINT, wParam, 0);
}
HDC windowDc = GetWindowDC(hwnd);
HDC compatDc = CompatGdiDc::getDc(windowDc);
HDC compatDc = Gdi::Dc::getDc(windowDc);
if (compatDc)
{
CompatGdi::TitleBar titleBar(hwnd, compatDc);
Gdi::TitleBar titleBar(hwnd, compatDc);
titleBar.drawAll();
titleBar.excludeFromClipRegion();
CompatGdi::ScrollBar scrollBar(hwnd, compatDc);
Gdi::ScrollBar scrollBar(hwnd, compatDc);
scrollBar.drawAll();
scrollBar.excludeFromClipRegion();
SendMessage(hwnd, WM_PRINT, reinterpret_cast<WPARAM>(compatDc), PRF_NONCLIENT);
CompatGdiDc::releaseDc(windowDc);
Gdi::Dc::releaseDc(windowDc);
}
ReleaseDC(hwnd, windowDc);
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
return 0;
}
LRESULT onPaint(HWND hwnd, WNDPROC origWndProc)
{
if (!hwnd || !CompatGdi::beginGdiRendering())
if (!hwnd || !Gdi::beginGdiRendering())
{
return origWndProc(hwnd, WM_PAINT, 0, 0);
}
PAINTSTRUCT paint = {};
HDC dc = BeginPaint(hwnd, &paint);
HDC compatDc = CompatGdiDc::getDc(dc);
HDC compatDc = Gdi::Dc::getDc(dc);
if (compatDc)
{
origWndProc(hwnd, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(compatDc), PRF_CLIENT);
CompatGdiDc::releaseDc(dc);
Gdi::Dc::releaseDc(dc);
}
else
{
@ -269,30 +269,30 @@ namespace
EndPaint(hwnd, &paint);
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
return 0;
}
LRESULT onPrint(HWND hwnd, UINT msg, HDC dc, LONG flags, WNDPROC origWndProc)
{
if (!CompatGdi::beginGdiRendering())
if (!Gdi::beginGdiRendering())
{
return origWndProc(hwnd, msg, reinterpret_cast<WPARAM>(dc), flags);
}
LRESULT result = 0;
HDC compatDc = CompatGdiDc::getDc(dc);
HDC compatDc = Gdi::Dc::getDc(dc);
if (compatDc)
{
result = origWndProc(hwnd, msg, reinterpret_cast<WPARAM>(compatDc), flags);
CompatGdiDc::releaseDc(dc);
Gdi::Dc::releaseDc(dc);
}
else
{
result = origWndProc(hwnd, msg, reinterpret_cast<WPARAM>(dc), flags);
}
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
return result;
}
@ -325,30 +325,33 @@ namespace
}
}
namespace CompatGdiPaintHandlers
namespace Gdi
{
void installHooks()
namespace PaintHandlers
{
disableImmersiveContextMenus();
void installHooks()
{
disableImmersiveContextMenus();
CompatGdi::hookWndProc("ComboLBox", g_origComboListBoxWndProc, &comboListBoxWndProc);
CompatGdi::hookWndProc("Edit", g_origEditWndProc, &editWndProc);
CompatGdi::hookWndProc("ListBox", g_origListBoxWndProc, &listBoxWndProc);
CompatGdi::hookWndProc("#32768", g_origMenuWndProc, &menuWndProc);
CompatGdi::hookWndProc("ScrollBar", g_origScrollBarWndProc, &scrollBarWndProc);
Gdi::hookWndProc("ComboLBox", g_origComboListBoxWndProc, &comboListBoxWndProc);
Gdi::hookWndProc("Edit", g_origEditWndProc, &editWndProc);
Gdi::hookWndProc("ListBox", g_origListBoxWndProc, &listBoxWndProc);
Gdi::hookWndProc("#32768", g_origMenuWndProc, &menuWndProc);
Gdi::hookWndProc("ScrollBar", g_origScrollBarWndProc, &scrollBarWndProc);
HOOK_FUNCTION(user32, DefWindowProcA, defWindowProcA);
HOOK_FUNCTION(user32, DefWindowProcW, defWindowProcW);
HOOK_FUNCTION(user32, DefDlgProcA, defDlgProcA);
HOOK_FUNCTION(user32, DefDlgProcW, defDlgProcW);
}
HOOK_FUNCTION(user32, DefWindowProcA, defWindowProcA);
HOOK_FUNCTION(user32, DefWindowProcW, defWindowProcW);
HOOK_FUNCTION(user32, DefDlgProcA, defDlgProcA);
HOOK_FUNCTION(user32, DefDlgProcW, defDlgProcW);
}
void uninstallHooks()
{
CompatGdi::unhookWndProc("ComboLBox", g_origComboListBoxWndProc);
CompatGdi::unhookWndProc("Edit", g_origEditWndProc);
CompatGdi::unhookWndProc("ListBox", g_origListBoxWndProc);
CompatGdi::unhookWndProc("#32768", g_origMenuWndProc);
CompatGdi::unhookWndProc("ScrollBar", g_origScrollBarWndProc);
void uninstallHooks()
{
Gdi::unhookWndProc("ComboLBox", g_origComboListBoxWndProc);
Gdi::unhookWndProc("Edit", g_origEditWndProc);
Gdi::unhookWndProc("ListBox", g_origListBoxWndProc);
Gdi::unhookWndProc("#32768", g_origMenuWndProc);
Gdi::unhookWndProc("ScrollBar", g_origScrollBarWndProc);
}
}
}

View File

@ -0,0 +1,10 @@
#pragma once
namespace Gdi
{
namespace PaintHandlers
{
void installHooks();
void uninstallHooks();
}
}

View File

@ -1,5 +1,5 @@
#include "CompatGdi.h"
#include "CompatGdiScrollBar.h"
#include "Gdi/Gdi.h"
#include "Gdi/ScrollBar.h"
#include "Hook.h"
namespace
@ -15,7 +15,7 @@ namespace
};
}
namespace CompatGdi
namespace Gdi
{
ScrollBar::ScrollBar(HWND hwnd, HDC compatDc) :
m_hwnd(hwnd), m_compatDc(compatDc), m_windowRect(),

View File

@ -4,7 +4,7 @@
#include <Windows.h>
namespace CompatGdi
namespace Gdi
{
class ScrollBar
{

View File

@ -1,6 +1,6 @@
#include "CompatGdi.h"
#include "CompatGdiScrollFunctions.h"
#include "DDrawLog.h"
#include "Gdi/Gdi.h"
#include "Gdi/ScrollFunctions.h"
#include "Hook.h"
#include "RealPrimarySurface.h"
@ -13,7 +13,7 @@ namespace
BOOL result = CALL_ORIG_FUNC(ScrollWindow)(hWnd, XAmount, YAmount, lpRect, lpClipRect);
if (result)
{
CompatGdiScrollFunctions::updateScrolledWindow(hWnd);
Gdi::ScrollFunctions::updateScrolledWindow(hWnd);
}
Compat::LogLeave("scrollWindow", hWnd, XAmount, YAmount, lpRect, lpClipRect) << result;
return result;
@ -34,7 +34,7 @@ namespace
hWnd, dx, dy, prcScroll, prcClip, hrgnUpdate, prcUpdate, flags);
if (ERROR != result)
{
CompatGdiScrollFunctions::updateScrolledWindow(hWnd);
Gdi::ScrollFunctions::updateScrolledWindow(hWnd);
}
Compat::LogLeave("scrollWindowEx",
@ -43,22 +43,25 @@ namespace
}
}
namespace CompatGdiScrollFunctions
namespace Gdi
{
void installHooks()
namespace ScrollFunctions
{
HOOK_FUNCTION(user32, ScrollWindow, scrollWindow);
HOOK_FUNCTION(user32, ScrollWindowEx, scrollWindowEx);
}
void updateScrolledWindow(HWND hwnd)
{
if (CompatGdi::isEmulationEnabled())
void installHooks()
{
RealPrimarySurface::disableUpdates();
RedrawWindow(hwnd, nullptr, nullptr,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW);
RealPrimarySurface::enableUpdates();
HOOK_FUNCTION(user32, ScrollWindow, scrollWindow);
HOOK_FUNCTION(user32, ScrollWindowEx, scrollWindowEx);
}
void updateScrolledWindow(HWND hwnd)
{
if (Gdi::isEmulationEnabled())
{
RealPrimarySurface::disableUpdates();
RedrawWindow(hwnd, nullptr, nullptr,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW);
RealPrimarySurface::enableUpdates();
}
}
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
namespace Gdi
{
namespace ScrollFunctions
{
void installHooks();
void updateScrolledWindow(HWND hwnd);
}
}

View File

@ -1,6 +1,6 @@
#include "CompatGdi.h"
#include "CompatGdiTitleBar.h"
#include "CompatPrimarySurface.h"
#include "Gdi/Gdi.h"
#include "Gdi/TitleBar.h"
#include "Hook.h"
namespace
@ -15,7 +15,7 @@ namespace
};
}
namespace CompatGdi
namespace Gdi
{
TitleBar::TitleBar(HWND hwnd, HDC compatDc) :
m_hwnd(hwnd), m_compatDc(compatDc), m_buttonWidth(0), m_buttonHeight(0), m_tbi(),

View File

@ -6,7 +6,7 @@
#include <Windows.h>
namespace CompatGdi
namespace Gdi
{
class TitleBar
{

View File

@ -5,13 +5,13 @@
#include <dwmapi.h>
#include <Windows.h>
#include "CompatGdi.h"
#include "CompatGdiDc.h"
#include "CompatGdiScrollBar.h"
#include "CompatGdiScrollFunctions.h"
#include "CompatGdiTitleBar.h"
#include "CompatGdiWinProc.h"
#include "DDrawLog.h"
#include "Gdi/Dc.h"
#include "Gdi/Gdi.h"
#include "Gdi/ScrollBar.h"
#include "Gdi/ScrollFunctions.h"
#include "Gdi/TitleBar.h"
#include "Gdi/WinProc.h"
#include "ScopedCriticalSection.h"
namespace
@ -40,7 +40,7 @@ namespace
}
else if (WM_DESTROY == ret->message)
{
Compat::ScopedCriticalSection lock(CompatGdi::g_gdiCriticalSection);
Compat::ScopedCriticalSection lock(Gdi::g_gdiCriticalSection);
g_prevWindowRect.erase(ret->hwnd);
}
else if (WM_WINDOWPOSCHANGED == ret->message)
@ -56,7 +56,7 @@ namespace
auto notifCode = HIWORD(ret->wParam);
if (ret->lParam && (EN_HSCROLL == notifCode || EN_VSCROLL == notifCode))
{
CompatGdiScrollFunctions::updateScrolledWindow(reinterpret_cast<HWND>(ret->lParam));
Gdi::ScrollFunctions::updateScrolledWindow(reinterpret_cast<HWND>(ret->lParam));
}
}
else if (WM_MENUSELECT == ret->message)
@ -92,38 +92,38 @@ namespace
{
if (OBJID_TITLEBAR == idObject || OBJID_HSCROLL == idObject || OBJID_VSCROLL == idObject)
{
if (!hwnd || !CompatGdi::beginGdiRendering())
if (!hwnd || !Gdi::beginGdiRendering())
{
return;
}
HDC windowDc = GetWindowDC(hwnd);
HDC compatDc = CompatGdiDc::getDc(windowDc);
HDC compatDc = Gdi::Dc::getDc(windowDc);
if (compatDc)
{
if (OBJID_TITLEBAR == idObject)
{
CompatGdi::TitleBar(hwnd, compatDc).drawButtons();
Gdi::TitleBar(hwnd, compatDc).drawButtons();
}
else if (OBJID_HSCROLL == idObject)
{
CompatGdi::ScrollBar(hwnd, compatDc).drawHorizArrows();
Gdi::ScrollBar(hwnd, compatDc).drawHorizArrows();
}
else if (OBJID_VSCROLL == idObject)
{
CompatGdi::ScrollBar(hwnd, compatDc).drawVertArrows();
Gdi::ScrollBar(hwnd, compatDc).drawVertArrows();
}
CompatGdiDc::releaseDc(windowDc);
Gdi::Dc::releaseDc(windowDc);
}
ReleaseDC(hwnd, windowDc);
CompatGdi::endGdiRendering();
Gdi::endGdiRendering();
}
}
void onActivate(HWND hwnd)
{
if (!CompatGdi::isEmulationEnabled())
if (!Gdi::isEmulationEnabled())
{
return;
}
@ -146,7 +146,7 @@ namespace
void onMenuSelect()
{
if (!CompatGdi::isEmulationEnabled())
if (!Gdi::isEmulationEnabled())
{
return;
}
@ -161,17 +161,17 @@ namespace
void onWindowPosChanged(HWND hwnd)
{
Compat::ScopedCriticalSection lock(CompatGdi::g_gdiCriticalSection);
Compat::ScopedCriticalSection lock(Gdi::g_gdiCriticalSection);
const auto it = g_prevWindowRect.find(hwnd);
if (it != g_prevWindowRect.end())
{
CompatGdi::invalidate(&it->second);
Gdi::invalidate(&it->second);
}
if (IsWindowVisible(hwnd))
{
if (CompatGdi::isEmulationEnabled())
if (Gdi::isEmulationEnabled())
{
GetWindowRect(hwnd, it != g_prevWindowRect.end() ? &it->second : &g_prevWindowRect[hwnd]);
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
@ -193,19 +193,22 @@ namespace
}
}
namespace CompatGdiWinProc
namespace Gdi
{
void installHooks()
namespace WinProc
{
const DWORD threadId = GetCurrentThreadId();
g_callWndRetProcHook = SetWindowsHookEx(WH_CALLWNDPROCRET, callWndRetProc, nullptr, threadId);
g_objectStateChangeEventHook = SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE,
nullptr, &objectStateChangeEvent, 0, threadId, WINEVENT_OUTOFCONTEXT);
}
void installHooks()
{
const DWORD threadId = GetCurrentThreadId();
g_callWndRetProcHook = SetWindowsHookEx(WH_CALLWNDPROCRET, callWndRetProc, nullptr, threadId);
g_objectStateChangeEventHook = SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE,
nullptr, &objectStateChangeEvent, 0, threadId, WINEVENT_OUTOFCONTEXT);
}
void uninstallHooks()
{
UnhookWinEvent(g_objectStateChangeEventHook);
UnhookWindowsHookEx(g_callWndRetProcHook);
void uninstallHooks()
{
UnhookWinEvent(g_objectStateChangeEventHook);
UnhookWindowsHookEx(g_callWndRetProcHook);
}
}
}

10
DDrawCompat/Gdi/WinProc.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
namespace Gdi
{
namespace WinProc
{
void installHooks();
void uninstallHooks();
}
}

View File

@ -1,7 +1,6 @@
#include <atomic>
#include "CompatDirectDrawSurface.h"
#include "CompatGdi.h"
#include "CompatPaletteConverter.h"
#include "CompatPrimarySurface.h"
#include "CompatPtr.h"
@ -9,6 +8,7 @@
#include "DDrawScopedThreadLock.h"
#include "DDrawProcs.h"
#include "DDrawTypes.h"
#include "Gdi/Gdi.h"
#include "Hook.h"
#include "IReleaseNotifier.h"
#include "RealPrimarySurface.h"
@ -375,7 +375,7 @@ void RealPrimarySurface::update()
void RealPrimarySurface::updatePalette(DWORD startingEntry, DWORD count)
{
CompatPaletteConverter::updatePalette(startingEntry, count);
CompatGdi::updatePalette(startingEntry, count);
Gdi::updatePalette(startingEntry, count);
if (CompatPrimarySurface::g_palette)
{
invalidate(nullptr);