https://git.reactos.org/?p=reactos.git;a=commitdiff;h=588285881ea5490946763…
commit 588285881ea5490946763515501dd89ee6a88ac2
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sun May 22 14:23:26 2022 +0200
Commit: Hervé Poussineau <hpoussin(a)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 */