https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9db63ad59552fd58d94934ebb158b18177da468a

commit 9db63ad59552fd58d94934ebb158b18177da468a
Author:     Hervé Poussineau <[email protected]>
AuthorDate: Sun Mar 20 15:45:19 2022 +0100
Commit:     hpoussin <[email protected]>
CommitDate: Fri Apr 15 23:09:16 2022 +0200

    [WIN32SS] Add functions related to MDEV (creation, destruction...)
---
 win32ss/gdi/eng/mdevobj.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++
 win32ss/gdi/eng/mdevobj.h |  29 +++++++
 2 files changed, 224 insertions(+)

diff --git a/win32ss/gdi/eng/mdevobj.c b/win32ss/gdi/eng/mdevobj.c
index 25b85b6e94c..98d835e6c5a 100644
--- a/win32ss/gdi/eng/mdevobj.c
+++ b/win32ss/gdi/eng/mdevobj.c
@@ -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);
+}
diff --git a/win32ss/gdi/eng/mdevobj.h b/win32ss/gdi/eng/mdevobj.h
index 1d687d436a4..6dfb7aea4cf 100644
--- a/win32ss/gdi/eng/mdevobj.h
+++ b/win32ss/gdi/eng/mdevobj.h
@@ -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 */

Reply via email to