mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +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)
|
||||
{
|
||||
UNICODE_STRING ustrCurrent;
|
||||
PPDEVOBJ ppdev;
|
||||
PPDEVOBJ ppdev = NULL;
|
||||
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||
ULONG i;
|
||||
|
||||
/* Acquire PDEV lock */
|
||||
EngAcquireSemaphore(ghsemPDEV);
|
||||
|
@ -653,16 +654,17 @@ EngpGetPDEV(
|
|||
if (pustrDeviceName)
|
||||
{
|
||||
/* 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 */
|
||||
pGraphicsDevice = ppdev->pGraphicsDevice;
|
||||
pGraphicsDevice = gpmdev->dev[i].ppdev->pGraphicsDevice;
|
||||
|
||||
/* Compare the name */
|
||||
RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
|
||||
if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
|
||||
{
|
||||
/* Found! */
|
||||
ppdev = gpmdev->dev[i].ppdev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -679,27 +681,6 @@ EngpGetPDEV(
|
|||
/* Yes, reference the PDEV */
|
||||
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 */
|
||||
EngReleaseSemaphore(ghsemPDEV);
|
||||
|
@ -707,6 +688,168 @@ EngpGetPDEV(
|
|||
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
|
||||
NTAPI
|
||||
PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
|
||||
|
|
|
@ -228,4 +228,20 @@ PDEVOBJ_Create(
|
|||
_In_opt_ PDEVMODEW pdm,
|
||||
_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 */
|
||||
|
|
|
@ -263,10 +263,9 @@ co_IntInitializeDesktopGraphics(VOID)
|
|||
UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
|
||||
PDESKTOP pdesk;
|
||||
|
||||
gpmdev = ExAllocatePoolZero(PagedPool, sizeof(MDEVOBJ), GDITAG_MDEV);
|
||||
if (!gpmdev)
|
||||
if (PDEVOBJ_lChangeDisplaySettings(NULL, NULL, NULL, &gpmdev, TRUE) != DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
ERR("Failed to allocate MDEV.\n");
|
||||
ERR("PDEVOBJ_lChangeDisplaySettings() failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue