mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 00:31:31 +00:00
[idd] config: reload persisted display modes
Rebuild the driver's cached mode list before replugging the monitor so Windows enumerates the settings saved by the helper. Keep saved mode refresh rates intact and update only ExtraMode to the configured default refresh.
This commit is contained in:
@@ -635,6 +635,39 @@ void CIndirectDeviceContext::ReplugMonitor()
|
|||||||
m_finishInitQueued.store(1);
|
m_finishInitQueued.store(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIndirectDeviceContext::ReloadSettings()
|
||||||
|
{
|
||||||
|
bool modesLoaded = false;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&m_modeReloadLock);
|
||||||
|
|
||||||
|
CSettings::DisplayMode extraMode;
|
||||||
|
if (g_settings.GetExtraMode(extraMode))
|
||||||
|
{
|
||||||
|
const unsigned refresh = g_settings.GetDefaultRefresh();
|
||||||
|
if (extraMode.refresh != refresh)
|
||||||
|
{
|
||||||
|
extraMode.refresh = refresh;
|
||||||
|
if (!g_settings.SetExtraMode(extraMode))
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&m_modeReloadLock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modesLoaded = PopulateDefaultModes();
|
||||||
|
ReleaseSRWLockExclusive(&m_modeReloadLock);
|
||||||
|
|
||||||
|
if (!modesLoaded)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to reload the display mode list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplugMonitor();
|
||||||
|
}
|
||||||
|
|
||||||
void CIndirectDeviceContext::OnMonitorDestroyed(IDDCX_MONITOR monitor)
|
void CIndirectDeviceContext::OnMonitorDestroyed(IDDCX_MONITOR monitor)
|
||||||
{
|
{
|
||||||
AcquireSRWLockExclusive(&m_stateLock);
|
AcquireSRWLockExclusive(&m_stateLock);
|
||||||
@@ -936,19 +969,23 @@ void CIndirectDeviceContext::SetResolution(uint32_t width, uint32_t height)
|
|||||||
mode.refresh = g_settings.GetDefaultRefresh();
|
mode.refresh = g_settings.GetDefaultRefresh();
|
||||||
mode.preferred = true;
|
mode.preferred = true;
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_stateLock);
|
bool modesLoaded = false;
|
||||||
m_setMode = mode;
|
AcquireSRWLockExclusive(&m_modeReloadLock);
|
||||||
m_doSetMode = true;
|
if (g_settings.SetExtraMode(mode))
|
||||||
ReleaseSRWLockExclusive(&m_stateLock);
|
modesLoaded = PopulateDefaultModes();
|
||||||
|
ReleaseSRWLockExclusive(&m_modeReloadLock);
|
||||||
|
|
||||||
g_settings.SetExtraMode(mode);
|
if (!modesLoaded)
|
||||||
|
|
||||||
if (!PopulateDefaultModes())
|
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to rebuild the display mode list");
|
DEBUG_ERROR("Failed to rebuild the display mode list");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&m_stateLock);
|
||||||
|
m_setMode = mode;
|
||||||
|
m_doSetMode = true;
|
||||||
|
ReleaseSRWLockExclusive(&m_stateLock);
|
||||||
|
|
||||||
// IddCxMonitorUpdateModes[2] does not invalidate Windows' cached mode list,
|
// IddCxMonitorUpdateModes[2] does not invalidate Windows' cached mode list,
|
||||||
// so the only reliable way to apply a new mode is to depart and re-arrive the
|
// so the only reliable way to apply a new mode is to depart and re-arrive the
|
||||||
// monitor, forcing Windows to rebuild the topology from the new mode list.
|
// monitor, forcing Windows to rebuild the topology from the new mode list.
|
||||||
|
|||||||
@@ -215,6 +215,11 @@ private:
|
|||||||
// Never held across an IddCx API call - snapshot then call.
|
// Never held across an IddCx API call - snapshot then call.
|
||||||
mutable SRWLOCK m_modeLock = SRWLOCK_INIT;
|
mutable SRWLOCK m_modeLock = SRWLOCK_INIT;
|
||||||
|
|
||||||
|
// Serializes registry-backed mode changes with rebuilding m_displayModes.
|
||||||
|
// Reload requests arrive on the pipe thread while dynamic resolution
|
||||||
|
// requests arrive on the LGMP timer thread.
|
||||||
|
SRWLOCK m_modeReloadLock = SRWLOCK_INIT;
|
||||||
|
|
||||||
CSettings::DisplayModes m_displayModes;
|
CSettings::DisplayModes m_displayModes;
|
||||||
CEdid m_edid;
|
CEdid m_edid;
|
||||||
|
|
||||||
@@ -238,6 +243,7 @@ public:
|
|||||||
void InitAdapter();
|
void InitAdapter();
|
||||||
void FinishAdapterInit(UINT connectorIndex);
|
void FinishAdapterInit(UINT connectorIndex);
|
||||||
void FinishInit(UINT connectorIndex);
|
void FinishInit(UINT connectorIndex);
|
||||||
|
void ReloadSettings();
|
||||||
void ReplugMonitor();
|
void ReplugMonitor();
|
||||||
|
|
||||||
void OnMonitorDestroyed(IDDCX_MONITOR monitor);
|
void OnMonitorDestroyed(IDDCX_MONITOR monitor);
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ void CPipeServer::HandleReloadSettings()
|
|||||||
|
|
||||||
AcquireSRWLockShared(&m_deviceContextLock);
|
AcquireSRWLockShared(&m_deviceContextLock);
|
||||||
if (m_deviceContext)
|
if (m_deviceContext)
|
||||||
m_deviceContext->ReplugMonitor();
|
m_deviceContext->ReloadSettings();
|
||||||
ReleaseSRWLockShared(&m_deviceContextLock);
|
ReleaseSRWLockShared(&m_deviceContextLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ CSettings::DisplayModes CSettings::LoadModes()
|
|||||||
return displayModes;
|
return displayModes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSettings::SetExtraMode(const DisplayMode& mode)
|
bool CSettings::SetExtraMode(const DisplayMode& mode)
|
||||||
{
|
{
|
||||||
WCHAR buf[64];
|
WCHAR buf[64];
|
||||||
_snwprintf_s(buf, _countof(buf), _TRUNCATE, L"%ux%u@%u%s",
|
_snwprintf_s(buf, _countof(buf), _TRUNCATE, L"%ux%u@%u%s",
|
||||||
@@ -94,15 +94,24 @@ void CSettings::SetExtraMode(const DisplayMode& mode)
|
|||||||
|
|
||||||
if (ec != ERROR_SUCCESS)
|
if (ec != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Failed to write key");
|
DEBUG_ERROR_HR(ec, "Failed to open settings key for ExtraMode");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WCHAR* valueName = L"ExtraMode";
|
const WCHAR* valueName = L"ExtraMode";
|
||||||
const DWORD cb = (DWORD)((wcslen(buf) + 1) * sizeof(WCHAR));
|
const DWORD cb = (DWORD)((wcslen(buf) + 1) * sizeof(WCHAR));
|
||||||
|
|
||||||
RegSetValueExW(hKey, valueName, 0, REG_SZ, (const BYTE*)buf, cb);
|
ec = RegSetValueExW(hKey, valueName, 0, REG_SZ,
|
||||||
|
(const BYTE*)buf, cb);
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
if (ec != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR_HR(ec, "Failed to write ExtraMode");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring CSettings::ReadStringValue(const wchar_t* name, const wchar_t* defaultValue)
|
std::wstring CSettings::ReadStringValue(const wchar_t* name, const wchar_t* defaultValue)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class CSettings
|
|||||||
CSettings();
|
CSettings();
|
||||||
|
|
||||||
DisplayModes LoadModes();
|
DisplayModes LoadModes();
|
||||||
void SetExtraMode(const DisplayMode & mode);
|
bool SetExtraMode(const DisplayMode & mode);
|
||||||
bool GetExtraMode(DisplayMode & mode);
|
bool GetExtraMode(DisplayMode & mode);
|
||||||
unsigned GetDefaultRefresh() const;
|
unsigned GetDefaultRefresh() const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user