mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Fixed various multi-monitor display issues
This commit is contained in:
parent
727be63db1
commit
291a9c2f9a
@ -81,9 +81,9 @@ namespace D3dDdi
|
||||
return g_ddiVersion;
|
||||
}
|
||||
|
||||
void installHooks()
|
||||
void installHooks(HMODULE origDDrawModule)
|
||||
{
|
||||
KernelModeThunks::installHooks();
|
||||
KernelModeThunks::installHooks(origDDrawModule);
|
||||
}
|
||||
|
||||
void onUmdFileNameQueried(const std::wstring& umdFileName)
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace D3dDdi
|
||||
{
|
||||
UINT getDdiVersion();
|
||||
void installHooks();
|
||||
void installHooks(HMODULE origDDrawModule);
|
||||
void onUmdFileNameQueried(const std::wstring& umdFileName);
|
||||
void uninstallHooks();
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
@ -34,6 +35,7 @@ namespace
|
||||
std::map<D3DKMT_HANDLE, ContextInfo> g_contexts;
|
||||
AdapterInfo g_gdiAdapterInfo = {};
|
||||
AdapterInfo g_lastOpenAdapterInfo = {};
|
||||
std::string g_lastDDrawCreateDcDevice;
|
||||
UINT g_lastFlipInterval = 0;
|
||||
UINT g_flipIntervalOverride = 0;
|
||||
D3DKMT_HANDLE g_lastPresentContext = 0;
|
||||
@ -108,6 +110,13 @@ namespace
|
||||
return LOG_RESULT(result);
|
||||
}
|
||||
|
||||
HDC WINAPI ddrawCreateDcA(LPCSTR pwszDriver, LPCSTR pwszDevice, LPCSTR pszPort, const DEVMODEA* pdm)
|
||||
{
|
||||
LOG_FUNC("ddrawCreateDCA", pwszDriver, pwszDevice, pszPort, pdm);
|
||||
g_lastDDrawCreateDcDevice = pwszDevice ? pwszDevice : std::string();
|
||||
return LOG_RESULT(CALL_ORIG_FUNC(CreateDCA)(pwszDriver, pwszDevice, pszPort, pdm));
|
||||
}
|
||||
|
||||
NTSTATUS APIENTRY destroyContext(const D3DKMT_DESTROYCONTEXT* pData)
|
||||
{
|
||||
LOG_FUNC("D3DKMTDestroyContext", pData);
|
||||
@ -123,18 +132,35 @@ namespace
|
||||
return LOG_RESULT(result);
|
||||
}
|
||||
|
||||
BOOL CALLBACK findDDrawMonitorRect(HMONITOR hMonitor, HDC /*hdcMonitor*/, LPRECT /*lprcMonitor*/, LPARAM dwData)
|
||||
{
|
||||
MONITORINFOEX mi = {};
|
||||
mi.cbSize = sizeof(mi);
|
||||
GetMonitorInfo(hMonitor, &mi);
|
||||
if (g_lastDDrawCreateDcDevice == mi.szDevice)
|
||||
{
|
||||
*reinterpret_cast<RECT*>(dwData) = mi.rcMonitor;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
AdapterInfo getAdapterInfo(const D3DKMT_OPENADAPTERFROMHDC& data)
|
||||
{
|
||||
AdapterInfo adapterInfo = {};
|
||||
adapterInfo.adapter = data.hAdapter;
|
||||
adapterInfo.vidPnSourceId = data.VidPnSourceId;
|
||||
|
||||
POINT p = {};
|
||||
GetDCOrgEx(data.hDc, &p);
|
||||
MONITORINFO mi = {};
|
||||
mi.cbSize = sizeof(mi);
|
||||
GetMonitorInfo(MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY), &mi);
|
||||
adapterInfo.monitorRect = mi.rcMonitor;
|
||||
EnumDisplayMonitors(nullptr, nullptr, findDDrawMonitorRect,
|
||||
reinterpret_cast<LPARAM>(&adapterInfo.monitorRect));
|
||||
|
||||
if (IsRectEmpty(&adapterInfo.monitorRect))
|
||||
{
|
||||
MONITORINFO mi = {};
|
||||
mi.cbSize = sizeof(mi);
|
||||
GetMonitorInfo(MonitorFromPoint({}, MONITOR_DEFAULTTOPRIMARY), &mi);
|
||||
adapterInfo.monitorRect = mi.rcMonitor;
|
||||
}
|
||||
|
||||
return adapterInfo;
|
||||
}
|
||||
@ -282,7 +308,7 @@ namespace D3dDdi
|
||||
{
|
||||
lastDisplaySettingsUniqueness = currentDisplaySettingsUniqueness;
|
||||
CompatPtr<IUnknown> ddUnk;
|
||||
primary->GetDDInterface(primary, reinterpret_cast<void**>(&ddUnk.getRef()));
|
||||
primary.get()->lpVtbl->GetDDInterface(primary, reinterpret_cast<void**>(&ddUnk.getRef()));
|
||||
CompatPtr<IDirectDraw7> dd7(ddUnk);
|
||||
|
||||
DDDEVICEIDENTIFIER2 di = {};
|
||||
@ -297,7 +323,7 @@ namespace D3dDdi
|
||||
return g_qpcLastVerticalBlank;
|
||||
}
|
||||
|
||||
void installHooks()
|
||||
void installHooks(HMODULE origDDrawModule)
|
||||
{
|
||||
HOOK_FUNCTION(gdi32, D3DKMTCloseAdapter, closeAdapter);
|
||||
HOOK_FUNCTION(gdi32, D3DKMTCreateContext, createContext);
|
||||
@ -308,6 +334,7 @@ namespace D3dDdi
|
||||
HOOK_FUNCTION(gdi32, D3DKMTQueryAdapterInfo, queryAdapterInfo);
|
||||
HOOK_FUNCTION(gdi32, D3DKMTPresent, present);
|
||||
HOOK_FUNCTION(gdi32, D3DKMTSetQueuedLimit, setQueuedLimit);
|
||||
Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "CreateDCA", ddrawCreateDcA);
|
||||
|
||||
// Functions not available in Windows Vista
|
||||
Compat::hookFunction("gdi32", "D3DKMTCreateContextVirtual",
|
||||
|
@ -13,7 +13,7 @@ namespace D3dDdi
|
||||
UINT getLastSubmittedFrameCount();
|
||||
RECT getMonitorRect();
|
||||
long long getQpcLastVerticalBlank();
|
||||
void installHooks();
|
||||
void installHooks(HMODULE origDDrawModule);
|
||||
void setFlipIntervalOverride(UINT flipInterval);
|
||||
void waitForVerticalBlank();
|
||||
}
|
||||
|
@ -28,22 +28,6 @@ namespace
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface7> createCompatibleSurface(DWORD bpp)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
desc.dwWidth = 1;
|
||||
desc.dwHeight = 1;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
desc.ddpfPixelFormat = getRgbPixelFormat(bpp);
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
auto dd = DDraw::Repository::getDirectDraw();
|
||||
dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
void* getDdObject(TDirectDraw& dd)
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "Common/CompatPtr.h"
|
||||
#include "Common/CompatRef.h"
|
||||
#include "Common/CompatVtable.h"
|
||||
#include "DDraw/Visitors/DirectDrawVtblVisitor.h"
|
||||
@ -10,8 +9,6 @@
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface7> createCompatibleSurface(DWORD bpp);
|
||||
|
||||
template <typename TDirectDraw>
|
||||
void* getDdObject(TDirectDraw& dd);
|
||||
|
||||
|
@ -2,8 +2,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CompatRef.h"
|
||||
#include "D3dDdi/KernelModeThunks.h"
|
||||
#include "DDraw/DirectDrawClipper.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Gdi/Region.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -28,9 +30,16 @@ namespace
|
||||
void updateWindowClipList(CompatRef<IDirectDrawClipper> clipper, ClipperData& data)
|
||||
{
|
||||
HDC dc = GetDC(data.hwnd);
|
||||
HRGN rgn = CreateRectRgn(0, 0, 0, 0);
|
||||
|
||||
Gdi::Region rgn;
|
||||
GetRandomRgn(dc, rgn, SYSRGN);
|
||||
CALL_ORIG_FUNC(ReleaseDC)(data.hwnd, dc);
|
||||
|
||||
RECT primaryRect = D3dDdi::KernelModeThunks::getMonitorRect();
|
||||
if (0 != primaryRect.left || 0 != primaryRect.top)
|
||||
{
|
||||
rgn.offset(-primaryRect.left, -primaryRect.top);
|
||||
}
|
||||
|
||||
DWORD rgnSize = GetRegionData(rgn, 0, nullptr);
|
||||
std::vector<unsigned char> rgnData(rgnSize);
|
||||
GetRegionData(rgn, rgnSize, reinterpret_cast<RGNDATA*>(rgnData.data()));
|
||||
@ -40,9 +49,6 @@ namespace
|
||||
{
|
||||
clipper->SetHWnd(&clipper, 0, data.hwnd);
|
||||
}
|
||||
|
||||
DeleteObject(rgn);
|
||||
CALL_ORIG_FUNC(ReleaseDC)(data.hwnd, dc);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetHWnd(IDirectDrawClipper* This, HWND* lphWnd)
|
||||
@ -115,6 +121,24 @@ namespace
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
HRGN DirectDrawClipper::getClipRgn(CompatRef<IDirectDrawClipper> clipper)
|
||||
{
|
||||
std::vector<unsigned char> rgnData;
|
||||
DWORD size = 0;
|
||||
clipper->GetClipList(&clipper, nullptr, nullptr, &size);
|
||||
rgnData.resize(size);
|
||||
clipper->GetClipList(&clipper, nullptr, reinterpret_cast<RGNDATA*>(rgnData.data()), &size);
|
||||
return ExtCreateRegion(nullptr, size, reinterpret_cast<RGNDATA*>(rgnData.data()));
|
||||
}
|
||||
|
||||
HRESULT DirectDrawClipper::setClipRgn(CompatRef<IDirectDrawClipper> clipper, HRGN rgn)
|
||||
{
|
||||
std::vector<unsigned char> rgnData;
|
||||
rgnData.resize(GetRegionData(rgn, 0, nullptr));
|
||||
GetRegionData(rgn, rgnData.size(), reinterpret_cast<RGNDATA*>(rgnData.data()));
|
||||
return clipper->SetClipList(&clipper, reinterpret_cast<RGNDATA*>(rgnData.data()), 0);
|
||||
}
|
||||
|
||||
void DirectDrawClipper::setCompatVtable(IDirectDrawClipperVtbl& vtable)
|
||||
{
|
||||
vtable.GetHWnd = &GetHWnd;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CompatRef.h"
|
||||
#include "Common/CompatVtable.h"
|
||||
#include "DDraw/Visitors/DirectDrawClipperVtblVisitor.h"
|
||||
|
||||
@ -8,6 +9,9 @@ namespace DDraw
|
||||
class DirectDrawClipper : public CompatVtable<IDirectDrawClipperVtbl>
|
||||
{
|
||||
public:
|
||||
static HRGN getClipRgn(CompatRef<IDirectDrawClipper> clipper);
|
||||
static HRESULT setClipRgn(CompatRef<IDirectDrawClipper> clipper, HRGN rgn);
|
||||
|
||||
static void setCompatVtable(IDirectDrawClipperVtbl& vtable);
|
||||
};
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace
|
||||
HRESULT STDMETHODCALLTYPE callImpl(TSurface* This, Params... params)
|
||||
{
|
||||
DDraw::Surface* surface = This ? DDraw::Surface::getSurface(*This) : nullptr;
|
||||
if (!surface)
|
||||
if (!surface || !(surface->getImpl<TSurface>()))
|
||||
{
|
||||
return (CompatVtable<Vtable<TSurface>>::s_origVtable.*origMethod)(This, params...);
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ namespace
|
||||
void bltToWindowViaGdi(Gdi::Region* primaryRegion)
|
||||
{
|
||||
std::unique_ptr<HDC__, void(*)(HDC)> virtualScreenDc(nullptr, &Gdi::VirtualScreen::deleteDc);
|
||||
RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds();
|
||||
|
||||
for (auto windowPair : Gdi::Window::getWindows())
|
||||
{
|
||||
@ -110,12 +111,14 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
Gdi::GdiAccessGuard gdiAccessGuard(Gdi::ACCESS_READ);
|
||||
Gdi::GdiAccessGuard gdiAccessGuard(Gdi::ACCESS_READ, !primaryRegion);
|
||||
HWND presentationWindow = windowPair.second->getPresentationWindow();
|
||||
HDC dc = GetWindowDC(presentationWindow);
|
||||
RECT rect = windowPair.second->getWindowRect();
|
||||
CALL_ORIG_FUNC(BitBlt)(dc, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
|
||||
virtualScreenDc.get(), rect.left, rect.top, SRCCOPY);
|
||||
visibleRegion.offset(-rect.left, -rect.top);
|
||||
SelectClipRgn(dc, visibleRegion);
|
||||
CALL_ORIG_FUNC(BitBlt)(dc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, virtualScreenDc.get(),
|
||||
rect.left - virtualScreenBounds.left, rect.top - virtualScreenBounds.top, SRCCOPY);
|
||||
CALL_ORIG_FUNC(ReleaseDC)(presentationWindow, dc);
|
||||
}
|
||||
}
|
||||
@ -138,6 +141,7 @@ namespace
|
||||
|
||||
HDC backBufferDc = nullptr;
|
||||
backBuffer->GetDC(backBuffer, &backBufferDc);
|
||||
RECT ddrawMonitorRect = D3dDdi::KernelModeThunks::getMonitorRect();
|
||||
|
||||
for (auto it = visibleLayeredWindows.rbegin(); it != visibleLayeredWindows.rend(); ++it)
|
||||
{
|
||||
@ -145,6 +149,12 @@ namespace
|
||||
HRGN rgn = Gdi::getVisibleWindowRgn(*it);
|
||||
RECT wr = {};
|
||||
GetWindowRect(*it, &wr);
|
||||
|
||||
if (0 != ddrawMonitorRect.left || 0 != ddrawMonitorRect.top)
|
||||
{
|
||||
OffsetRect(&wr, -ddrawMonitorRect.left, -ddrawMonitorRect.top);
|
||||
OffsetRgn(rgn, -ddrawMonitorRect.left, -ddrawMonitorRect.top);
|
||||
}
|
||||
|
||||
SelectClipRgn(backBufferDc, rgn);
|
||||
CALL_ORIG_FUNC(BitBlt)(backBufferDc, wr.left, wr.top, wr.right - wr.left, wr.bottom - wr.top,
|
||||
|
@ -1,12 +1,69 @@
|
||||
#include "Common/CompatPtr.h"
|
||||
#include "D3dDdi/KernelModeThunks.h"
|
||||
#include "DDraw/DirectDrawClipper.h"
|
||||
#include "DDraw/DirectDrawPalette.h"
|
||||
#include "DDraw/DirectDrawSurface.h"
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
|
||||
#include "Dll/Procs.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Gdi/Region.h"
|
||||
#include "Gdi/VirtualScreen.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename TSurface>
|
||||
void bltToGdi(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
||||
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
|
||||
{
|
||||
if (!lpDestRect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawClipper> clipper;
|
||||
CompatVtable<Vtable<TSurface>>::s_origVtable.GetClipper(This, &clipper.getRef());
|
||||
if (!clipper)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Gdi::Region clipRgn(DDraw::DirectDrawClipper::getClipRgn(*clipper));
|
||||
RECT monitorRect = D3dDdi::KernelModeThunks::getMonitorRect();
|
||||
RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds();
|
||||
clipRgn.offset(monitorRect.left, monitorRect.top);
|
||||
clipRgn &= virtualScreenBounds;
|
||||
clipRgn -= monitorRect;
|
||||
if (clipRgn.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto gdiSurface(Gdi::VirtualScreen::createSurface(virtualScreenBounds));
|
||||
if (!gdiSurface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawClipper> gdiClipper;
|
||||
CALL_ORIG_PROC(DirectDrawCreateClipper, 0, &gdiClipper.getRef(), nullptr);
|
||||
if (!gdiClipper)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RECT dstRect = *lpDestRect;
|
||||
OffsetRect(&dstRect, monitorRect.left - virtualScreenBounds.left, monitorRect.top - virtualScreenBounds.top);
|
||||
clipRgn.offset(-virtualScreenBounds.left, -virtualScreenBounds.top);
|
||||
DDraw::DirectDrawClipper::setClipRgn(*gdiClipper, clipRgn);
|
||||
|
||||
auto srcSurface(CompatPtr<IDirectDrawSurface7>::from(lpDDSrcSurface));
|
||||
gdiSurface->SetClipper(gdiSurface, gdiClipper);
|
||||
gdiSurface->Blt(gdiSurface, &dstRect, srcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||
gdiSurface->SetClipper(gdiSurface, nullptr);
|
||||
}
|
||||
|
||||
void restorePrimaryCaps(DWORD& caps)
|
||||
{
|
||||
caps &= ~DDSCAPS_OFFSCREENPLAIN;
|
||||
@ -41,6 +98,7 @@ namespace DDraw
|
||||
HRESULT result = m_impl.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
bltToGdi(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||
RealPrimarySurface::update();
|
||||
}
|
||||
return result;
|
||||
|
@ -122,7 +122,7 @@ namespace DDraw
|
||||
privateData.get(), sizeof(privateData.get()), DDSPD_IUNKNOWNPOINTER)))
|
||||
{
|
||||
CompatPtr<IUnknown> dd;
|
||||
dds->GetDDInterface(&dds, reinterpret_cast<void**>(&dd.getRef()));
|
||||
dds.get().lpVtbl->GetDDInterface(&dds, reinterpret_cast<void**>(&dd.getRef()));
|
||||
|
||||
privateData->createImpl();
|
||||
privateData->m_impl->m_data = privateData.get();
|
||||
|
@ -39,7 +39,7 @@ namespace
|
||||
Compat::Log() << "Installing registry hooks";
|
||||
Win32::Registry::installHooks();
|
||||
Compat::Log() << "Installing Direct3D driver hooks";
|
||||
D3dDdi::installHooks();
|
||||
D3dDdi::installHooks(g_origDDrawModule);
|
||||
Compat::Log() << "Installing display mode hooks";
|
||||
Win32::DisplayMode::installHooks(g_origDDrawModule);
|
||||
Gdi::VirtualScreen::init();
|
||||
|
@ -111,13 +111,15 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void setClippingRegion(const CompatDc& compatDc, std::shared_ptr<Gdi::Window> rootWindow, const POINT& origin)
|
||||
void setClippingRegion(const CompatDc& compatDc, std::shared_ptr<Gdi::Window> rootWindow,
|
||||
const POINT& origin, const RECT& virtualScreenBounds)
|
||||
{
|
||||
if (rootWindow)
|
||||
{
|
||||
Gdi::Region sysRgn;
|
||||
CALL_ORIG_FUNC(GetRandomRgn)(compatDc.origDc, sysRgn, SYSRGN);
|
||||
sysRgn &= rootWindow->getVisibleRegion();
|
||||
OffsetRgn(sysRgn, -virtualScreenBounds.left, -virtualScreenBounds.top);
|
||||
SelectClipRgn(compatDc.dc, sysRgn);
|
||||
}
|
||||
else
|
||||
@ -206,15 +208,18 @@ namespace Gdi
|
||||
POINT origin = {};
|
||||
GetDCOrgEx(origDc, &origin);
|
||||
RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds();
|
||||
origin.x -= virtualScreenBounds.left;
|
||||
origin.y -= virtualScreenBounds.top;
|
||||
if (wnd && GetDesktopWindow() != wnd)
|
||||
{
|
||||
origin.x -= virtualScreenBounds.left;
|
||||
origin.y -= virtualScreenBounds.top;
|
||||
}
|
||||
|
||||
compatDc.refCount = 1;
|
||||
compatDc.origDc = origDc;
|
||||
compatDc.threadId = GetCurrentThreadId();
|
||||
compatDc.savedState = useMetaRgn ? SaveDC(compatDc.dc) : 0;
|
||||
copyDcAttributes(compatDc, origDc, origin);
|
||||
setClippingRegion(compatDc, rootWindow, origin);
|
||||
setClippingRegion(compatDc, rootWindow, origin, virtualScreenBounds);
|
||||
|
||||
g_origDcToCompatDc.insert(CompatDcMap::value_type(origDc, compatDc));
|
||||
|
||||
|
@ -14,6 +14,11 @@ namespace
|
||||
|
||||
namespace Gdi
|
||||
{
|
||||
Region::Region(HRGN rgn)
|
||||
: m_region(rgn)
|
||||
{
|
||||
}
|
||||
|
||||
Region::Region(const RECT& rect)
|
||||
: m_region(CreateRectRgnIndirect(&rect))
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ namespace Gdi
|
||||
class Region
|
||||
{
|
||||
public:
|
||||
Region(HRGN rgn);
|
||||
Region(const RECT& rect = RECT{ 0, 0, 0, 0 });
|
||||
~Region();
|
||||
Region(const Region& other);
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include "Common/Hook.h"
|
||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Gdi/Region.h"
|
||||
#include "Gdi/TitleBar.h"
|
||||
#include "Gdi/VirtualScreen.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -101,11 +103,11 @@ namespace Gdi
|
||||
flags |= DC_GRADIENT;
|
||||
}
|
||||
|
||||
RECT virtualScreenBounds = VirtualScreen::getBounds();
|
||||
RECT clipRect = m_tbi.rcTitleBar;
|
||||
OffsetRect(&clipRect, m_windowRect.left, m_windowRect.top);
|
||||
HRGN clipRgn = CreateRectRgnIndirect(&clipRect);
|
||||
OffsetRect(&clipRect, m_windowRect.left - virtualScreenBounds.left, m_windowRect.top - virtualScreenBounds.top);
|
||||
Region clipRgn(clipRect);
|
||||
SelectClipRgn(m_compatDc, clipRgn);
|
||||
DeleteObject(clipRgn);
|
||||
|
||||
RECT textRect = m_tbi.rcTitleBar;
|
||||
if (m_hasIcon)
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include <set>
|
||||
|
||||
#include "DDraw/DirectDraw.h"
|
||||
#include "DDraw/Repository.h"
|
||||
#include "DDraw/ScopedThreadLock.h"
|
||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Gdi/Region.h"
|
||||
#include "Gdi/VirtualScreen.h"
|
||||
@ -134,8 +134,12 @@ namespace Gdi
|
||||
(rect.top - g_bounds.top) * g_pitch +
|
||||
(rect.left - g_bounds.left) * g_bpp / 8;
|
||||
|
||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||
CompatPtr<IUnknown> ddUnk;
|
||||
primary.get()->lpVtbl->GetDDInterface(primary, reinterpret_cast<void**>(&ddUnk.getRef()));
|
||||
CompatPtr<IDirectDraw7> dd(ddUnk);
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
auto dd(DDraw::Repository::getDirectDraw());
|
||||
dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user