https://git.reactos.org/?p=reactos.git;a=commitdiff;h=588285881ea54909467635...
commit 588285881ea5490946763515501dd89ee6a88ac2 Author: Hervé Poussineau hpoussin@reactos.org AuthorDate: Sun May 22 14:23:26 2022 +0200 Commit: Hervé Poussineau hpoussin@reactos.org CommitDate: Sun May 22 17:32:44 2022 +0200
[WIN32SS] Change LDEVOBJ_bProbeAndCaptureDevmode to load missing settings from registry
- use EngpGetDisplayDriverParameters to get display settings from registry - update searched display settings with the provided ones (+ add missing SEH2) - then, search exact mode
User can now change only one display setting, without specifying other ones. --- win32ss/gdi/eng/ldevobj.c | 137 ++++++++++++++++++++++++++++++++++------------ win32ss/gdi/eng/mdevobj.c | 56 +------------------ 2 files changed, 105 insertions(+), 88 deletions(-)
diff --git a/win32ss/gdi/eng/ldevobj.c b/win32ss/gdi/eng/ldevobj.c index 4a929ec4d24..bd6d282c23c 100644 --- a/win32ss/gdi/eng/ldevobj.c +++ b/win32ss/gdi/eng/ldevobj.c @@ -710,56 +710,113 @@ LDEVOBJ_bProbeAndCaptureDevmode( _Out_ PDEVMODEW *pSelectedMode, _In_ BOOL bSearchClosestMode) { + DEVMODEW dmSearch; PDEVMODEW pdmCurrent, pdm, pdmSelected = NULL; ULONG i; - DWORD dwFields; + ULONG ulVirtualWidth = 0, ulVirtualHeight = 0; + BOOL bResult = TRUE; + NTSTATUS Status;
if (!LDEVOBJ_bBuildDevmodeList(pGraphicsDevice)) return FALSE;
- if (bSearchClosestMode) + /* At first, load information from registry */ + RtlZeroMemory(&dmSearch, sizeof(dmSearch)); + Status = EngpGetDisplayDriverParameters(pGraphicsDevice, &dmSearch, NULL); + if (!NT_SUCCESS(Status)) { - /* Search the closest mode */ - if (!LDEVOBJ_bGetClosestMode(pGraphicsDevice, RequestedMode, &pdmSelected)) - return FALSE; - ASSERT(pdmSelected); + ERR("EngpGetDisplayDriverParameters() failed with status 0x%08x\n", Status); + return FALSE; } - else + + /* Override values with the new ones provided */ + + _SEH2_TRY { - /* Search if requested mode exists */ - for (i = 0; i < pGraphicsDevice->cDevModes; i++) + bSearchClosestMode |= RequestedMode->dmFields == 0; + + /* Copy standard fields (if provided) */ + if (RequestedMode->dmFields & DM_BITSPERPEL && RequestedMode->dmBitsPerPel != 0) + dmSearch.dmBitsPerPel = RequestedMode->dmBitsPerPel; + if (RequestedMode->dmFields & DM_PELSWIDTH && RequestedMode->dmPelsWidth != 0) + dmSearch.dmPelsWidth = RequestedMode->dmPelsWidth; + if (RequestedMode->dmFields & DM_PELSHEIGHT && RequestedMode->dmPelsHeight != 0) + dmSearch.dmPelsHeight = RequestedMode->dmPelsHeight; + if (RequestedMode->dmFields & DM_DISPLAYFREQUENCY && RequestedMode->dmDisplayFrequency != 0) + dmSearch.dmDisplayFrequency = RequestedMode->dmDisplayFrequency; + + if ((RequestedMode->dmFields & (DM_PANNINGWIDTH | DM_PANNINGHEIGHT)) == (DM_PANNINGWIDTH | DM_PANNINGHEIGHT) && + RequestedMode->dmPanningWidth != 0 && RequestedMode->dmPanningHeight != 0 && + RequestedMode->dmPanningWidth < dmSearch.dmPelsWidth && + RequestedMode->dmPanningHeight < dmSearch.dmPelsHeight) { - pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm; - - /* Compare asked DEVMODE fields - * Only compare those that are valid in both DEVMODE structs */ - dwFields = pdmCurrent->dmFields & RequestedMode->dmFields; - - /* For now, we only need those */ - if ((dwFields & DM_BITSPERPEL) && - (pdmCurrent->dmBitsPerPel != RequestedMode->dmBitsPerPel)) continue; - if ((dwFields & DM_PELSWIDTH) && - (pdmCurrent->dmPelsWidth != RequestedMode->dmPelsWidth)) continue; - if ((dwFields & DM_PELSHEIGHT) && - (pdmCurrent->dmPelsHeight != RequestedMode->dmPelsHeight)) continue; - if ((dwFields & DM_DISPLAYFREQUENCY) && - (pdmCurrent->dmDisplayFrequency != RequestedMode->dmDisplayFrequency)) continue; - - pdmSelected = pdmCurrent; - break; + /* Get new panning values */ + ulVirtualWidth = RequestedMode->dmPelsWidth; + ulVirtualHeight = RequestedMode->dmPelsHeight; + dmSearch.dmPelsWidth = RequestedMode->dmPanningWidth; + dmSearch.dmPelsHeight = RequestedMode->dmPanningHeight; + } + else if (dmSearch.dmPanningWidth != 0 && dmSearch.dmPanningHeight != 0 && + dmSearch.dmPanningWidth < dmSearch.dmPelsWidth && + dmSearch.dmPanningHeight < dmSearch.dmPelsHeight) + { + /* Keep existing panning values */ + ulVirtualWidth = dmSearch.dmPelsWidth; + ulVirtualHeight = dmSearch.dmPelsHeight; + dmSearch.dmPelsWidth = dmSearch.dmPanningWidth; + dmSearch.dmPelsHeight = dmSearch.dmPanningHeight; } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + bResult = FALSE; + } + _SEH2_END; + + if (!bResult) + return FALSE;
- if (!pdmSelected) + if (bSearchClosestMode) + { + if (LDEVOBJ_bGetClosestMode(pGraphicsDevice, &dmSearch, &pdmSelected)) { - WARN("Requested mode not found (%dx%dx%d %d Hz)\n", - RequestedMode->dmFields & DM_PELSWIDTH ? RequestedMode->dmPelsWidth : 0, - RequestedMode->dmFields & DM_PELSHEIGHT ? RequestedMode->dmPelsHeight : 0, - RequestedMode->dmFields & DM_BITSPERPEL ? RequestedMode->dmBitsPerPel : 0, - RequestedMode->dmFields & DM_DISPLAYFREQUENCY ? RequestedMode->dmDisplayFrequency : 0); - return FALSE; + /* Ok, found a closest mode. Update search */ + dmSearch.dmBitsPerPel = pdmSelected->dmBitsPerPel; + dmSearch.dmPelsWidth = pdmSelected->dmPelsWidth; + dmSearch.dmPelsHeight = pdmSelected->dmPelsHeight; + dmSearch.dmDisplayFrequency = pdmSelected->dmDisplayFrequency; } }
+ /* Now, search the exact mode to return to caller */ + for (i = 0; i < pGraphicsDevice->cDevModes; i++) + { + pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm; + + /* For now, we only need those */ + if (pdmCurrent->dmBitsPerPel != dmSearch.dmBitsPerPel) + continue; + if (pdmCurrent->dmPelsWidth != dmSearch.dmPelsWidth) + continue; + if (pdmCurrent->dmPelsHeight != dmSearch.dmPelsHeight) + continue; + if (pdmCurrent->dmDisplayFrequency != dmSearch.dmDisplayFrequency) + continue; + + pdmSelected = pdmCurrent; + break; + } + + if (!pdmSelected) + { + ERR("Requested mode not found (%dx%dx%d %d Hz)\n", + dmSearch.dmPelsWidth, + dmSearch.dmPelsHeight, + dmSearch.dmBitsPerPel, + dmSearch.dmDisplayFrequency); + return FALSE; + } + /* Allocate memory for output */ pdm = ExAllocatePoolZero(PagedPool, pdmSelected->dmSize + pdmSelected->dmDriverExtra, GDITAG_DEVMODE); if (!pdm) @@ -771,6 +828,18 @@ LDEVOBJ_bProbeAndCaptureDevmode( (PVOID)((ULONG_PTR)pdmSelected + pdmSelected->dmSize), pdmSelected->dmDriverExtra);
+ /* Add back panning */ + if (ulVirtualWidth != 0 && ulVirtualHeight != 0 && + pdm->dmPelsWidth < ulVirtualWidth && + pdm->dmPelsHeight < ulVirtualHeight) + { + pdm->dmFields |= DM_PANNINGWIDTH | DM_PANNINGHEIGHT; + pdm->dmPanningWidth = pdm->dmPelsWidth; + pdm->dmPanningHeight = pdm->dmPelsHeight; + pdm->dmPelsWidth = ulVirtualWidth; + pdm->dmPelsHeight = ulVirtualHeight; + } + *pSelectedMode = pdm; return TRUE; } diff --git a/win32ss/gdi/eng/mdevobj.c b/win32ss/gdi/eng/mdevobj.c index 2b6ce26b0ca..620e5451f8c 100644 --- a/win32ss/gdi/eng/mdevobj.c +++ b/win32ss/gdi/eng/mdevobj.c @@ -99,62 +99,10 @@ MDEVOBJ_Create(
if (!pdm) { - /* No settings requested. Read default settings from registry to dmDefault */ - HKEY hKey; - WCHAR DeviceKey[128]; - ULONG cbSize; - NTSTATUS Status; - DWORD dwValue; - + /* No settings requested. Provide nothing and LDEVOBJ_bProbeAndCaptureDevmode + * will read default settings from registry */ RtlZeroMemory(&dmDefault, sizeof(dmDefault)); dmDefault.dmSize = sizeof(dmDefault); - - Status = RegOpenKey(L"\Registry\Machine\HARDWARE\DEVICEMAP\VIDEO", &hKey); - if (!NT_SUCCESS(Status)) - { - /* Ignore this device and continue */ - ERR("Failed to open VIDEO key: status 0x%08x\n", Status); - continue; - } - cbSize = sizeof(DeviceKey); - Status = RegQueryValue(hKey, - pGraphicsDevice->szNtDeviceName, - REG_SZ, - DeviceKey, - &cbSize); - ZwClose(hKey); - if (!NT_SUCCESS(Status)) - { - /* Ignore this device and continue */ - ERR("Failed to open get device key for '%S': status 0x%08x\n", pGraphicsDevice->szNtDeviceName, Status); - continue; - } - Status = RegOpenKey(DeviceKey, &hKey); - if (!NT_SUCCESS(Status)) - { - /* Ignore this device and continue */ - ERR("Failed to open open device key '%S' for '%S': status 0x%08x\n", DeviceKey, pGraphicsDevice->szNtDeviceName, Status); - continue; - } -#define READ(field, str, flag) \ - if (RegReadDWORD(hKey, L##str, &dwValue)) \ - { \ - dmDefault.field = dwValue; \ - dmDefault.dmFields |= flag; \ - } - READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL); - READ(dmPelsWidth, "DefaultSettings.XResolution", DM_PELSWIDTH); - READ(dmPelsHeight, "DefaultSettings.YResolution", DM_PELSHEIGHT); - READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS); - READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY); - READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH); - READ(dmPanningHeight, "DefaultSettings.YPanning", DM_PANNINGHEIGHT); - READ(dmDisplayOrientation, "DefaultSettings.Orientation", DM_DISPLAYORIENTATION); - READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput", DM_DISPLAYFIXEDOUTPUT); - READ(dmPosition.x, "Attach.RelativeX", DM_POSITION); - READ(dmPosition.y, "Attach.RelativeY", DM_POSITION); - RegReadDWORD(hKey, L"Acceleration.Level", &dwAccelerationLevel); - ZwClose(hKey); }
/* Get or create a PDEV for these settings */