mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Updated to latest WinLibrary version
This version of WinLibrary improves handling of multiple display adapters to cope with multiple displays across multiple display adapters. Hopefully fixes #60 (but no guarantees yet)
This commit is contained in:
parent
a4bfc62c92
commit
b34cdcce6c
@ -137,11 +137,20 @@ namespace DisplayMagicianShared.Windows
|
|||||||
public enum QDC : uint
|
public enum QDC : uint
|
||||||
{
|
{
|
||||||
Zero = 0x0,
|
Zero = 0x0,
|
||||||
QDC_ALL_PATHS = 0x00000001, // Get all paths
|
// Get all paths
|
||||||
QDC_ONLY_ACTIVE_PATHS = 0x00000002, // Get only the active paths currently in use
|
QDC_ALL_PATHS = 0x00000001,
|
||||||
QDC_DATABASE_CURRENT = 0x00000004, // Get the currently active paths as stored in the display database
|
// Get only the active paths currently in use
|
||||||
QDC_VIRTUAL_MODE_AWARE = 0x00000010, // Get the virtual mode aware paths
|
QDC_ONLY_ACTIVE_PATHS = 0x00000002,
|
||||||
|
// Get the currently active paths as stored in the display database
|
||||||
|
QDC_DATABASE_CURRENT = 0x00000004,
|
||||||
|
// This flag should be bitwise OR'ed with other flags to indicate that the caller is aware of virtual mode support. Supported starting in Windows 10.
|
||||||
|
QDC_VIRTUAL_MODE_AWARE = 0x00000010,
|
||||||
|
// This flag should be bitwise OR'ed with QDC_ONLY_ACTIVE_PATHS to indicate that the caller would like to include head-mounted displays (HMDs) in the list of active paths. See Remarks for more information.
|
||||||
|
// Supported starting in Windows 10 1703 Creators Update.
|
||||||
QDC_INCLUDE_HMD = 0x00000020,
|
QDC_INCLUDE_HMD = 0x00000020,
|
||||||
|
// This flag should be bitwise OR'ed with other flags to indicate that the caller is aware of virtual refresh rate support.
|
||||||
|
// Supported starting in Windows 11.
|
||||||
|
QDC_VIRTUAL_REFRESH_RATE_AWARE = 0x00000040,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -168,24 +168,33 @@ namespace DisplayMagicianShared.Windows
|
|||||||
return myDefaultConfig;
|
return myDefaultConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PatchAdapterIDs(ref WINDOWS_DISPLAY_CONFIG savedDisplayConfig, Dictionary<ulong, string> currentAdapterMap)
|
private void PatchAdapterIDs(ref WINDOWS_DISPLAY_CONFIG savedDisplayConfig)
|
||||||
{
|
{
|
||||||
|
|
||||||
Dictionary<ulong, ulong> adapterOldToNewMap = new Dictionary<ulong, ulong>();
|
Dictionary<ulong, ulong> adapterOldToNewMap = new Dictionary<ulong, ulong>();
|
||||||
|
Dictionary<ulong, string> currentAdapterMap = GetCurrentAdapterIDs();
|
||||||
|
|
||||||
SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to figure out the old adapterIDs");
|
SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to figure out the old adapterIDs");
|
||||||
foreach (KeyValuePair<ulong, string> savedAdapter in savedDisplayConfig.DisplayAdapters)
|
foreach (KeyValuePair<ulong, string> savedAdapter in savedDisplayConfig.DisplayAdapters)
|
||||||
{
|
{
|
||||||
|
bool adapterMatched = false;
|
||||||
foreach (KeyValuePair<ulong, string> currentAdapter in currentAdapterMap)
|
foreach (KeyValuePair<ulong, string> currentAdapter in currentAdapterMap)
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: Checking if saved adapter {savedAdapter.Key} (AdapterName is {savedAdapter.Value}) is equal to current adapter id {currentAdapter.Key} (AdapterName is {currentAdapter.Value})");
|
||||||
|
|
||||||
if (currentAdapter.Value.Equals(savedAdapter.Value))
|
if (currentAdapter.Value.Equals(savedAdapter.Value))
|
||||||
{
|
{
|
||||||
// we have found the new LUID Value for the same adapter
|
// we have found the new LUID Value for the same adapter
|
||||||
// So we want to store it
|
// So we want to store it
|
||||||
SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: We found that saved adapter {savedAdapter.Key} has now been assigned adapter id {currentAdapter.Key} (AdapterName is {savedAdapter.Value})");
|
SharedLogger.logger.Trace($"WinLibrary/PatchAdapterIDs: We found that saved adapter {savedAdapter.Key} has now been assigned adapter id {currentAdapter.Key} (AdapterName is {savedAdapter.Value})");
|
||||||
adapterOldToNewMap.Add(savedAdapter.Key, currentAdapter.Key);
|
adapterOldToNewMap.Add(savedAdapter.Key, currentAdapter.Key);
|
||||||
|
adapterMatched = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!adapterMatched)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Error($"WinLibrary/PatchAdapterIDs: Saved adapter {savedAdapter.Key} (AdapterName is {savedAdapter.Value}) doesn't have a current match! The adapters have changed since the configuration was last saved.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong newAdapterValue = 0;
|
ulong newAdapterValue = 0;
|
||||||
@ -282,16 +291,18 @@ namespace DisplayMagicianShared.Windows
|
|||||||
public WINDOWS_DISPLAY_CONFIG GetActiveConfig()
|
public WINDOWS_DISPLAY_CONFIG GetActiveConfig()
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Trace($"WinLibrary/GetActiveConfig: Getting the currently active config");
|
SharedLogger.logger.Trace($"WinLibrary/GetActiveConfig: Getting the currently active config");
|
||||||
return GetWindowsDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS);
|
// We want to include head mounted devices, inform windows we're virtual mode aware
|
||||||
|
// We'll leave virtual refresh rate aware until we can reliably detect Windows 11 versions.
|
||||||
|
return GetWindowsDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS)
|
private WINDOWS_DISPLAY_CONFIG GetWindowsDisplayConfig(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD)
|
||||||
{
|
{
|
||||||
// Get the size of the largest Active Paths and Modes arrays
|
// Get the size of the largest Active Paths and Modes arrays
|
||||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays");
|
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays");
|
||||||
int pathCount = 0;
|
int pathCount = 0;
|
||||||
int modeCount = 0;
|
int modeCount = 0;
|
||||||
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
|
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(selector, out pathCount, out modeCount);
|
||||||
if (err != WIN32STATUS.ERROR_SUCCESS)
|
if (err != WIN32STATUS.ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
|
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
|
||||||
@ -301,14 +312,14 @@ namespace DisplayMagicianShared.Windows
|
|||||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays");
|
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays");
|
||||||
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||||
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||||
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
err = CCDImport.QueryDisplayConfig(selector, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
||||||
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
|
SharedLogger.logger.Warn($"WinLibrary/GetWindowsDisplayConfig: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
|
||||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays");
|
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the size of the largest Active Paths and Modes arrays");
|
||||||
// Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again
|
// Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again
|
||||||
// as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig
|
// as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig
|
||||||
err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
|
err = CCDImport.GetDisplayConfigBufferSizes(selector, out pathCount, out modeCount);
|
||||||
if (err != WIN32STATUS.ERROR_SUCCESS)
|
if (err != WIN32STATUS.ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
|
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
|
||||||
@ -317,7 +328,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays");
|
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Getting the current Display Config path and mode arrays");
|
||||||
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||||
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||||
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
err = CCDImport.QueryDisplayConfig(selector, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
||||||
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
|
SharedLogger.logger.Error($"WinLibrary/GetWindowsDisplayConfig: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
|
||||||
@ -995,7 +1006,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
{
|
{
|
||||||
// Get the all possible windows display configs
|
// Get the all possible windows display configs
|
||||||
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Generating a list of all the current display configs");
|
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Generating a list of all the current display configs");
|
||||||
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS);
|
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD);
|
||||||
|
|
||||||
if (displayConfig.IsCloned)
|
if (displayConfig.IsCloned)
|
||||||
{
|
{
|
||||||
@ -1008,7 +1019,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
|
|
||||||
// Now we go through the Paths to update the LUIDs as per Soroush's suggestion
|
// Now we go through the Paths to update the LUIDs as per Soroush's suggestion
|
||||||
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Patching the adapter IDs to make the saved config valid");
|
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Patching the adapter IDs to make the saved config valid");
|
||||||
PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.DisplayAdapters);
|
PatchAdapterIDs(ref displayConfig);
|
||||||
|
|
||||||
uint myPathsCount = (uint)displayConfig.DisplayConfigPaths.Length;
|
uint myPathsCount = (uint)displayConfig.DisplayConfigPaths.Length;
|
||||||
uint myModesCount = (uint)displayConfig.DisplayConfigModes.Length;
|
uint myModesCount = (uint)displayConfig.DisplayConfigModes.Length;
|
||||||
@ -1275,7 +1286,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
public bool IsValidConfig(WINDOWS_DISPLAY_CONFIG displayConfig)
|
public bool IsValidConfig(WINDOWS_DISPLAY_CONFIG displayConfig)
|
||||||
{
|
{
|
||||||
// Get the current windows display configs
|
// Get the current windows display configs
|
||||||
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS);
|
WINDOWS_DISPLAY_CONFIG allWindowsDisplayConfig = GetWindowsDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD);
|
||||||
|
|
||||||
SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to make sure they still exist");
|
SharedLogger.logger.Trace("WinLibrary/PatchAdapterIDs: Going through the list of adapters we stored in the config to make sure they still exist");
|
||||||
// Firstly check that the Adapter Names are still currently available (i.e. the adapter hasn't been replaced).
|
// Firstly check that the Adapter Names are still currently available (i.e. the adapter hasn't been replaced).
|
||||||
@ -1293,7 +1304,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
|
|
||||||
// Now we go through the Paths to update the LUIDs as per Soroush's suggestion
|
// Now we go through the Paths to update the LUIDs as per Soroush's suggestion
|
||||||
SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Attemptong to patch the saved display configuration's adapter IDs so that it will still work (these change at each boot)");
|
SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Attemptong to patch the saved display configuration's adapter IDs so that it will still work (these change at each boot)");
|
||||||
PatchAdapterIDs(ref displayConfig, allWindowsDisplayConfig.DisplayAdapters);
|
PatchAdapterIDs(ref displayConfig);
|
||||||
|
|
||||||
SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Testing whether the display configuration is valid ");
|
SharedLogger.logger.Trace($"WinLibrary/IsPossibleConfig: Testing whether the display configuration is valid ");
|
||||||
// Test whether a specified display configuration is supported on the computer
|
// Test whether a specified display configuration is supported on the computer
|
||||||
@ -1339,16 +1350,16 @@ namespace DisplayMagicianShared.Windows
|
|||||||
public List<string> GetCurrentDisplayIdentifiers()
|
public List<string> GetCurrentDisplayIdentifiers()
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Trace($"WinLibrary/GetCurrentDisplayIdentifiers: Getting the current display identifiers for the displays in use now");
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentDisplayIdentifiers: Getting the current display identifiers for the displays in use now");
|
||||||
return GetSomeDisplayIdentifiers(QDC.QDC_ONLY_ACTIVE_PATHS);
|
return GetSomeDisplayIdentifiers(QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> GetAllConnectedDisplayIdentifiers()
|
public List<string> GetAllConnectedDisplayIdentifiers()
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Trace($"WinLibrary/GetAllConnectedDisplayIdentifiers: Getting all the display identifiers that can possibly be used");
|
SharedLogger.logger.Trace($"WinLibrary/GetAllConnectedDisplayIdentifiers: Getting all the display identifiers that can possibly be used");
|
||||||
return GetSomeDisplayIdentifiers(QDC.QDC_ALL_PATHS);
|
return GetSomeDisplayIdentifiers(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> GetSomeDisplayIdentifiers(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS)
|
private List<string> GetSomeDisplayIdentifiers(QDC selector = QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Debug($"WinLibrary/GetCurrentDisplayIdentifiers: Generating the unique Display Identifiers for the currently active configuration");
|
SharedLogger.logger.Debug($"WinLibrary/GetCurrentDisplayIdentifiers: Generating the unique Display Identifiers for the currently active configuration");
|
||||||
|
|
||||||
@ -1545,7 +1556,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
// Get the size of the largest Active Paths and Modes arrays
|
// Get the size of the largest Active Paths and Modes arrays
|
||||||
int pathCount = 0;
|
int pathCount = 0;
|
||||||
int modeCount = 0;
|
int modeCount = 0;
|
||||||
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
|
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD, out pathCount, out modeCount);
|
||||||
if (err != WIN32STATUS.ERROR_SUCCESS)
|
if (err != WIN32STATUS.ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
|
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
|
||||||
@ -1555,7 +1566,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays");
|
SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays");
|
||||||
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||||
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||||
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
||||||
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Warn($"WinLibrary/GetCurrentPCIVideoCardVendors: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
|
SharedLogger.logger.Warn($"WinLibrary/GetCurrentPCIVideoCardVendors: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
|
||||||
@ -1571,7 +1582,7 @@ namespace DisplayMagicianShared.Windows
|
|||||||
SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays");
|
SharedLogger.logger.Trace($"WinLibrary/GetSomeDisplayIdentifiers: Getting the current Display Config path and mode arrays");
|
||||||
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||||
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||||
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
err = CCDImport.QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
||||||
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
|
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
|
||||||
@ -1649,6 +1660,91 @@ namespace DisplayMagicianShared.Windows
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Dictionary<ulong, string> GetCurrentAdapterIDs()
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the current adapter ids for the videocards Windows knows about");
|
||||||
|
Dictionary<ulong, string> currentAdapterMap = new Dictionary<ulong, string>();
|
||||||
|
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Testing whether the display configuration is valid (allowing tweaks).");
|
||||||
|
// Get the size of the largest All Paths and Modes arrays
|
||||||
|
int pathCount = 0;
|
||||||
|
int modeCount = 0;
|
||||||
|
WIN32STATUS err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, out pathCount, out modeCount);
|
||||||
|
if (err != WIN32STATUS.ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
|
||||||
|
throw new WinLibraryException($"GetCurrentAdapterIDs returned WIN32STATUS {err} when trying to get the maximum path and mode sizes");
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the current Display Config path and mode arrays");
|
||||||
|
var paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||||
|
var modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||||
|
err = CCDImport.QueryDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
||||||
|
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Warn($"WinLibrary/GetCurrentAdapterIDs: The displays were modified between GetDisplayConfigBufferSizes and QueryDisplayConfig so we need to get the buffer sizes again.");
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the size of the largest Active Paths and Modes arrays");
|
||||||
|
// Screen changed in between GetDisplayConfigBufferSizes and QueryDisplayConfig, so we need to get buffer sizes again
|
||||||
|
// as per https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig
|
||||||
|
err = CCDImport.GetDisplayConfigBufferSizes(QDC.QDC_ALL_PATHS, out pathCount, out modeCount);
|
||||||
|
if (err != WIN32STATUS.ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
|
||||||
|
throw new WinLibraryException($"GetDisplayConfigBufferSizes returned WIN32STATUS {err} when trying to get the maximum path and mode sizes again");
|
||||||
|
}
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Getting the current Display Config path and mode arrays");
|
||||||
|
paths = new DISPLAYCONFIG_PATH_INFO[pathCount];
|
||||||
|
modes = new DISPLAYCONFIG_MODE_INFO[modeCount];
|
||||||
|
err = CCDImport.QueryDisplayConfig(QDC.QDC_ALL_PATHS | QDC.QDC_INCLUDE_HMD, ref pathCount, paths, ref modeCount, modes, IntPtr.Zero);
|
||||||
|
if (err == WIN32STATUS.ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
|
||||||
|
throw new WinLibraryException($"The displays were still modified between GetDisplayConfigBufferSizes and QueryDisplayConfig, even though we tried twice. Something is wrong.");
|
||||||
|
}
|
||||||
|
else if (err != WIN32STATUS.ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again");
|
||||||
|
throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (err != WIN32STATUS.ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Error($"WinLibrary/GetCurrentAdapterIDs: ERROR - QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays");
|
||||||
|
throw new WinLibraryException($"QueryDisplayConfig returned WIN32STATUS {err} when trying to query all available displays.");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var path in paths)
|
||||||
|
{
|
||||||
|
if (path.TargetInfo.TargetAvailable == false)
|
||||||
|
{
|
||||||
|
// We want to skip this one cause it's not valid
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Skipping path due to TargetAvailable not existing in display #{path.TargetInfo.Id}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get display adapter name
|
||||||
|
var adapterInfo = new DISPLAYCONFIG_ADAPTER_NAME();
|
||||||
|
adapterInfo.Header.Type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME;
|
||||||
|
adapterInfo.Header.Size = (uint)Marshal.SizeOf<DISPLAYCONFIG_ADAPTER_NAME>();
|
||||||
|
adapterInfo.Header.AdapterId = path.TargetInfo.AdapterId;
|
||||||
|
adapterInfo.Header.Id = path.TargetInfo.Id;
|
||||||
|
err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo);
|
||||||
|
if (err == WIN32STATUS.ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Trace($"WinLibrary/GetCurrentAdapterIDs: Successfully got the display name info from {path.TargetInfo.Id}.");
|
||||||
|
currentAdapterMap[path.TargetInfo.AdapterId.Value] = adapterInfo.AdapterDevicePath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Warn($"WinLibrary/GetCurrentAdapterIDs: WARNING - DisplayConfigGetDeviceInfo returned WIN32STATUS {err} when trying to get the target info for display #{path.TargetInfo.Id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentAdapterMap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static bool GDISettingsEqual(Dictionary<string, GDI_DISPLAY_SETTING> gdi1, Dictionary<string, GDI_DISPLAY_SETTING> gdi2)
|
public static bool GDISettingsEqual(Dictionary<string, GDI_DISPLAY_SETTING> gdi1, Dictionary<string, GDI_DISPLAY_SETTING> gdi2)
|
||||||
{
|
{
|
||||||
if (gdi1.Count == gdi2.Count)
|
if (gdi1.Count == gdi2.Count)
|
||||||
|
Loading…
Reference in New Issue
Block a user