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

Added DpiAwareness setting

This commit is contained in:
narzoul 2022-06-04 19:51:55 +02:00
parent fa99142587
commit 96ad1d6ab6
10 changed files with 127 additions and 23 deletions

View File

@ -13,6 +13,7 @@ namespace Config
Settings::DisplayFilter displayFilter;
Settings::DisplayRefreshRate displayRefreshRate;
Settings::DisplayResolution displayResolution;
Settings::DpiAwareness dpiAwareness;
Settings::ForceD3D9On12 forceD3D9On12;
Settings::FullscreenMode fullscreenMode;
Settings::LogLevel logLevel;

View File

@ -11,6 +11,7 @@
#include <Config/Settings/DisplayFilter.h>
#include <Config/Settings/DisplayRefreshRate.h>
#include <Config/Settings/DisplayResolution.h>
#include <Config/Settings/DpiAwareness.h>
#include <Config/Settings/ForceD3D9On12.h>
#include <Config/Settings/FullscreenMode.h>
#include <Config/Settings/LogLevel.h>
@ -39,6 +40,7 @@ namespace Config
extern Settings::DisplayFilter displayFilter;
extern Settings::DisplayRefreshRate displayRefreshRate;
extern Settings::DisplayResolution displayResolution;
extern Settings::DpiAwareness dpiAwareness;
extern Settings::ForceD3D9On12 forceD3D9On12;
extern Settings::FullscreenMode fullscreenMode;
extern Settings::LogLevel logLevel;

View File

@ -50,6 +50,18 @@ namespace Config
throw ParsingError("MappedSetting::getValueStr(): value not found in mapping");
}
std::string convertToString(Value value)
{
for (const auto& pair : m_valueMapping)
{
if (pair.second == value)
{
return pair.first;
}
}
return {};
}
protected:
MappedSetting(const std::string& name, const std::string& default,
const std::vector<std::pair<std::string, Value>>& valueMapping)

View File

@ -0,0 +1,25 @@
#pragma once
#include <Config/MappedSetting.h>
namespace Config
{
namespace Settings
{
class DpiAwareness : public MappedSetting<DPI_AWARENESS_CONTEXT>
{
public:
DpiAwareness()
: MappedSetting("DpiAwareness", "permonitor", {
{"app", nullptr},
{"unaware", DPI_AWARENESS_CONTEXT_UNAWARE},
{"system", DPI_AWARENESS_CONTEXT_SYSTEM_AWARE},
{"permonitor", DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE},
{"permonitorv2", DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2},
{"gdiscaled", DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED}
})
{
}
};
}
}

View File

@ -528,6 +528,7 @@ namespace D3dDdi
void Resource::createGdiLockResource()
{
LOG_FUNC("Resource::createGdiLockResource");
auto gdiSurfaceDesc(Gdi::VirtualScreen::getSurfaceDesc(DDraw::PrimarySurface::getMonitorRect()));
if (!gdiSurfaceDesc.lpSurface)
{

View File

@ -222,18 +222,6 @@ namespace DDraw
g_primarySurface = m_surface;
g_gdiResourceHandle = DirectDrawSurface::getRuntimeResourceHandle(*g_primarySurface);
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
m_surface->GetSurfaceDesc(m_surface, &desc);
if (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
{
DDSURFACEDESC2 gdiDesc = Gdi::VirtualScreen::getSurfaceDesc(g_monitorRect);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE;
desc.lPitch = gdiDesc.lPitch;
desc.lpSurface = gdiDesc.lpSurface;
m_surface->SetSurfaceDesc(m_surface, &desc, 0);
}
updateFrontResource();
D3dDdi::Device::setGdiResourceHandle(g_frontResource);

View File

@ -169,6 +169,7 @@
<ClInclude Include="Config\Settings\DisplayFilter.h" />
<ClInclude Include="Config\Settings\DisplayRefreshRate.h" />
<ClInclude Include="Config\Settings\DisplayResolution.h" />
<ClInclude Include="Config\Settings\DpiAwareness.h" />
<ClInclude Include="Config\Settings\ForceD3D9On12.h" />
<ClInclude Include="Config\Settings\FullscreenMode.h" />
<ClInclude Include="Config\Settings\LogLevel.h" />

View File

@ -573,6 +573,9 @@
<ClInclude Include="Config\Settings\AlignSysMemSurfaces.h">
<Filter>Header Files\Config\Settings</Filter>
</ClInclude>
<ClInclude Include="Config\Settings\DpiAwareness.h">
<Filter>Header Files\Config\Settings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">

View File

@ -131,6 +131,12 @@ namespace
(!Compat::isEqual(currentDllPath, dciman32DllPath) && GetModuleHandleW(dciman32DllPath.c_str()));
}
void logDpiAwareness(bool isSuccessful, DPI_AWARENESS_CONTEXT dpiAwareness, const char* funcName)
{
LOG_INFO << (isSuccessful ? "DPI awareness was successfully changed" : "Failed to change process DPI awareness")
<< " to \"" << Config::dpiAwareness.convertToString(dpiAwareness) << "\" via " << funcName;
}
void onDirectDrawCreate(GUID* lpGUID, LPDIRECTDRAW* lplpDD, IUnknown* /*pUnkOuter*/)
{
return DDraw::DirectDraw::onCreate(lpGUID, *CompatPtr<IDirectDraw7>::from(*lplpDD));
@ -148,17 +154,67 @@ namespace
void setDpiAwareness()
{
HMODULE shcore = LoadLibrary("shcore");
if (shcore)
auto dpiAwareness = Config::dpiAwareness.get();
if (!dpiAwareness)
{
auto setProcessDpiAwareness = reinterpret_cast<decltype(&SetProcessDpiAwareness)>(
Compat::getProcAddress(shcore, "SetProcessDpiAwareness"));
if (setProcessDpiAwareness && SUCCEEDED(setProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)))
{
return;
}
return;
}
SetProcessDPIAware();
HMODULE user32 = LoadLibrary("user32");
auto isValidDpiAwarenessContext = reinterpret_cast<decltype(&IsValidDpiAwarenessContext)>(
Compat::getProcAddress(user32, "IsValidDpiAwarenessContext"));
auto setProcessDpiAwarenessContext = reinterpret_cast<decltype(&SetProcessDpiAwarenessContext)>(
Compat::getProcAddress(user32, "SetProcessDpiAwarenessContext"));
if (isValidDpiAwarenessContext && setProcessDpiAwarenessContext)
{
if (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 == dpiAwareness &&
!isValidDpiAwarenessContext(dpiAwareness))
{
dpiAwareness = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE;
}
if (DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED == dpiAwareness &&
!isValidDpiAwarenessContext(dpiAwareness))
{
dpiAwareness = DPI_AWARENESS_CONTEXT_UNAWARE;
}
logDpiAwareness(setProcessDpiAwarenessContext(dpiAwareness), dpiAwareness, "SetProcessDpiAwarenessContext");
return;
}
auto setProcessDpiAwareness = reinterpret_cast<decltype(&SetProcessDpiAwareness)>(
Compat::getProcAddress(LoadLibrary("shcore"), "SetProcessDpiAwareness"));
if (setProcessDpiAwareness)
{
HRESULT result = S_OK;
if (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE == dpiAwareness ||
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 == dpiAwareness)
{
dpiAwareness = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE;
result = setProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
}
else if (DPI_AWARENESS_CONTEXT_SYSTEM_AWARE == dpiAwareness)
{
result = setProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE);
}
else
{
dpiAwareness = DPI_AWARENESS_CONTEXT_UNAWARE;
result = setProcessDpiAwareness(PROCESS_DPI_UNAWARE);
}
logDpiAwareness(SUCCEEDED(result), dpiAwareness, "SetProcessDpiAwareness");
return;
}
if (DPI_AWARENESS_CONTEXT_UNAWARE == dpiAwareness ||
DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED == dpiAwareness)
{
LOG_INFO << "DPI awareness was not changed";
}
logDpiAwareness(SetProcessDPIAware(), DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, "SetProcessDPIAware");
}
}

View File

@ -38,10 +38,25 @@ namespace
std::map<HDC, VirtualScreenDc> g_dcs;
BOOL CALLBACK addMonitorRectToRegion(
HMONITOR /*hMonitor*/, HDC /*hdcMonitor*/, LPRECT lprcMonitor, LPARAM dwData)
HMONITOR hMonitor, HDC /*hdcMonitor*/, LPRECT lprcMonitor, LPARAM dwData)
{
MONITORINFOEX mi = {};
mi.cbSize = sizeof(mi);
CALL_ORIG_FUNC(GetMonitorInfoA)(hMonitor, &mi);
DEVMODE dm = {};
dm.dmSize = sizeof(dm);
CALL_ORIG_FUNC(EnumDisplaySettingsExA)(mi.szDevice, ENUM_CURRENT_SETTINGS, &dm, 0);
RECT rect = *lprcMonitor;
if (0 != dm.dmPelsWidth && 0 != dm.dmPelsHeight)
{
rect.right = rect.left + dm.dmPelsWidth;
rect.bottom = rect.top + dm.dmPelsHeight;
}
Gdi::Region& virtualScreenRegion = *reinterpret_cast<Gdi::Region*>(dwData);
Gdi::Region monitorRegion(*lprcMonitor);
Gdi::Region monitorRegion(rect);
virtualScreenRegion |= monitorRegion;
return TRUE;
}