mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[WIN32SS] Rewrite PDEVOBJ_pdmMatchDevMode to LDEVOBJ_bProbeAndCaptureDevmode
- make it return a new allocated PDEVMODEW instead of a pointer into existing PGRAPHICS_DEVICE (usefull when available display modes can dynamically change: VirtualBox, RDP, ...) - update all callers
This commit is contained in:
parent
21ddeb76d9
commit
3cb1dd8ab2
6 changed files with 114 additions and 83 deletions
|
@ -130,25 +130,18 @@ EngpPopulateDeviceModeList(
|
|||
_In_ PDEVMODEW pdmDefault)
|
||||
{
|
||||
PDEVMODEINFO pdminfo;
|
||||
PDEVMODEW pdm;
|
||||
PDEVMODEW pdm, pdmSelected;
|
||||
ULONG i;
|
||||
BOOLEAN bModeMatch = FALSE;
|
||||
|
||||
ASSERT(pGraphicsDevice->pdevmodeInfo == NULL);
|
||||
ASSERT(pGraphicsDevice->pDevModeList == NULL);
|
||||
|
||||
if (!LDEVOBJ_bBuildDevmodeList(pGraphicsDevice))
|
||||
if (!LDEVOBJ_bProbeAndCaptureDevmode(pGraphicsDevice, pdmDefault, &pdmSelected, TRUE))
|
||||
{
|
||||
ERR("LDEVOBJ_bBuildDevmodeList() failed\n");
|
||||
ERR("LDEVOBJ_bProbeAndCaptureDevmode() failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE("Looking for mode %lux%lux%lu(%lu Hz)\n",
|
||||
pdmDefault->dmPelsWidth,
|
||||
pdmDefault->dmPelsHeight,
|
||||
pdmDefault->dmBitsPerPel,
|
||||
pdmDefault->dmDisplayFrequency);
|
||||
|
||||
/* Loop through all DEVMODEINFOs */
|
||||
for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0;
|
||||
pdminfo;
|
||||
|
@ -159,20 +152,14 @@ EngpPopulateDeviceModeList(
|
|||
{
|
||||
pdm = pGraphicsDevice->pDevModeList[i].pdm;
|
||||
|
||||
/* Compare with the default entry */
|
||||
if (!bModeMatch &&
|
||||
pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
|
||||
pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
|
||||
pdm->dmPelsHeight == pdmDefault->dmPelsHeight)
|
||||
/* Compare with the selected entry */
|
||||
if (pdm->dmSize == pdmSelected->dmSize &&
|
||||
RtlCompareMemory(pdm, pdmSelected, pdm->dmSize) == pdm->dmSize)
|
||||
{
|
||||
pGraphicsDevice->iDefaultMode = i;
|
||||
pGraphicsDevice->iCurrentMode = i;
|
||||
TRACE("Found default entry: %lu '%ls'\n", i, pdm->dmDeviceName);
|
||||
if (pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency)
|
||||
{
|
||||
/* Uh oh, even the display frequency matches. */
|
||||
bModeMatch = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -558,6 +558,77 @@ LDEVOBJ_bBuildDevmodeList(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
LDEVOBJ_bProbeAndCaptureDevmode(
|
||||
_Inout_ PGRAPHICS_DEVICE pGraphicsDevice,
|
||||
_In_ PDEVMODEW RequestedMode,
|
||||
_Out_ PDEVMODEW *pSelectedMode,
|
||||
_In_ BOOL bSearchClosestMode)
|
||||
{
|
||||
PDEVMODEW pdmCurrent, pdm, pdmSelected = NULL;
|
||||
ULONG i;
|
||||
DWORD dwFields;
|
||||
|
||||
if (!LDEVOBJ_bBuildDevmodeList(pGraphicsDevice))
|
||||
return FALSE;
|
||||
|
||||
/* Search if requested mode exists */
|
||||
for (i = 0; i < pGraphicsDevice->cDevModes; i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (!bSearchClosestMode || pGraphicsDevice->cDevModes == 0)
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: need to search the closest mode instead of taking the first one */
|
||||
pdmSelected = pGraphicsDevice->pDevModeList[0].pdm;
|
||||
WARN("Replacing it by %dx%dx%d %d Hz\n",
|
||||
pdmSelected->dmFields & DM_PELSWIDTH ? pdmSelected->dmPelsWidth : 0,
|
||||
pdmSelected->dmFields & DM_PELSHEIGHT ? pdmSelected->dmPelsHeight : 0,
|
||||
pdmSelected->dmFields & DM_BITSPERPEL ? pdmSelected->dmBitsPerPel : 0,
|
||||
pdmSelected->dmFields & DM_DISPLAYFREQUENCY ? pdmSelected->dmDisplayFrequency : 0);
|
||||
}
|
||||
|
||||
/* Allocate memory for output */
|
||||
pdm = ExAllocatePoolZero(PagedPool, pdmSelected->dmSize + pdmSelected->dmDriverExtra, GDITAG_DEVMODE);
|
||||
if (!pdm)
|
||||
return FALSE;
|
||||
|
||||
/* Copy selected mode */
|
||||
RtlCopyMemory(pdm, pdmSelected, pdmSelected->dmSize);
|
||||
RtlCopyMemory((PVOID)((ULONG_PTR)pdm + pdm->dmSize),
|
||||
(PVOID)((ULONG_PTR)pdmSelected + pdmSelected->dmSize),
|
||||
pdmSelected->dmDriverExtra);
|
||||
|
||||
*pSelectedMode = pdm;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Exported functions ********************************************************/
|
||||
|
||||
HANDLE
|
||||
|
|
|
@ -56,6 +56,14 @@ BOOL
|
|||
LDEVOBJ_bBuildDevmodeList(
|
||||
_Inout_ PGRAPHICS_DEVICE pGraphicsDevice);
|
||||
|
||||
/* This function selects the best available mode corresponding to requested mode */
|
||||
BOOL
|
||||
LDEVOBJ_bProbeAndCaptureDevmode(
|
||||
_Inout_ PGRAPHICS_DEVICE pGraphicsDevice,
|
||||
_In_ PDEVMODEW RequestedMode,
|
||||
_Out_ PDEVMODEW *pSelectedMode,
|
||||
_In_ BOOL bSearchClosestMode);
|
||||
|
||||
PLDEVOBJ
|
||||
NTAPI
|
||||
EngGetLDEV(
|
||||
|
|
|
@ -83,6 +83,8 @@ PDEVOBJ_vDeletePDEV(
|
|||
PPDEVOBJ ppdev)
|
||||
{
|
||||
EngDeleteSemaphore(ppdev->hsemDevLock);
|
||||
if (ppdev->pdmwDev)
|
||||
ExFreePoolWithTag(ppdev->pdmwDev, GDITAG_DEVMODE);
|
||||
if (ppdev->pEDDgpl)
|
||||
ExFreePoolWithTag(ppdev->pEDDgpl, GDITAG_PDEV);
|
||||
ExFreePoolWithTag(ppdev, GDITAG_PDEV);
|
||||
|
@ -266,18 +268,13 @@ PDEVOBJ_vRefreshModeList(
|
|||
{
|
||||
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||
PDEVMODEINFO pdminfo, pdmiNext;
|
||||
DEVMODEW dmDefault;
|
||||
DEVMODEW dmCurrent;
|
||||
PDEVMODEW newDevMode;
|
||||
|
||||
/* Lock the PDEV */
|
||||
EngAcquireSemaphore(ppdev->hsemDevLock);
|
||||
|
||||
pGraphicsDevice = ppdev->pGraphicsDevice;
|
||||
|
||||
/* Remember our default mode */
|
||||
dmDefault = *pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
|
||||
dmCurrent = *ppdev->pdmwDev;
|
||||
|
||||
/* Clear out the modes */
|
||||
for (pdminfo = pGraphicsDevice->pdevmodeInfo;
|
||||
pdminfo;
|
||||
|
@ -290,57 +287,17 @@ PDEVOBJ_vRefreshModeList(
|
|||
ExFreePoolWithTag(pGraphicsDevice->pDevModeList, GDITAG_GDEVICE);
|
||||
pGraphicsDevice->pDevModeList = NULL;
|
||||
|
||||
/* Now re-populate the list */
|
||||
if (!EngpPopulateDeviceModeList(pGraphicsDevice, &dmDefault))
|
||||
/* Search an available display mode */
|
||||
if (LDEVOBJ_bProbeAndCaptureDevmode(pGraphicsDevice, ppdev->pdmwDev, &newDevMode, TRUE))
|
||||
{
|
||||
DPRINT1("FIXME: EngpPopulateDeviceModeList failed, we just destroyed a perfectly good mode list\n");
|
||||
ExFreePoolWithTag(ppdev->pdmwDev, GDITAG_DEVMODE);
|
||||
ppdev->pdmwDev = newDevMode;
|
||||
}
|
||||
|
||||
ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, &dmCurrent);
|
||||
|
||||
/* Unlock PDEV */
|
||||
EngReleaseSemaphore(ppdev->hsemDevLock);
|
||||
}
|
||||
|
||||
PDEVMODEW
|
||||
NTAPI
|
||||
PDEVOBJ_pdmMatchDevMode(
|
||||
PPDEVOBJ ppdev,
|
||||
PDEVMODEW pdm)
|
||||
{
|
||||
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||
PDEVMODEW pdmCurrent;
|
||||
ULONG i;
|
||||
DWORD dwFields;
|
||||
|
||||
pGraphicsDevice = ppdev->pGraphicsDevice;
|
||||
|
||||
for (i = 0; i < pGraphicsDevice->cDevModes; i++)
|
||||
{
|
||||
pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
|
||||
|
||||
/* Compare asked DEVMODE fields
|
||||
* Only compare those that are valid in both DEVMODE structs */
|
||||
dwFields = pdmCurrent->dmFields & pdm->dmFields;
|
||||
|
||||
/* For now, we only need those */
|
||||
if ((dwFields & DM_BITSPERPEL) &&
|
||||
(pdmCurrent->dmBitsPerPel != pdm->dmBitsPerPel)) continue;
|
||||
if ((dwFields & DM_PELSWIDTH) &&
|
||||
(pdmCurrent->dmPelsWidth != pdm->dmPelsWidth)) continue;
|
||||
if ((dwFields & DM_PELSHEIGHT) &&
|
||||
(pdmCurrent->dmPelsHeight != pdm->dmPelsHeight)) continue;
|
||||
if ((dwFields & DM_DISPLAYFREQUENCY) &&
|
||||
(pdmCurrent->dmDisplayFrequency != pdm->dmDisplayFrequency)) continue;
|
||||
|
||||
/* Match! Return the DEVMODE */
|
||||
return pdmCurrent;
|
||||
}
|
||||
|
||||
/* Nothing found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
PPDEVOBJ
|
||||
EngpCreatePDEV(
|
||||
|
@ -349,6 +306,7 @@ EngpCreatePDEV(
|
|||
{
|
||||
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||
PPDEVOBJ ppdev;
|
||||
PDEVMODEW newDevMode;
|
||||
|
||||
DPRINT("EngpCreatePDEV(%wZ, %p)\n", pustrDeviceName, pdm);
|
||||
|
||||
|
@ -410,7 +368,13 @@ EngpCreatePDEV(
|
|||
ppdev->hSpooler = ppdev->pGraphicsDevice->DeviceObject;
|
||||
|
||||
// Should we change the ative mode of pGraphicsDevice ?
|
||||
ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
|
||||
if (!LDEVOBJ_bProbeAndCaptureDevmode(pGraphicsDevice, pdm, &newDevMode, TRUE))
|
||||
{
|
||||
DPRINT1("LDEVOBJ_bProbeAndCaptureDevmode() failed\n");
|
||||
PDEVOBJ_vRelease(ppdev);
|
||||
return NULL;
|
||||
}
|
||||
ppdev->pdmwDev = newDevMode;
|
||||
|
||||
/* FIXME! */
|
||||
ppdev->flFlags = PDEV_DISPLAY;
|
||||
|
@ -525,7 +489,7 @@ PDEVOBJ_bSwitchMode(
|
|||
DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
|
||||
|
||||
// Lookup the GraphicsDevice + select DEVMODE
|
||||
// pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
|
||||
// pdm = LDEVOBJ_bProbeAndCaptureDevmode(ppdev, pdm);
|
||||
|
||||
/* 1. Temporarily disable the current PDEV and reset video to its default mode */
|
||||
if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE))
|
||||
|
|
|
@ -213,10 +213,4 @@ PDEVOBJ_bSwitchMode(
|
|||
PPDEVOBJ ppdev,
|
||||
PDEVMODEW pdm);
|
||||
|
||||
PDEVMODEW
|
||||
NTAPI
|
||||
PDEVOBJ_pdmMatchDevMode(
|
||||
PPDEVOBJ ppdev,
|
||||
PDEVMODEW pdm);
|
||||
|
||||
#endif /* !__WIN32K_PDEVOBJ_H */
|
||||
|
|
|
@ -657,6 +657,7 @@ UserChangeDisplaySettings(
|
|||
PPDEVOBJ ppdev;
|
||||
WORD OrigBC;
|
||||
//PDESKTOP pdesk;
|
||||
PDEVMODEW newDevMode = NULL;
|
||||
|
||||
/* If no DEVMODE is given, use registry settings */
|
||||
if (!pdm)
|
||||
|
@ -707,8 +708,7 @@ UserChangeDisplaySettings(
|
|||
dm.dmDisplayFrequency = ppdev->pdmwDev->dmDisplayFrequency;
|
||||
|
||||
/* Look for the requested DEVMODE */
|
||||
pdm = PDEVOBJ_pdmMatchDevMode(ppdev, &dm);
|
||||
if (!pdm)
|
||||
if (!LDEVOBJ_bProbeAndCaptureDevmode(ppdev->pGraphicsDevice, &dm, &newDevMode, FALSE))
|
||||
{
|
||||
ERR("Could not find a matching DEVMODE\n");
|
||||
lResult = DISP_CHANGE_BADMODE;
|
||||
|
@ -729,7 +729,7 @@ UserChangeDisplaySettings(
|
|||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Store the settings */
|
||||
RegWriteDisplaySettings(hkey, pdm);
|
||||
RegWriteDisplaySettings(hkey, newDevMode);
|
||||
|
||||
/* Close the registry key */
|
||||
ZwClose(hkey);
|
||||
|
@ -742,7 +742,9 @@ UserChangeDisplaySettings(
|
|||
}
|
||||
|
||||
/* Check if DEVMODE matches the current mode */
|
||||
if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET))
|
||||
if (newDevMode->dmSize == ppdev->pdmwDev->dmSize &&
|
||||
RtlCompareMemory(newDevMode, ppdev->pdmwDev, newDevMode->dmSize) == newDevMode->dmSize &&
|
||||
!(flags & CDS_RESET))
|
||||
{
|
||||
ERR("DEVMODE matches, nothing to do\n");
|
||||
goto leave;
|
||||
|
@ -759,7 +761,7 @@ UserChangeDisplaySettings(
|
|||
pvOldCursor = UserSetCursor(NULL, TRUE);
|
||||
|
||||
/* Do the mode switch */
|
||||
ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm);
|
||||
ulResult = PDEVOBJ_bSwitchMode(ppdev, newDevMode);
|
||||
|
||||
/* Restore mouse pointer, no hooks called */
|
||||
pvOldCursor = UserSetCursor(pvOldCursor, TRUE);
|
||||
|
@ -781,6 +783,8 @@ UserChangeDisplaySettings(
|
|||
{
|
||||
/* Setting mode succeeded */
|
||||
lResult = DISP_CHANGE_SUCCESSFUL;
|
||||
ExFreePoolWithTag(ppdev->pdmwDev, GDITAG_DEVMODE);
|
||||
ppdev->pdmwDev = newDevMode;
|
||||
|
||||
UserUpdateFullscreen(flags);
|
||||
|
||||
|
@ -847,6 +851,9 @@ UserChangeDisplaySettings(
|
|||
}
|
||||
|
||||
leave:
|
||||
if (newDevMode && newDevMode != ppdev->pdmwDev)
|
||||
ExFreePoolWithTag(newDevMode, GDITAG_DEVMODE);
|
||||
|
||||
/* Release the PDEV */
|
||||
PDEVOBJ_vRelease(ppdev);
|
||||
|
||||
|
|
Loading…
Reference in a new issue