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

Set overlay window positions based on the real primary surface

This commit is contained in:
narzoul 2022-11-27 13:40:46 +01:00
parent 483bf5f6dd
commit 9068a8d9a6
7 changed files with 55 additions and 42 deletions

View File

@ -1235,7 +1235,8 @@ namespace D3dDdi
if (!IsRectEmpty(&g_presentationRect))
{
presentLayeredWindows(*rt, rtIndex, rtRect);
presentLayeredWindows(*rt, rtIndex, rtRect,
Gdi::Window::getVisibleLayeredWindows(), DDraw::PrimarySurface::getMonitorRect());
}
const auto cursorInfo = Gdi::Cursor::getEmulatedCursorInfo();
@ -1289,15 +1290,23 @@ namespace D3dDdi
}
clearRectExterior(data.DstSubResourceIndex, data.DstRect);
if (!IsRectEmpty(&g_presentationRect))
{
auto dstRect = DDraw::RealPrimarySurface::getMonitorRect();
OffsetRect(&dstRect, -dstRect.left, -dstRect.top);
presentLayeredWindows(*this, data.DstSubResourceIndex, dstRect,
Gdi::Window::getVisibleOverlayWindows(), dstRect);
}
return LOG_RESULT(S_OK);
}
void Resource::presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect)
void Resource::presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect,
std::vector<Gdi::Window::LayeredWindow> layeredWindows, const RECT& monitorRect)
{
auto& blitter = m_device.getShaderBlitter();
auto& repo = SurfaceRepository::get(m_device.getAdapter());
RECT monitorRect = DDraw::PrimarySurface::getMonitorRect();
auto layeredWindows(Gdi::Window::getVisibleLayeredWindows());
for (auto& layeredWindow : layeredWindows)
{
@ -1325,7 +1334,7 @@ namespace D3dDdi
ReleaseDC(layeredWindow.hwnd, srcDc);
copySubResourceRegion(*texture.resource, 0, srcRect, *windowSurface.resource, 0, srcRect);
texture.resource->notifyLock(0);
windowSurface.resource->notifyLock(0);
DeviceState::ShaderConstF ck = {};
COLORREF colorKey = 0;

View File

@ -9,6 +9,7 @@
#include <D3dDdi/FormatInfo.h>
#include <D3dDdi/ResourceDeleter.h>
#include <D3dDdi/SurfaceRepository.h>
#include <Gdi/Window.h>
namespace D3dDdi
{
@ -116,7 +117,8 @@ namespace D3dDdi
void loadSysMemResource(UINT subResourceIndex);
void loadVidMemResource(UINT subResourceIndex);
void notifyLock(UINT subResourceIndex);
void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect);
void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect,
std::vector<Gdi::Window::LayeredWindow> layeredWindows, const RECT& monitorRect);
void resolveMsaaDepthBuffer();
HRESULT shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource);
bool shouldBltViaCpu(const D3DDDIARG_BLT &data, Resource& srcResource);

View File

@ -152,13 +152,6 @@ namespace
CALL_ORIG_FUNC(ReleaseDC)(hwnd, windowDc);
}
void presentOverlayWindow(CompatWeakPtr<IDirectDrawSurface7> dst, HWND hwnd, const RECT& monitorRect, HDC& dstDc)
{
RECT wr = {};
GetWindowRect(hwnd, &wr);
presentLayeredWindow(dst, hwnd, wr, monitorRect, dstDc);
}
void updatePosition(Window& window, const RECT& oldWindowRect, const RECT& oldClientRect,
const Gdi::Region& oldVisibleRegion, Gdi::Region& invalidatedRegion)
{
@ -394,7 +387,12 @@ namespace Gdi
layeredWindows.push_back({ window.hwnd, window.windowRect, window.visibleRegion });
}
}
return layeredWindows;
}
std::vector<LayeredWindow> getVisibleOverlayWindows()
{
std::vector<LayeredWindow> layeredWindows;
RECT wr = {};
auto statsWindow = GuiThread::getStatsWindow();
if (statsWindow && statsWindow->isVisible())

View File

@ -19,6 +19,7 @@ namespace Gdi
HWND getPresentationWindow(HWND hwnd);
std::vector<LayeredWindow> getVisibleLayeredWindows();
std::vector<LayeredWindow> getVisibleOverlayWindows();
bool hasFullscreenWindow();
bool isTopLevelWindow(HWND hwnd);
void onStyleChanged(HWND hwnd, WPARAM wParam);

View File

@ -12,6 +12,7 @@
#include <Gdi/GuiThread.h>
#include <Gdi/PresentationWindow.h>
#include <Input/Input.h>
#include <Overlay/ConfigWindow.h>
#include <Overlay/Window.h>
namespace
@ -46,7 +47,10 @@ namespace
BeginPaint(hwnd, &ps);
HDC dc = CreateCompatibleDC(nullptr);
HGDIOBJ origBmp = SelectObject(dc, g_bmpArrow);
CALL_ORIG_FUNC(BitBlt)(ps.hdc, 0, 0, g_bmpArrowSize.cx, g_bmpArrowSize.cy, dc, 0, 0, SRCCOPY);
RECT wr = {};
GetWindowRect(hwnd, &wr);
CALL_ORIG_FUNC(StretchBlt)(ps.hdc, 0, 0, wr.right - wr.left, wr.bottom - wr.top,
dc, 0, 0, g_bmpArrowSize.cx, g_bmpArrowSize.cy, SRCCOPY);
SelectObject(dc, origBmp);
DeleteDC(dc);
EndPaint(hwnd, &ps);
@ -275,7 +279,7 @@ namespace Input
MONITORINFO mi = {};
mi.cbSize = sizeof(mi);
GetMonitorInfo(MonitorFromWindow(window->getWindow(), MONITOR_DEFAULTTOPRIMARY), &mi);
CALL_ORIG_FUNC(GetMonitorInfoA)(MonitorFromWindow(window->getWindow(), MONITOR_DEFAULTTOPRIMARY), &mi);
g_monitorRect = mi.rcMonitor;
if (!g_mouseHook)
@ -306,9 +310,13 @@ namespace Input
{
Gdi::GuiThread::execute([]()
{
CALL_ORIG_FUNC(SetWindowPos)(g_cursorWindow, DDraw::RealPrimarySurface::getTopmost(),
g_cursorPos.x, g_cursorPos.y, g_bmpArrowSize.cx, g_bmpArrowSize.cy,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING);
if (g_cursorWindow)
{
auto scaleFactor = Gdi::GuiThread::getConfigWindow()->getScaleFactor();
CALL_ORIG_FUNC(SetWindowPos)(g_cursorWindow, DDraw::RealPrimarySurface::getTopmost(),
g_cursorPos.x, g_cursorPos.y, g_bmpArrowSize.cx * scaleFactor, g_bmpArrowSize.cy * scaleFactor,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
}
});
}
}

View File

@ -14,7 +14,6 @@
#include <Input/Input.h>
#include <Overlay/Control.h>
#include <Overlay/Window.h>
#include <Win32/DisplayMode.h>
namespace
{
@ -181,32 +180,28 @@ namespace Overlay
void Window::updatePos()
{
auto monitorRect = Win32::DisplayMode::getEmulatedDisplayMode().rect;
RECT monitorRect = DDraw::RealPrimarySurface::getMonitorRect();
if (IsRectEmpty(&monitorRect))
{
monitorRect = DDraw::PrimarySurface::getMonitorRect();
HMONITOR monitor = nullptr;
HWND foregroundWindow = GetForegroundWindow();
if (foregroundWindow)
{
monitor = MonitorFromWindow(foregroundWindow, MONITOR_DEFAULTTONEAREST);
}
else
{
monitor = MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY);
}
MONITORINFO mi = {};
mi.cbSize = sizeof(mi);
CALL_ORIG_FUNC(GetMonitorInfoA)(monitor, &mi);
monitorRect = mi.rcMonitor;
if (IsRectEmpty(&monitorRect))
{
HMONITOR monitor = nullptr;
HWND foregroundWindow = GetForegroundWindow();
if (foregroundWindow)
{
monitor = MonitorFromWindow(foregroundWindow, MONITOR_DEFAULTTONEAREST);
}
else
{
monitor = MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY);
}
MONITORINFO mi = {};
mi.cbSize = sizeof(mi);
CALL_ORIG_FUNC(GetMonitorInfoA)(monitor, &mi);
monitorRect = mi.rcMonitor;
if (IsRectEmpty(&monitorRect))
{
monitorRect = { 0, 0, m_rect.right - m_rect.left, m_rect.bottom - m_rect.top };
}
monitorRect = { 0, 0, m_rect.right - m_rect.left, m_rect.bottom - m_rect.top };
}
}

View File

@ -696,7 +696,7 @@ namespace
{
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
if (GetCurrentProcessId() == pid && !Gdi::GuiThread::isGuiThreadWindow(hwnd))
if (GetCurrentProcessId() == pid)
{
SendNotifyMessage(hwnd, WM_DISPLAYCHANGE, 0, lParam);
}