mirror of
https://github.com/reactos/reactos.git
synced 2024-11-23 11:33:31 +08:00
[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.
This commit is contained in:
parent
9acd895f18
commit
588285881e
@ -710,54 +710,111 @@ 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;
|
||||
|
||||
/* At first, load information from registry */
|
||||
RtlZeroMemory(&dmSearch, sizeof(dmSearch));
|
||||
Status = EngpGetDisplayDriverParameters(pGraphicsDevice, &dmSearch, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("EngpGetDisplayDriverParameters() failed with status 0x%08x\n", Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Override values with the new ones provided */
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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 (bSearchClosestMode)
|
||||
{
|
||||
/* Search the closest mode */
|
||||
if (!LDEVOBJ_bGetClosestMode(pGraphicsDevice, RequestedMode, &pdmSelected))
|
||||
return FALSE;
|
||||
ASSERT(pdmSelected);
|
||||
if (LDEVOBJ_bGetClosestMode(pGraphicsDevice, &dmSearch, &pdmSelected))
|
||||
{
|
||||
/* Ok, found a closest mode. Update search */
|
||||
dmSearch.dmBitsPerPel = pdmSelected->dmBitsPerPel;
|
||||
dmSearch.dmPelsWidth = pdmSelected->dmPelsWidth;
|
||||
dmSearch.dmPelsHeight = pdmSelected->dmPelsHeight;
|
||||
dmSearch.dmDisplayFrequency = pdmSelected->dmDisplayFrequency;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/* Now, search the exact mode to return to caller */
|
||||
for (i = 0; i < pGraphicsDevice->cDevModes; i++)
|
||||
{
|
||||
/* Search if requested mode exists */
|
||||
for (i = 0; i < pGraphicsDevice->cDevModes; i++)
|
||||
{
|
||||
pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
|
||||
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 (pdmCurrent->dmBitsPerPel != dmSearch.dmBitsPerPel)
|
||||
continue;
|
||||
if (pdmCurrent->dmPelsWidth != dmSearch.dmPelsWidth)
|
||||
continue;
|
||||
if (pdmCurrent->dmPelsHeight != dmSearch.dmPelsHeight)
|
||||
continue;
|
||||
if (pdmCurrent->dmDisplayFrequency != dmSearch.dmDisplayFrequency)
|
||||
continue;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
pdmSelected = pdmCurrent;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!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;
|
||||
}
|
||||
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 */
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user