[WIN32K:ENG]

- Split populating the display mode list out from EngpRegisterGraphicsDevice, into its own function, EngpPopulateDeviceModeList. Based on a patch by Ismael Ferreras Morezuelas.
CORE-6742

svn path=/trunk/; revision=74359
This commit is contained in:
Thomas Faber
2017-04-17 19:44:32 +00:00
parent 4677d6bfe0
commit 670ebb242c
2 changed files with 136 additions and 111 deletions
+131 -111
View File
@@ -30,6 +30,132 @@ InitDeviceImpl(VOID)
return STATUS_SUCCESS;
}
BOOLEAN
EngpPopulateDeviceModeList(
_Inout_ PGRAPHICS_DEVICE pGraphicsDevice,
_In_ PDEVMODEW pdmDefault)
{
PWSTR pwsz;
PLDEVOBJ pldev;
PDEVMODEINFO pdminfo;
PDEVMODEW pdm, pdmEnd;
ULONG i, cModes = 0;
BOOLEAN bModeMatch = FALSE;
ASSERT(pGraphicsDevice->pdevmodeInfo == NULL);
ASSERT(pGraphicsDevice->pDevModeList == NULL);
pwsz = pGraphicsDevice->pDiplayDrivers;
/* Loop through the driver names
* This is a REG_MULTI_SZ string */
for (; *pwsz; pwsz += wcslen(pwsz) + 1)
{
TRACE("trying driver: %ls\n", pwsz);
/* Try to load the display driver */
pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY);
if (!pldev)
{
ERR("Could not load driver: '%ls'\n", pwsz);
continue;
}
/* Get the mode list from the driver */
pdminfo = LDEVOBJ_pdmiGetModes(pldev, pGraphicsDevice->DeviceObject);
if (!pdminfo)
{
ERR("Could not get mode list for '%ls'\n", pwsz);
continue;
}
/* Attach the mode info to the device */
pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
pGraphicsDevice->pdevmodeInfo = pdminfo;
/* Loop all DEVMODEs */
pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
for (pdm = pdminfo->adevmode;
(pdm + 1 <= pdmEnd) && (pdm->dmSize != 0);
pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
{
/* Count this DEVMODE */
cModes++;
/* Some drivers like the VBox driver don't fill the dmDeviceName
with the name of the display driver. So fix that here. */
wcsncpy(pdm->dmDeviceName, pwsz, CCHDEVICENAME);
pdm->dmDeviceName[CCHDEVICENAME - 1] = 0;
}
// FIXME: release the driver again until it's used?
}
if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
{
ERR("No devmodes\n");
return FALSE;
}
/* Allocate an index buffer */
pGraphicsDevice->cDevModes = cModes;
pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
cModes * sizeof(DEVMODEENTRY),
GDITAG_GDEVICE);
if (!pGraphicsDevice->pDevModeList)
{
ERR("No devmode list\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;
pdminfo = pdminfo->pdmiNext)
{
/* Calculate End of the DEVMODEs */
pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
/* Loop through the DEVMODEs */
for (pdm = pdminfo->adevmode;
(pdm + 1 <= pdmEnd) && (pdm->dmSize != 0);
pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
{
TRACE(" %S has mode %lux%lux%lu(%lu Hz)\n",
pdm->dmDeviceName,
pdm->dmPelsWidth,
pdm->dmPelsHeight,
pdm->dmBitsPerPel,
pdm->dmDisplayFrequency);
/* Compare with the default entry */
if (!bModeMatch &&
pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
pdm->dmPelsHeight == pdmDefault->dmPelsHeight)
{
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;
}
}
/* Initialize the entry */
pGraphicsDevice->pDevModeList[i].dwFlags = 0;
pGraphicsDevice->pDevModeList[i].pdm = pdm;
i++;
}
}
return TRUE;
}
PGRAPHICS_DEVICE
NTAPI
@@ -44,13 +170,9 @@ EngpRegisterGraphicsDevice(
PFILE_OBJECT pFileObject;
NTSTATUS Status;
PWSTR pwsz;
ULONG i, cj, cModes = 0;
ULONG cj;
SIZE_T cjWritten;
BOOL bEnable = TRUE;
PDEVMODEINFO pdminfo;
PDEVMODEW pdm, pdmEnd;
PLDEVOBJ pldev;
BOOLEAN bModeMatch = FALSE;
TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName);
@@ -124,116 +246,14 @@ EngpRegisterGraphicsDevice(
// FIXME: initialize state flags
pGraphicsDevice->StateFlags = 0;
/* Loop through the driver names
* This is a REG_MULTI_SZ string */
for (; *pwsz; pwsz += wcslen(pwsz) + 1)
/* Create the mode list */
pGraphicsDevice->pDevModeList = NULL;
if (!EngpPopulateDeviceModeList(pGraphicsDevice, pdmDefault))
{
TRACE("trying driver: %ls\n", pwsz);
/* Try to load the display driver */
pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY);
if (!pldev)
{
ERR("Could not load driver: '%ls'\n", pwsz);
continue;
}
/* Get the mode list from the driver */
pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject);
if (!pdminfo)
{
ERR("Could not get mode list for '%ls'\n", pwsz);
continue;
}
/* Attach the mode info to the device */
pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
pGraphicsDevice->pdevmodeInfo = pdminfo;
/* Loop all DEVMODEs */
pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
for (pdm = pdminfo->adevmode;
(pdm + 1 <= pdmEnd) && (pdm->dmSize != 0);
pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
{
/* Count this DEVMODE */
cModes++;
/* Some drivers like the VBox driver don't fill the dmDeviceName
with the name of the display driver. So fix that here. */
wcsncpy(pdm->dmDeviceName, pwsz, CCHDEVICENAME);
pdm->dmDeviceName[CCHDEVICENAME - 1] = 0;
}
// FIXME: release the driver again until it's used?
}
if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
{
ERR("No devmodes\n");
ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
return NULL;
}
/* Allocate an index buffer */
pGraphicsDevice->cDevModes = cModes;
pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
cModes * sizeof(DEVMODEENTRY),
GDITAG_GDEVICE);
if (!pGraphicsDevice->pDevModeList)
{
ERR("No devmode list\n");
ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
return NULL;
}
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;
pdminfo = pdminfo->pdmiNext)
{
/* Calculate End of the DEVMODEs */
pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
/* Loop through the DEVMODEs */
for (pdm = pdminfo->adevmode;
(pdm + 1 <= pdmEnd) && (pdm->dmSize != 0);
pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
{
TRACE(" %S has mode %lux%lux%lu(%lu Hz)\n",
pdm->dmDeviceName,
pdm->dmPelsWidth,
pdm->dmPelsHeight,
pdm->dmBitsPerPel,
pdm->dmDisplayFrequency);
/* Compare with the default entry */
if (!bModeMatch &&
pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
pdm->dmPelsHeight == pdmDefault->dmPelsHeight)
{
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;
}
}
/* Initialize the entry */
pGraphicsDevice->pDevModeList[i].dwFlags = 0;
pGraphicsDevice->pDevModeList[i].pdm = pdm;
i++;
}
}
/* Lock loader */
EngAcquireSemaphore(ghsemGraphicsDeviceList);
@@ -250,7 +270,7 @@ EngpRegisterGraphicsDevice(
/* Unlock loader */
EngReleaseSemaphore(ghsemGraphicsDeviceList);
TRACE("Prepared %lu modes for %ls\n", cModes, pGraphicsDevice->pwszDescription);
TRACE("Prepared %lu modes for %ls\n", pGraphicsDevice->cDevModes, pGraphicsDevice->pwszDescription);
return pGraphicsDevice;
}
+5
View File
@@ -29,6 +29,11 @@ EngpRegisterGraphicsDevice(
_In_ PUNICODE_STRING pustrDescription,
_In_ PDEVMODEW pdmDefault);
BOOLEAN
EngpPopulateDeviceModeList(
_Inout_ PGRAPHICS_DEVICE pGraphicsDevice,
_In_ PDEVMODEW pdmDefault);
INIT_FUNCTION
NTSTATUS
NTAPI