mirror of
https://github.com/reactos/reactos.git
synced 2024-12-03 16:33:37 +08:00
[WIN32SS] Add functions related to MDEV (creation, destruction...)
This commit is contained in:
parent
a0cfdcd409
commit
9db63ad595
@ -9,5 +9,200 @@
|
||||
#include <win32k.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DBG_DEFAULT_CHANNEL(EngMDev);
|
||||
|
||||
PMDEVOBJ gpmdev = NULL; /* FIXME: should be stored in gpDispInfo->pmdev */
|
||||
|
||||
VOID
|
||||
MDEVOBJ_vEnable(
|
||||
_Inout_ PMDEVOBJ pmdev)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < pmdev->cDev; i++)
|
||||
{
|
||||
PDEVOBJ_vEnableDisplay(pmdev->dev[i].ppdev);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
MDEVOBJ_bDisable(
|
||||
_Inout_ PMDEVOBJ pmdev)
|
||||
{
|
||||
BOOL bSuccess = TRUE;
|
||||
ULONG i, j;
|
||||
|
||||
for (i = 0; i < pmdev->cDev; i++)
|
||||
{
|
||||
if (!PDEVOBJ_bDisableDisplay(pmdev->dev[i].ppdev))
|
||||
{
|
||||
bSuccess = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bSuccess)
|
||||
{
|
||||
/* Failed to disable all PDEVs. Reenable those we have disabled */
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
PDEVOBJ_vEnableDisplay(pmdev->dev[i].ppdev);
|
||||
}
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
PMDEVOBJ
|
||||
MDEVOBJ_Create(
|
||||
_In_opt_ PUNICODE_STRING pustrDeviceName,
|
||||
_In_opt_ PDEVMODEW pdm)
|
||||
{
|
||||
PMDEVOBJ pmdev = NULL;
|
||||
PPDEVOBJ ppdev;
|
||||
PGRAPHICS_DEVICE pGraphicsDevice;
|
||||
DEVMODEW dmDefault;
|
||||
PDEVMODEW localPdm;
|
||||
ULONG iDevNum = 0;
|
||||
|
||||
TRACE("MDEVOBJ_Create('%wZ' '%dx%dx%d (%d Hz)')\n",
|
||||
pustrDeviceName,
|
||||
pdm ? pdm->dmPelsWidth : 0,
|
||||
pdm ? pdm->dmPelsHeight : 0,
|
||||
pdm ? pdm->dmBitsPerPel : 0,
|
||||
pdm ? pdm->dmDisplayFrequency : 0);
|
||||
|
||||
pmdev = ExAllocatePoolZero(PagedPool, sizeof(MDEVOBJ), GDITAG_MDEV);
|
||||
if (!pmdev)
|
||||
{
|
||||
ERR("Failed to allocate memory for MDEV\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pmdev->cDev = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/* Get the right graphics devices: either the specified one, or all of them (one after one) */
|
||||
if (pustrDeviceName)
|
||||
pGraphicsDevice = (iDevNum == 0) ? EngpFindGraphicsDevice(pustrDeviceName, 0) : NULL;
|
||||
else
|
||||
pGraphicsDevice = EngpFindGraphicsDevice(NULL, iDevNum);
|
||||
iDevNum++;
|
||||
|
||||
if (!pGraphicsDevice)
|
||||
{
|
||||
TRACE("Done enumeration of graphic devices (DeviceName '%wZ' iDevNum %d)\n", pustrDeviceName, iDevNum);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pdm)
|
||||
{
|
||||
/* No settings requested. Read default settings from registry to dmDefault */
|
||||
HKEY hKey;
|
||||
WCHAR DeviceKey[128];
|
||||
ULONG cbSize;
|
||||
NTSTATUS Status;
|
||||
DWORD dwValue;
|
||||
|
||||
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);
|
||||
ZwClose(hKey);
|
||||
}
|
||||
|
||||
/* Get or create a PDEV for these settings */
|
||||
if (LDEVOBJ_bProbeAndCaptureDevmode(pGraphicsDevice, pdm ? pdm : &dmDefault, &localPdm, !pdm))
|
||||
{
|
||||
ppdev = PDEVOBJ_Create(pGraphicsDevice, localPdm, LDEV_DEVICE_DISPLAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppdev = NULL;
|
||||
}
|
||||
|
||||
if (ppdev)
|
||||
{
|
||||
/* Great. We have a found a matching PDEV. Store it in MDEV */
|
||||
TRACE("Adding '%S' to MDEV %p\n", pGraphicsDevice->szWinDeviceName, pmdev);
|
||||
PDEVOBJ_vReference(ppdev);
|
||||
pmdev->dev[pmdev->cDev].ppdev = ppdev;
|
||||
pmdev->cDev++;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Failed to add '%S' to MDEV %p\n", pGraphicsDevice->szWinDeviceName, pmdev);
|
||||
}
|
||||
}
|
||||
|
||||
if (pmdev->cDev == 0)
|
||||
{
|
||||
TRACE("Failed to add any device to MDEV. Returning NULL\n");
|
||||
MDEVOBJ_vDestroy(pmdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("Returning new MDEV %p with %d devices\n", pmdev, pmdev->cDev);
|
||||
return pmdev;
|
||||
}
|
||||
|
||||
VOID
|
||||
MDEVOBJ_vDestroy(
|
||||
_Inout_ PMDEVOBJ pmdev)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < pmdev->cDev; i++)
|
||||
{
|
||||
PDEVOBJ_vRelease(pmdev->dev[i].ppdev);
|
||||
}
|
||||
|
||||
if (pmdev->cDev > 1)
|
||||
PDEVOBJ_vRelease(pmdev->ppdevGlobal);
|
||||
|
||||
ExFreePoolWithTag(pmdev, GDITAG_MDEV);
|
||||
}
|
||||
|
@ -7,11 +7,40 @@ typedef struct _PDEVOBJ *PPDEVOBJ;
|
||||
|
||||
typedef struct _MDEVOBJ
|
||||
{
|
||||
ULONG cDev;
|
||||
PPDEVOBJ ppdevGlobal;
|
||||
struct
|
||||
{
|
||||
PPDEVOBJ ppdev;
|
||||
} dev[10]; /* FIXME: max number of displays. Needs dynamic allocation */
|
||||
} MDEVOBJ, *PMDEVOBJ;
|
||||
|
||||
/* Globals ********************************************************************/
|
||||
|
||||
extern PMDEVOBJ gpmdev; /* FIXME: should be stored in gpDispInfo->pmdev */
|
||||
|
||||
/* Function prototypes ********************************************************/
|
||||
|
||||
VOID
|
||||
MDEVOBJ_vEnable(
|
||||
_Inout_ PMDEVOBJ pmdev);
|
||||
|
||||
BOOL
|
||||
MDEVOBJ_bDisable(
|
||||
_Inout_ PMDEVOBJ pmdev);
|
||||
|
||||
/* Create a new MDEV:
|
||||
* - pustrDeviceName: name of the device to put in MDEV. If NULL, will put all graphics devices in MDEV
|
||||
* - pdm: settings associated to pustrDeviceName. Unused if pustrDeviceName is NULL.
|
||||
* Return value: the new MDEV (or NULL in case of error)
|
||||
*/
|
||||
PMDEVOBJ
|
||||
MDEVOBJ_Create(
|
||||
_In_opt_ PUNICODE_STRING pustrDeviceName,
|
||||
_In_opt_ PDEVMODEW pdm);
|
||||
|
||||
VOID
|
||||
MDEVOBJ_vDestroy(
|
||||
_Inout_ PMDEVOBJ pmdev);
|
||||
|
||||
#endif /* !__WIN32K_MDEVOBJ_H */
|
||||
|
Loading…
Reference in New Issue
Block a user