2020-03-04 10:49:10 +01:00
|
|
|
#include "util_monitor.h"
|
2020-03-04 11:15:10 +01:00
|
|
|
#include "util_string.h"
|
2020-03-04 10:49:10 +01:00
|
|
|
|
|
|
|
#include "./log/log.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
HMONITOR GetDefaultMonitor() {
|
|
|
|
return ::MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-04 11:15:10 +01:00
|
|
|
BOOL SetMonitorDisplayMode(
|
|
|
|
HMONITOR hMonitor,
|
|
|
|
DEVMODEW* pMode) {
|
|
|
|
::MONITORINFOEXW monInfo;
|
|
|
|
monInfo.cbSize = sizeof(monInfo);
|
|
|
|
|
|
|
|
if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
|
|
|
|
Logger::err("Failed to query monitor info");
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger::info(str::format("Setting display mode: ",
|
|
|
|
pMode->dmPelsWidth, "x", pMode->dmPelsHeight, "@",
|
|
|
|
pMode->dmDisplayFrequency));
|
|
|
|
|
2020-03-04 11:41:55 +01:00
|
|
|
DEVMODEW curMode = { };
|
|
|
|
curMode.dmSize = sizeof(curMode);
|
|
|
|
|
|
|
|
if (GetMonitorDisplayMode(hMonitor, ENUM_CURRENT_SETTINGS, &curMode)) {
|
|
|
|
bool eq = curMode.dmPelsWidth == pMode->dmPelsWidth
|
|
|
|
&& curMode.dmPelsHeight == pMode->dmPelsHeight
|
|
|
|
&& curMode.dmBitsPerPel == pMode->dmBitsPerPel;
|
|
|
|
|
|
|
|
if (pMode->dmFields & DM_DISPLAYFREQUENCY)
|
|
|
|
eq &= curMode.dmDisplayFrequency == pMode->dmDisplayFrequency;
|
|
|
|
|
|
|
|
if (eq)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-03-04 11:15:10 +01:00
|
|
|
LONG status = ::ChangeDisplaySettingsExW(monInfo.szDevice,
|
|
|
|
pMode, nullptr, CDS_FULLSCREEN, nullptr);
|
|
|
|
|
|
|
|
if (status != DISP_CHANGE_SUCCESSFUL) {
|
|
|
|
pMode->dmFields &= ~DM_DISPLAYFREQUENCY;
|
|
|
|
|
|
|
|
status = ::ChangeDisplaySettingsExW(monInfo.szDevice,
|
|
|
|
pMode, nullptr, CDS_FULLSCREEN, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
return status == DISP_CHANGE_SUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL GetMonitorDisplayMode(
|
|
|
|
HMONITOR hMonitor,
|
|
|
|
DWORD modeNum,
|
|
|
|
DEVMODEW* pMode) {
|
|
|
|
::MONITORINFOEXW monInfo;
|
|
|
|
monInfo.cbSize = sizeof(monInfo);
|
|
|
|
|
|
|
|
if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
|
|
|
|
Logger::err("Failed to query monitor info");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ::EnumDisplaySettingsW(monInfo.szDevice, modeNum, pMode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-31 17:01:59 +02:00
|
|
|
BOOL CALLBACK RestoreMonitorDisplayModeCallback(
|
|
|
|
HMONITOR hMonitor,
|
|
|
|
HDC hDC,
|
|
|
|
LPRECT pRect,
|
|
|
|
LPARAM pUserdata) {
|
|
|
|
auto success = reinterpret_cast<bool*>(pUserdata);
|
|
|
|
|
2020-03-04 11:15:10 +01:00
|
|
|
DEVMODEW devMode = { };
|
|
|
|
devMode.dmSize = sizeof(devMode);
|
|
|
|
|
2021-05-31 17:01:59 +02:00
|
|
|
if (!GetMonitorDisplayMode(hMonitor, ENUM_REGISTRY_SETTINGS, &devMode)) {
|
|
|
|
*success = false;
|
2020-03-04 11:15:10 +01:00
|
|
|
return false;
|
2021-05-31 17:01:59 +02:00
|
|
|
}
|
2020-03-04 11:15:10 +01:00
|
|
|
|
|
|
|
Logger::info(str::format("Restoring display mode: ",
|
|
|
|
devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@",
|
|
|
|
devMode.dmDisplayFrequency));
|
|
|
|
|
2021-05-31 17:01:59 +02:00
|
|
|
if (!SetMonitorDisplayMode(hMonitor, &devMode)) {
|
|
|
|
*success = false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL RestoreMonitorDisplayMode() {
|
|
|
|
bool success = true;
|
|
|
|
bool result = ::EnumDisplayMonitors(nullptr, nullptr,
|
|
|
|
&RestoreMonitorDisplayModeCallback,
|
|
|
|
reinterpret_cast<LPARAM>(&success));
|
|
|
|
|
|
|
|
return result && success;
|
2020-03-04 11:15:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-04 10:49:10 +01:00
|
|
|
void GetWindowClientSize(
|
|
|
|
HWND hWnd,
|
|
|
|
UINT* pWidth,
|
|
|
|
UINT* pHeight) {
|
|
|
|
RECT rect = { };
|
|
|
|
::GetClientRect(hWnd, &rect);
|
|
|
|
|
|
|
|
if (pWidth)
|
|
|
|
*pWidth = rect.right - rect.left;
|
|
|
|
|
|
|
|
if (pHeight)
|
|
|
|
*pHeight = rect.bottom - rect.top;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GetMonitorClientSize(
|
|
|
|
HMONITOR hMonitor,
|
|
|
|
UINT* pWidth,
|
|
|
|
UINT* pHeight) {
|
|
|
|
::MONITORINFOEXW monInfo;
|
|
|
|
monInfo.cbSize = sizeof(monInfo);
|
|
|
|
|
|
|
|
if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
|
|
|
|
Logger::err("Failed to query monitor info");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto rect = monInfo.rcMonitor;
|
|
|
|
|
|
|
|
if (pWidth)
|
|
|
|
*pWidth = rect.right - rect.left;
|
|
|
|
|
|
|
|
if (pHeight)
|
|
|
|
*pHeight = rect.bottom - rect.top;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GetMonitorRect(
|
|
|
|
HMONITOR hMonitor,
|
|
|
|
RECT* pRect) {
|
|
|
|
::MONITORINFOEXW monInfo;
|
|
|
|
monInfo.cbSize = sizeof(monInfo);
|
|
|
|
|
|
|
|
if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
|
|
|
|
Logger::err("Failed to query monitor info");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pRect = monInfo.rcMonitor;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|