mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 05:58:13 +00:00
[WIN32SS] Implement PDEVOBJ_lChangeDisplaySettings to create initial MDEV
This function can create a MDEV for the whole display (maybe containing multiple PDEVs), or update settings of a specific PDEV. - call PDEVOBJ_lChangeDisplaySettings when switching to graphics mode. - modify EngpGetPDEV to search requested PDEV only in current MDEV
This commit is contained in:
parent
9db63ad595
commit
2d2824f1b9
3 changed files with 185 additions and 27 deletions
|
@ -643,8 +643,9 @@ EngpGetPDEV(
|
||||||
_In_opt_ PUNICODE_STRING pustrDeviceName)
|
_In_opt_ PUNICODE_STRING pustrDeviceName)
|
||||||
{
|
{
|
||||||
UNICODE_STRING ustrCurrent;
|
UNICODE_STRING ustrCurrent;
|
||||||
PPDEVOBJ ppdev;
|
PPDEVOBJ ppdev = NULL;
|
||||||
PGRAPHICS_DEVICE pGraphicsDevice;
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
/* Acquire PDEV lock */
|
/* Acquire PDEV lock */
|
||||||
EngAcquireSemaphore(ghsemPDEV);
|
EngAcquireSemaphore(ghsemPDEV);
|
||||||
|
@ -653,16 +654,17 @@ EngpGetPDEV(
|
||||||
if (pustrDeviceName)
|
if (pustrDeviceName)
|
||||||
{
|
{
|
||||||
/* Loop all present PDEVs */
|
/* Loop all present PDEVs */
|
||||||
for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
|
for (i = 0; i < gpmdev->cDev; i++)
|
||||||
{
|
{
|
||||||
/* Get a pointer to the GRAPHICS_DEVICE */
|
/* Get a pointer to the GRAPHICS_DEVICE */
|
||||||
pGraphicsDevice = ppdev->pGraphicsDevice;
|
pGraphicsDevice = gpmdev->dev[i].ppdev->pGraphicsDevice;
|
||||||
|
|
||||||
/* Compare the name */
|
/* Compare the name */
|
||||||
RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
|
RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
|
||||||
if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
|
if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
|
||||||
{
|
{
|
||||||
/* Found! */
|
/* Found! */
|
||||||
|
ppdev = gpmdev->dev[i].ppdev;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,27 +681,6 @@ EngpGetPDEV(
|
||||||
/* Yes, reference the PDEV */
|
/* Yes, reference the PDEV */
|
||||||
PDEVOBJ_vReference(ppdev);
|
PDEVOBJ_vReference(ppdev);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pustrDeviceName)
|
|
||||||
pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0);
|
|
||||||
if (!pGraphicsDevice)
|
|
||||||
pGraphicsDevice = gpPrimaryGraphicsDevice;
|
|
||||||
|
|
||||||
/* No, create a new PDEV for the given device */
|
|
||||||
ppdev = PDEVOBJ_Create(pGraphicsDevice,
|
|
||||||
pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm,
|
|
||||||
LDEV_DEVICE_DISPLAY);
|
|
||||||
if (ppdev)
|
|
||||||
{
|
|
||||||
/* Set as primary PDEV, if we don't have one yet */
|
|
||||||
if (!gpmdev->ppdevGlobal)
|
|
||||||
{
|
|
||||||
gpmdev->ppdevGlobal = ppdev;
|
|
||||||
ppdev->pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release PDEV lock */
|
/* Release PDEV lock */
|
||||||
EngReleaseSemaphore(ghsemPDEV);
|
EngReleaseSemaphore(ghsemPDEV);
|
||||||
|
@ -707,6 +688,168 @@ EngpGetPDEV(
|
||||||
return ppdev;
|
return ppdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
PDEVOBJ_lChangeDisplaySettings(
|
||||||
|
_In_opt_ PUNICODE_STRING pustrDeviceName,
|
||||||
|
_In_opt_ PDEVMODEW RequestedMode,
|
||||||
|
_In_opt_ PMDEVOBJ pmdevOld,
|
||||||
|
_Out_ PMDEVOBJ *ppmdevNew,
|
||||||
|
_In_ BOOL bSearchClosestMode)
|
||||||
|
{
|
||||||
|
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||||
|
PMDEVOBJ pmdev = NULL;
|
||||||
|
PDEVMODEW pdm = NULL;
|
||||||
|
ULONG lRet = DISP_CHANGE_SUCCESSFUL;
|
||||||
|
ULONG i, j;
|
||||||
|
|
||||||
|
TRACE("PDEVOBJ_lChangeDisplaySettings('%wZ' '%dx%dx%d (%d Hz)' %p %p)\n",
|
||||||
|
pustrDeviceName,
|
||||||
|
RequestedMode ? RequestedMode->dmPelsWidth : 0,
|
||||||
|
RequestedMode ? RequestedMode->dmPelsHeight : 0,
|
||||||
|
RequestedMode ? RequestedMode->dmBitsPerPel : 0,
|
||||||
|
RequestedMode ? RequestedMode->dmDisplayFrequency : 0,
|
||||||
|
pmdevOld, ppmdevNew);
|
||||||
|
|
||||||
|
if (pustrDeviceName)
|
||||||
|
{
|
||||||
|
pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0);
|
||||||
|
if (!pGraphicsDevice)
|
||||||
|
{
|
||||||
|
ERR("Wrong device name provided: '%wZ'\n", pustrDeviceName);
|
||||||
|
lRet = DISP_CHANGE_BADPARAM;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (RequestedMode)
|
||||||
|
{
|
||||||
|
pGraphicsDevice = gpPrimaryGraphicsDevice;
|
||||||
|
if (!pGraphicsDevice)
|
||||||
|
{
|
||||||
|
ERR("Wrong device'\n");
|
||||||
|
lRet = DISP_CHANGE_BADPARAM;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pGraphicsDevice)
|
||||||
|
{
|
||||||
|
if (!LDEVOBJ_bProbeAndCaptureDevmode(pGraphicsDevice, RequestedMode, &pdm, bSearchClosestMode))
|
||||||
|
{
|
||||||
|
ERR("DrvProbeAndCaptureDevmode() failed\n");
|
||||||
|
lRet = DISP_CHANGE_BADMODE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here, we know that input parameters were correct */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Create new MDEV. Note that if we provide a device name,
|
||||||
|
* MDEV will only contain one device.
|
||||||
|
* */
|
||||||
|
|
||||||
|
if (pmdevOld)
|
||||||
|
{
|
||||||
|
/* Disable old MDEV */
|
||||||
|
if (MDEVOBJ_bDisable(pmdevOld))
|
||||||
|
{
|
||||||
|
/* Create new MDEV. On failure, reenable old MDEV */
|
||||||
|
pmdev = MDEVOBJ_Create(pustrDeviceName, pdm);
|
||||||
|
if (!pmdev)
|
||||||
|
MDEVOBJ_vEnable(pmdevOld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pmdev = MDEVOBJ_Create(pustrDeviceName, pdm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pmdev)
|
||||||
|
{
|
||||||
|
ERR("Failed to create new MDEV\n");
|
||||||
|
lRet = DISP_CHANGE_FAILED;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
lRet = DISP_CHANGE_SUCCESSFUL;
|
||||||
|
*ppmdevNew = pmdev;
|
||||||
|
|
||||||
|
/* We now have to do the mode switch */
|
||||||
|
|
||||||
|
if (pustrDeviceName && pmdevOld)
|
||||||
|
{
|
||||||
|
/* We changed settings of one device. Add other devices which were already present */
|
||||||
|
for (i = 0; i < pmdevOld->cDev; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < pmdev->cDev; j++)
|
||||||
|
{
|
||||||
|
if (pmdev->dev[j].ppdev->pGraphicsDevice == pmdevOld->dev[i].ppdev->pGraphicsDevice)
|
||||||
|
{
|
||||||
|
if (PDEVOBJ_bDynamicModeChange(pmdevOld->dev[i].ppdev, pmdev->dev[j].ppdev))
|
||||||
|
{
|
||||||
|
PPDEVOBJ tmp = pmdevOld->dev[i].ppdev;
|
||||||
|
pmdevOld->dev[i].ppdev = pmdev->dev[j].ppdev;
|
||||||
|
pmdev->dev[j].ppdev = tmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR("Failed to apply new settings\n");
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == pmdev->cDev)
|
||||||
|
{
|
||||||
|
PDEVOBJ_vReference(pmdevOld->dev[i].ppdev);
|
||||||
|
pmdev->dev[pmdev->cDev].ppdev = pmdevOld->dev[i].ppdev;
|
||||||
|
pmdev->cDev++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pmdev->cDev == 1)
|
||||||
|
{
|
||||||
|
pmdev->ppdevGlobal = pmdev->dev[0].ppdev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: currently, only use the first display */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
PDEVOBJ_vReference(pmdev->dev[0].ppdev);
|
||||||
|
pmdev->ppdevGlobal = pmdev->dev[0].ppdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pmdevOld)
|
||||||
|
{
|
||||||
|
/* Search PDEVs which were in pmdevOld, but are not anymore in pmdev, and disable them */
|
||||||
|
for (i = 0; i < pmdevOld->cDev; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < pmdev->cDev; j++)
|
||||||
|
{
|
||||||
|
if (pmdev->dev[j].ppdev->pGraphicsDevice == pmdevOld->dev[i].ppdev->pGraphicsDevice)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j == pmdev->cDev)
|
||||||
|
PDEVOBJ_bDisableDisplay(pmdevOld->dev[i].ppdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (lRet != DISP_CHANGE_SUCCESSFUL)
|
||||||
|
{
|
||||||
|
*ppmdevNew = NULL;
|
||||||
|
if (pmdev)
|
||||||
|
MDEVOBJ_vDestroy(pmdev);
|
||||||
|
if (pdm && pdm != RequestedMode)
|
||||||
|
ExFreePoolWithTag(pdm, GDITAG_DEVMODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lRet;
|
||||||
|
}
|
||||||
|
|
||||||
INT
|
INT
|
||||||
NTAPI
|
NTAPI
|
||||||
PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
|
PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
|
||||||
|
|
|
@ -228,4 +228,20 @@ PDEVOBJ_Create(
|
||||||
_In_opt_ PDEVMODEW pdm,
|
_In_opt_ PDEVMODEW pdm,
|
||||||
_In_ ULONG ldevtype);
|
_In_ ULONG ldevtype);
|
||||||
|
|
||||||
|
/* Change display settings:
|
||||||
|
* - pustrDeviceName: name of the device to change settings. Can be NULL to specify whole display surface
|
||||||
|
* - RequestedMode: new parameters for device. Ignored if pstrDeviceName is NULL
|
||||||
|
* - pmdevOld: old MDEVOBJ. Can be NULL if we are creating the first one
|
||||||
|
* - ppdevNew: MDEVOBJ created by this function, with the new settings
|
||||||
|
* - bSearchClosestMode: do we need to search exact requested mode, or a mostly similar one
|
||||||
|
* Return value: a DISP_CHANGE_* value
|
||||||
|
*/
|
||||||
|
LONG
|
||||||
|
PDEVOBJ_lChangeDisplaySettings(
|
||||||
|
_In_opt_ PUNICODE_STRING pustrDeviceName,
|
||||||
|
_In_opt_ PDEVMODEW RequestedMode,
|
||||||
|
_In_opt_ PMDEVOBJ pmdevOld,
|
||||||
|
_Out_ PMDEVOBJ *ppmdevNew,
|
||||||
|
_In_ BOOL bSearchClosestMode);
|
||||||
|
|
||||||
#endif /* !__WIN32K_PDEVOBJ_H */
|
#endif /* !__WIN32K_PDEVOBJ_H */
|
||||||
|
|
|
@ -263,10 +263,9 @@ co_IntInitializeDesktopGraphics(VOID)
|
||||||
UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
|
UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
|
||||||
PDESKTOP pdesk;
|
PDESKTOP pdesk;
|
||||||
|
|
||||||
gpmdev = ExAllocatePoolZero(PagedPool, sizeof(MDEVOBJ), GDITAG_MDEV);
|
if (PDEVOBJ_lChangeDisplaySettings(NULL, NULL, NULL, &gpmdev, TRUE) != DISP_CHANGE_SUCCESSFUL)
|
||||||
if (!gpmdev)
|
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate MDEV.\n");
|
ERR("PDEVOBJ_lChangeDisplaySettings() failed.\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue