Commit the stuff. Lots of changes. I'll write a proper list of changes when it's...
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 30 Jan 2010 21:12:42 +0000 (21:12 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 30 Jan 2010 21:12:42 +0000 (21:12 +0000)
svn path=/branches/reactos-yarotows/; revision=45355

36 files changed:
subsystems/win32/csrss/win32csr/win32csr.rbuild
subsystems/win32/win32k/eng/device.c
subsystems/win32/win32k/eng/ldevobj.c [new file with mode: 0644]
subsystems/win32/win32k/eng/pdevobj.c [new file with mode: 0644]
subsystems/win32/win32k/eng/semaphor.c
subsystems/win32/win32k/include/dc.h
subsystems/win32/win32k/include/device.h [new file with mode: 0644]
subsystems/win32/win32k/include/intgdi.h
subsystems/win32/win32k/include/ldevobj.h [new file with mode: 0644]
subsystems/win32/win32k/include/pdevobj.h
subsystems/win32/win32k/include/win32k.h
subsystems/win32/win32k/ldr/loader.c
subsystems/win32/win32k/main/dllmain.c
subsystems/win32/win32k/misc/driver.c
subsystems/win32/win32k/misc/file.c
subsystems/win32/win32k/misc/registry.c
subsystems/win32/win32k/ntddraw/dxeng.c
subsystems/win32/win32k/ntuser/display.c
subsystems/win32/win32k/ntuser/kbdlayout.c
subsystems/win32/win32k/ntuser/metric.c
subsystems/win32/win32k/ntuser/ntstubs.c
subsystems/win32/win32k/ntuser/ntuser.c
subsystems/win32/win32k/ntuser/windc.c
subsystems/win32/win32k/objects/bitmaps.c
subsystems/win32/win32k/objects/cliprgn.c
subsystems/win32/win32k/objects/dcattr.c
subsystems/win32/win32k/objects/dclife.c
subsystems/win32/win32k/objects/dcstate.c
subsystems/win32/win32k/objects/device.c
subsystems/win32/win32k/objects/dibobj.c
subsystems/win32/win32k/objects/freetype.c
subsystems/win32/win32k/objects/gdibatch.c
subsystems/win32/win32k/objects/gdidbg.c
subsystems/win32/win32k/objects/gdiobj.c
subsystems/win32/win32k/stubs/stubs.c
subsystems/win32/win32k/win32k.rbuild

index 7a14f63..34292a8 100644 (file)
@@ -9,9 +9,10 @@
        <include base="console">.</include>
        <compilerflag compilerset="gcc">-fms-extensions</compilerflag>
        <library>ntdll</library>
-       <library>user32</library>
-       <library>gdi32</library>
-       <library>advapi32</library>
+       <library delayimport="true">user32</library>
+       <library delayimport="true">gdi32</library>
+       <library delayimport="true">advapi32</library>
+       <library>delayimp</library>
        <library>win32ksys</library>
        <library>psapi</library>
        <pch>w32csr.h</pch>
index 301497a..057edc5 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+static PGRAPHICS_DEVICE gpGraphicsDeviceFirst = NULL;
+static PGRAPHICS_DEVICE gpGraphicsDeviceLast = NULL;
+static HSEMAPHORE ghsemGraphicsDeviceList;
+static ULONG giDevNum = 1;
+
+BOOL
+NTAPI
+InitDeviceImpl()
+{
+    ghsemGraphicsDeviceList = EngCreateSemaphore();
+    if (!ghsemGraphicsDeviceList)
+        return FALSE;
+
+    return TRUE;
+}
+
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpRegisterGraphicsDevice(
+    PUNICODE_STRING pustrDeviceName,
+    PUNICODE_STRING pustrDiplayDrivers,
+    PUNICODE_STRING pustrDescription,
+    PDEVMODEW pdmDefault)
+{
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    PDEVICE_OBJECT pDeviceObject;
+    PFILE_OBJECT pFileObject;
+    NTSTATUS Status;
+    PWSTR pwsz;
+    ULONG i, cj, cModes = 0;
+    BOOL bEnable = TRUE;
+    PDEVMODEINFO pdminfo;
+    PDEVMODEW pdm, pdmEnd;
+    PLDEVOBJ pldev;
+
+    DPRINT1("EngpRegisterGraphicsDevice(%S)\n", pustrDeviceName->Buffer);
+
+    /* Allocate a GRAPHICS_DEVICE structure */
+    pGraphicsDevice = ExAllocatePoolWithTag(PagedPool,
+                                            sizeof(GRAPHICS_DEVICE),
+                                            GDITAG_GDEVICE);
+    if (!pGraphicsDevice)
+    {
+        DPRINT1("ExAllocatePoolWithTag failed\n");
+        return NULL;
+    }
+
+    /* Try to open the driver */
+    Status = IoGetDeviceObjectPointer(pustrDeviceName,
+                                      FILE_READ_DATA | FILE_WRITE_DATA,
+                                      &pFileObject,
+                                      &pDeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Could not open driver, 0x%lx\n", Status);
+        ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
+        return NULL;
+    }
+
+    /* Enable the device */
+    EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cj);
+
+    /* Copy the device and file object pointers */
+    pGraphicsDevice->DeviceObject = pDeviceObject;
+    pGraphicsDevice->FileObject = pFileObject;
+
+    /* Copy device name */
+    wcsncpy(pGraphicsDevice->szNtDeviceName,
+            pustrDeviceName->Buffer,
+            sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR));
+
+    /* Create a win device name (FIXME: virtual devices!) */
+    swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum);
+
+    /* Allocate a buffer for the strings */
+    cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
+    pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP);
+    if (!pwsz)
+    {
+        DPRINT1("Could not allocate string buffer\n");
+        ASSERT(FALSE); // FIXME
+    }
+
+    /* Copy display driver names */
+    pGraphicsDevice->pDiplayDrivers = pwsz;
+    RtlCopyMemory(pGraphicsDevice->pDiplayDrivers,
+                  pustrDiplayDrivers->Buffer,
+                  pustrDiplayDrivers->Length);
+
+    /* Copy description */
+    pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR);
+    RtlCopyMemory(pGraphicsDevice->pwszDescription,
+                  pustrDescription->Buffer,
+                  pustrDescription->Length + sizeof(WCHAR));
+
+    /* Initialize the pdevmodeInfo list and default index  */
+    pGraphicsDevice->pdevmodeInfo = NULL;
+    pGraphicsDevice->iDefaultMode = 0;
+    pGraphicsDevice->iCurrentMode = 0;
+
+    // FIXME: initialize state flags
+    pGraphicsDevice->StateFlags = 0;
+
+    /* Loop through the driver names */
+    for (; *pwsz; pwsz += wcslen(pwsz) + 1)
+    {
+        DPRINT1("trying driver: %ls\n", pwsz);
+        /* Try to load the display driver */
+        pldev = EngLoadDriver(pwsz, LDEV_DEVICE_DISPLAY);
+        if (!pldev)
+        {
+            DPRINT1("Could not load driver: '%ls'\n", pwsz);
+            continue;
+        }
+
+        /* Get the mode list from the driver */
+        pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject);
+        if (!pdminfo)
+        {
+            DPRINT1("Could not get mode list for '%ls'\n", pwsz);
+            continue;
+        }
+
+        /* Attach the mode info to the device */
+        pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
+        pGraphicsDevice->pdevmodeInfo = pdminfo;
+
+        /* Count DEVMODEs */
+        pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
+        for (pdm = pdminfo->adevmode;
+             pdm + 1 <= pdmEnd;
+             pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
+        {
+            cModes++;
+        }
+
+        // FIXME: release the driver again until it's used?
+    }
+
+    if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
+    {
+        DPRINT1("No devmodes\n");
+        ExFreePool(pGraphicsDevice);
+        return NULL;
+    }
+
+    /* Allocate an index buffer */
+    pGraphicsDevice->cDevModes = cModes;
+    pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
+                                                          cModes * sizeof(DEVMODEENTRY),
+                                                          GDITAG_GDEVICE);
+    if (!pGraphicsDevice->pDevModeList)
+    {
+        DPRINT1("No devmode list\n");
+        ExFreePool(pGraphicsDevice);
+        return NULL;
+    }
+
+    /* 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 = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
+        {
+            /* Compare with the default entry */
+            if (pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
+                pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
+                pdm->dmPelsHeight == pdmDefault->dmPelsHeight &&
+                pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency)
+            {
+                pGraphicsDevice->iDefaultMode = i;
+                pGraphicsDevice->iCurrentMode = i;
+                DPRINT1("Found default entry: %ld '%ls'\n", i, pdm->dmDeviceName);
+            }
+
+            /* Initialize the entry */
+            pGraphicsDevice->pDevModeList[i].dwFlags = 0;
+            pGraphicsDevice->pDevModeList[i].pdm = pdm;
+            i++;
+        }
+     }
+
+    /* Lock loader */
+    EngAcquireSemaphore(ghsemGraphicsDeviceList);
+
+    /* Insert the device into the global list */
+    pGraphicsDevice->pNextGraphicsDevice = gpGraphicsDeviceLast;
+    gpGraphicsDeviceLast = pGraphicsDevice;
+    if (!gpGraphicsDeviceFirst)
+        gpGraphicsDeviceFirst = pGraphicsDevice;
+
+    /* Increment device number */
+    giDevNum++;
+
+    /* Unlock loader */
+    EngReleaseSemaphore(ghsemGraphicsDeviceList);
+    DPRINT1("Prepared %ld modes for %ls\n", cModes, pGraphicsDevice->pwszDescription);
+
+    return pGraphicsDevice;
+}
+
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpFindGraphicsDevice(
+    PUNICODE_STRING pustrDevice,
+    ULONG iDevNum,
+    DWORD dwFlags)
+{
+    UNICODE_STRING ustrCurrent;
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    ULONG i;
+
+    /* Lock list */
+    EngAcquireSemaphore(ghsemGraphicsDeviceList);
+
+    if (pustrDevice)
+    {
+        /* Loop through the list of devices */
+        for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
+             pGraphicsDevice;
+             pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++)
+        {
+            /* Compare the device name */
+            RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
+            if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE))
+            {
+                break;
+            }
+        }
+    }
+    else
+    {
+        /* Loop through the list of devices */
+        for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
+             pGraphicsDevice && i < iDevNum;
+             pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++);
+    }
+
+    /* Unlock list */
+    EngReleaseSemaphore(ghsemGraphicsDeviceList);
+
+    return pGraphicsDevice;
+}
+
+
 static
 NTSTATUS
 EngpFileIoRequest(
@@ -39,7 +293,7 @@ EngpFileIoRequest(
     /* Initialize an event */
     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
 
-    /* Build IPR */
+    /* Build IRP */
     liStartOffset.QuadPart = ullStartOffset;
     pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
                                         pDeviceObject,
@@ -113,7 +367,7 @@ EngFileIoControl(
     /* Initialize an event */
     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
 
-    /* Build IO control IPR */
+    /* Build IO control IRP */
     pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode,
                                          pDeviceObject,
                                          lpInBuffer,
diff --git a/subsystems/win32/win32k/eng/ldevobj.c b/subsystems/win32/win32k/eng/ldevobj.c
new file mode 100644 (file)
index 0000000..87b9a17
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * PURPOSE:          Support for logical devices
+ * FILE:             subsystems/win32/win32k/eng/ldevobj.c
+ * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include <w32k.h>
+
+#include <intrin.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#ifndef RVA_TO_ADDR
+#define RVA_TO_ADDR(Base,Rva) ((PVOID)(((ULONG_PTR)(Base)) + (Rva)))
+#endif
+
+/** Globals *******************************************************************/
+
+HSEMAPHORE ghsemLDEVList;
+LDEVOBJ *gpldevHead = NULL;
+LDEVOBJ *gpldevWin32k = NULL;
+
+
+/** Private functions *********************************************************/
+
+BOOL
+NTAPI
+InitLDEVImpl()
+{
+    /* Initialize the loader lock */
+    ghsemLDEVList = EngCreateSemaphore();
+    if (!ghsemLDEVList)
+    {
+        return FALSE;
+    }
+
+    /* Allocate a LDEVOBJ for win32k */
+    gpldevWin32k = ExAllocatePoolWithTag(PagedPool,
+                                         sizeof(LDEVOBJ) + 
+                                         sizeof(SYSTEM_GDI_DRIVER_INFORMATION),
+                                         GDITAG_LDEV);
+    if (!gpldevWin32k)
+    {
+        return FALSE;
+    }
+
+    /* Initialize the LDEVOBJ for win32k */
+    gpldevWin32k->pldevNext = NULL;
+    gpldevWin32k->pldevPrev = NULL;
+    gpldevWin32k->ldevtype = LDEV_DEVICE_DISPLAY;
+    gpldevWin32k->cRefs = 1;
+    gpldevWin32k->ulDriverVersion = GDI_ENGINE_VERSION;
+    gpldevWin32k->pGdiDriverInfo = (PVOID)(gpldevWin32k + 1);
+    gpldevWin32k->pGdiDriverInfo->DriverName.Buffer = NULL; // FIXME
+    gpldevWin32k->pGdiDriverInfo->ImageAddress = &__ImageBase;
+    gpldevWin32k->pGdiDriverInfo->SectionPointer = NULL;
+    gpldevWin32k->pGdiDriverInfo->EntryPoint = (PVOID)DriverEntry;
+    gpldevWin32k->pGdiDriverInfo->ExportSectionPointer = NULL;
+    gpldevWin32k->pGdiDriverInfo->ImageLength = 0; // FIXME;
+
+    return TRUE;
+}
+
+PLDEVOBJ
+NTAPI
+LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype)
+{
+    PLDEVOBJ pldev;
+
+    /* Allocate the structure from paged pool */
+    pldev = ExAllocatePoolWithTag(PagedPool, sizeof(LDEVOBJ), GDITAG_LDEV);
+    if (!pldev)
+    {
+        DPRINT1("Failed to allocate LDEVOBJ.\n");
+        return NULL;
+    }
+
+    /* Zero out the structure */
+    RtlZeroMemory(pldev, sizeof(LDEVOBJ));
+    
+    /* Set the ldevtype */
+    pldev->ldevtype = ldevtype;
+
+    return pldev;
+}
+
+VOID
+NTAPI
+LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev)
+{
+    /* Make sure we don't have a driver loaded */
+    ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
+
+    /* Free the memory */
+    ExFreePoolWithTag(pldev, TAG_LDEV);
+}
+
+PDEVMODEINFO
+NTAPI
+LDEVOBJ_pdmiGetModes(
+    PLDEVOBJ pldev,
+    HANDLE hDriver)
+{
+    ULONG cbSize, cbFull;
+    PDEVMODEINFO pdminfo;
+
+    DPRINT1("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver);
+
+    /* Call the driver to get the required size */
+    cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
+    if (!cbSize)
+    {
+        DPRINT1("DrvGetModes returned 0\n");
+        return NULL;
+    }
+
+    /* Add space for the header */
+    cbFull = cbSize + FIELD_OFFSET(DEVMODEINFO, adevmode);
+
+    /* Allocate a buffer for the DEVMODE array */
+    pdminfo = ExAllocatePoolWithTag(PagedPool, cbFull, GDITAG_DEVMODE);
+    if (!pdminfo)
+    {
+        DPRINT1("Could not allocate devmodeinfo\n");
+        return NULL;
+    }
+
+    pdminfo->pldev = pldev;
+    pdminfo->cbdevmode = cbSize;
+
+    /* Call the driver again to fill the buffer */
+    cbSize = pldev->pfn.GetModes(hDriver, cbSize, pdminfo->adevmode);
+    if (!cbSize)
+    {
+        /* Could not get modes */
+        DPRINT1("returned size %ld(%ld)\n", cbSize, pdminfo->cbdevmode);
+        ExFreePool(pdminfo);
+        pdminfo = NULL;
+    }
+
+    return pdminfo;
+}
+
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadImage(
+    IN PLDEVOBJ pldev,
+    PUNICODE_STRING pstrPathName)
+{
+    PSYSTEM_GDI_DRIVER_INFORMATION pDriverInfo;
+    NTSTATUS Status;
+    ULONG cbSize;
+
+    /* Make sure no image is loaded yet */
+    ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
+
+    /* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */
+    cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pstrPathName->Length;
+    pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV);
+    if (!pDriverInfo)
+    {
+        DPRINT1("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n");
+        return FALSE;
+    }
+
+    /* Initialize the UNICODE_STRING */
+    pDriverInfo->DriverName.Buffer = (PWSTR)(pDriverInfo + 1);
+    pDriverInfo->DriverName.Length = pstrPathName->Length;
+    pDriverInfo->DriverName.MaximumLength = pstrPathName->Length;
+
+    /* Copy the driver name */
+//    RtlCopyUnicodeString(pDriverInfo->DriverName, pstrPathName);
+    RtlCopyMemory(pDriverInfo->DriverName.Buffer,
+                  pstrPathName->Buffer,
+                  pstrPathName->Length);
+
+    /* Try to load the driver */
+    Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation,
+                                    pDriverInfo,
+                                    sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to load a GDI driver: '%S'\n", pstrPathName->Buffer);
+        ASSERT(FALSE);
+        /* Free the allocated memory */
+        ExFreePoolWithTag(pDriverInfo, TAG_LDEV);
+        return FALSE;
+    }
+
+    /* Set the driver info */
+    pldev->pGdiDriverInfo = pDriverInfo;
+
+    /* Return success. */
+    return TRUE;
+}
+
+VOID
+NTAPI
+LDEVOBJ_vUnloadImage(
+    IN PLDEVOBJ pldev)
+{
+    NTSTATUS Status;
+
+    /* Make sure we have a driver info */
+    ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+    /* Check if we have loaded a driver */
+    if (pldev->pfn.DisableDriver)
+    {
+        /* Call the unload function */
+        pldev->pfn.DisableDriver();
+    }
+
+    /* Unload the driver */
+    Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
+                                    &pldev->pGdiDriverInfo->ImageAddress,
+                                    sizeof(HANDLE));
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to unload the driver, this is bad.\n");
+    }
+
+    /* Free the driver info structure */
+    ExFreePoolWithTag(pldev->pGdiDriverInfo, GDITAG_LDEV);
+    pldev->pGdiDriverInfo = NULL;
+}
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadDriver(
+    IN PLDEVOBJ pldev)
+{
+    PFN_DrvEnableDriver pfnEnableDriver;
+    DRVENABLEDATA ded;
+    ULONG i;
+
+    /* Make sure we have a driver info */
+    ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+    /* Call the drivers DrvEnableDriver function */
+    RtlZeroMemory(&ded, sizeof(ded));
+    pfnEnableDriver = pldev->pGdiDriverInfo->EntryPoint;
+    if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded))
+    {
+        DPRINT1("DrvEnableDriver failed\n");
+
+        /* Unload the image. */
+        LDEVOBJ_vUnloadImage(pldev);
+        return FALSE;
+    }
+
+    /* Copy the returned driver version */
+    pldev->ulDriverVersion = ded.iDriverVersion;
+
+    /* Fill the driver function array */
+    for (i = 0; i < ded.c; i++)
+    {
+        pldev->apfn[ded.pdrvfn[i].iFunc] = ded.pdrvfn[i].pfn;
+    }
+
+    /* Return success. */
+    return TRUE;
+}
+
+
+PVOID
+NTAPI
+LDEVOBJ_pvFindImageProcAddress(
+    IN PLDEVOBJ pldev,
+    IN LPSTR    pszProcName)
+{
+    PVOID pvImageBase;
+    PIMAGE_EXPORT_DIRECTORY pExportDir;
+    PVOID pvProcAdress = NULL;
+    PUSHORT pOrdinals;
+    PULONG pNames, pAddresses;
+    ULONG i, cbSize;
+
+    /* Make sure we have a driver info */
+    ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+    /* Get the pointer to the export directory */
+    pvImageBase = pldev->pGdiDriverInfo->ImageAddress;
+    pExportDir = RtlImageDirectoryEntryToData(pvImageBase,
+                                              TRUE,
+                                              IMAGE_DIRECTORY_ENTRY_EXPORT,
+                                              &cbSize);
+    if (!pExportDir)
+    {
+        return NULL;
+    }
+
+    /* Get pointers to some tables */
+    pNames = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNames);
+    pOrdinals = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNameOrdinals);
+    pAddresses = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfFunctions);
+
+    /* Loop the export table */
+    for (i = 0; i < pExportDir->NumberOfNames; i++)
+    {
+        /* Compare the name */
+        if (_stricmp(pszProcName, RVA_TO_ADDR(pvImageBase, pNames[i])) == 0)
+        {
+            /* Found! Calculate the procedure address */
+            pvProcAdress = RVA_TO_ADDR(pvImageBase, pAddresses[pOrdinals[i]]);
+            break;
+        }
+    }
+
+    /* Return the address */
+    return pvProcAdress;
+}
+
+PLDEVOBJ
+NTAPI
+EngLoadImageEx(
+    LPWSTR pwszDriverName,
+    ULONG ldevtype)
+{
+    PLDEVOBJ pldev;
+    UNICODE_STRING strDriverName;
+
+    DPRINT("EngLoadImageEx(%ls, %ld)\n", pwszDriverName, ldevtype);
+
+    /* Initialize the driver name */
+    RtlInitUnicodeString(&strDriverName, pwszDriverName);
+
+    /* Lock loader */
+    EngAcquireSemaphore(ghsemLDEVList);
+
+    /* Search the List of LDEVS for the driver name */
+    for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext)
+    {
+        /* Check if the ldev is associated with a file */
+        if (pldev->pGdiDriverInfo)
+        {
+            /* Check for match */
+            if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1))
+            {
+                /* Image found in LDEV list */
+                break;
+            }
+        }
+    }
+
+    /* Did we find one? */
+    if (!pldev)
+    {
+        /* No, allocate a new LDEVOBJ */
+        pldev = LDEVOBJ_AllocLDEV(ldevtype);
+        if (!pldev)
+        {
+            DPRINT1("Could not allocate LDEV\n");
+            goto leave;
+        }
+
+        /* Load the image */
+        if (!LDEVOBJ_bLoadImage(pldev, &strDriverName))
+        {
+            LDEVOBJ_vFreeLDEV(pldev);
+            pldev = NULL;
+            DPRINT1("LDEVOBJ_bLoadImage failed\n");
+            goto leave;
+        }
+
+        /* Shall we load a driver? */
+        if (ldevtype != LDEV_IMAGE)
+        {
+            /* Load the driver */
+            if (!LDEVOBJ_bLoadDriver(pldev))
+            {
+                DPRINT1("LDEVOBJ_bLoadDriver failed\n");
+                LDEVOBJ_vFreeLDEV(pldev);
+                pldev = NULL;
+                goto leave;
+            }
+        }
+
+        /* Insert the LDEV into the global list */
+        pldev->pldevPrev = NULL;
+        pldev->pldevNext = gpldevHead;
+        gpldevHead = pldev;
+    }
+
+    /* Increase ref count */
+    pldev->cRefs++;
+
+leave:
+    /* Unlock loader */
+    EngReleaseSemaphore(ghsemLDEVList);
+
+    DPRINT("EngLoadImageEx returning %p\n", pldev);
+
+    return pldev;
+}
+
+PLDEVOBJ
+APIENTRY
+EngLoadDriver(
+    LPWSTR pwszDriverName,
+    ULONG ldevtype)
+{
+    WCHAR acwBuffer[MAX_PATH];
+    PLDEVOBJ pldev;
+
+    ASSERT(pwszDriverName);
+    DPRINT("EngLoadDriver(%ls, %ld)\n", pwszDriverName, ldevtype);
+
+    /* Create a full file name */ // FIXME: do better than that
+    swprintf(acwBuffer, L"\\SystemRoot\\System32\\%ls.dll", pwszDriverName);
+
+    pldev = EngLoadImageEx(acwBuffer, ldevtype);
+
+    return pldev;
+}
+
+/** Exported functions ********************************************************/
+
+HANDLE
+APIENTRY
+EngLoadImage(
+    LPWSTR pwszDriverName)
+{
+    return (HANDLE)EngLoadImageEx(pwszDriverName, LDEV_IMAGE);
+}
+
+
+VOID
+APIENTRY
+EngUnloadImage(
+    IN HANDLE hModule)
+{
+    PLDEVOBJ pldev = (PLDEVOBJ)hModule;
+
+    /* Make sure the LDEV is in the list */
+    ASSERT(pldev->pldevPrev || pldev->pldevNext);
+
+    /* Lock loader */
+    EngAcquireSemaphore(ghsemLDEVList);
+
+    /* Decrement reference count */
+    pldev->cRefs--;
+
+    /* No more references left? */
+    if (pldev->cRefs == 0)
+    {
+        /* Remove ldev from the list */
+        if (pldev->pldevPrev)
+            pldev->pldevPrev->pldevNext = pldev->pldevNext;
+        if (pldev->pldevNext)
+            pldev->pldevNext->pldevPrev = pldev->pldevPrev;
+
+        /* Unload the image */
+        LDEVOBJ_vUnloadImage(pldev);
+    }
+
+    /* Unlock loader */
+    EngReleaseSemaphore(ghsemLDEVList);
+}
+
+
+PVOID
+APIENTRY
+EngFindImageProcAddress(
+    IN HANDLE hModule,
+    IN LPSTR  lpProcName)
+{
+    PLDEVOBJ pldev = (PLDEVOBJ)hModule;
+
+    ASSERT(gpldevWin32k != NULL);
+
+    /* Check if win32k is requested */
+    if (!pldev)
+    {
+        pldev = gpldevWin32k;
+    }
+
+    /* Check if the drivers entry point is requested */
+    if (_strnicmp(lpProcName, "DrvEnableDriver", 15) == 0)
+    {
+        return pldev->pGdiDriverInfo->EntryPoint;
+    }
+
+    /* Try to find the address */
+    return LDEVOBJ_pvFindImageProcAddress(pldev, lpProcName);
+}
+
diff --git a/subsystems/win32/win32k/eng/pdevobj.c b/subsystems/win32/win32k/eng/pdevobj.c
new file mode 100644 (file)
index 0000000..f28eb8e
--- /dev/null
@@ -0,0 +1,793 @@
+/*
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * PURPOSE:          Support for physical devices
+ * FILE:             subsystems/win32/win32k/eng/pdevobj.c
+ * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include <w32k.h>
+
+#include <intrin.h>
+
+#define NDEBUG
+#include <debug.h>
+
+static PPDEVOBJ gppdevList = NULL;
+PPDEVOBJ gppdevPrimary = NULL;
+static HSEMAPHORE ghsemPDEV;
+
+BOOL
+NTAPI
+InitPDEVImpl()
+{
+    ghsemPDEV = EngCreateSemaphore();
+    return TRUE;
+}
+
+
+PPDEVOBJ
+PDEVOBJ_AllocPDEV()
+{
+    PPDEVOBJ ppdev;
+
+    ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV);
+    if (!ppdev)
+        return NULL;
+    
+    RtlZeroMemory(ppdev, sizeof(PDEVOBJ));
+    
+    ppdev->cPdevRefs = 1;
+
+    return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev)
+{
+    /* Lock loader */
+    EngAcquireSemaphore(ghsemPDEV);
+
+    /* Decrease reference count */
+    --ppdev->cPdevRefs;
+    
+    /* Check if references are left */
+    if (ppdev->cPdevRefs == 0)
+    {
+        // FIXME: should delete the PDEV now
+        UNIMPLEMENTED;
+        ASSERT(FALSE);
+    }
+
+    /* Unlock loader */
+    EngReleaseSemaphore(ghsemPDEV);
+
+}
+
+BOOL
+NTAPI
+PDEVOBJ_bEnablePDEV(
+    PPDEVOBJ ppdev,
+    PDEVMODEW pdevmode,
+    PWSTR pwszLogAddress)
+{
+    PFN_DrvEnablePDEV pfnEnablePDEV;
+
+    DPRINT1("PDEVOBJ_bEnablePDEV()\n");
+
+    /* Get the DrvEnablePDEV function */
+    pfnEnablePDEV = ppdev->pldev->pfn.EnablePDEV;
+
+    /* Call the drivers DrvEnablePDEV function */
+    ppdev->dhpdev = pfnEnablePDEV(pdevmode,
+                                  pwszLogAddress,
+                                  HS_DDI_MAX,
+                                  ppdev->ahsurf,
+                                  sizeof(GDIINFO),
+                                  &ppdev->gdiinfo,
+                                  sizeof(DEVINFO),
+                                  &ppdev->devinfo,
+                                  (HDEV)ppdev,
+                                  ppdev->pGraphicsDevice->pwszDescription,
+                                  ppdev->pGraphicsDevice->DeviceObject);
+
+    DPRINT1("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
+
+    return TRUE;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vCompletePDEV(
+    PPDEVOBJ ppdev)
+{
+    /* Call the drivers DrvCompletePDEV function */
+    ppdev->pldev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+}
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+    PPDEVOBJ ppdev)
+{
+    HSURF hsurf;
+
+    DPRINT1("PDEVOBJ_pSurface()\n");
+
+    /* Check if we already have a surface */
+    if (ppdev->pSurface)
+    {
+        /* Increment reference count */
+        GDIOBJ_IncrementShareCount(&ppdev->pSurface->BaseObject);
+    }
+    else
+    {
+        /* Call the drivers DrvEnableSurface */
+        hsurf = ppdev->pldev->pfn.EnableSurface(ppdev->dhpdev);
+
+        /* Lock the surface */
+        ppdev->pSurface = SURFACE_ShareLockSurface(hsurf);
+    }
+
+    DPRINT1("PDEVOBJ_pSurface() returning %p\n", ppdev->pSurface);
+    return ppdev->pSurface;
+}
+
+PDEVMODEW
+NTAPI
+PDEVOBJ_pdmMatchDevMode(
+    PPDEVOBJ ppdev,
+    PDEVMODEW pdm)
+{
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    PDEVMODEW pdmCurrent;
+    INT i;
+
+    pGraphicsDevice = ppdev->pGraphicsDevice;
+
+    for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+    {
+        pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
+
+        /* Compare DEVMODE fields */
+        if (pdmCurrent->dmBitsPerPel == pdm->dmBitsPerPel &&
+            pdmCurrent->dmPelsWidth == pdm->dmPelsWidth &&
+            pdmCurrent->dmPelsHeight == pdm->dmPelsHeight &&
+            pdmCurrent->dmDisplayFrequency == pdm->dmDisplayFrequency)
+        {
+            /* Match! Return the DEVMODE */
+            return pdmCurrent;
+        }
+    }
+
+    /* Nothing found */
+    return NULL;
+}
+
+
+static
+PPDEVOBJ
+EngpCreatePDEV(
+    PUNICODE_STRING pustrDeviceName,
+    PDEVMODEW pdm)
+{
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    PPDEVOBJ ppdev;
+
+    /* Try to find the GRAPHICS_DEVICE */
+    pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0, 0);
+    if (!pGraphicsDevice)
+    {
+        DPRINT1("No GRAPHICS_DEVICE found for %ls!\n", 
+                pustrDeviceName ? pustrDeviceName->Buffer : 0);
+        return NULL;
+    }
+
+    /* Allocate a new PDEVOBJ */
+    ppdev = PDEVOBJ_AllocPDEV();
+    if (!ppdev)
+    {
+        DPRINT1("failed to allocate a PDEV\n");
+        return NULL;
+    }
+
+    /* If no DEVMODEW is given, ... */
+    if (!pdm)
+    {
+        /* ... use the device's default one */
+        pdm = pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
+        DPRINT1("Using iDefaultMode = %ld\n", pGraphicsDevice->iDefaultMode);
+    }
+
+    /* Try to get a diplay driver */
+    ppdev->pldev = EngLoadDriver(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
+    if (!ppdev->pldev)
+    {
+        DPRINT1("Could not load diplsay driver '%ls'\n", pGraphicsDevice->pDiplayDrivers);
+        ExFreePoolWithTag(ppdev, GDITAG_PDEV);
+        return NULL;
+    }
+
+    /* Copy the function table */
+    ppdev->pfn = ppdev->pldev->pfn;
+
+    /* Set MovePointer function */
+    ppdev->pfnMovePointer = ppdev->pfn.MovePointer;
+    if (!ppdev->pfnMovePointer)
+        ppdev->pfnMovePointer = EngMovePointer;
+
+    ppdev->pGraphicsDevice = pGraphicsDevice;
+    ppdev->hsemDevLock = EngCreateSemaphore();
+    ppdev->pdmwDev = pGraphicsDevice->pDevModeList[pGraphicsDevice->iCurrentMode].pdm;
+
+    /* FIXME! */
+    ppdev->flFlags = PDEV_DISPLAY;
+
+    /* HACK: Don't use the pointer */
+    ppdev->Pointer.Exclude.right = -1;
+
+    /* Call the driver to enable the PDEV */
+    if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL))
+    {
+        DPRINT1("Failed to enable PDEV!\n");
+        ASSERT(FALSE);
+    }
+
+    /* Fix up some values */
+    if (ppdev->gdiinfo.ulLogPixelsX == 0)
+        ppdev->gdiinfo.ulLogPixelsX = 96;
+
+    if (ppdev->gdiinfo.ulLogPixelsY == 0)
+        ppdev->gdiinfo.ulLogPixelsY = 96;
+
+    /* FIXME: this must be done in a better way */
+    pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
+
+    /* Tell the driver that the PDEV is ready */
+    PDEVOBJ_vCompletePDEV(ppdev);
+
+    /* Return the PDEV */
+    return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vSwitchPdev(
+    PPDEVOBJ ppdev,
+    PPDEVOBJ ppdev2)
+{
+    PDEVOBJ pdevTmp;
+    HDEV hdev;
+
+    /* Exchange data */
+    pdevTmp = *ppdev;
+
+    /* Exchange driver functions */
+    ppdev->pfn = ppdev2->pfn;
+    ppdev2->pfn = pdevTmp.pfn;
+
+    /* Exchange LDEVs */ 
+    ppdev->pldev = ppdev2->pldev;
+    ppdev2->pldev = pdevTmp.pldev;
+
+    /* Exchange DHPDEV */
+    ppdev->dhpdev = ppdev2->dhpdev;
+    ppdev2->dhpdev = pdevTmp.dhpdev;
+
+    /* Exchange surface */
+    ppdev->pSurface = ppdev2->pSurface;
+    ppdev2->pSurface = pdevTmp.pSurface;
+    hdev = ppdev->pSurface->SurfObj.hdev;
+    ppdev->pSurface->SurfObj.hdev = ppdev2->pSurface->SurfObj.hdev;
+    ppdev2->pSurface->SurfObj.hdev = hdev;
+
+    /* Exchange devinfo */
+    ppdev->devinfo = ppdev2->devinfo;
+    ppdev2->devinfo = pdevTmp.devinfo;
+
+    /* Exchange gdiinfo */
+    ppdev->gdiinfo = ppdev2->gdiinfo;
+    ppdev2->gdiinfo = pdevTmp.gdiinfo;
+
+    /* Notify each driver instance of its new HDEV association */
+    ppdev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev); 
+    ppdev2->pfn.CompletePDEV(ppdev2->dhpdev, (HDEV)ppdev2); 
+}
+
+void
+TestDraw()
+{
+    RECTL rclTrg;
+    PPDEVOBJ ppdev;
+    PDC pdc;
+
+    ppdev = EngpGetPDEV(0);
+
+    pdc = DC_AllocDcWithHandle();
+    DC_vInitDc(pdc, 0, ppdev);
+
+
+    rclTrg.left = rclTrg.top = 0;
+    rclTrg.right = rclTrg.bottom = 400;
+
+    IntEngBitBltEx(&ppdev->pSurface->SurfObj,
+                   NULL,
+                   NULL,
+                   NULL,
+                   NULL,
+                   &rclTrg,
+                   NULL,
+                   NULL,
+                   &pdc->eboFill.BrushObject,
+                   NULL,
+                   ROP3_TO_ROP4(PATCOPY),
+                   FALSE);
+
+    ASSERT(FALSE);
+}
+
+BOOL
+NTAPI
+PDEVOBJ_bSwitchMode(
+    PPDEVOBJ ppdev,
+    PDEVMODEW pdm)
+{
+    UNICODE_STRING ustrDevice;
+    PPDEVOBJ ppdevTmp;
+    PSURFACE pSurface;
+    BOOL retval = FALSE;
+
+    // FIXME: dynamic mode switching is broken, need to fix PDEV locking first!
+    return FALSE;
+
+    /* Lock the PDEV */
+    EngAcquireSemaphore(ppdev->hsemDevLock);
+
+    DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+
+    // Lookup the GraphicsDevice + select DEVMODE
+    // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
+
+    /* 1. Temporarily disable the current PDEV */
+    if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE))
+    {
+        DPRINT1("DrvAssertMode failed\n");
+        goto leave;
+    }
+
+    /* 2. Create new PDEV */
+    RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName);
+    ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm);
+    if (!ppdevTmp)
+    {
+        DPRINT1("Failed to create a new PDEV\n");
+        goto leave;
+    }
+
+    /* 3. Create a new surface */
+    pSurface = PDEVOBJ_pSurface(ppdevTmp);
+    if (!pSurface)
+    {
+        DPRINT1("DrvEnableSurface failed\n");
+        goto leave;
+    }
+
+    ASSERT(pSurface->BitsLock);
+
+    /* 4. Get DirectDraw information */
+    /* 5. Enable DirectDraw Not traced */
+    /* 6. Copy old PDEV state to new PDEV instance */
+
+    /* 7. Switch the PDEVs */
+    PDEVOBJ_vSwitchPdev(ppdev, ppdevTmp);
+    ASSERT(ppdev->pSurface->BitsLock);
+
+    /* 8. Disable DirectDraw */
+
+    /* 9. Disable old surface */
+    SURFACE_ShareUnlockSurface(ppdevTmp->pSurface);
+    ppdevTmp->pfn.DisableSurface(ppdevTmp->dhpdev);
+
+    /* 10. Disable old PDEV */
+    ppdevTmp->pfn.DisablePDEV(ppdevTmp->dhpdev);
+//    PDEVOBJ_vReleasePdev(ppdevTmp);
+
+    /* Success! */
+    retval = TRUE;
+leave:
+    /* Unlock PDEV */
+    EngReleaseSemaphore(ppdev->hsemDevLock);
+
+    DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+    ASSERT(ppdev->pSurface->BitsLock);
+
+    TestDraw();
+
+    return retval;
+}
+
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(
+    PUNICODE_STRING pustrDeviceName)
+{
+    UNICODE_STRING ustrCurrent;
+    PPDEVOBJ ppdev;
+    PGRAPHICS_DEVICE pGraphicsDevice;
+
+    /* Acquire PDEV lock */
+    EngAcquireSemaphore(ghsemPDEV);
+
+    /* If no device name is given, ... */
+    if (!pustrDeviceName && gppdevPrimary)
+    {
+        /* ... use the primary PDEV */
+        ppdev = gppdevPrimary;
+
+        /* Reference the pdev */
+        InterlockedIncrement(&ppdev->cPdevRefs);
+        goto leave;
+    }
+
+    /* Loop all present PDEVs */
+    for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
+    {
+        /* Get a pointer to the GRAPHICS_DEVICE */
+        pGraphicsDevice = ppdev->pGraphicsDevice;
+
+        /* Compare the name */
+        RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
+        if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
+        {
+            /* Found! Reference the PDEV */
+            InterlockedIncrement(&ppdev->cPdevRefs);
+            break;
+        }
+    }
+
+    /* Did we find one? */
+    if (!ppdev)
+    {
+        /* No, create a new PDEV */
+        ppdev = EngpCreatePDEV(pustrDeviceName, NULL);
+        if (ppdev)
+        {
+            /* Insert the PDEV into the list */
+            ppdev->ppdevNext = gppdevList;
+            gppdevList = ppdev;
+
+            /* Set as primary PDEV, if we don't have one yet */
+            if (!gppdevPrimary)
+            {
+                gppdevPrimary = ppdev;
+            }
+        }
+    }
+
+leave:
+    /* Release PDEV lock */
+    EngReleaseSemaphore(ghsemPDEV);
+
+    return ppdev;
+}
+
+INT
+NTAPI
+PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
+{
+    INT ret = CM_NONE;
+
+    if (ppdev->flFlags & PDEV_DISPLAY)
+    {
+        if (ppdev->devinfo.iDitherFormat == BMF_8BPP ||
+            ppdev->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
+            ret = CM_GAMMA_RAMP;
+    }
+
+    if (ppdev->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
+        ret |= CM_CMYK_COLOR;
+    if (ppdev->devinfo.flGraphicsCaps & GCAPS_ICM)
+        ret |= CM_DEVICE_ICM;
+
+    return ret;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+    IN PPDEVOBJ ppdev,
+    OUT PDEVCAPS pDevCaps)
+{
+    PGDIINFO pGdiInfo = &ppdev->gdiinfo;
+
+    pDevCaps->ulVersion = pGdiInfo->ulVersion;
+    pDevCaps->ulTechnology = pGdiInfo->ulTechnology;
+    pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000;
+    pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000;
+    pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize;
+    pDevCaps->ulVertSize = pGdiInfo->ulVertSize;
+    pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes;
+    pDevCaps->ulVertRes = pGdiInfo->ulVertRes;
+    pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel;
+    if (pDevCaps->ulBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
+    pDevCaps->ulPlanes = pGdiInfo->cPlanes;
+    pDevCaps->ulNumPens = pGdiInfo->ulNumColors;
+    if (pDevCaps->ulNumPens != -1) pDevCaps->ulNumPens *= 5;
+    pDevCaps->ulNumFonts = 0; // PDEVOBJ_cFonts(ppdev);
+    pDevCaps->ulNumColors = pGdiInfo->ulNumColors;
+    pDevCaps->ulRasterCaps = pGdiInfo->flRaster;
+    pDevCaps->ulAspectX = pGdiInfo->ulAspectX;
+    pDevCaps->ulAspectY = pGdiInfo->ulAspectY;
+    pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY;
+    pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX;
+    pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY;
+    pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg;
+    pDevCaps->ulColorRes = pGdiInfo->ulDACRed + 
+                           pGdiInfo->ulDACGreen + 
+                           pGdiInfo->ulDACBlue;
+    pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx;
+    pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy;
+    pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
+    pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
+    pDevCaps->ulTextCaps = pGdiInfo->flTextCaps;
+    pDevCaps->ulTextCaps |= (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
+    if (pGdiInfo->ulTechnology != DT_PLOTTER)
+        pDevCaps->ulTextCaps |= TC_VA_ABLE;
+    pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh;
+    pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes;
+    pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes;
+    pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment;
+    pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes;
+    pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes;
+    pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
+    pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
+    pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend;
+    pDevCaps->ulColorMgmtCaps = PDEVOBJ_iGetColorManagementCaps(ppdev);
+}
+
+
+/** Exported functions ********************************************************/
+
+LPWSTR
+APIENTRY
+EngGetDriverName(IN HDEV hdev)
+{
+    PPDEVOBJ ppdev = (PPDEVOBJ)hdev;
+    PLDEVOBJ pldev;
+
+    if (!hdev)
+        return NULL;
+
+    pldev = ppdev->pldev;
+    ASSERT(pldev);
+
+    if (!pldev->pGdiDriverInfo)
+        return NULL;
+
+    return pldev->pGdiDriverInfo->DriverName.Buffer;
+}
+
+
+INT
+APIENTRY
+NtGdiGetDeviceCaps(
+    HDC hdc,
+    INT Index)
+{
+    PDC pdc;
+    DEVCAPS devcaps;
+
+    /* Lock the given DC */
+    pdc = DC_LockDc(hdc);
+    if (!pdc)
+    {
+        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        return 0;
+    }
+
+    /* Get the data */
+    PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+    /* Unlock the DC */
+    DC_UnlockDc(pdc);
+
+    /* Return capability */
+    switch (Index)
+    {
+        case DRIVERVERSION:
+            return devcaps.ulVersion;
+
+        case TECHNOLOGY:
+            return devcaps.ulTechnology;
+
+        case HORZSIZE:
+            return devcaps.ulHorzSize;
+
+        case VERTSIZE:
+            return devcaps.ulVertSize;
+
+        case HORZRES:
+            return devcaps.ulHorzRes;
+
+        case VERTRES:
+            return devcaps.ulVertRes;
+
+        case LOGPIXELSX:
+            return devcaps.ulLogPixelsX;
+
+        case LOGPIXELSY:
+            return devcaps.ulLogPixelsY;
+
+        case BITSPIXEL:
+            return devcaps.ulBitsPixel;
+
+        case PLANES:
+            return devcaps.ulPlanes;
+
+        case NUMBRUSHES:
+            return -1;
+
+        case NUMPENS:
+            return devcaps.ulNumPens;
+
+        case NUMFONTS:
+            return devcaps.ulNumFonts;
+
+        case NUMCOLORS:
+            return devcaps.ulNumColors;
+
+        case ASPECTX:
+            return devcaps.ulAspectX;
+
+        case ASPECTY:
+            return devcaps.ulAspectY;
+
+        case ASPECTXY:
+            return devcaps.ulAspectXY;
+
+        case CLIPCAPS:
+            return CP_RECTANGLE;
+
+        case SIZEPALETTE:
+            return devcaps.ulSizePalette;
+
+        case NUMRESERVED:
+            return 20;
+
+        case COLORRES:
+            return devcaps.ulColorRes;
+
+        case DESKTOPVERTRES:
+            return devcaps.ulVertRes;
+
+        case DESKTOPHORZRES:
+            return devcaps.ulHorzRes;
+
+        case BLTALIGNMENT:
+            return devcaps.ulBltAlignment;
+
+        case SHADEBLENDCAPS:
+            return devcaps.ulShadeBlend;
+
+        case COLORMGMTCAPS:
+            return devcaps.ulColorMgmtCaps;
+
+        case PHYSICALWIDTH:
+            return devcaps.ulPhysicalWidth;
+
+        case PHYSICALHEIGHT:
+            return devcaps.ulPhysicalHeight;
+
+        case PHYSICALOFFSETX:
+            return devcaps.ulPhysicalOffsetX;
+
+        case PHYSICALOFFSETY:
+            return devcaps.ulPhysicalOffsetY;
+
+        case VREFRESH:
+            return devcaps.ulVRefresh;
+
+        case RASTERCAPS:
+            return devcaps.ulRasterCaps;
+
+        case CURVECAPS:
+            return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+                    CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+
+        case LINECAPS:
+            return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+                    LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+
+        case POLYGONALCAPS:
+            return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+                    PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+
+        case TEXTCAPS:
+            return devcaps.ulTextCaps;
+
+        case CAPS1:
+        case PDEVICESIZE:
+        case SCALINGFACTORX:
+        case SCALINGFACTORY:
+        default:
+            return 0;
+    }
+
+    return 0;
+}
+
+
+BOOL
+APIENTRY
+NtGdiGetDeviceCapsAll(
+    IN HDC hDC,
+    OUT PDEVCAPS pDevCaps)
+{
+    PDC pdc;
+    DEVCAPS devcaps;
+    BOOL bResult = TRUE;
+
+    /* Lock the given DC */
+    pdc = DC_LockDc(hDC);
+    if (!pdc)
+    {
+        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    /* Get the data */
+    PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+    /* Unlock the DC */
+    DC_UnlockDc(pdc);
+
+    /* Copy data to caller */
+    _SEH2_TRY
+    {
+        ProbeForWrite(pDevCaps, sizeof(DEVCAPS), 1);
+        RtlCopyMemory(pDevCaps, &devcaps, sizeof(DEVCAPS));
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        SetLastNtError(_SEH2_GetExceptionCode());
+        bResult = FALSE;
+    }
+    _SEH2_END;
+
+    return bResult;
+}
+
+DHPDEV
+APIENTRY
+NtGdiGetDhpdev(
+    IN HDEV hdev)
+{
+    PPDEVOBJ ppdev;
+    DHPDEV dhpdev = NULL;
+
+    /* Check parameter */
+    if (!hdev || (PCHAR)hdev < (PCHAR)MmSystemRangeStart)
+        return NULL;
+
+    /* Lock PDEV list */
+    EngAcquireSemaphore(ghsemPDEV);
+
+    /* Walk through the list of PDEVs */
+    for (ppdev = gppdevList;  ppdev; ppdev = ppdev->ppdevNext)
+    {
+        /* Compare with the given HDEV */
+        if (ppdev == hdev)
+        {
+            /* Found the PDEV! Get it's dhpdev and break */
+            dhpdev = ppdev->dhpdev;
+            break;
+        }
+    }
+
+    /* Unlock PDEV list */
+    EngReleaseSemaphore(ghsemPDEV);
+
+    return dhpdev;
+}
index 5ef403d..7dc55b6 100644 (file)
@@ -69,6 +69,15 @@ EngReleaseSemaphore ( IN HSEMAPHORE hsem )
   IntGdiReleaseSemaphore ( hsem );
 }
 
+VOID
+NTAPI
+EngAcquireSemaphoreShared(
+    IN HSEMAPHORE hsem)
+{
+    ASSERT(hsem);
+    ExEnterCriticalRegionAndAcquireResourceShared((PERESOURCE)hsem);
+}
+
 /*
  * @implemented
  */
index f8fec03..61c09f8 100644 (file)
@@ -21,6 +21,30 @@ typedef struct _DC *PDC;
 /* fl */
 #define DC_FL_PAL_BACK 1
 
+#define DC_DISPLAY  1
+#define DC_DIRECT 2
+#define DC_CANCELED 4
+#define DC_PERMANANT 0x08
+#define DC_DIRTY_RAO 0x10
+#define DC_ACCUM_WMGR 0x20
+#define DC_ACCUM_APP 0x40
+#define DC_RESET 0x80
+#define DC_SYNCHRONIZEACCESS 0x100
+#define DC_EPSPRINTINGESCAPE 0x200
+#define DC_TEMPINFODC 0x400
+#define DC_FULLSCREEN 0x800
+#define DC_IN_CLONEPDEV 0x1000
+#define DC_REDIRECTION 0x2000
+#define DC_SHAREACCESS 0x4000
+
+typedef enum
+{
+  DCTYPE_DIRECT = 0,
+  DCTYPE_MEMORY = 1,
+  DCTYPE_INFO = 2,
+} DCTYPE;
+
+
 /* Type definitions ***********************************************************/
 
 typedef struct _ROS_DC_INFO
@@ -140,22 +164,44 @@ typedef struct _DC
 
 /* Internal functions *********************************************************/
 
+#if 0
 #define  DC_LockDc(hDC)  \
   ((PDC) GDIOBJ_LockObj ((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC))
 #define  DC_UnlockDc(pDC)  \
   GDIOBJ_UnlockObjByPtr ((POBJ)pDC)
+#endif
+
+VOID NTAPI EngAcquireSemaphoreShared(IN HSEMAPHORE hsem);
+
+PDC
+FORCEINLINE
+DC_LockDc(HDC hdc)
+{
+    PDC pdc;
+    pdc = GDIOBJ_LockObj(hdc, GDI_OBJECT_TYPE_DC);
+//    EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
+    return pdc;
+}
+
+void
+FORCEINLINE
+DC_UnlockDc(PDC pdc)
+{
+//    EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+    GDIOBJ_UnlockObjByPtr(&pdc->BaseObject);
+}
+
 
 extern PDC defaultDCstate;
 
 NTSTATUS FASTCALL InitDcImpl(VOID);
 PPDEVOBJ FASTCALL IntEnumHDev(VOID);
-HDC  FASTCALL DC_AllocDC(PUNICODE_STRING  Driver);
+PDC NTAPI DC_AllocDcWithHandle();
 VOID FASTCALL DC_InitDC(HDC  DCToInit);
-HDC  FASTCALL DC_FindOpenDC(PUNICODE_STRING  Driver);
 VOID FASTCALL DC_AllocateDcAttr(HDC);
 VOID FASTCALL DC_FreeDcAttr(HDC);
 BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
-BOOL FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner);
+BOOL FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner);
 VOID FASTCALL DC_LockDisplay(HDC);
 VOID FASTCALL DC_UnlockDisplay(HDC);
 BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
@@ -169,9 +215,13 @@ VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
 VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
 VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
 
+VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
+
 BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC);
 BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC);
 VOID FASTCALL DCU_SetDcUndeletable(HDC);
+VOID NTAPI DC_vFreeDcAttr(PDC pdc);
+VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev);
 
 COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color);
 INT FASTCALL IntGdiSetBkMode(HDC  hDC, INT  backgroundMode);
@@ -187,9 +237,6 @@ VOID FASTCALL IntGdiUnreferencePdev(PPDEVOBJ pPDev, DWORD CleanUpType);
 HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
 BOOL FASTCALL IntGdiCleanDC(HDC hDC);
 VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
-INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
-
-extern PPDEVOBJ pPrimarySurface;
 
 VOID
 FORCEINLINE
@@ -239,8 +286,4 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal)
     pdc->dclevel.ppal = ppal;
 }
 
-BOOL FASTCALL
-IntPrepareDriverIfNeeded(VOID);
-extern PDEVOBJ PrimarySurface;
-
 #endif /* not __WIN32K_DC_H */
diff --git a/subsystems/win32/win32k/include/device.h b/subsystems/win32/win32k/include/device.h
new file mode 100644 (file)
index 0000000..307a21d
--- /dev/null
@@ -0,0 +1,70 @@
+
+//#define _PDEVOBJ _PDEVOBJ2
+//#define PDEVOBJ PDEVOBJ2
+//#define PPDEVOBJ PPDEVOBJ2
+
+//typedef struct _PDEVOBJ *PPDEVOBJ;
+
+#define TAG_GDEV 'gdev'
+
+VOID
+APIENTRY
+EngFileWrite(
+    IN PFILE_OBJECT pFileObject,
+    IN PVOID lpBuffer,
+    IN SIZE_T nLength,
+    IN PSIZE_T lpBytesWritten);
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpFindGraphicsDevice(
+    PUNICODE_STRING pustrDevice,
+    DWORD iDevNum,
+    DWORD dwFlags);
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpRegisterGraphicsDevice(
+    PUNICODE_STRING pustrDeviceName,
+    PUNICODE_STRING pustrDiplayDrivers,
+    PUNICODE_STRING pustrDescription,
+    PDEVMODEW pdmDefault);
+
+BOOL
+NTAPI
+InitDeviceImpl();
+
+BOOL
+FASTCALL
+DC_AllocDcAttr(PDC pdc);
+
+//#define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl(TAG('R', 'o', 's', 'D'), (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
+NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
+
+
+NTSTATUS
+NTAPI
+RegOpenKey(
+    LPCWSTR pwszKeyName,
+    PHKEY phkey);
+
+NTSTATUS
+NTAPI
+RegQueryValue(
+    IN HKEY hkey,
+    IN PCWSTR pwszValueName,
+    IN ULONG ulType,
+    OUT PVOID pvData,
+    IN OUT PULONG pcbValue);
+
+BOOL
+NTAPI
+PDEVOBJ_bSwitchMode(
+    PPDEVOBJ ppdev,
+    PDEVMODEW pdm);
+
+PDEVMODEW
+NTAPI
+PDEVOBJ_pdmMatchDevMode(
+    PPDEVOBJ ppdev,
+    PDEVMODEW pdm);
index d5e63c9..2085c2e 100644 (file)
@@ -163,9 +163,6 @@ IntGetSysColor(INT nIndex);
 
 /* Other Stuff */
 
-INT FASTCALL
-IntGdiGetDeviceCaps(PDC dc, INT Index);
-
 INT
 FASTCALL
 IntGdiEscape(PDC    dc,
@@ -182,14 +179,6 @@ IntEnumDisplaySettings(
   IN OUT LPDEVMODEW pDevMode,
   IN DWORD dwFlags);
 
-LONG
-FASTCALL
-IntChangeDisplaySettings(
-  IN PUNICODE_STRING pDeviceName  OPTIONAL,
-  IN LPDEVMODEW pDevMode,
-  IN DWORD dwflags,
-  IN PVOID lParam  OPTIONAL);
-
 HBITMAP
 FASTCALL
 IntCreateCompatibleBitmap(PDC Dc,
diff --git a/subsystems/win32/win32k/include/ldevobj.h b/subsystems/win32/win32k/include/ldevobj.h
new file mode 100644 (file)
index 0000000..6bff0fe
--- /dev/null
@@ -0,0 +1,86 @@
+
+#ifdef __GNUC__
+/* Hack, for bug in ld.  Will be removed soon.  */
+#define __ImageBase _image_base__
+#endif
+extern IMAGE_DOS_HEADER __ImageBase;
+
+
+#define TAG_LDEV 'Gldv'
+
+#define GDI_ENGINE_VERSION DDI_DRIVER_VERSION_NT5_01
+
+typedef enum
+{
+    LDEV_DEVICE_DISPLAY = 1,
+    LDEV_DEVICE_PRINTER = 2,
+    LDEV_DEVICE_META = 3,
+    LDEV_DEVICE_MIRROR = 4,
+    LDEV_IMAGE = 5,
+    LDEV_FONT = 6,
+} LDEVTYPE;
+
+typedef struct _LDEVOBJ
+{
+    struct _LDEVOBJ *pldevNext;
+    struct _LDEVOBJ *pldevPrev;
+    SYSTEM_GDI_DRIVER_INFORMATION *pGdiDriverInfo;
+    LDEVTYPE ldevtype;
+    ULONG cRefs;
+    ULONG ulDriverVersion;
+
+    union
+    {
+        PVOID apfn[INDEX_LAST];
+        DRIVER_FUNCTIONS pfn;
+    };
+
+} LDEVOBJ, *PLDEVOBJ;
+
+extern PLDEVOBJ gpldevHead;
+extern HSEMAPHORE ghsemDriverMgmt;
+
+PLDEVOBJ
+NTAPI
+LDEVOBJ_pldevLoadImage(
+    PUNICODE_STRING pusPathName,
+    LDEVTYPE ldevtype);
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadDriver(
+    IN PLDEVOBJ pldev);
+
+PVOID
+NTAPI
+LDEVOBJ_pvFindImageProcAddress(
+    IN PLDEVOBJ pldev,
+    IN LPSTR    lpProcName);
+
+PDEVMODEINFO
+NTAPI
+LDEVOBJ_pdmiGetModes(
+    PLDEVOBJ pldev,
+    HANDLE hDriver);
+
+BOOL
+NTAPI
+InitLDEVImpl();
+
+PLDEVOBJ
+APIENTRY
+EngLoadDriver(
+    LPWSTR pwszDriverName,
+    ULONG ldevtype);
+
+PLDEVOBJ
+NTAPI
+EngGetLDEV(
+    PDEVMODEW pdm);
+
+NTSTATUS
+APIENTRY
+DriverEntry (
+  IN   PDRIVER_OBJECT  DriverObject,
+  IN   PUNICODE_STRING RegistryPath);
+
index 94b3d56..0e868a7 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef __WIN32K_PDEVOBJ_H
 #define __WIN32K_PDEVOBJ_H
 
-#include <drivers/directx/directxint.h>
-
 /* PDEVOBJ flags */
 #define PDEV_DISPLAY             0x00000001 /* Display device */
 #define PDEV_HARDWARE_POINTER    0x00000002 /* Supports hardware cursor */
@@ -38,6 +36,21 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
   RECTL    Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
 } GDIPOINTER, *PGDIPOINTER;
 
+typedef struct _DEVMODEINFO
+{
+    struct _DEVMODEINFO *pdmiNext;
+    struct _LDEVOBJ *pldev;
+    ULONG cbdevmode;
+    DEVMODEW adevmode[1];
+} DEVMODEINFO, *PDEVMODEINFO;
+
+typedef struct
+{
+    DWORD dwFlags;
+    PDEVMODEW pdm;
+    
+} DEVMODEENTRY, *PDEVMODEENTRY;
+
 typedef struct _GRAPHICS_DEVICE
 {
     WCHAR            szNtDeviceName[CCHDEVICENAME/2];
@@ -49,15 +62,17 @@ typedef struct _GRAPHICS_DEVICE
     DWORD            hkClassDriverConfig;
     DWORD            StateFlags;                     /* See DISPLAY_DEVICE_* */
     ULONG            cbdevmodeInfo;
-    PVOID            devmodeInfo;
-    DWORD            cbdevmodeInfo1;
-    PVOID            devmodeInfo1;
-    LPWSTR           pwszDeviceNames;
+    PDEVMODEINFO     pdevmodeInfo;
+    ULONG            cDevModes;
+    PDEVMODEENTRY    pDevModeList;
+    LPWSTR           pDiplayDrivers;
     LPWSTR           pwszDescription;
     DWORD            dwUnknown;
     PVOID            pUnknown;
     PFILE_OBJECT     FileObject;
     DWORD            ProtocolType;
+    ULONG            iDefaultMode;
+    ULONG            iCurrentMode;
 } GRAPHICS_DEVICE, *PGRAPHICS_DEVICE;
 
 typedef struct _PDEVOBJ
@@ -65,8 +80,8 @@ typedef struct _PDEVOBJ
     BASEOBJECT                BaseObject;
 
     struct _PDEVOBJ *         ppdevNext;
-    INT                       cPdevRefs;
-    INT                       cPdevOpenRefs;
+    LONG                      cPdevRefs;
+    LONG                      cPdevOpenRefs;
     struct _PDEVOBJ *         ppdevParent;
     FLONG                     flFlags;  // flags
 //  FLONG                     flAccelerated;
@@ -99,17 +114,17 @@ typedef struct _PDEVOBJ
 //  PFN_DrvSetPalette         pfnDrvSetPalette;
 //  PFN_DrvNotify             pfnDrvNotify;
 //  ULONG                     TagSig;
-//  PLDEVOBJ                  pldev;
+    struct _LDEVOBJ *         pldev;
     DHPDEV                    dhpdev;         /* DHPDEV for device. */
     PVOID                     ppalSurf;       /* PEPALOBJ/PPALETTE for this device. */
     DEVINFO                   devinfo;
     GDIINFO                   gdiinfo;
-    HSURF                     pSurface;       /* SURFACE for this device., FIXME: PSURFACE */
+    PSURFACE                  pSurface;       /* SURFACE for this device. */
 //  HANDLE                    hSpooler;       /* Handle to spooler, if spooler dev driver. */
 //  PVOID                     pDesktopId;
     PGRAPHICS_DEVICE          pGraphicsDevice;
 //  POINTL                    ptlOrigion;
-    PVOID                     pdmwDev;        /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
+    PDEVMODEW                 pdmwDev;        /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
 //  DWORD                     Unknown3;
     FLONG                     DxDd_Flags;     /* DxDD active status flags. */
 //  LONG                      devAttr;
@@ -118,15 +133,12 @@ typedef struct _PDEVOBJ
     union
     {
       DRIVER_FUNCTIONS        DriverFunctions;
+      DRIVER_FUNCTIONS        pfn;
       PVOID                   apfn[INDEX_LAST];         // B8C 0x0598
     };
 
     /* ros specific */
     ULONG         DxDd_nCount;
-    ULONG         DisplayNumber;
-    DEVMODEW      DMW;
-    PFILE_OBJECT  VideoFileObject;
-    BOOLEAN       PreparedDriver;
     GDIPOINTER    Pointer;
     /* Stuff to keep track of software cursors; win32k gdi part */
     UINT SafetyRemoveLevel; /* at what level was the cursor removed?
@@ -135,13 +147,43 @@ typedef struct _PDEVOBJ
     struct _EDD_DIRECTDRAW_GLOBAL * pEDDgpl;
 } PDEVOBJ, *PPDEVOBJ;
 
-/* PDEV and EDDX extra data container.*/
-typedef struct _PDEVEDD
-{
-    PDEVOBJ pdevobj;
-    EDD_DIRECTDRAW_GLOBAL EDDgpl;
-} PDEVEDD, *PPDEVEDD;
+/* Globals ********************************************************************/
+
+extern PPDEVOBJ gppdevPrimary;
+#define pPrimarySurface gppdevPrimary
+
+
+/* Function prototypes ********************************************************/
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(PUNICODE_STRING pustrDevice);
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev);
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+    PPDEVOBJ ppdev);
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+    PPDEVOBJ ppdev,
+    PDEVCAPS pDevCaps);
+
+BOOL
+NTAPI
+InitPDEVImpl();
+
+BOOL
+NTAPI
+InitLDEVImpl();
 
-extern ULONG gdwDirectDrawContext;
+BOOL
+NTAPI
+InitDeviceImpl();
 
 #endif /* !__WIN32K_PDEVOBJ_H */
index 4cd9e7b..3db2531 100644 (file)
@@ -78,6 +78,8 @@
 #include <include/gdifloat.h>
 #include <include/engobjects.h>
 #include <include/engevent.h>
+#include <include/ldevobj.h>
+#include <include/device.h>
 #include <dib/dib.h>
 
 #endif /* __WIN32K_H */
index 9803c8d..30eb272 100644 (file)
@@ -1,24 +1,4 @@
-/*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/* $Id$
- *
- */
+
 
 #include <w32k.h>
 
 #include <debug.h>
 
 
-extern LIST_ENTRY GlobalDriverListHead;
-
-
-/*
- * Blatantly stolen from ldr/utils.c in ntdll.  I can't link ntdll from
- * here, though.
- */
-NTSTATUS APIENTRY
-LdrGetProcedureAddress (IN PVOID BaseAddress,
-                        IN PANSI_STRING Name,
-                        IN ULONG Ordinal,
-                        OUT PVOID *ProcedureAddress)
-{
-   PIMAGE_EXPORT_DIRECTORY ExportDir;
-   PUSHORT OrdinalPtr;
-   PULONG NamePtr;
-   PULONG AddressPtr;
-   ULONG i = 0;
-
-   DPRINT("LdrGetProcedureAddress (BaseAddress %x Name %Z Ordinal %lu ProcedureAddress %x)\n",
-          BaseAddress, Name, Ordinal, ProcedureAddress);
-
-   /* Get the pointer to the export directory */
-   ExportDir = (PIMAGE_EXPORT_DIRECTORY)
-                RtlImageDirectoryEntryToData (BaseAddress,
-                                              TRUE,
-                                              IMAGE_DIRECTORY_ENTRY_EXPORT,
-                                              &i);
-
-   DPRINT("ExportDir %x i %lu\n", ExportDir, i);
-
-   if (!ExportDir || !i || !ProcedureAddress)
-     {
-        return STATUS_INVALID_PARAMETER;
-     }
-
-   AddressPtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfFunctions);
-   if (Name && Name->Length)
-     {
-        /* by name */
-        OrdinalPtr = (PUSHORT)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals);
-        NamePtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNames);
-        for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
-          {
-             if (!strcmp(Name->Buffer, (char*)((ULONG_PTR)BaseAddress + *NamePtr)))
-               {
-                  *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]);
-                  return STATUS_SUCCESS;
-               }
-          }
-        DPRINT1("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
-     }
-   else
-     {
-        /* by ordinal */
-        Ordinal &= 0x0000FFFF;
-        if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
-          {
-             *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG_PTR)AddressPtr[Ordinal - ExportDir->Base]);
-             return STATUS_SUCCESS;
-          }
-        DPRINT1("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
-  }
-
-   return STATUS_PROCEDURE_NOT_FOUND;
-}
-
-PVOID APIENTRY
-EngFindImageProcAddress(IN HANDLE Module,
-                       IN LPSTR ProcName)
-{
-  PVOID Function;
-  NTSTATUS Status;
-  ANSI_STRING ProcNameString;
-  unsigned i;
-  static struct
-    {
-      PCSTR ProcName;
-      PVOID ProcAddress;
-    }
-  Win32kExports[] =
-    {
-      { "BRUSHOBJ_hGetColorTransform",    BRUSHOBJ_hGetColorTransform    },
-      { "EngAlphaBlend",                  EngAlphaBlend                  },
-      { "EngClearEvent",                  EngClearEvent                  },
-      { "EngControlSprites",              EngControlSprites              },
-      { "EngCreateEvent",                 EngCreateEvent                 },
-      { "EngDeleteEvent",                 EngDeleteEvent                 },
-      { "EngDeleteFile",                  EngDeleteFile                  },
-      { "EngDeleteSafeSemaphore",         EngDeleteSafeSemaphore         },
-      { "EngDeleteWnd",                   EngDeleteWnd                   },
-      { "EngDitherColor",                 EngDitherColor                 },
-      { "EngGetPrinterDriver",            EngGetPrinterDriver            },
-      { "EngGradientFill",                EngGradientFill                },
-      { "EngHangNotification",            EngHangNotification            },
-      { "EngInitializeSafeSemaphore",     EngInitializeSafeSemaphore     },
-      { "EngLockDirectDrawSurface",       EngLockDirectDrawSurface       },
-      { "EngLpkInstalled",                EngLpkInstalled                },
-      { "EngMapEvent",                    EngMapEvent                    },
-      { "EngMapFile",                     EngMapFile                     },
-      { "EngMapFontFileFD",               EngMapFontFileFD               },
-      { "EngModifySurface",               EngModifySurface               },
-      { "EngMovePointer",                 EngMovePointer                 },
-      { "EngPlgBlt",                      EngPlgBlt                      },
-      { "EngQueryDeviceAttribute",        EngQueryDeviceAttribute        },
-      { "EngQueryPalette",                EngQueryPalette                },
-      { "EngQuerySystemAttribute",        EngQuerySystemAttribute        },
-      { "EngReadStateEvent",              EngReadStateEvent              },
-      { "EngRestoreFloatingPointState",   EngRestoreFloatingPointState   },
-      { "EngSaveFloatingPointState",      EngSaveFloatingPointState      },
-      { "EngSetEvent",                    EngSetEvent                    },
-      { "EngSetPointerShape",             EngSetPointerShape             },
-      { "EngSetPointerTag",               EngSetPointerTag               },
-      { "EngStretchBltROP",               EngStretchBltROP               },
-      { "EngTransparentBlt",              EngTransparentBlt              },
-      { "EngUnlockDirectDrawSurface",     EngUnlockDirectDrawSurface     },
-      { "EngUnmapEvent",                  EngUnmapEvent                  },
-      { "EngUnmapFile",                   EngUnmapFile                   },
-      { "EngUnmapFontFileFD",             EngUnmapFontFileFD             },
-      { "EngWaitForSingleObject",         EngWaitForSingleObject         },
-      { "FONTOBJ_pfdg",                   FONTOBJ_pfdg                   },
-      { "FONTOBJ_pjOpenTypeTablePointer", FONTOBJ_pjOpenTypeTablePointer },
-      { "FONTOBJ_pQueryGlyphAttrs",       FONTOBJ_pQueryGlyphAttrs       },
-      { "FONTOBJ_pwszFontFilePaths",      FONTOBJ_pwszFontFilePaths      },
-      { "HeapVidMemAllocAligned",         HeapVidMemAllocAligned         },
-      { "HT_Get8BPPMaskPalette",          HT_Get8BPPMaskPalette          },
-      { "STROBJ_bEnumPositionsOnly",      STROBJ_bEnumPositionsOnly      },
-      { "STROBJ_bGetAdvanceWidths",       STROBJ_bGetAdvanceWidths       },
-      { "STROBJ_fxBreakExtra",            STROBJ_fxBreakExtra            },
-      { "STROBJ_fxCharacterExtra",        STROBJ_fxCharacterExtra        },
-      { "VidMemFree",                     VidMemFree                     },
-      { "XLATEOBJ_hGetColorTransform",    XLATEOBJ_hGetColorTransform    }
-    };
-
-  if (NULL == Module)
-    {
-      DPRINT("Looking for win32k export %s\n", ProcName);
-      for (i = 0; i < sizeof(Win32kExports) / sizeof(Win32kExports[0]); i++)
-        {
-          if (0 == strcmp(ProcName, Win32kExports[i].ProcName))
-            {
-              DPRINT("Found it index %u address %p\n", i, Win32kExports[i].ProcName);
-              return Win32kExports[i].ProcAddress;
-            }
-        }
-      return NULL;
-    }
-  RtlInitAnsiString(&ProcNameString, ProcName);
-  Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress,
-                                 &ProcNameString,
-                                 0,
-                                 &Function);
-  if (!NT_SUCCESS(Status))
-    {
-      return(NULL);
-    }
-  return(Function);
-}
-
-
-/*
- * @implemented
- */
-HANDLE
-APIENTRY
-EngLoadImage (LPWSTR DriverName)
-{
-       SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
-       PDRIVERS DriverInfo = NULL;
-       NTSTATUS Status;
-
-       RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
-       if( !IsListEmpty(&GlobalDriverListHead) )
-       {
-               PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink;
-               PDRIVERS Current;
-               /* probably the driver was already loaded, let's try to find it out */
-               while( CurrentEntry != &GlobalDriverListHead )
-               {
-                       Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry);
-                       if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) {
-                               DriverInfo = Current;
-                               break;
-                       }
-                       CurrentEntry = CurrentEntry->Flink;
-               };
-       }
-
-       if( !DriverInfo )
-       {
-               /* the driver was not loaded before, so let's do that */
-               Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-               if (!NT_SUCCESS(Status)) {
-                       DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status);
-               }
-               else {
-                       DriverInfo = ExAllocatePool(PagedPool, sizeof(DRIVERS));
-                       DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength;
-                       DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length;
-                       DriverInfo->DriverName.Buffer = ExAllocatePool(PagedPool, GdiDriverInfo.DriverName.MaximumLength);
-                       RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName);
-                       DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer;
-            DriverInfo->BaseAddress = GdiDriverInfo.ImageAddress;
-                       InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry);
-               }
-       }
-
-       return DriverInfo;
-}
-
-VOID
-APIENTRY
-EngUnloadImage ( IN HANDLE hModule )
-{
-  NTSTATUS Status;
-  PDRIVERS DriverInfo = (PDRIVERS)hModule;
-
-  DPRINT("hModule 0x%x\n", hModule);
-
-  Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
-    DriverInfo->SectionPointer, sizeof(PVOID));
-
-  if(!NT_SUCCESS(Status))
-  {
-    DPRINT1("ZwSetSystemInformation failed with status 0x%08X\n",
-      Status);
-  }
-  else
-  {
-    ExFreePool(DriverInfo->DriverName.Buffer);
-    RemoveEntryList(&DriverInfo->ListEntry);
-    ExFreePool(DriverInfo);
-  }
-}
-
-/* EOF */
index 346974a..d1873d0 100644 (file)
@@ -34,8 +34,6 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
 PGDI_HANDLE_TABLE GdiHandleTable = NULL;
 PSECTION_OBJECT GdiTableSection = NULL;
 
-LIST_ENTRY GlobalDriverListHead;
-
 HANDLE GlobalUserHeap = NULL;
 PSECTION_OBJECT GlobalUserHeapSection = NULL;
 
@@ -358,6 +356,7 @@ Win32kInitWin32Thread(PETHREAD Thread)
   return(STATUS_SUCCESS);
 }
 
+C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE);
 
 /*
  * This definition doesn't work
@@ -413,8 +412,19 @@ DriverEntry (
         return STATUS_UNSUCCESSFUL;
     }
 
-  /* Initialize a list of loaded drivers in Win32 subsystem */
-  InitializeListHead(&GlobalDriverListHead);
+   if (!gpsi)
+   {
+      gpsi = UserHeapAlloc(sizeof(SERVERINFO));
+      if (gpsi)
+      {
+         RtlZeroMemory(gpsi, sizeof(SERVERINFO));
+         DPRINT("Global Server Data -> %x\n", gpsi);
+      }
+      else
+      {
+          ASSERT(FALSE);
+      }
+   }
 
   if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
 
@@ -425,6 +435,23 @@ DriverEntry (
       return STATUS_UNSUCCESSFUL;
   }
 
+  /* Create stock objects, ie. precreated objects commonly
+     used by win32 applications */
+  CreateStockObjects();
+  CreateSysColorObjects();
+
+  InitXlateImpl();
+  InitPDEVImpl();
+  InitLDEVImpl();
+  InitDeviceImpl();
+
+  Status = InitDcImpl();
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT1("Failed to initialize Device context implementation!\n");
+    return STATUS_UNSUCCESSFUL;
+  }
+
   Status = InitUserImpl();
   if (!NT_SUCCESS(Status))
   {
@@ -516,13 +543,6 @@ DriverEntry (
       return(Status);
     }
 
-  Status = InitDcImpl();
-  if (!NT_SUCCESS(Status))
-  {
-    DPRINT1("Failed to initialize Device context implementation!\n");
-    return STATUS_UNSUCCESSFUL;
-  }
-
   /* Initialize FreeType library */
   if (! InitFontSupport())
     {
@@ -530,13 +550,6 @@ DriverEntry (
       return STATUS_UNSUCCESSFUL;
     }
 
-  InitXlateImpl();
-
-  /* Create stock objects, ie. precreated objects commonly
-     used by win32 applications */
-  CreateStockObjects();
-  CreateSysColorObjects();
-
   gusLanguageID = IntGdiGetLanguageID();
 
   return STATUS_SUCCESS;
index e713f32..8b13789 100644 (file)
@@ -1,621 +1 @@
-/*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/* $Id$
- *
- * GDI Driver support routines
- * (mostly swiped from Wine)
- *
- */
 
-#include <w32k.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* #define TRACE_DRV_CALLS to get a log of all calls into the display driver. */
-#undef TRACE_DRV_CALLS
-
-
-typedef struct _GRAPHICS_DRIVER
-{
-  PWSTR  Name;
-  PFN_DrvEnableDriver  EnableDriver;
-  int  ReferenceCount;
-  struct _GRAPHICS_DRIVER  *Next;
-} GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
-
-static PGRAPHICS_DRIVER  DriverList;
-static PGRAPHICS_DRIVER  GenericDriver = NULL;
-
-BOOL DRIVER_RegisterDriver(LPCWSTR  Name, PFN_DrvEnableDriver  EnableDriver)
-{
-  PGRAPHICS_DRIVER  Driver;
-  
-  DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
-  
-  if (GenericDriver != NULL)
-  {
-     return FALSE;
-  }
-  Driver = ExAllocatePoolWithTag(PagedPool, sizeof(*Driver), TAG_DRIVER);
-  if (!Driver)  return  FALSE;
-  Driver->ReferenceCount = 0;
-  Driver->EnableDriver = EnableDriver;
-  if (Name)
-  {
-    Driver->Name = ExAllocatePoolWithTag(PagedPool,
-                                         (wcslen(Name) + 1) * sizeof(WCHAR),
-                                         TAG_DRIVER);
-    if (Driver->Name == NULL)
-    {
-        DPRINT1("Out of memory\n");
-        ExFreePoolWithTag(Driver, TAG_DRIVER);
-        return  FALSE;
-    }
-
-    wcscpy(Driver->Name, Name);
-    Driver->Next  = DriverList;
-    DriverList = Driver;
-    return  TRUE;
-  }
-
-  GenericDriver = Driver;
-  return  TRUE;
-}
-
-PFN_DrvEnableDriver DRIVER_FindExistingDDIDriver(LPCWSTR Name)
-{
-  GRAPHICS_DRIVER *Driver = DriverList;
-  while (Driver && Name)
-  {
-    if (!_wcsicmp(Driver->Name, Name))
-    {
-      return Driver->EnableDriver;
-    }
-    Driver = Driver->Next;
-  }
-
-  return NULL;
-}
-
-PFN_DrvEnableDriver DRIVER_FindDDIDriver(LPCWSTR Name)
-{
-  static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
-  static WCHAR DefaultExtension[] = L".DLL";
-  PFN_DrvEnableDriver ExistingDriver;
-  SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
-  NTSTATUS Status;
-  LPWSTR FullName;
-  LPCWSTR p;
-  BOOL PathSeparatorFound;
-  BOOL DotFound;
-  UINT Size;
-
-  DotFound = FALSE;
-  PathSeparatorFound = FALSE;
-  p = Name;
-  while (L'\0' != *p)
-  {
-    if (L'\\' == *p || L'/' == *p)
-    {
-      PathSeparatorFound = TRUE;
-      DotFound = FALSE;
-    }
-    else if (L'.' == *p)
-    {
-      DotFound = TRUE;
-    }
-    p++;
-  }
-
-  Size = (wcslen(Name) + 1) * sizeof(WCHAR);
-  if (! PathSeparatorFound)
-  {
-    Size += sizeof(DefaultPath) - sizeof(WCHAR);
-  }
-  if (! DotFound)
-  {
-    Size += sizeof(DefaultExtension) - sizeof(WCHAR);
-  }
-  FullName = ExAllocatePoolWithTag(PagedPool, Size, TAG_DRIVER);
-  if (NULL == FullName)
-  {
-    DPRINT1("Out of memory\n");
-    return NULL;
-  }
-  if (PathSeparatorFound)
-  {
-    FullName[0] = L'\0';
-  }
-  else
-  {
-    wcscpy(FullName, DefaultPath);
-  }
-  wcscat(FullName, Name);
-  if (! DotFound)
-  {
-    wcscat(FullName, DefaultExtension);
-  }
-
-  /* First see if the driver hasn't already been loaded */
-  ExistingDriver = DRIVER_FindExistingDDIDriver(FullName);
-  if (ExistingDriver)
-  {
-    ExFreePoolWithTag(FullName, TAG_DRIVER);
-    return ExistingDriver;
-  }
-
-  /* If not, then load it */
-  RtlInitUnicodeString (&GdiDriverInfo.DriverName, FullName);
-  Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-
-  if (!NT_SUCCESS(Status))
-  {
-    ExFreePool(FullName);
-    return NULL;
-  }
-
-  DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
-  DRIVER_RegisterDriver( FullName, GdiDriverInfo.EntryPoint);
-  ExFreePoolWithTag(FullName, TAG_DRIVER);
-  return (PFN_DrvEnableDriver)GdiDriverInfo.EntryPoint;
-}
-
-#define BEGIN_FUNCTION_MAP() \
-  ULONG i; \
-  for (i = 0; i < DED->c; i++) \
-  { \
-    switch(DED->pdrvfn[i].iFunc) \
-    {
-
-#define END_FUNCTION_MAP() \
-      default: \
-        DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
-        break; \
-    } \
-  }
-
-#ifdef TRACE_DRV_CALLS
-
-typedef struct _TRACEDRVINFO
-  {
-  unsigned Index;
-  char *Name;
-  PVOID DrvRoutine;
-  }
-TRACEDRVINFO, *PTRACEDRVINFO;
-
-__asm__(
-" .text\n"
-"TraceDrv:\n"
-" pushl %eax\n"
-" call  _FindTraceInfo\n"
-" add   $4,%esp\n"
-" pushl %eax\n"
-" pushl 4(%eax)\n"
-" call  _DbgPrint\n"
-" addl  $4,%esp\n"
-" popl  %eax\n"
-" mov   8(%eax),%eax\n"
-" jmp   *%eax\n"
-);
-
-#define TRACEDRV_ROUTINE(function) \
-unsigned TraceDrvIndex##function = INDEX_Drv##function; \
-__asm__ ( \
-" .text\n" \
-"_Trace" #function ":\n" \
-" movl _TraceDrvIndex" #function ",%eax\n" \
-" jmp TraceDrv\n" \
-); \
-extern PVOID Trace##function;
-
-TRACEDRV_ROUTINE(EnablePDEV)
-TRACEDRV_ROUTINE(CompletePDEV)
-TRACEDRV_ROUTINE(DisablePDEV)
-TRACEDRV_ROUTINE(EnableSurface)
-TRACEDRV_ROUTINE(DisableSurface)
-TRACEDRV_ROUTINE(AssertMode)
-TRACEDRV_ROUTINE(Offset)
-TRACEDRV_ROUTINE(ResetPDEV)
-TRACEDRV_ROUTINE(DisableDriver)
-TRACEDRV_ROUTINE(CreateDeviceBitmap)
-TRACEDRV_ROUTINE(DeleteDeviceBitmap)
-TRACEDRV_ROUTINE(RealizeBrush)
-TRACEDRV_ROUTINE(DitherColor)
-TRACEDRV_ROUTINE(StrokePath)
-TRACEDRV_ROUTINE(FillPath)
-TRACEDRV_ROUTINE(StrokeAndFillPath)
-TRACEDRV_ROUTINE(Paint)
-TRACEDRV_ROUTINE(BitBlt)
-TRACEDRV_ROUTINE(TransparentBlt)
-TRACEDRV_ROUTINE(CopyBits)
-TRACEDRV_ROUTINE(StretchBlt)
-TRACEDRV_ROUTINE(StretchBltROP)
-TRACEDRV_ROUTINE(SetPalette)
-TRACEDRV_ROUTINE(TextOut)
-TRACEDRV_ROUTINE(Escape)
-TRACEDRV_ROUTINE(DrawEscape)
-TRACEDRV_ROUTINE(QueryFont)
-TRACEDRV_ROUTINE(QueryFontTree)
-TRACEDRV_ROUTINE(QueryFontData)
-TRACEDRV_ROUTINE(SetPointerShape)
-TRACEDRV_ROUTINE(MovePointer)
-TRACEDRV_ROUTINE(LineTo)
-TRACEDRV_ROUTINE(SendPage)
-TRACEDRV_ROUTINE(StartPage)
-TRACEDRV_ROUTINE(EndDoc)
-TRACEDRV_ROUTINE(StartDoc)
-TRACEDRV_ROUTINE(GetGlyphMode)
-TRACEDRV_ROUTINE(Synchronize)
-TRACEDRV_ROUTINE(SaveScreenBits)
-TRACEDRV_ROUTINE(GetModes)
-TRACEDRV_ROUTINE(Free)
-TRACEDRV_ROUTINE(DestroyFont)
-TRACEDRV_ROUTINE(QueryFontCaps)
-TRACEDRV_ROUTINE(LoadFontFile)
-TRACEDRV_ROUTINE(UnloadFontFile)
-TRACEDRV_ROUTINE(FontManagement)
-TRACEDRV_ROUTINE(QueryTrueTypeTable)
-TRACEDRV_ROUTINE(QueryTrueTypeOutline)
-TRACEDRV_ROUTINE(GetTrueTypeFile)
-TRACEDRV_ROUTINE(QueryFontFile)
-TRACEDRV_ROUTINE(QueryAdvanceWidths)
-TRACEDRV_ROUTINE(SetPixelFormat)
-TRACEDRV_ROUTINE(DescribePixelFormat)
-TRACEDRV_ROUTINE(SwapBuffers)
-TRACEDRV_ROUTINE(StartBanding)
-TRACEDRV_ROUTINE(NextBand)
-TRACEDRV_ROUTINE(GetDirectDrawInfo)
-TRACEDRV_ROUTINE(EnableDirectDraw)
-TRACEDRV_ROUTINE(DisableDirectDraw)
-TRACEDRV_ROUTINE(QuerySpoolType)
-TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp)
-TRACEDRV_ROUTINE(GradientFill)
-TRACEDRV_ROUTINE(SynchronizeSurface)
-TRACEDRV_ROUTINE(AlphaBlend)
-
-#define TRACEDRVINFO_ENTRY(function) \
-    { INDEX_Drv##function, "Drv" #function "\n", NULL }
-static TRACEDRVINFO TraceDrvInfo[] =
-  {
-    TRACEDRVINFO_ENTRY(EnablePDEV),
-    TRACEDRVINFO_ENTRY(CompletePDEV),
-    TRACEDRVINFO_ENTRY(DisablePDEV),
-    TRACEDRVINFO_ENTRY(EnableSurface),
-    TRACEDRVINFO_ENTRY(DisableSurface),
-    TRACEDRVINFO_ENTRY(AssertMode),
-    TRACEDRVINFO_ENTRY(Offset),
-    TRACEDRVINFO_ENTRY(ResetPDEV),
-    TRACEDRVINFO_ENTRY(DisableDriver),
-    TRACEDRVINFO_ENTRY(CreateDeviceBitmap),
-    TRACEDRVINFO_ENTRY(DeleteDeviceBitmap),
-    TRACEDRVINFO_ENTRY(RealizeBrush),
-    TRACEDRVINFO_ENTRY(DitherColor),
-    TRACEDRVINFO_ENTRY(StrokePath),
-    TRACEDRVINFO_ENTRY(FillPath),
-    TRACEDRVINFO_ENTRY(StrokeAndFillPath),
-    TRACEDRVINFO_ENTRY(Paint),
-    TRACEDRVINFO_ENTRY(BitBlt),
-    TRACEDRVINFO_ENTRY(TransparentBlt),
-    TRACEDRVINFO_ENTRY(CopyBits),
-    TRACEDRVINFO_ENTRY(StretchBlt),
-    TRACEDRVINFO_ENTRY(StretchBltROP),
-    TRACEDRVINFO_ENTRY(SetPalette),
-    TRACEDRVINFO_ENTRY(TextOut),
-    TRACEDRVINFO_ENTRY(Escape),
-    TRACEDRVINFO_ENTRY(DrawEscape),
-    TRACEDRVINFO_ENTRY(QueryFont),
-    TRACEDRVINFO_ENTRY(QueryFontTree),
-    TRACEDRVINFO_ENTRY(QueryFontData),
-    TRACEDRVINFO_ENTRY(SetPointerShape),
-    TRACEDRVINFO_ENTRY(MovePointer),
-    TRACEDRVINFO_ENTRY(LineTo),
-    TRACEDRVINFO_ENTRY(SendPage),
-    TRACEDRVINFO_ENTRY(StartPage),
-    TRACEDRVINFO_ENTRY(EndDoc),
-    TRACEDRVINFO_ENTRY(StartDoc),
-    TRACEDRVINFO_ENTRY(GetGlyphMode),
-    TRACEDRVINFO_ENTRY(Synchronize),
-    TRACEDRVINFO_ENTRY(SaveScreenBits),
-    TRACEDRVINFO_ENTRY(GetModes),
-    TRACEDRVINFO_ENTRY(Free),
-    TRACEDRVINFO_ENTRY(DestroyFont),
-    TRACEDRVINFO_ENTRY(QueryFontCaps),
-    TRACEDRVINFO_ENTRY(LoadFontFile),
-    TRACEDRVINFO_ENTRY(UnloadFontFile),
-    TRACEDRVINFO_ENTRY(FontManagement),
-    TRACEDRVINFO_ENTRY(QueryTrueTypeTable),
-    TRACEDRVINFO_ENTRY(QueryTrueTypeOutline),
-    TRACEDRVINFO_ENTRY(GetTrueTypeFile),
-    TRACEDRVINFO_ENTRY(QueryFontFile),
-    TRACEDRVINFO_ENTRY(QueryAdvanceWidths),
-    TRACEDRVINFO_ENTRY(SetPixelFormat),
-    TRACEDRVINFO_ENTRY(DescribePixelFormat),
-    TRACEDRVINFO_ENTRY(SwapBuffers),
-    TRACEDRVINFO_ENTRY(StartBanding),
-    TRACEDRVINFO_ENTRY(NextBand),
-    TRACEDRVINFO_ENTRY(GetDirectDrawInfo),
-    TRACEDRVINFO_ENTRY(EnableDirectDraw),
-    TRACEDRVINFO_ENTRY(DisableDirectDraw),
-    TRACEDRVINFO_ENTRY(QuerySpoolType),
-    TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp),
-    TRACEDRVINFO_ENTRY(GradientFill),
-    TRACEDRVINFO_ENTRY(SynchronizeSurface),
-    TRACEDRVINFO_ENTRY(AlphaBlend)
-  };
-
-PTRACEDRVINFO
-FindTraceInfo(unsigned Index)
-{
-  unsigned i;
-
-  for (i = 0; i < sizeof(TraceDrvInfo) / sizeof(TRACEDRVINFO); i++)
-    {
-      if (TraceDrvInfo[i].Index == Index)
-        {
-          return TraceDrvInfo + i;
-        }
-    }
-
-  return NULL;
-}
-
-#define DRIVER_FUNCTION(function) \
-      case INDEX_Drv##function: \
-        FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \
-        *(PVOID*)&DF->function = &Trace##function; \
-        break
-#else
-#define DRIVER_FUNCTION(function) \
-      case INDEX_Drv##function: \
-        *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
-        break
-#endif
-
-BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA  DED,
-                               PDRIVER_FUNCTIONS  DF)
-{
-  BEGIN_FUNCTION_MAP();
-    DRIVER_FUNCTION(EnablePDEV);   
-    DRIVER_FUNCTION(CompletePDEV);
-    DRIVER_FUNCTION(DisablePDEV);
-    DRIVER_FUNCTION(EnableSurface);
-    DRIVER_FUNCTION(DisableSurface);
-    DRIVER_FUNCTION(AssertMode);
-    DRIVER_FUNCTION(Offset);
-    DRIVER_FUNCTION(ResetPDEV);
-    DRIVER_FUNCTION(DisableDriver);
-    DRIVER_FUNCTION(Unknown1);
-    DRIVER_FUNCTION(CreateDeviceBitmap);
-    DRIVER_FUNCTION(DeleteDeviceBitmap);
-    DRIVER_FUNCTION(RealizeBrush);
-    DRIVER_FUNCTION(DitherColor);
-    DRIVER_FUNCTION(StrokePath);
-    DRIVER_FUNCTION(FillPath);
-    DRIVER_FUNCTION(StrokeAndFillPath);
-    DRIVER_FUNCTION(Paint);
-    DRIVER_FUNCTION(BitBlt);
-    DRIVER_FUNCTION(CopyBits);
-    DRIVER_FUNCTION(StretchBlt);
-    DRIVER_FUNCTION(Unknown2);    
-    DRIVER_FUNCTION(SetPalette);
-    DRIVER_FUNCTION(TextOut);
-    DRIVER_FUNCTION(Escape);
-    DRIVER_FUNCTION(DrawEscape);
-    DRIVER_FUNCTION(QueryFont);
-    DRIVER_FUNCTION(QueryFontTree);
-    DRIVER_FUNCTION(QueryFontData);
-    DRIVER_FUNCTION(SetPointerShape);
-    DRIVER_FUNCTION(MovePointer);
-    DRIVER_FUNCTION(LineTo);
-    DRIVER_FUNCTION(SendPage);
-    DRIVER_FUNCTION(StartPage);
-    DRIVER_FUNCTION(EndDoc);
-    DRIVER_FUNCTION(StartDoc);
-    DRIVER_FUNCTION(Unknown3);
-    DRIVER_FUNCTION(GetGlyphMode);
-    DRIVER_FUNCTION(Synchronize);
-    DRIVER_FUNCTION(Unknown4);
-    DRIVER_FUNCTION(SaveScreenBits);
-    DRIVER_FUNCTION(GetModes);
-    DRIVER_FUNCTION(Free);
-    DRIVER_FUNCTION(DestroyFont);
-    DRIVER_FUNCTION(QueryFontCaps);
-    DRIVER_FUNCTION(LoadFontFile);
-    DRIVER_FUNCTION(UnloadFontFile);
-    DRIVER_FUNCTION(FontManagement);
-    DRIVER_FUNCTION(QueryTrueTypeTable);
-    DRIVER_FUNCTION(QueryTrueTypeOutline);
-    DRIVER_FUNCTION(GetTrueTypeFile);
-    DRIVER_FUNCTION(QueryFontFile);
-    DRIVER_FUNCTION(QueryAdvanceWidths);
-    DRIVER_FUNCTION(SetPixelFormat);
-    DRIVER_FUNCTION(DescribePixelFormat);
-    DRIVER_FUNCTION(SwapBuffers);
-    DRIVER_FUNCTION(StartBanding);
-    DRIVER_FUNCTION(NextBand);
-    DRIVER_FUNCTION(GetDirectDrawInfo);
-    DRIVER_FUNCTION(EnableDirectDraw);
-    DRIVER_FUNCTION(DisableDirectDraw);
-    DRIVER_FUNCTION(QuerySpoolType);
-    DRIVER_FUNCTION(Unknown5);   
-    DRIVER_FUNCTION(IcmCreateColorTransform);   
-    DRIVER_FUNCTION(IcmDeleteColorTransform);   
-    DRIVER_FUNCTION(IcmCheckBitmapBits);   
-    DRIVER_FUNCTION(IcmSetDeviceGammaRamp);   
-    DRIVER_FUNCTION(GradientFill);   
-    DRIVER_FUNCTION(StretchBltROP);   
-    DRIVER_FUNCTION(PlgBlt);   
-    DRIVER_FUNCTION(AlphaBlend);   
-    DRIVER_FUNCTION(SynthesizeFont);   
-    DRIVER_FUNCTION(GetSynthesizedFontFiles);   
-    DRIVER_FUNCTION(TransparentBlt);   
-    DRIVER_FUNCTION(QueryPerBandInfo);   
-    DRIVER_FUNCTION(QueryDeviceSupport);   
-    DRIVER_FUNCTION(Reserved1);   
-    DRIVER_FUNCTION(Reserved2);   
-    DRIVER_FUNCTION(Reserved3);   
-    DRIVER_FUNCTION(Reserved4);   
-    DRIVER_FUNCTION(Reserved5);   
-    DRIVER_FUNCTION(Reserved6); 
-    DRIVER_FUNCTION(Reserved7); 
-    DRIVER_FUNCTION(Reserved8); 
-    DRIVER_FUNCTION(DeriveSurface); 
-    DRIVER_FUNCTION(QueryGlyphAttrs); 
-    DRIVER_FUNCTION(Notify); 
-    DRIVER_FUNCTION(SynchronizeSurface); 
-    DRIVER_FUNCTION(ResetDevice); 
-    DRIVER_FUNCTION(Reserved9); 
-    DRIVER_FUNCTION(Reserved10); 
-    DRIVER_FUNCTION(Reserved11);     
-  END_FUNCTION_MAP();
-
-  return TRUE;
-}
-
-typedef LONG VP_STATUS;
-typedef VP_STATUS (APIENTRY *PMP_DRIVERENTRY)(PVOID, PVOID);
-
-PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber)
-{
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  WCHAR DeviceNameBuffer[20];
-  UNICODE_STRING DeviceName;
-  IO_STATUS_BLOCK Iosb;
-  HANDLE DisplayHandle;
-  NTSTATUS Status;
-  PFILE_OBJECT VideoFileObject;
-
-  swprintf(DeviceNameBuffer, L"\\??\\DISPLAY%d", DisplayNumber + 1);
-  RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &DeviceName,
-                            0,
-                            NULL,
-                            NULL);
-  Status = ZwOpenFile(&DisplayHandle,
-                     FILE_ALL_ACCESS,
-                     &ObjectAttributes,
-                     &Iosb,
-                     0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
-  if (NT_SUCCESS(Status))
-    {
-      Status = ObReferenceObjectByHandle(DisplayHandle,
-                                         FILE_READ_DATA | FILE_WRITE_DATA,
-                                         IoFileObjectType,
-                                         KernelMode,
-                                         (PVOID *)&VideoFileObject,
-                                         NULL);
-      ZwClose(DisplayHandle);
-    }
-
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("Unable to connect to miniport (Status %lx)\n", Status);
-      DPRINT1("Perhaps the miniport wasn't loaded?\n");
-      return(NULL);
-    }
-
-  return VideoFileObject;
-}
-
-
-BOOL DRIVER_UnregisterDriver(LPCWSTR  Name)
-{
-  PGRAPHICS_DRIVER  Driver = NULL;
-
-  if (Name)
-  {
-    if (DriverList != NULL)
-    {
-      if (!_wcsicmp(DriverList->Name, Name))
-      {
-        Driver = DriverList;
-        DriverList = DriverList->Next;
-      }
-      else
-      {
-        Driver = DriverList;
-        while (Driver->Next && _wcsicmp(Driver->Name, Name))
-        {
-          Driver = Driver->Next;
-        }
-      }
-    }
-  }
-  else
-  {
-    if (GenericDriver != NULL)
-    {
-      Driver = GenericDriver;
-      GenericDriver = NULL;
-    }
-  }
-
-  if (Driver != NULL)
-  {
-    ExFreePool(Driver->Name);
-    ExFreePool(Driver);
-
-    return  TRUE;
-  }
-  else
-  {
-    return  FALSE;
-  }
-}
-
-INT DRIVER_ReferenceDriver (LPCWSTR  Name)
-{
-  GRAPHICS_DRIVER *Driver = DriverList;
-
-  while (Driver && Name)
-  {
-    DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
-    if (!_wcsicmp( Driver->Name, Name))
-    {
-      return ++Driver->ReferenceCount;
-    }
-    Driver = Driver->Next;
-  }
-  DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
-  assert( GenericDriver != 0 );
-  return ++GenericDriver->ReferenceCount;
-}
-
-INT DRIVER_UnreferenceDriver (LPCWSTR  Name)
-{
-  GRAPHICS_DRIVER *Driver = DriverList;
-
-  while (Driver && Name)
-  {
-    DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
-    if (!_wcsicmp( Driver->Name, Name))
-    {
-      return --Driver->ReferenceCount;
-    }
-    Driver = Driver->Next;
-  }
-  DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
-  assert( GenericDriver != 0 );
-  return --GenericDriver->ReferenceCount;
-}
-/* EOF */
index 263ed12..ed94c35 100644 (file)
@@ -302,22 +302,30 @@ UserLoadImage(PCWSTR pwszName)
     HBITMAP hbmp = 0;
     BITMAPV5INFO bmiLocal;
 
+    DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
+
     /* Open the file */
     hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
-    if (hFile == INVALID_HANDLE_VALUE)
-          return NULL;
+    if (!hFile)
+    {
+        return NULL;
+    }
 
     /* Create a section */
     hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
     ZwClose(hFile);
     if (!hSection)
-          return NULL;
+    {
+        return NULL;
+    }
 
     /* Map the section */
     pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
     ZwClose(hSection);
     if (!pbmfh)
-          return NULL;
+    {
+        return NULL;
+    }
 
     /* Get a pointer to the BITMAPINFO */
     pbmi = (LPBITMAPINFO)(pbmfh + 1);
index f03de06..1f81281 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+NTSTATUS
+NTAPI
+RegOpenKey(
+    LPCWSTR pwszKeyName,
+    PHKEY phkey)
+{
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING ustrKeyName;
+    HKEY hkey;
+
+    /* Initialize the key name */
+    RtlInitUnicodeString(&ustrKeyName, pwszKeyName);
+
+    /* Initialize object attributes */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &ustrKeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    /* Open the key */
+    Status = ZwOpenKey(&hkey, KEY_READ, &ObjectAttributes);
+    if (NT_SUCCESS(Status))
+    {
+        *phkey = hkey;
+    }
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RegQueryValue(
+    IN HKEY hkey,
+    IN PCWSTR pwszValueName,
+    IN ULONG ulType,
+    OUT PVOID pvData,
+    IN OUT PULONG pcbValue)
+{
+    NTSTATUS Status;
+    UNICODE_STRING ustrValueName;
+    BYTE ajBuffer[100];
+    PKEY_VALUE_PARTIAL_INFORMATION pInfo;
+    ULONG cbInfoSize;
+
+    /* Check if the local buffer is sufficient */
+    cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue;
+    if (cbInfoSize <= sizeof(ajBuffer))
+    {
+        pInfo = (PVOID)ajBuffer;
+    }
+    else
+    {
+        /* It's not, allocate a sufficient buffer */
+        pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
+        if (!pInfo)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+    }
+
+    /* Query the value */
+    RtlInitUnicodeString(&ustrValueName, pwszValueName);
+    Status = ZwQueryValueKey(hkey,
+                             &ustrValueName,
+                             KeyValuePartialInformation,
+                             (PVOID)pInfo,
+                             cbInfoSize,
+                             &cbInfoSize);
+    if (NT_SUCCESS(Status))
+    {
+        /* Did we get the right type */
+        if (pInfo->Type == ulType)
+        {
+            /* Copy the contents to the caller */
+            RtlCopyMemory(pvData, pInfo->Data, *pcbValue);
+        }
+        else
+            Status = STATUS_OBJECT_TYPE_MISMATCH;
+    }
+
+    /* Return the data size to the caller */
+    *pcbValue = cbInfoSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+
+    /* Cleanup */
+    if (pInfo != (PVOID)ajBuffer)
+        ExFreePoolWithTag(pInfo, TAG_TEMP);
+
+    return Status;
+
+}
+
+
 BOOL
 NTAPI
 RegReadUserSetting(
@@ -163,7 +257,8 @@ RegWriteUserSetting(
     Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n", Status, usKeyName.Length, usKeyName.MaximumLength);
+        DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n", 
+                Status, usKeyName.Length, usKeyName.MaximumLength);
         return FALSE;
     }
 
index 586c496..95aafe8 100644 (file)
@@ -1,4 +1,4 @@
-  /*
+/*
  * PROJECT:          ReactOS Win32 Subsystem
  * LICENSE:          GPL - See COPYING in the top level directory
  * FILE:             subsystems/win32/win32k/ntddraw/dxeng.c
@@ -297,8 +297,7 @@ DxEngGetHdevData(HDEV hDev,
         break;
       case DxEGShDevData_hSpooler:
         DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_hSpooler\n");
-         // retVal = (DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
-        retVal = (DWORD_PTR) PDev->VideoFileObject->DeviceObject;
+        retVal = 0;//(DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
         break;
       case DxEGShDevData_DitherFmt:
         DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_DitherFmt\n");
index c652e30..e5748fc 100644 (file)
 /*
- * PROJECT:         ReactOS Kernel
- * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            subsystems/win32/win32k/ntuser/display.c
- * PURPOSE:         display settings
- * COPYRIGHT:       Copyright 2007 ReactOS
- *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * PURPOSE:          Video initialization and display settings
+ * FILE:             subsystems/win32/win32k/ntuser/display.c
+ * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
  */
 
-/* INCLUDES ******************************************************************/
-
 #include <w32k.h>
 
+#include <intrin.h>
+
 #define NDEBUG
 #include <debug.h>
 
-#define SIZEOF_DEVMODEW_300 188
-#define SIZEOF_DEVMODEW_400 212
-#define SIZEOF_DEVMODEW_500 220
+PDEVOBJ *gpdevPrimary;
 
-/* PUBLIC FUNCTIONS ***********************************************************/
+const PWCHAR KEY_ROOT = L"";
+const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
 
 NTSTATUS
-APIENTRY
-NtUserEnumDisplaySettings(
-   PUNICODE_STRING pusDeviceName,
-   DWORD iModeNum,
-   LPDEVMODEW lpDevMode, /* FIXME is this correct? */
-   DWORD dwFlags )
+NTAPI
+UserEnumDisplayDevices(
+    PUNICODE_STRING pustrDevice,
+    DWORD iDevNum,
+    PDISPLAY_DEVICEW pdispdev,
+    DWORD dwFlags);
+
+VOID
+RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData)
+{
+    UNICODE_STRING ustrValue;
+    UNICODE_STRING ustrData;
+
+    RtlInitUnicodeString(&ustrValue, pwszValue);
+    RtlInitUnicodeString(&ustrData, pwszData);
+    ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR));
+}
+
+VOID
+RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData)
+{
+    UNICODE_STRING ustrValue;
+
+    RtlInitUnicodeString(&ustrValue, pwszValue);
+    ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD));
+}
+
+
+BOOL
+RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData)
 {
     NTSTATUS Status;
-    LPDEVMODEW pSafeDevMode;
-    PUNICODE_STRING pusSafeDeviceName = NULL;
-    UNICODE_STRING usSafeDeviceName;
-    USHORT Size = 0, ExtraSize = 0;
+    ULONG cbSize = sizeof(DWORD);
+    Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize);
+    return NT_SUCCESS(Status);
+}
+
+VOID
+RegWriteDisplaySettings(HKEY hkey, PDEVMODEW pdm)
+{
+    RegWriteDWORD(hkey, L"DefaultSettings.BitsPerPel", pdm->dmBitsPerPel);
+    RegWriteDWORD(hkey, L"DefaultSettings.XResolution", pdm->dmPelsWidth);
+    RegWriteDWORD(hkey, L"DefaultSettings.YResolution", pdm->dmPelsHeight);
+    RegWriteDWORD(hkey, L"DefaultSettings.Flags", pdm->dmDisplayFlags);
+    RegWriteDWORD(hkey, L"DefaultSettings.VRefresh", pdm->dmDisplayFrequency);
+    RegWriteDWORD(hkey, L"DefaultSettings.XPanning", pdm->dmPanningWidth);
+    RegWriteDWORD(hkey, L"DefaultSettings.YPanning", pdm->dmPanningHeight);
+    RegWriteDWORD(hkey, L"DefaultSettings.Orientation", pdm->dmDisplayOrientation);
+    RegWriteDWORD(hkey, L"DefaultSettings.FixedOutput", pdm->dmDisplayFixedOutput);
+    RegWriteDWORD(hkey, L"Attach.RelativeX", pdm->dmPosition.x);
+    RegWriteDWORD(hkey, L"Attach.RelativeY", pdm->dmPosition.y);
+//    RegWriteDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", pdm->);
+}
 
-    /* Copy the devmode */
-    _SEH2_TRY
+VOID
+RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm)
+{
+    DWORD dwValue;
+
+    RtlZeroMemory(pdm, sizeof(DEVMODEW));
+
+    if (RegReadDWORD(hkey, L"DefaultSettings.BitsPerPel", &dwValue))
+    {
+        pdm->dmBitsPerPel = dwValue;
+        pdm->dmFields |= DM_BITSPERPEL;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.XResolution", &dwValue))
+    {
+        pdm->dmPelsWidth = dwValue;
+//        pdm->dmFields |= DM_XRESOLUTION;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.YResolution", &dwValue))
+    {
+        pdm->dmPelsHeight = dwValue;
+        pdm->dmFields |= DM_YRESOLUTION;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.Flags", &dwValue))
+    {
+        pdm->dmDisplayFlags = dwValue;
+        pdm->dmFields |= DM_BITSPERPEL;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.VRefresh", &dwValue))
+    {
+        pdm->dmDisplayFrequency = dwValue;
+        pdm->dmFields |= DM_DISPLAYFREQUENCY;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.XPanning", &dwValue))
+    {
+        pdm->dmPanningWidth = dwValue;
+        pdm->dmFields |= DM_PANNINGWIDTH;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.YPanning", &dwValue))
+    {
+        pdm->dmPanningHeight = dwValue;
+        pdm->dmFields |= DM_PANNINGHEIGHT;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.Orientation", &dwValue))
+    {
+        pdm->dmDisplayOrientation = dwValue;
+        pdm->dmFields |= DM_DISPLAYORIENTATION;
+    }
+    if (RegReadDWORD(hkey, L"DefaultSettings.FixedOutput", &dwValue))
     {
-        ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
-        Size = lpDevMode->dmSize;
-        ExtraSize = lpDevMode->dmDriverExtra;
+        pdm->dmDisplayFixedOutput = dwValue;
+        pdm->dmFields |= DM_BITSPERPEL;
     }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    if (RegReadDWORD(hkey, L"Attach.RelativeX", &dwValue))
     {
-        DPRINT("FIXME ? : Out of range of DEVMODEW size \n");
-        _SEH2_YIELD(return _SEH2_GetExceptionCode());
+        pdm->dmPosition.x = dwValue;
+        pdm->dmFields |= DM_POSITION;
     }
-    _SEH2_END;
+    if (RegReadDWORD(hkey, L"Attach.RelativeY", &dwValue))
+    {
+        pdm->dmPosition.y = dwValue;
+        pdm->dmFields |= DM_POSITION;
+    }
+//    RegReadDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", &pdm->);
+
+}
+
 
-    if (Size != sizeof(DEVMODEW))
+
+
+enum
+{
+    VF_USEVGA = 0x1,
+};
+
+BOOL
+InitDisplayDriver(
+    PUNICODE_STRING pustrRegPath,
+    FLONG flags)
+{
+//    PWSTR pwszDriverName;
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    NTSTATUS Status;
+
+    /* Setup QueryTable for direct registry query */
+    RtlZeroMemory(QueryTable, sizeof(QueryTable));
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED|RTL_QUERY_REGISTRY_DIRECT;
+
+
+    /* Check if vga mode is requested */
+    if (flags & VF_USEVGA)
     {
-        return STATUS_BUFFER_TOO_SMALL;
+        DWORD dwVgaCompatible;
+
+        /*  */
+        QueryTable[0].Name = L"VgaCompatible";
+        QueryTable[0].EntryContext = &dwVgaCompatible;
+
+        /* Check if the driver is vga */
+        Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+                                        pustrRegPath->Buffer,
+                                        QueryTable,
+                                        NULL,
+                                        NULL);
+        
+        if (!dwVgaCompatible)
+        {
+            /* This driver is not a vga driver */
+            return FALSE;
+        }
     }
 
-    pSafeDevMode = ExAllocatePool(PagedPool, Size + ExtraSize);
-    if (pSafeDevMode == NULL)
+#if 0
+
+    /* Query the adapter's registry path */
+    swprintf(awcBuffer, L"\\Device\\Video%lu", iDevNum);
+    QueryTable[0].Name = pGraphicsDevice->szNtDeviceName;
+
+    /* Set string for the registry key */
+    ustrRegistryPath.Buffer = pdispdev->DeviceKey;
+    ustrRegistryPath.Length = 128;
+    ustrRegistryPath.MaximumLength = 128;
+    QueryTable[0].EntryContext = &ustrRegistryPath;
+
+    /* Query the registry */
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
+                                    L"VIDEO",
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
+
+    RegQueryValue(KEY_VIDEO, awcBuffer, REG_SZ, pdispdev->DeviceKey, 256);
+
     {
-        return STATUS_NO_MEMORY;
+        HANDLE hmod;
+
+        hmod = EngLoadImage(pwszDriverName);
+
+        /* Jump to next name */
+        pwszDriverName += wcslen(pwszDriverName) + 1;
     }
-    pSafeDevMode->dmSize = Size;
-    pSafeDevMode->dmDriverExtra = ExtraSize;
+    while (pwszDriverName < 0);
+#endif
 
-    /* Copy the device name */
-    if (pusDeviceName != NULL)
+    return 0;
+}
+
+
+NTSTATUS
+NTAPI
+DisplayDriverQueryRoutine(
+    IN PWSTR ValueName,
+    IN ULONG ValueType,
+    IN PVOID ValueData,
+    IN ULONG ValueLength,
+    IN PVOID Context,
+    IN PVOID EntryContext)
+{
+    PWSTR pwszRegKey = ValueData;
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    UNICODE_STRING ustrDeviceName, ustrDisplayDrivers, ustrDescription;
+    NTSTATUS Status;
+    WCHAR awcBuffer[128];
+    ULONG cbSize;
+    HKEY hkey;
+    DEVMODEW dmDefault;
+
+    UNREFERENCED_PARAMETER(ValueLength);
+    UNREFERENCED_PARAMETER(Context);
+    UNREFERENCED_PARAMETER(EntryContext);
+
+    DPRINT1("DisplayDriverQueryRoutine(%S, %S);\n", 
+            ValueName, pwszRegKey);
+
+    /* Check if we have a correct entry */
+    if (ValueType != REG_SZ || ValueName[0] != '\\')
     {
-        Status = IntSafeCopyUnicodeString(&usSafeDeviceName, pusDeviceName);
-        if (!NT_SUCCESS(Status))
+        /* Something else, just skip it */
+        return STATUS_SUCCESS;
+    }
+
+    /* Open the driver's registry key */
+    Status = RegOpenKey(pwszRegKey, &hkey);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open registry key\n");
+        return STATUS_SUCCESS;
+    }
+
+// HACK: only use 1st adapter
+//if (ValueName[13] != '0')
+//    return STATUS_SUCCESS;
+
+    /* Query the diplay drivers */
+    cbSize = sizeof(awcBuffer) - 10;
+    Status = RegQueryValue(hkey,
+                           L"InstalledDisplayDrivers",
+                           REG_MULTI_SZ,
+                           awcBuffer,
+                           &cbSize);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Didn't find 'InstalledDisplayDrivers', status = 0x%lx\n", Status);
+        ZwClose(hkey);
+        return STATUS_SUCCESS;
+    }
+
+    /* Initialize the UNICODE_STRING */
+    ustrDisplayDrivers.Buffer = awcBuffer;
+    ustrDisplayDrivers.MaximumLength = cbSize;
+    ustrDisplayDrivers.Length = cbSize;
+
+    /* Set Buffer for description and size of remaining buffer */
+    ustrDescription.Buffer = awcBuffer + (cbSize / sizeof(WCHAR));
+    cbSize = sizeof(awcBuffer) - cbSize;
+
+    /* Query the device string */
+    Status = RegQueryValue(hkey,
+                           L"Device Description",
+                           REG_SZ,
+                           ustrDescription.Buffer,
+                           &cbSize);
+    if (NT_SUCCESS(Status))
+    {
+        ustrDescription.MaximumLength = cbSize;
+        ustrDescription.Length = cbSize;
+    }
+    else
+    {
+        RtlInitUnicodeString(&ustrDescription, L"<unknown>");
+    }
+
+    /* Query the default settings */
+    RegReadDisplaySettings(hkey, &dmDefault);
+
+    /* Close the registry key */
+    ZwClose(hkey);
+
+    /* Register the device with GDI */
+    RtlInitUnicodeString(&ustrDeviceName, ValueName);
+    pGraphicsDevice = EngpRegisterGraphicsDevice(&ustrDeviceName,
+                                                 &ustrDisplayDrivers,
+                                                 &ustrDescription,
+                                                 &dmDefault);
+
+    // FIXME: what to do with pGraphicsDevice?
+
+    return STATUS_SUCCESS;
+}
+
+BOOL InitSysParams();
+
+BOOL
+InitVideo(FLONG flags)
+{
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    NTSTATUS Status;
+
+    DPRINT1("----------------------------- InitVideo() -------------------------------\n");
+
+    /* Setup QueryTable for registry query */
+    RtlZeroMemory(QueryTable, sizeof(QueryTable));
+    QueryTable[0].QueryRoutine = DisplayDriverQueryRoutine;
+
+    /* Query the registry */
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
+                                    L"VIDEO",
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
+
+    InitSysParams();
+
+    return 0;
+}
+
+
+NTSTATUS
+NTAPI
+UserEnumDisplayDevices(
+    PUNICODE_STRING pustrDevice,
+    DWORD iDevNum,
+    PDISPLAY_DEVICEW pdispdev,
+    DWORD dwFlags)
+{
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    ULONG cbSize;
+    HKEY hkey;
+    NTSTATUS Status;
+
+    /* Ask gdi for the GRAPHICS_DEVICE */
+    pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, iDevNum, 0);
+    if (!pGraphicsDevice)
+    {
+        /* No device found */
+        DPRINT1("No GRAPHICS_DEVICE found\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Open thhe device map registry key */
+    Status = RegOpenKey(KEY_VIDEO, &hkey);
+    if (!NT_SUCCESS(Status))
+    {
+        /* No device found */
+        DPRINT1("Could not open reg key\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Query the registry path */
+    cbSize = sizeof(pdispdev->DeviceKey);
+    RegQueryValue(hkey,
+                  pGraphicsDevice->szNtDeviceName,
+                  REG_SZ,
+                  pdispdev->DeviceKey,
+                  &cbSize);
+
+    /* Close registry key */
+    ZwClose(hkey);
+
+    /* Copy device name, device string and StateFlags */
+    wcsncpy(pdispdev->DeviceName, pGraphicsDevice->szWinDeviceName, 32);
+    wcsncpy(pdispdev->DeviceString, pGraphicsDevice->pwszDescription, 128);
+    pdispdev->StateFlags = pGraphicsDevice->StateFlags;
+
+    // FIXME: fill in DEVICE ID
+
+    return STATUS_SUCCESS;
+}
+
+//NTSTATUS
+BOOL
+NTAPI
+NtUserEnumDisplayDevices(
+    PUNICODE_STRING pustrDevice,
+    DWORD iDevNum,
+    PDISPLAY_DEVICEW pDisplayDevice,
+    DWORD dwFlags)             
+{
+    UNICODE_STRING ustrDevice;
+    WCHAR awcDevice[CCHDEVICENAME];
+    DISPLAY_DEVICEW dispdev;
+    NTSTATUS Status;
+
+    DPRINT1("Enter NtUserEnumDisplayDevices(%p, %ls, %ld)\n",
+            pustrDevice, pustrDevice ? pustrDevice->Buffer : 0, iDevNum);
+
+    // FIXME: HACK, desk.cpl passes broken crap
+    if (pustrDevice && iDevNum != 0)
+        return FALSE;
+
+    dispdev.cb = sizeof(DISPLAY_DEVICEW);
+
+    if (pustrDevice)
+    {
+        /* Initialize destination string */
+        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+        _SEH2_TRY
         {
-            ExFreePool(pSafeDevMode);
-            return Status;
+            /* Probe the UNICODE_STRING and the buffer */
+            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+            /* Copy the string */
+            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
         }
-        pusSafeDeviceName = &usSafeDeviceName;
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+//            _SEH2_YIELD(return _SEH2_GetExceptionCode());
+            _SEH2_YIELD(return NT_SUCCESS(_SEH2_GetExceptionCode()));
+        }
+        _SEH2_END
+
+        if (ustrDevice.Length > 0)
+            pustrDevice = &ustrDevice;
+        else
+            pustrDevice = NULL;
+   }
+
+    /* Acquire global USER lock */
+    UserEnterExclusive();
+
+    /* Call the internal function */
+    Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags);
+
+    /* Release lock */
+    UserLeave();
+
+    /* On success copy data to caller */
+    if (NT_SUCCESS(Status))
+    {
+        /* Enter SEH */
+        _SEH2_TRY
+        {
+            /* First probe the cb field */
+            ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1);
+
+            /* Check the buffer size */
+            if (pDisplayDevice->cb)
+            {
+                /* Probe the output buffer */
+                pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev));
+                ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1);
+
+                /* Copy as much as the given buffer allows */
+                RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb);
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END
     }
 
-    /* Call internal function */
-    Status = IntEnumDisplaySettings(pusSafeDeviceName, iModeNum, pSafeDevMode, dwFlags);
+    DPRINT1("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status);
+    /* Return the result */
+//    return Status;
+    return NT_SUCCESS(Status); // FIXME
+}
 
-    if (pusSafeDeviceName != NULL)
-        RtlFreeUnicodeString(pusSafeDeviceName);
+NTSTATUS
+NTAPI
+UserEnumCurrentDisplaySettings(
+    PUNICODE_STRING pustrDevice,
+    PDEVMODEW *ppdm)
+{
+    PPDEVOBJ ppdev;
 
-    if (!NT_SUCCESS(Status))
+    /* Get the PDEV for the device */
+    ppdev = EngpGetPDEV(pustrDevice);
+    if (!ppdev)
+    {
+        /* No device found */
+        DPRINT1("No PDEV found!\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    *ppdm = ppdev->pdmwDev;
+    
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+UserEnumDisplaySettings(
+   PUNICODE_STRING pustrDevice,
+   DWORD iModeNum,
+   LPDEVMODEW *ppdm,
+   DWORD dwFlags)
+{
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    PDEVMODEENTRY pdmentry;
+    ULONG i, iFoundMode;
+
+    DPRINT1("Enter UserEnumDisplaySettings('%ls', %ld)\n",
+            pustrDevice ? pustrDevice->Buffer : NULL, iModeNum);
+
+    /* Ask gdi for the GRAPHICS_DEVICE */
+    pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0);
+    if (!pGraphicsDevice)
+    {
+        /* No device found */
+        DPRINT1("No device found!\n");
+        return FALSE;
+    }
+
+    if (iModeNum == 0)
     {
-        ExFreePool(pSafeDevMode);
+        DPRINT1("Should initialize modes somehow\n");
+        // Update DISPLAY_DEVICEs?
+    }
+
+    iFoundMode = 0;
+    for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+    {
+        pdmentry = &pGraphicsDevice->pDevModeList[i];
+
+//        if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) || // FIXME!
+//            (dwFlags & EDS_RAWMODE))
+        {
+            /* Is this the one we want? */
+            if (iFoundMode == iModeNum)
+            {
+                *ppdm = pdmentry->pdm;
+                return STATUS_SUCCESS;
+            }
+
+            /* Increment number of found modes */
+            iFoundMode++;
+        }
+    }
+
+    /* Nothing was found */
+    return STATUS_INVALID_PARAMETER;
+}
+
+NTSTATUS
+NTAPI
+UserOpenDisplaySettingsKey(
+    OUT PHKEY phkey,
+    IN PUNICODE_STRING pustrDevice,
+    IN BOOL bGlobal)
+{
+    HKEY hkey;
+    DISPLAY_DEVICEW dispdev;
+    NTSTATUS Status;
+
+    /* Get device info */
+    Status = UserEnumDisplayDevices(pustrDevice, 0, &dispdev, 0);
+    if (!NT_SUCCESS(Status))
         return Status;
+
+    if (bGlobal)
+    {
+        // FIXME: need to fix the registry key somehow
     }
 
-    /* Copy some information back */
-    _SEH2_TRY
+    /* Open the registry key */
+    Status = RegOpenKey(dispdev.DeviceKey, &hkey);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    *phkey = hkey;
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+UserEnumRegistryDisplaySettings(
+    IN PUNICODE_STRING pustrDevice,
+    OUT LPDEVMODEW pdm)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+APIENTRY
+NtUserEnumDisplaySettings(
+    IN PUNICODE_STRING pustrDevice,
+    IN DWORD iModeNum,
+    OUT LPDEVMODEW lpDevMode,
+    IN DWORD dwFlags)
+{
+    UNICODE_STRING ustrDevice;
+    WCHAR awcDevice[CCHDEVICENAME];
+    NTSTATUS Status;
+    ULONG cbSize, cbExtra;
+    DEVMODEW dmReg, *pdm;
+
+    DPRINT1("Enter NtUserEnumDisplaySettings(%ls, %ld)\n",
+            pustrDevice ? pustrDevice->Buffer:0, iModeNum);
+
+    if (pustrDevice)
     {
-        ProbeForWrite(lpDevMode,Size + ExtraSize, 1);
-        lpDevMode->dmPelsWidth = pSafeDevMode->dmPelsWidth;
-        lpDevMode->dmPelsHeight = pSafeDevMode->dmPelsHeight;
-        lpDevMode->dmBitsPerPel = pSafeDevMode->dmBitsPerPel;
-        lpDevMode->dmDisplayFrequency = pSafeDevMode->dmDisplayFrequency;
-        lpDevMode->dmDisplayFlags = pSafeDevMode->dmDisplayFlags;
+        /* Initialize destination string */
+        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
 
-        /* output private/extra driver data */
-        if (ExtraSize > 0)
+        _SEH2_TRY
+        {
+            /* Probe the UNICODE_STRING and the buffer */
+            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+            /* Copy the string */
+            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            memcpy((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize);
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
+        _SEH2_END
+
+        pustrDevice = &ustrDevice;
+   }
+
+    /* Acquire global USER lock */
+    UserEnterExclusive();
+
+    if (iModeNum == ENUM_REGISTRY_SETTINGS)
+    {
+        /* Get the registry settings */
+        Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
+        pdm = &dmReg;
+    }
+    else if (iModeNum == ENUM_CURRENT_SETTINGS)
+    {
+        /* Get the current settings */
+        Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm);
+    }
+    else
+    {
+        /* Get specified settings */
+        Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags);
     }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+
+    /* Release lock */
+    UserLeave();
+
+    /* Did we succeed? */
+    if (NT_SUCCESS(Status))
     {
-        Status = _SEH2_GetExceptionCode();
+        /* Copy some information back */
+        _SEH2_TRY
+        {
+            ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
+            cbSize = lpDevMode->dmSize;
+            cbExtra = lpDevMode->dmDriverExtra;
+
+            ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
+            lpDevMode->dmPelsWidth = pdm->dmPelsWidth;
+            lpDevMode->dmPelsHeight = pdm->dmPelsHeight;
+            lpDevMode->dmBitsPerPel = pdm->dmBitsPerPel;
+            lpDevMode->dmDisplayFrequency = pdm->dmDisplayFrequency;
+            lpDevMode->dmDisplayFlags = pdm->dmDisplayFlags;
+
+            /* output private/extra driver data */
+            if (cbExtra > 0 && pdm->dmDriverExtra > 0)
+            {
+                RtlCopyMemory((PCHAR)lpDevMode + cbSize,
+                              (PCHAR)pdm + pdm->dmSize,
+                              min(cbExtra, pdm->dmDriverExtra));
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END;
     }
-    _SEH2_END;
 
-    ExFreePool(pSafeDevMode);
     return Status;
 }
 
 
 LONG
 APIENTRY
-NtUserChangeDisplaySettings(
-   PUNICODE_STRING lpszDeviceName,
-   LPDEVMODEW lpDevMode,
+UserChangeDisplaySettings(
+   PUNICODE_STRING pustrDevice,
+   LPDEVMODEW pdm,
    HWND hwnd,
-   DWORD dwflags,
+   DWORD flags,
    LPVOID lParam)
 {
-   NTSTATUS Status = STATUS_SUCCESS;
-   LPDEVMODEW lpSafeDevMode = NULL;
-   DEVMODEW DevMode;
-   PUNICODE_STRING pSafeDeviceName = NULL;
-   UNICODE_STRING SafeDeviceName;
-   LONG Ret;
-
-   /* Check arguments */
-#ifdef CDS_VIDEOPARAMETERS
-    if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL)
-#else
-    if (lParam != NULL)
-#endif
+    DEVMODEW dmReg;
+    LONG lResult = DISP_CHANGE_SUCCESSFUL;
+    HKEY hkey;
+    NTSTATUS Status;
+    PPDEVOBJ ppdev;
+
+    /* If no DEVMODE is given, use registry settings */
+    if (!pdm)
     {
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        /* Get the registry settings */
+        Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Could not load registry settings\n");
+            return DISP_CHANGE_BADPARAM;
+        }
+        pdm = &dmReg;
+    }
+
+    /* Get the PDEV */
+    ppdev = EngpGetPDEV(pustrDevice);
+    if (!ppdev)
+    {
+        DPRINT1("failed to get PDEV\n");
         return DISP_CHANGE_BADPARAM;
     }
 
-    if (hwnd != NULL)
+    /* Look for the requested DEVMODE */
+    pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
+    if (!pdm)
+    {
+        DPRINT1("Could not find a matching DEVMODE\n");
+        lResult = DISP_CHANGE_BADMODE;
+        goto leave;
+    }
+
+    /* Shall we update the registry? */
+    if (flags & CDS_UPDATEREGISTRY)
+    {
+        /* Open the local or global settings key */
+        Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, flags & CDS_GLOBAL);
+        if (NT_SUCCESS(Status))
+        {
+            /* Store the settings */
+            RegWriteDisplaySettings(hkey, pdm);
+
+            /* Close the registry key */
+            ZwClose(hkey);
+        }
+        else
+        {
+            DPRINT1("Could not open registry key\n");
+            lResult = DISP_CHANGE_NOTUPDATED;
+        }       
+    }
+
+    /* Check if DEVMODE matches the current mode */
+    if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET))
+    {
+        DPRINT1("DEVMODE matches, nothing to do\n");
+        goto leave;
+    }
+
+    /* Shall we apply the settings? */
+    if (!(flags & CDS_NORESET))
+    {
+        if (!PDEVOBJ_bSwitchMode(ppdev, pdm))
+        {
+            DPRINT1("failed to set mode\n");
+            lResult = (lResult == DISP_CHANGE_NOTUPDATED) ? 
+                DISP_CHANGE_FAILED : DISP_CHANGE_RESTART;
+        }
+        
+        /* Send message */
+        
+    }
+
+leave:
+//    PDEVOBJ_vReleasePdev(ppdev);
+
+    return lResult;
+}
+
+LONG
+APIENTRY
+NtUserChangeDisplaySettings(
+    PUNICODE_STRING pustrDevice,
+    LPDEVMODEW lpDevMode,
+    HWND hwnd,
+    DWORD dwflags,
+    LPVOID lParam)
+{
+    WCHAR awcDevice[CCHDEVICENAME];
+    UNICODE_STRING ustrDevice;
+    DEVMODEW dmLocal;
+    LONG Ret;
+
+    /* Check arguments */
+    if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) ||
+        (hwnd != NULL))
     {
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
         return DISP_CHANGE_BADPARAM;
     }
 
-    /* Copy devmode */
-    if (lpDevMode != NULL)
+    /* Check flags */
+    if ((dwflags & (CDS_GLOBAL|CDS_NORESET)) && !(dwflags & CDS_UPDATEREGISTRY))
     {
+        return DISP_CHANGE_BADFLAGS;
+    }
+
+    /* Copy the device name */
+    if (pustrDevice)
+    {
+        /* Initialize destination string */
+        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
         _SEH2_TRY
         {
-            ProbeForRead(lpDevMode, sizeof(DevMode.dmSize), 1);
-            DevMode.dmSize = lpDevMode->dmSize;
-            DevMode.dmSize = min(sizeof(DevMode), DevMode.dmSize);
-            ProbeForRead(lpDevMode, DevMode.dmSize, 1);
-            RtlCopyMemory(&DevMode, lpDevMode, DevMode.dmSize);
+            /* Probe the UNICODE_STRING and the buffer */
+            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+            /* Copy the string */
+            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            Status = _SEH2_GetExceptionCode();
+            SetLastNtError(_SEH2_GetExceptionCode());
+            _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
         }
         _SEH2_END
 
-        if (!NT_SUCCESS(Status))
+        pustrDevice = &ustrDevice;
+   }
+
+    /* Copy devmode */
+    if (lpDevMode)
+    {
+        _SEH2_TRY
         {
-            SetLastNtError(Status);
-            return DISP_CHANGE_BADPARAM;
+            ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1);
+            dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize);
+            ProbeForRead(lpDevMode, dmLocal.dmSize, 1);
+            RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize);
+            dmLocal.dmSize = sizeof(dmLocal);
         }
-
-        if (DevMode.dmDriverExtra > 0)
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
-            DevMode.dmDriverExtra = 0;
+            SetLastNtError(_SEH2_GetExceptionCode());
+            _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
         }
-        lpSafeDevMode = &DevMode;
-    }
+        _SEH2_END
 
-    /* Copy the device name */
-    if (lpszDeviceName != NULL)
-    {
-        Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
-        if (!NT_SUCCESS(Status))
+        if (dmLocal.dmDriverExtra > 0)
         {
-            SetLastNtError(Status);
-            return DISP_CHANGE_BADPARAM;
+            DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
+            dmLocal.dmDriverExtra = 0;
         }
-        pSafeDeviceName = &SafeDeviceName;
+        lpDevMode = &dmLocal;
     }
 
-    /* Call internal function */
-    Ret = IntChangeDisplaySettings(pSafeDeviceName, lpSafeDevMode, dwflags, lParam);
+    // FIXME: Copy videoparameters
 
-    if (pSafeDeviceName != NULL)
-        RtlFreeUnicodeString(pSafeDeviceName);
+    /* Call internal function */
+    Ret = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL);
 
     return Ret;
 }
index ec07d34..8e3f3a5 100644 (file)
@@ -163,10 +163,7 @@ static BOOL UserLoadKbdDll(WCHAR *wsKLID,
       DPRINT("Loaded %wZ\n", &FullLayoutPath);
 
       RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
-      LdrGetProcedureAddress((*(PDRIVERS*)phModule)->BaseAddress,
-                             &kbdProcedureName,
-                             0,
-                             (PVOID*)&layerDescGetFn);
+      layerDescGetFn = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
 
       if(layerDescGetFn)
       {
index 4519ff8..b6a7f2e 100644 (file)
@@ -24,9 +24,22 @@ FASTCALL
 InitMetrics(VOID)
 {
     INT *piSysMet;
+    PPDEVOBJ ppdev;
+    ULONG Width, Height;
 
-    ULONG Width = pPrimarySurface->gdiinfo.ulHorzRes;
-    ULONG Height = pPrimarySurface->gdiinfo.ulVertRes;
+    /* FIXME: HACK, due to missing PDEV on first init */
+    ppdev = EngpGetPDEV(NULL);
+
+    if (!ppdev)
+    {
+        Width = 640;
+        Height = 480;
+    }
+    else
+    {
+        Width = ppdev->gdiinfo.ulHorzRes;
+        Height = ppdev->gdiinfo.ulVertRes;
+    }
 
     piSysMet = gpsi->aiSysMet;
 
index 33abd9a..5781d10 100644 (file)
@@ -199,39 +199,6 @@ NtUserDrawAnimatedRects(
    return 0;
 }
 
-BOOL
-APIENTRY
-NtUserEnumDisplayDevices (
-   PUNICODE_STRING lpDevice, /* device name */
-   DWORD iDevNum, /* display device */
-   PDISPLAY_DEVICEW lpDisplayDevice, /* device information */
-   DWORD dwFlags ) /* reserved */
-{
-   DPRINT1("NtUserEnumDisplayDevices() is UNIMPLEMENTED!\n");
-   if (lpDevice->Length == 0 && iDevNum > 0)
-   {
-      /* Only one display device present */
-      return FALSE;
-   }
-   else if (lpDevice->Length != 0)
-   {
-       /* Can't enumerate monitors :( */
-       return FALSE;
-   }
-   if (lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
-      return FALSE;
-
-   wcscpy(lpDisplayDevice->DeviceName, L"\\\\.\\DISPLAY1");
-   wcscpy(lpDisplayDevice->DeviceString, L"<Unknown>");
-   lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
-                                 | DISPLAY_DEVICE_MODESPRUNED
-                                 | DISPLAY_DEVICE_PRIMARY_DEVICE
-                                 | DISPLAY_DEVICE_VGA_COMPATIBLE;
-   lpDisplayDevice->DeviceID[0] = L'0';
-   lpDisplayDevice->DeviceKey[0] = L'0';
-   return TRUE;
-}
-
 DWORD
 APIENTRY
 NtUserEvent(
index e51db8e..47ce355 100644 (file)
@@ -73,16 +73,6 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
       return Status;
    }
 
-   if (!gpsi)
-   {
-      gpsi = UserHeapAlloc(sizeof(SERVERINFO));
-      if (gpsi)
-      {
-         RtlZeroMemory(gpsi, sizeof(SERVERINFO));
-         DPRINT("Global Server Data -> %x\n", gpsi);
-      }
-   }
-
    InitUserAtoms();
 
    InitSysParams();
@@ -90,6 +80,8 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
    return STATUS_SUCCESS;
 }
 
+BOOL
+InitVideo(ULONG);
 
 NTSTATUS
 NTAPI
@@ -102,6 +94,7 @@ UserInitialize(
 // Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
 // Create Object Directory,,, Looks like create workstation. "\\Windows\\WindowStations"
 // Create Event for Diconnect Desktop.
+    InitVideo(0);
 // Initialize Video.
 // {
 //     DrvInitConsole.
@@ -139,8 +132,8 @@ NtUserInitialize(
 {
     NTSTATUS Status;
 
-    DPRINT("Enter NtUserInitialize(%lx, %p, %p)\n",
-           dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
+    DPRINT1("Enter NtUserInitialize(%lx, %p, %p)\n",
+            dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
 
     /* Check the Windows version */
     if (dwWinVersion != 0)
index 2b8e198..aea084a 100644 (file)
@@ -36,6 +36,9 @@ DceCreateDisplayDC(VOID)
   UNICODE_STRING DriverName;
   RtlInitUnicodeString(&DriverName, L"DISPLAY");
   hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
+
+  co_IntGraphicsCheck(TRUE);
+
 //
 // If NULL, first time through! Build the default window dc!
 //
index 658b53d..25960d4 100644 (file)
@@ -145,8 +145,8 @@ IntCreateCompatibleBitmap(
         {
             Bmp = IntGdiCreateBitmap(abs(Width),
                                      abs(Height),
-                                     IntGdiGetDeviceCaps(Dc,PLANES),
-                                     IntGdiGetDeviceCaps(Dc,BITSPIXEL),
+                                     Dc->ppdev->gdiinfo.cPlanes,
+                                     Dc->ppdev->gdiinfo.cBitsPixel,
                                      NULL);
         }
         else
@@ -176,7 +176,7 @@ IntCreateCompatibleBitmap(
                     Bmp = IntGdiCreateBitmap(abs(Width),
                                              abs(Height),
                                              dibs.dsBm.bmPlanes,
-                                             IntGdiGetDeviceCaps(Dc,BITSPIXEL),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
+                                             Dc->ppdev->gdiinfo.cBitsPixel,//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
                                              NULL);
                 }
                 else
index be7e5e7..61281ca 100644 (file)
@@ -27,6 +27,9 @@ CLIPPING_UpdateGCRegion(DC* Dc)
 {
    PROSRGNDATA CombinedRegion;
 
+    // would prefer this, but the rest of the code sucks
+//    ASSERT(Dc->rosdc.hGCClipRgn);
+//    ASSERT(Dc->rosdc.hClipRgn);
    if (!Dc->rosdc.hVisRgn)
    {
       DPRINT1("Warning, hVisRgn is NULL!\n");
index 562d754..dd58a5b 100644 (file)
@@ -152,35 +152,49 @@ FreeDcAttr(PDC_ATTR pDc_Attr)
   return;
 }
 
+BOOL
+FASTCALL
+DC_AllocDcAttr(PDC pdc)
+{
+    DC_AllocateDcAttr(pdc->BaseObject.hHmgr);
+    *pdc->pdcattr = pdc->dcattr;
+    return TRUE;
+}
+
+// CHECK against current head
 VOID
 FASTCALL
 DC_AllocateDcAttr(HDC hDC)
 {
   PVOID NewMem = NULL;
   PDC pDC;
-
+  HANDLE Pid = NtCurrentProcess();
+  ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
+
+  NTSTATUS Status = ZwAllocateVirtualMemory(Pid,
+                                        &NewMem,
+                                              0,
+                                       &MemSize,
+                         MEM_COMMIT|MEM_RESERVE,
+                                 PAGE_READWRITE);
   {
     INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
     PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
-
-    NewMem = AllocateDcAttr();
-
     // FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
-
-    if (NewMem)
+    if (NT_SUCCESS(Status))
     {
-       RtlZeroMemory(NewMem, sizeof(DC_ATTR));
-       Entry->UserData = NewMem;
-       DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
+      RtlZeroMemory(NewMem, MemSize);
+      Entry->UserData  = NewMem;
+      DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
     }
     else
     {
-       DPRINT1("DC_ATTR not allocated!\n");
+       DPRINT("DC_ATTR not allocated!\n");
     }
   }
   pDC = DC_LockDc(hDC);
   ASSERT(pDC->pdcattr == &pDC->dcattr);
-  if (NewMem)
+  if(NewMem)
   {
      pDC->pdcattr = NewMem; // Store pointer
   }
@@ -188,23 +202,37 @@ DC_AllocateDcAttr(HDC hDC)
 }
 
 VOID
-FASTCALL
-DC_FreeDcAttr(HDC  DCToFree )
+NTAPI
+DC_vFreeDcAttr(PDC pdc)
 {
-  PDC pDC = DC_LockDc(DCToFree);
-  if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object!
-  pDC->pdcattr = &pDC->dcattr;
-  DC_UnlockDc(pDC);
+    HANDLE Pid = NtCurrentProcess();
+    INT Index;
+    PGDI_TABLE_ENTRY pent;
 
-  {
-    INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
-    PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
-    if (Entry->UserData)
+    if (pdc->pdcattr == &pdc->dcattr)
     {
-       FreeDcAttr(Entry->UserData);
-       Entry->UserData = NULL;
+        // Internal DC object!
+        return;
+    }
+
+    pdc->pdcattr = &pdc->dcattr;
+
+    Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
+    pent = &GdiHandleTable->Entries[Index];
+    if(pent->UserData)
+    {
+        ULONG MemSize = sizeof(DC_ATTR);
+        NTSTATUS Status = ZwFreeVirtualMemory(Pid,
+                                              &pent->UserData,
+                                              &MemSize,
+                                              MEM_RELEASE);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("DC_FreeDC failed to free DC_ATTR 0x%p\n", pent->UserData);
+            ASSERT(FALSE);
+        }
+        pent->UserData = NULL;
     }
-  }
 }
 
 
@@ -219,12 +247,8 @@ CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
 
   _SEH2_TRY
   {
-      ProbeForWrite( pdcattr,
-             sizeof(DC_ATTR),
-                           1);
-      RtlCopyMemory( pdcattr,
-                &dc->dcattr,
-             sizeof(DC_ATTR));
+      ProbeForWrite(pdcattr, sizeof(DC_ATTR), 1);
+      RtlCopyMemory(pdcattr, &dc->dcattr, sizeof(DC_ATTR));
   }
   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
   {
index be3ad34..ba5b7f1 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-/** Internal functions ********************************************************/
+//FIXME: windows uses 0x0012009f
+#define DIRTY_DEFAULT DIRTY_CHARSET|DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL
 
-HDC FASTCALL
-DC_AllocDC(PUNICODE_STRING Driver)
-{
-    PDC  NewDC;
-    PDC_ATTR pdcattr;
-    HDC  hDC;
-    PWSTR Buf = NULL;
-    XFORM xformTemplate;
-    PBRUSH pbrush;
-    HSURF hsurf;
-
-    if (Driver != NULL)
-    {
-        Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
-        if (!Buf)
-        {
-            DPRINT1("ExAllocatePoolWithTag failed\n");
-            return NULL;
-        }
-        RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
-    }
+PSURFACE psurfDefaultBitmap = NULL;
+PBRUSH pbrDefaultBrush = NULL;
 
-    NewDC = (PDC)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DC);
-    if (!NewDC)
-    {
-        if (Buf)
-        {
-            ExFreePoolWithTag(Buf, TAG_DC);
-        }
-        DPRINT1("GDIOBJ_AllocObjWithHandle failed\n");
-        return NULL;
-    }
-
-    hDC = NewDC->BaseObject.hHmgr;
-
-    NewDC->pdcattr = &NewDC->dcattr;
-    DC_AllocateDcAttr(hDC);
-
-    if (Driver != NULL)
-    {
-        RtlCopyMemory(&NewDC->rosdc.DriverName, Driver, sizeof(UNICODE_STRING));
-        NewDC->rosdc.DriverName.Buffer = Buf;
-    }
-    pdcattr = NewDC->pdcattr;
+// FIXME: these should go to floatobj.h or something
+#define FLOATOBJ_0 {0x00000000, 0x00000000}
+#define FLOATOBJ_1 {0x40000000, 0x00000002}
+#define FLOATOBJ_16 {0x40000000, 0x00000006}
+#define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
 
-    // FIXME: no floating point in the kernel!
-    xformTemplate.eM11 = 1.0f;
-    xformTemplate.eM12 = 0.0f;
-    xformTemplate.eM21 = 0.0f;
-    xformTemplate.eM22 = 1.0f;
-    xformTemplate.eDx = 0.0f;
-    xformTemplate.eDy = 0.0f;
-    XForm2MatrixS(&NewDC->dclevel.mxWorldToDevice, &xformTemplate);
-    XForm2MatrixS(&NewDC->dclevel.mxDeviceToWorld, &xformTemplate);
-    XForm2MatrixS(&NewDC->dclevel.mxWorldToPage, &xformTemplate);
+static const FLOATOBJ gef0 = FLOATOBJ_0;
+static const FLOATOBJ gef1 = FLOATOBJ_1;
+static const FLOATOBJ gef16 = FLOATOBJ_16;
 
-    // Setup syncing bits for the dcattr data packets.
-    pdcattr->flXform = DEVICE_TO_PAGE_INVALID;
+static const MATRIX    gmxWorldToDeviceDefault =
+{
+    FLOATOBJ_16, FLOATOBJ_0,
+    FLOATOBJ_0, FLOATOBJ_16,
+    FLOATOBJ_0, FLOATOBJ_0,
+    0, 0, 0x4b
+};
 
-    pdcattr->ulDirty_ = 0;  // Server side
+static const MATRIX    gmxDeviceToWorldDefault =
+{
+    FLOATOBJ_1_16, FLOATOBJ_0,
+    FLOATOBJ_0, FLOATOBJ_1_16,
+    FLOATOBJ_0, FLOATOBJ_0,
+    0, 0, 0x53
+};
 
-    pdcattr->iMapMode = MM_TEXT;
-    pdcattr->iGraphicsMode = GM_COMPATIBLE;
-    pdcattr->jFillMode = ALTERNATE;
+static const MATRIX    gmxWorldToPageDefault =
+{
+    FLOATOBJ_1, FLOATOBJ_0,
+    FLOATOBJ_0, FLOATOBJ_1,
+    FLOATOBJ_0, FLOATOBJ_0,
+    0, 0, 0x63
+};
 
-    pdcattr->szlWindowExt.cx = 1; // Float to Int,,, WRONG!
-    pdcattr->szlWindowExt.cy = 1;
-    pdcattr->szlViewportExt.cx = 1;
-    pdcattr->szlViewportExt.cy = 1;
+// HACK!! Fix XFORMOBJ then use 1:16 / 16:1
+#define gmxWorldToDeviceDefault gmxWorldToPageDefault
+#define gmxDeviceToWorldDefault gmxWorldToPageDefault
 
-    pdcattr->crForegroundClr = 0;
-    pdcattr->ulForegroundClr = 0;
+/** Internal functions ********************************************************/
 
-    pdcattr->ulBackgroundClr = 0xffffff;
-    pdcattr->crBackgroundClr = 0xffffff;
+NTSTATUS
+InitDcImpl()
+{
+    psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
+    if (!psurfDefaultBitmap)
+        return STATUS_UNSUCCESSFUL;
 
-    pdcattr->ulPenClr = RGB(0, 0, 0);
-    pdcattr->crPenClr = RGB(0, 0, 0);
+    pbrDefaultBrush = BRUSH_ShareLockBrush(StockObjects[BLACK_BRUSH]);
+    if (!pbrDefaultBrush)
+        return STATUS_UNSUCCESSFUL;
 
-    pdcattr->ulBrushClr = RGB(255, 255, 255);   // Do this way too.
-    pdcattr->crBrushClr = RGB(255, 255, 255);
+    return STATUS_SUCCESS;
+}
 
-//// This fixes the default brush and pen settings. See DC_InitDC.
 
-    /* Create the default fill brush */
-    pdcattr->hbrush = NtGdiGetStockObject(WHITE_BRUSH);
-    NewDC->dclevel.pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
-    EBRUSHOBJ_vInit(&NewDC->eboFill, NewDC->dclevel.pbrFill, NewDC);
+PDC
+NTAPI
+DC_AllocDcWithHandle()
+{
+    PDC pdc;
+    pdc = (PDC)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_DC_TYPE);
+    
+    pdc->pdcattr = &pdc->dcattr;
 
-    /* Create the default pen / line brush */
-    pdcattr->hpen = NtGdiGetStockObject(BLACK_PEN);
-    NewDC->dclevel.pbrLine = PEN_ShareLockPen(pdcattr->hpen);
-    EBRUSHOBJ_vInit(&NewDC->eboLine, NewDC->dclevel.pbrLine, NewDC);
+    return pdc;
+}
 
-    /* Create the default text brush */
-    pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(BLACK_BRUSH));
-    EBRUSHOBJ_vInit(&NewDC->eboText, pbrush, NewDC);
-    pdcattr->ulDirty_ |= DIRTY_TEXT;
 
-    /* Create the default background brush */
-    pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(WHITE_BRUSH));
-    EBRUSHOBJ_vInit(&NewDC->eboBackground, pbrush, NewDC);
+void
+DC_InitHack(PDC pdc)
+{
+    HRGN hVisRgn;
 
-    pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
-    TextIntRealizeFont(pdcattr->hlfntNew,NULL);
+    TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
+    pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
 
-    NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
-    NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal);
     /* This should never fail */
-    ASSERT(NewDC->dclevel.ppal);
+    ASSERT(pdc->dclevel.ppal);
+
+    /* Select regions */
+    // FIXME: too complicated, broken error handling
+    pdc->rosdc.hClipRgn = NULL;
+    pdc->rosdc.hGCClipRgn = NULL;
+    hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+    ASSERT(hVisRgn);
+    GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
+    GreDeleteObject(hVisRgn);
+    ASSERT(pdc->rosdc.hVisRgn);
+    pdc->rosdc.bitsPerPixel = pdc->ppdev->gdiinfo.cBitsPixel *
+                              pdc->ppdev->gdiinfo.cPlanes;
+}
 
-    NewDC->dclevel.laPath.eMiterLimit = 10.0; // FIXME: use FLOATL or FLOATOBJ!
+VOID
+NTAPI
+DC_vInitDc(
+    PDC pdc,
+    DCTYPE dctype,
+    PPDEVOBJ ppdev)
+{
 
-    NewDC->dclevel.lSaveDepth = 1;
+    /* Setup some basic fields */
+    pdc->dctype = dctype;
+    pdc->ppdev = ppdev;
+    pdc->dhpdev = ppdev->dhpdev;
+    pdc->hsem = ppdev->hsemDevLock;
+    pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
+    pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
+    pdc->fs = DC_DIRTY_RAO;
+
+    /* Setup dc attribute */
+    pdc->pdcattr = &pdc->dcattr;
+    pdc->dcattr.pvLDC = NULL;
+    pdc->dcattr.ulDirty_ = DIRTY_DEFAULT;
+    if (ppdev == gppdevPrimary)
+        pdc->dcattr.ulDirty_ |= DC_PRIMARY_DISPLAY;
+
+    /* Setup the DC size */
+    if (dctype == DCTYPE_MEMORY)
+    {
+        /* Memory DCs have a 1 x 1 bitmap by default */
+        pdc->dclevel.sizl.cx = 1;
+        pdc->dclevel.sizl.cy = 1;
+    }
+    else
+    {
+        /* Other DC's are as big as the related PDEV */
+           pdc->dclevel.sizl.cx = ppdev->gdiinfo.ulHorzRes;
+           pdc->dclevel.sizl.cy = ppdev->gdiinfo.ulVertRes;
+    }
 
-    hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that?
-    NewDC->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
+    /* Setup Window rect based on DC size */
+    pdc->erclWindow.left = 0;
+    pdc->erclWindow.top = 0;
+    pdc->erclWindow.right = pdc->dclevel.sizl.cx;
+    pdc->erclWindow.bottom = pdc->dclevel.sizl.cy;
+
+    if (dctype == DCTYPE_DIRECT)
+    {
+        /* Direct DCs get the surface from the PDEV */
+        pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
+
+        pdc->erclBounds.left = 0x7fffffff;
+        pdc->erclBounds.top = 0x7fffffff;
+        pdc->erclBounds.right = 0x80000000;
+        pdc->erclBounds.bottom = 0x80000000;
+        pdc->erclBoundsApp.left = 0xffffffff;
+        pdc->erclBoundsApp.top = 0xfffffffc;
+        pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
+        pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
+        pdc->erclClip = pdc->erclBounds;
+//        pdc->co
+
+        pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
+    }
+    else
+    {
+        /* Non-direct DCs don't have a surface by default */
+        pdc->dclevel.pSurface = NULL;
+
+        // FIXME: HACK, because our code expects a surface
+        pdc->dclevel.pSurface = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
+
+        pdc->erclBounds.left = 0;
+        pdc->erclBounds.top = 0;
+        pdc->erclBounds.right = 0;
+        pdc->erclBounds.bottom = 0;
+        pdc->erclBoundsApp = pdc->erclBounds;
+        pdc->erclClip = pdc->erclWindow;
+//        pdc->co = NULL
+    }
 
-    return NewDC;
+//        pdc->dcattr.VisRectRegion:
+
+    /* Setup coordinate transformation data */
+       pdc->dclevel.mxWorldToDevice = gmxWorldToDeviceDefault;
+       pdc->dclevel.mxDeviceToWorld = gmxDeviceToWorldDefault;
+       pdc->dclevel.mxWorldToPage = gmxWorldToPageDefault;
+       pdc->dclevel.efM11PtoD = gef16;
+       pdc->dclevel.efM22PtoD = gef16;
+       pdc->dclevel.efDxPtoD = gef0;
+       pdc->dclevel.efDyPtoD = gef0;
+       pdc->dclevel.efM11_TWIPS = gef0;
+       pdc->dclevel.efM22_TWIPS = gef0;
+       pdc->dclevel.efPr11 = gef0;
+       pdc->dclevel.efPr22 = gef0;
+       pdc->dcattr.mxWorldToDevice = pdc->dclevel.mxWorldToDevice;
+       pdc->dcattr.mxDeviceToWorld = pdc->dclevel.mxDeviceToWorld;
+       pdc->dcattr.mxWorldToPage = pdc->dclevel.mxWorldToPage;
+       pdc->dcattr.efM11PtoD = pdc->dclevel.efM11PtoD;
+       pdc->dcattr.efM22PtoD = pdc->dclevel.efM22PtoD;
+       pdc->dcattr.efDxPtoD = pdc->dclevel.efDxPtoD;
+       pdc->dcattr.efDyPtoD = pdc->dclevel.efDyPtoD;
+       pdc->dcattr.iMapMode = MM_TEXT;
+       pdc->dcattr.dwLayout = 0;
+       pdc->dcattr.flXform = PAGE_TO_DEVICE_SCALE_IDENTITY |
+                             PAGE_TO_DEVICE_IDENTITY |
+                             WORLD_TO_PAGE_IDENTITY;
+
+    /* Setup more coordinates */
+    pdc->ptlDCOrig.x = 0;
+    pdc->ptlDCOrig.y = 0;
+       pdc->dcattr.lWindowOrgx = 0;
+       pdc->dcattr.ptlWindowOrg.x = 0;
+       pdc->dcattr.ptlWindowOrg.y = 0;
+       pdc->dcattr.szlWindowExt.cx = 1;
+       pdc->dcattr.szlWindowExt.cy = 1;
+       pdc->dcattr.ptlViewportOrg.x = 0;
+       pdc->dcattr.ptlViewportOrg.y = 0;
+       pdc->dcattr.szlViewportExt.cx = 1;
+       pdc->dcattr.szlViewportExt.cy = 1;
+    pdc->dcattr.szlVirtualDevicePixel.cx = 0;
+    pdc->dcattr.szlVirtualDevicePixel.cy = 0;
+    pdc->dcattr.szlVirtualDeviceMm.cx = 0;
+    pdc->dcattr.szlVirtualDeviceMm.cy = 0;
+    pdc->dcattr.szlVirtualDeviceSize.cx = 0;
+    pdc->dcattr.szlVirtualDeviceSize.cy = 0;
+
+    /* Setup regions */
+    pdc->prgnAPI = NULL;
+    pdc->prgnVis = NULL; // FIXME
+    pdc->prgnRao = NULL;
+
+    /* Setup palette */
+    pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE];
+    pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
+
+    /* Setup path */
+       pdc->dclevel.hPath = NULL;
+    pdc->dclevel.flPath = 0;
+//     pdc->dclevel.lapath:
+
+    /* Setup colors */
+       pdc->dcattr.crBackgroundClr = RGB(0xff, 0xff, 0xff);
+       pdc->dcattr.ulBackgroundClr = RGB(0xff, 0xff, 0xff);
+       pdc->dcattr.crForegroundClr = RGB(0, 0, 0);
+       pdc->dcattr.ulForegroundClr = RGB(0, 0, 0);
+       pdc->dcattr.crBrushClr = RGB(0xff, 0xff, 0xff);
+       pdc->dcattr.ulBrushClr = RGB(0xff, 0xff, 0xff);
+       pdc->dcattr.crPenClr = RGB(0, 0, 0);
+       pdc->dcattr.ulPenClr = RGB(0, 0, 0);
+
+    /* Select the default fill and line brush */
+       pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH];
+       pdc->dcattr.hpen = StockObjects[BLACK_PEN];
+    pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush);
+    pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen);
+       pdc->dclevel.ptlBrushOrigin.x = 0;
+       pdc->dclevel.ptlBrushOrigin.y = 0;
+       pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin;
+
+    /* Initialize EBRUSHOBJs */
+    EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
+    EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
+    EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc);
+    EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc);
+
+    /* Setup fill data */
+       pdc->dcattr.jROP2 = R2_COPYPEN;
+       pdc->dcattr.jBkMode = 2;
+       pdc->dcattr.lBkMode = 2;
+       pdc->dcattr.jFillMode = ALTERNATE;
+       pdc->dcattr.lFillMode = 1;
+       pdc->dcattr.jStretchBltMode = 1;
+       pdc->dcattr.lStretchBltMode = 1;
+    pdc->ptlFillOrigin.x = 0;
+    pdc->ptlFillOrigin.y = 0;
+
+    /* Setup drawing position */
+       pdc->dcattr.ptlCurrent.x = 0;
+       pdc->dcattr.ptlCurrent.y = 0;
+       pdc->dcattr.ptfxCurrent.x = 0;
+       pdc->dcattr.ptfxCurrent.y = 0;
+
+       /* Setup ICM data */
+       pdc->dclevel.lIcmMode = 0;
+       pdc->dcattr.lIcmMode = 0;
+       pdc->dcattr.hcmXform = NULL;
+       pdc->dcattr.flIcmFlags = 0;
+       pdc->dcattr.IcmBrushColor = CLR_INVALID;
+       pdc->dcattr.IcmPenColor = CLR_INVALID;
+       pdc->dcattr.pvLIcm = NULL;
+    pdc->dcattr.hColorSpace = NULL; // FIXME: 0189001f
+       pdc->dclevel.pColorSpace = NULL; // FIXME
+    pdc->pClrxFormLnk = NULL;
+//     pdc->dclevel.ca = 
+
+       /* Setup font data */
+    pdc->hlfntCur = NULL; // FIXME: 2f0a0cf8
+    pdc->pPFFList = NULL;
+    pdc->flSimulationFlags = 0;
+    pdc->lEscapement = 0;
+    pdc->prfnt = NULL;
+       pdc->dcattr.flFontMapper = 0;
+       pdc->dcattr.flTextAlign = 0;
+       pdc->dcattr.lTextAlign = 0;
+       pdc->dcattr.lTextExtra = 0;
+       pdc->dcattr.lRelAbs = 1;
+       pdc->dcattr.lBreakExtra = 0;
+       pdc->dcattr.cBreak = 0;
+    pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT];
+//     pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
+
+    /* Other stuff */
+    pdc->hdcNext = NULL;
+    pdc->hdcPrev = NULL;
+    pdc->ipfdDevMax = 0x0000ffff;
+    pdc->ulCopyCount = -1;
+    pdc->ptlDoBanding.x = 0;
+    pdc->ptlDoBanding.y = 0;
+       pdc->dclevel.lSaveDepth = 1;
+       pdc->dclevel.hdcSave = NULL;
+       pdc->dcattr.iGraphicsMode = GM_COMPATIBLE;
+       pdc->dcattr.iCS_CP = 0;
+    pdc->pSurfInfo = NULL;
+
+    /* FIXME: HACK! */
+    DC_InitHack(pdc);
 }
 
-BOOL INTERNAL_CALL
+BOOL
+INTERNAL_CALL
 DC_Cleanup(PVOID ObjectBody)
 {
-    PDC pDC = (PDC)ObjectBody;
+    PDC pdc = (PDC)ObjectBody;
 
-    /* Free driver name (HACK) */
-    if (pDC->rosdc.DriverName.Buffer)
-        ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC);
+    /* Free DC_ATTR */
+    DC_vFreeDcAttr(pdc);
 
-    /* Deselect dc objects */
-    DC_vSelectSurface(pDC, NULL);
-    DC_vSelectFillBrush(pDC, NULL);
-    DC_vSelectLineBrush(pDC, NULL);
-    DC_vSelectPalette(pDC, NULL);
+    /* Delete saved DCs */
+    DC_vRestoreDC(pdc, 1);
 
-    /* Dereference default brushes */
-    BRUSH_ShareUnlockBrush(pDC->eboText.pbrush);
-    BRUSH_ShareUnlockBrush(pDC->eboBackground.pbrush);
+    /* Deselect dc objects */
+    DC_vSelectSurface(pdc, NULL);
+    DC_vSelectFillBrush(pdc, NULL);
+    DC_vSelectLineBrush(pdc, NULL);
+    DC_vSelectPalette(pdc, NULL);
 
     /* Cleanup the dc brushes */
-    EBRUSHOBJ_vCleanup(&pDC->eboFill);
-    EBRUSHOBJ_vCleanup(&pDC->eboLine);
-    EBRUSHOBJ_vCleanup(&pDC->eboText);
-    EBRUSHOBJ_vCleanup(&pDC->eboBackground);
+    EBRUSHOBJ_vCleanup(&pdc->eboFill);
+    EBRUSHOBJ_vCleanup(&pdc->eboLine);
+    EBRUSHOBJ_vCleanup(&pdc->eboText);
+    EBRUSHOBJ_vCleanup(&pdc->eboBackground);
+
+    /*  Free regions */
+    if (pdc->rosdc.hClipRgn)
+        GreDeleteObject(pdc->rosdc.hClipRgn);
+    if (pdc->rosdc.hVisRgn)
+        GreDeleteObject(pdc->rosdc.hVisRgn);
+ASSERT(pdc->rosdc.hGCClipRgn);
+    if (pdc->rosdc.hGCClipRgn)
+        GreDeleteObject(pdc->rosdc.hGCClipRgn);
+    if (NULL != pdc->rosdc.CombinedClip)
+        IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
+
+    PATH_Delete(pdc->dclevel.hPath);
 
     return TRUE;
 }
@@ -171,10 +385,21 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
     PGDI_TABLE_ENTRY Entry;
     PDC pDC;
 
-    if (!GDIOBJ_SetOwnership(hDC, Owner)) return FALSE;
+    /* FIXME: This function has broken error handling */
+
+    if (!GDIOBJ_SetOwnership(hDC, Owner))
+    {
+        DPRINT1("GDIOBJ_SetOwnership failed\n");
+        return FALSE;
+    }
+
     pDC = DC_LockDc(hDC);
-    if (pDC)
+    if (!pDC)
     {
+        DPRINT1("Could not lock DC\n");
+        return FALSE;
+    }
+
     /*
        System Regions:
           These regions do not use attribute sections and when allocated, use
@@ -212,167 +437,63 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
             if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) return FALSE;
         }
         DC_UnlockDc(pDC);
-    }
 
     return TRUE;
 }
 
-
-HDC FASTCALL
-IntGdiCreateDC(
-    PUNICODE_STRING Driver,
-    PUNICODE_STRING Device,
-    PVOID pUMdhpdev,
-    CONST PDEVMODEW InitData,
-    BOOL CreateAsIC)
+HDC
+NTAPI
+GreOpenDCW(
+    PUNICODE_STRING pustrDevice,
+    DEVMODEW *pdmInit,
+    PUNICODE_STRING pustrLogAddr,
+    ULONG iType,
+    BOOL bDisplay,
+    HANDLE hspool,
+    VOID *pDriverInfo2,
+    VOID *pUMdhpdev)
 {
-    HDC      hdc;
-    PDC      pdc;
-    PDC_ATTR pdcattr;
-    HRGN     hVisRgn;
-    UNICODE_STRING StdDriver;
-    BOOL calledFromUser;
+    PPDEVOBJ ppdev;
+    PDC pdc;
+    HDC hdc;
 
-    RtlInitUnicodeString(&StdDriver, L"DISPLAY");
+    DPRINT("GreOpenDCW(%S, iType=%ld)\n", 
+           pustrDevice ? pustrDevice->Buffer : NULL, iType);
 
-    DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver, Device);
-
-    if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
+    /* Get a PDEVOBJ for the device */
+    ppdev = EngpGetPDEV(pustrDevice);
+    if (!ppdev)
     {
-        if (CreateAsIC)
-        {
-            if (! IntPrepareDriverIfNeeded())
-            {
-                /* Here, we have two possibilities:
-                 * a) return NULL, and hope that the caller
-                 *    won't call us in a loop
-                 * b) bugcheck, but caller is unable to
-                 *    react on the problem
-                 */
-                /*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
-                return NULL;*/
-                KeBugCheck(VIDEO_DRIVER_INIT_FAILURE);
-            }
-        }
-        else
-        {
-            calledFromUser = UserIsEntered();
-            if (!calledFromUser)
-            {
-                UserEnterExclusive();
-            }
-
-            if (! co_IntGraphicsCheck(TRUE))
-            {
-                if (!calledFromUser)
-                {
-                    UserLeave();
-                }
-                DPRINT1("Unable to initialize graphics, returning NULL dc\n");
-                return NULL;
-            }
-
-            if (!calledFromUser)
-            {
-                UserLeave();
-            }
-
-        }
+        DPRINT1("Didn't find a suitable PDEV\n");
+        return NULL;
     }
 
-    /*  Check for existing DC object  */
-    if ((hdc = DC_FindOpenDC(Driver)) != NULL)
-    {
-        hdc = NtGdiCreateCompatibleDC(hdc);
-        if (!hdc)
-            DPRINT1("NtGdiCreateCompatibleDC() failed\n");
-        return hdc;
-    }
+    DPRINT("GreOpenDCW - ppdev = %p\n", ppdev);
 
-    /*  Allocate a DC object  */
-    pdc = DC_AllocDC(Driver);
-    if (pdc == NULL)
+    pdc = DC_AllocDcWithHandle();
+    if (!pdc)
     {
-        DPRINT1("DC_AllocDC() failed\n");
+        DPRINT1("Could not Allocate a DC\n");
+        PDEVOBJ_vRelease(ppdev);
         return NULL;
     }
     hdc = pdc->BaseObject.hHmgr;
-    pdcattr = pdc->pdcattr;
-
-    pdc->dctype = DC_TYPE_DIRECT;
-
-    pdc->dhpdev = PrimarySurface.dhpdev;
-    if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device.
-    pdc->ppdev = (PVOID)&PrimarySurface;
-
-    // ATM we only have one display.
-    pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY;
-
-    pdc->rosdc.bitsPerPixel = pdc->ppdev->gdiinfo.cBitsPixel *
-                              pdc->ppdev->gdiinfo.cPlanes;
-    DPRINT("Bits per pel: %u\n", pdc->rosdc.bitsPerPixel);
-
-    pdc->flGraphicsCaps  = PrimarySurface.devinfo.flGraphicsCaps;
-    pdc->flGraphicsCaps2 = PrimarySurface.devinfo.flGraphicsCaps2;
-
-    pdc->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
-
-    pdcattr->jROP2 = R2_COPYPEN;
-
-    pdc->erclWindow.top = pdc->erclWindow.left = 0;
-    pdc->erclWindow.right  = pdc->ppdev->gdiinfo.ulHorzRes;
-    pdc->erclWindow.bottom = pdc->ppdev->gdiinfo.ulVertRes;
-    pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW.
-
-    pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
-
-    hVisRgn = IntSysCreateRectRgn(0, 0, pdc->ppdev->gdiinfo.ulHorzRes,
-                                 pdc->ppdev->gdiinfo.ulVertRes);
-
-    if (!CreateAsIC)
-    {
-        pdc->pSurfInfo = NULL;
-//    pdc->dclevel.pSurface =
-        DC_UnlockDc(pdc);
 
-        /*  Initialize the DC state  */
-        IntGdiSetTextColor(hdc, RGB(0, 0, 0));
-        IntGdiSetBkColor(hdc, RGB(255, 255, 255));
-    }
-    else
-    {
-        /* From MSDN2:
-           The CreateIC function creates an information context for the specified device.
-           The information context provides a fast way to get information about the
-           device without creating a device context (DC). However, GDI drawing functions
-           cannot accept a handle to an information context.
-         */
-        pdc->dctype = DC_TYPE_INFO;
-//    pdc->pSurfInfo =
-//        DC_vSelectSurface(pdc, NULL);
-        pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255);
-        pdcattr->crForegroundClr = RGB(0, 0, 0);
-        DC_UnlockDc(pdc);
-    }
-    DC_InitDC(hdc);
+    DC_vInitDc(pdc, iType, ppdev);
+    DC_AllocDcAttr(pdc);
 
-    if (hVisRgn)
-    {
-        GdiSelectVisRgn(hdc, hVisRgn);
-        REGION_FreeRgnByHandle(hVisRgn);
-    }
+    DC_UnlockDc(pdc);
 
-    IntGdiSetTextAlign(hdc, TA_TOP);
-    IntGdiSetBkMode(hdc, OPAQUE);
+    DPRINT("returning hdc = %p\n", hdc);
 
     return hdc;
 }
 
-
-HDC APIENTRY
+HDC
+APIENTRY
 NtGdiOpenDCW(
-    PUNICODE_STRING Device,
-    DEVMODEW *InitData,
+    PUNICODE_STRING pustrDevice,
+    DEVMODEW *pdmInit,
     PUNICODE_STRING pustrLogAddr,
     ULONG iType,
     BOOL bDisplay,
@@ -380,319 +501,199 @@ NtGdiOpenDCW(
     VOID *pDriverInfo2,
     VOID *pUMdhpdev)
 {
-    UNICODE_STRING SafeDevice;
-    DEVMODEW SafeInitData;
-    PVOID Dhpdev;
-    HDC Ret;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    if (!Device) return UserGetDesktopDC(iType,FALSE,TRUE);
-
-    if (InitData)
+    UNICODE_STRING ustrDevice;
+    WCHAR awcDevice[CCHDEVICENAME];
+    DEVMODEW dmInit;
+    PVOID dhpdev;
+    HDC hdc;
+
+    /* Only if a devicename is given, we need any data */
+    if (pustrDevice)
     {
+        /* Initialize destination string */
+        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
         _SEH2_TRY
         {
+            /* Probe the UNICODE_STRING and the buffer */
+            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+            /* Copy the string */
+            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+
+            if (pdmInit)
+            {
+                /* FIXME: could be larger */
+                ProbeForRead(pdmInit, sizeof(DEVMODEW), 1);
+                RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW));
+            }
+
             if (pUMdhpdev)
             {
-                ProbeForWrite(pUMdhpdev, sizeof(PVOID), 1);
+                ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1);
             }
-            ProbeForRead(InitData, sizeof(DEVMODEW), 1);
-            RtlCopyMemory(&SafeInitData, InitData, sizeof(DEVMODEW));
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            Status = _SEH2_GetExceptionCode();
+            SetLastNtError(_SEH2_GetExceptionCode());
+            _SEH2_YIELD(return NULL);
         }
-        _SEH2_END;
+        _SEH2_END
+    }
+    else
+    {
+        pdmInit = NULL;
+        pUMdhpdev = NULL;
+    }
 
-        if (!NT_SUCCESS(Status))
+    /* FIXME: HACK! */
+    if (pustrDevice)
+    {
+        UNICODE_STRING ustrDISPLAY = RTL_CONSTANT_STRING(L"DISPLAY");
+        if (RtlEqualUnicodeString(&ustrDevice, &ustrDISPLAY, TRUE))
         {
-            SetLastNtError(Status);
-            return NULL;
+            pustrDevice = NULL;
         }
-        /* FIXME - InitData can have some more bytes! */
     }
 
-    if (Device)
+    /* Call the internal function */
+    hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
+                     pdmInit ? &dmInit : NULL,
+                     NULL, // fixme pwszLogAddress
+                     iType,
+                     bDisplay,
+                     hspool,
+                     NULL, //FIXME: pDriverInfo2
+                     pUMdhpdev ? &dhpdev : NULL);
+
+    /* If we got a HDC and a UM dhpdev is requested,... */
+    if (hdc && pUMdhpdev)
     {
-        Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
-        if (!NT_SUCCESS(Status))
+        /* Copy dhpdev to caller (FIXME: use dhpdev?? */
+        _SEH2_TRY
         {
-            SetLastNtError(Status);
-            return NULL;
+            /* Pointer was already probed */
+            *(HANDLE*)pUMdhpdev = dhpdev;
         }
-    }
-
-    Ret = IntGdiCreateDC(Device ? &SafeDevice : NULL,
-                         NULL,
-                         pUMdhpdev ? &Dhpdev : NULL,
-                         InitData ? &SafeInitData : NULL,
-                         (BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
-
-    // FIXME!!!!
-    if (pUMdhpdev) pUMdhpdev = Dhpdev;
-
-    return Ret;
-}
-
-HDC FASTCALL
-IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
-{
-    HDC hDC;
-    UNICODE_STRING DriverName;
-    RtlInitUnicodeString(&DriverName, L"DISPLAY");
-
-    if (DcType != DC_TYPE_MEMORY)
-        hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
-    else
-        hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
-//
-// There is room to grow here~
-//
-
-//
-// If NULL, first time through! Build the default (was window) dc!
-// Setup clean DC state for the system.
-//
-    if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
-    { // This is a cheesy way to do this.
-        PDC dc = DC_LockDc(hDC);
-        HSURF hsurf;
-        defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
-        if (!defaultDCstate)
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            DC_UnlockDc(dc);
-            return NULL;
+            /* Ignore error */
         }
-        RtlZeroMemory(defaultDCstate, sizeof(DC));
-        defaultDCstate->pdcattr = &defaultDCstate->dcattr;
-        hsurf = (HSURF)PrimarySurface.pSurface; // HAX¬≤
-        defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
-        DC_vCopyState(dc, defaultDCstate);
-        DC_UnlockDc(dc);
+        _SEH2_END
     }
-    return hDC;
+
+    return hdc;
 }
 
-BOOL
-FASTCALL
-IntGdiDeleteDC(HDC hDC, BOOL Force)
+
+HDC
+APIENTRY
+NtGdiCreateCompatibleDC(HDC hdc)
 {
-    PDC DCToDelete = DC_LockDc(hDC);
+    HDC hdcNew;
+    PPDEVOBJ ppdev;
+    PDC pdc, pdcNew;
 
-    if (DCToDelete == NULL)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
+    DPRINT("NtGdiCreateCompatibleDC(0x%p)\n", hdc);
 
-    if (!Force)
+    /* Did the caller provide a DC? */
+    if (hdc)
     {
-        if (DCToDelete->fs & DC_FLAG_PERMANENT)
+        /* Yes, try to lock it */
+        pdc = DC_LockDc(hdc);
+        if (!pdc)
         {
-            DPRINT1("No! You Naughty Application!\n");
-            DC_UnlockDc(DCToDelete);
-            return UserReleaseDC(NULL, hDC, FALSE);
+            DPRINT1("Could not lock source DC %p\n", hdc);
+            return NULL;
         }
-    }
 
-    /*  First delete all saved DCs  */
-    while (DCToDelete->dclevel.lSaveDepth > 1)
-    {
-        PDC  savedDC;
-        HDC  savedHDC;
-
-        savedHDC = DCToDelete->hdcNext;
-        savedDC = DC_LockDc(savedHDC);
-        if (savedDC == NULL)
-        {
-            break;
-        }
-        DCToDelete->hdcNext = savedDC->hdcNext;
-        DCToDelete->dclevel.lSaveDepth--;
-        DC_UnlockDc(savedDC);
-        IntGdiDeleteDC(savedHDC, Force);
-    }
+        /* Get the pdev from the DC */
+        ppdev = pdc->ppdev;
+        InterlockedIncrement(&ppdev->cPdevRefs);
 
-    /*  Free GDI resources allocated to this DC  */
-    if (!(DCToDelete->dclevel.flPath & DCPATH_SAVESTATE))
-    {
-        /*
-        NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
-        NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH);
-        NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT);
-        DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet  */
-    }
-    if (DCToDelete->rosdc.hClipRgn)
-    {
-        GreDeleteObject(DCToDelete->rosdc.hClipRgn);
+        /* Unlock the source DC */
+        DC_UnlockDc(pdc);
     }
-    if (DCToDelete->rosdc.hVisRgn)
+    else
     {
-        GreDeleteObject(DCToDelete->rosdc.hVisRgn);
+        /* No DC given, get default device */
+        ppdev = EngpGetPDEV(NULL);
     }
-    if (NULL != DCToDelete->rosdc.CombinedClip)
+
+    if (!ppdev)
     {
-        IntEngDeleteClipRegion(DCToDelete->rosdc.CombinedClip);
+        DPRINT1("Didn't find a suitable PDEV\n");
+        return NULL;
     }
-    if (DCToDelete->rosdc.hGCClipRgn)
+
+    /* Allocate a new DC */
+    pdcNew = DC_AllocDcWithHandle();
+    if (!pdcNew)
     {
-        GreDeleteObject(DCToDelete->rosdc.hGCClipRgn);
+        DPRINT1("Could not allocate a new DC\n");
+        PDEVOBJ_vRelease(ppdev);
+        return NULL;
     }
-    PATH_Delete(DCToDelete->dclevel.hPath);
+    hdcNew = pdcNew->BaseObject.hHmgr;
 
-    DC_UnlockDc(DCToDelete);
-    GreDeleteObject(hDC);
-    return TRUE;
-}
+    /* Initialize the new DC */
+    DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev);
 
-HDC FASTCALL
-DC_FindOpenDC(PUNICODE_STRING  Driver)
-{
-    return NULL;
-}
+    /* Allocate a dc attribute */
+    DC_AllocDcAttr(pdcNew);
 
-/*!
- * Initialize some common fields in the Device Context structure.
-*/
-VOID FASTCALL
-DC_InitDC(HDC  DCHandle)
-{
-//  NtGdiRealizeDefaultPalette(DCHandle);
+    PDEVOBJ_vRelease(ppdev);
 
-////  Removed for now.. See above brush and pen.
-//  NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
-//  NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
-////
-    //NtGdiSelectFont(DCHandle, hFont);
+    // HACK!
+    DC_vSelectSurface(pdcNew, psurfDefaultBitmap);
 
-    /*
-      {
-        int res;
-        res = CLIPPING_UpdateGCRegion(DCToInit);
-        ASSERT ( res != ERROR );
-      }
-    */
+    DC_UnlockDc(pdcNew);
 
-    /* Set virtual resolution */
-    NtGdiSetVirtualResolution(DCHandle, 0, 0, 0, 0);
-}
+    DPRINT("Leave NtGdiCreateCompatibleDC hdcNew = %p\n", hdcNew);
 
-/*
-* @unimplemented
-*/
-BOOL
-APIENTRY
-NtGdiMakeInfoDC(
-    IN HDC hdc,
-    IN BOOL bSet)
-{
-    UNIMPLEMENTED;
-    return FALSE;
+    return hdcNew;
 }
 
-HDC APIENTRY
-NtGdiCreateCompatibleDC(HDC hDC)
+BOOL
+FASTCALL
+IntGdiDeleteDC(HDC hDC, BOOL Force)
 {
-    PDC pdcNew, pdcOld;
-    PDC_ATTR pdcattrNew, pdcattrOld;
-    HDC hdcNew, DisplayDC = NULL;
-    HRGN hVisRgn;
-    UNICODE_STRING DriverName;
-    DWORD Layout = 0;
-    HSURF hsurf;
+    PDC DCToDelete = DC_LockDc(hDC);
 
-    if (hDC == NULL)
+    if (DCToDelete == NULL)
     {
-        RtlInitUnicodeString(&DriverName, L"DISPLAY");
-        DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
-        if (NULL == DisplayDC)
-        {
-            DPRINT1("Failed to create DisplayDC\n");
-            return NULL;
-        }
-        hDC = DisplayDC;
+        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        return FALSE;
     }
 
-    /*  Allocate a new DC based on the original DC's device  */
-    pdcOld = DC_LockDc(hDC);
-    if (NULL == pdcOld)
+    if (!Force)
     {
-        if (NULL != DisplayDC)
+        if (DCToDelete->fs & DC_FLAG_PERMANENT)
         {
-            NtGdiDeleteObjectApp(DisplayDC);
+            DPRINT1("No! You Naughty Application!\n");
+            DC_UnlockDc(DCToDelete);
+            return UserReleaseDC(NULL, hDC, FALSE);
         }
-        DPRINT1("Failed to lock hDC\n");
-        return NULL;
     }
-    pdcNew = DC_AllocDC(&pdcOld->rosdc.DriverName);
-    if (!pdcNew)
+
+    DC_UnlockDc(DCToDelete);
+    
+    if (!IsObjectDead(hDC))
     {
-        DPRINT1("Failed to create pdcNew\n");
-        DC_UnlockDc(pdcOld);
-        if (DisplayDC)
+        if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC))
         {
-            NtGdiDeleteObjectApp(DisplayDC);
+            DPRINT1("DC_FreeDC failed\n");
         }
-        return  NULL;
-    }
-    hdcNew = pdcNew->BaseObject.hHmgr;
-
-    pdcattrOld = pdcOld->pdcattr;
-    pdcattrNew = pdcNew->pdcattr;
-
-    /* Copy information from original DC to new DC  */
-    pdcNew->dclevel.hdcSave = hdcNew;
-
-    pdcNew->dhpdev = pdcOld->dhpdev;
-
-    pdcNew->rosdc.bitsPerPixel = pdcOld->rosdc.bitsPerPixel;
-
-    /* DriverName is copied in the AllocDC routine  */
-    pdcattrNew->ptlWindowOrg   = pdcattrOld->ptlWindowOrg;
-    pdcattrNew->szlWindowExt   = pdcattrOld->szlWindowExt;
-    pdcattrNew->ptlViewportOrg = pdcattrOld->ptlViewportOrg;
-    pdcattrNew->szlViewportExt = pdcattrOld->szlViewportExt;
-
-    pdcNew->dctype        = DC_TYPE_MEMORY; // Always!
-    hsurf      = NtGdiGetStockObject(DEFAULT_BITMAP);
-    pdcNew->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
-    pdcNew->ppdev          = pdcOld->ppdev;
-    pdcNew->dclevel.hpal    = pdcOld->dclevel.hpal;
-
-    pdcattrNew->lTextAlign      = pdcattrOld->lTextAlign;
-    pdcattrNew->lBkMode         = pdcattrOld->lBkMode;
-    pdcattrNew->jBkMode         = pdcattrOld->jBkMode;
-    pdcattrNew->jROP2           = pdcattrOld->jROP2;
-    pdcattrNew->dwLayout        = pdcattrOld->dwLayout;
-    if (pdcattrOld->dwLayout & LAYOUT_ORIENTATIONMASK) Layout = pdcattrOld->dwLayout;
-    pdcNew->dclevel.flPath     = pdcOld->dclevel.flPath;
-    pdcattrNew->ulDirty_        = pdcattrOld->ulDirty_;
-    pdcattrNew->iCS_CP          = pdcattrOld->iCS_CP;
-
-    pdcNew->erclWindow.left = pdcNew->erclWindow.top = 0;
-    pdcNew->erclWindow.right = pdcNew->erclWindow.bottom = 1;
-
-    DC_UnlockDc(pdcNew);
-    DC_UnlockDc(pdcOld);
-    if (NULL != DisplayDC)
-    {
-        NtGdiDeleteObjectApp(DisplayDC);
     }
-
-    hVisRgn = IntSysCreateRectRgn(0, 0, 1, 1);
-    if (hVisRgn)
+    else
     {
-        GdiSelectVisRgn(hdcNew, hVisRgn);
-        REGION_FreeRgnByHandle(hVisRgn);
+        DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC);
     }
-    if (Layout) NtGdiSetLayout(hdcNew, -1, Layout);
 
-    DC_InitDC(hdcNew);
-    return hdcNew;
+    return TRUE;
 }
 
-
 BOOL
 APIENTRY
 NtGdiDeleteObjectApp(HANDLE DCHandle)
@@ -718,32 +719,51 @@ NtGdiDeleteObjectApp(HANDLE DCHandle)
 
 BOOL
 APIENTRY
-NewNtGdiDeleteObjectApp(HANDLE DCHandle)
+NtGdiMakeInfoDC(
+    IN HDC hdc,
+    IN BOOL bSet)
 {
-  GDIOBJTYPE ObjType;
-
-  if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
-
-  ObjType = GDI_HANDLE_GET_TYPE(DCHandle) >> GDI_ENTRY_UPPER_SHIFT;
-
-  if (GreGetObjectOwner( DCHandle, ObjType))
-  {
-     switch(ObjType)
-     {
-        case GDIObjType_DC_TYPE:
-          return IntGdiDeleteDC(DCHandle, FALSE);
-
-        case GDIObjType_RGN_TYPE:
-        case GDIObjType_SURF_TYPE:
-        case GDIObjType_PAL_TYPE:
-        case GDIObjType_LFONT_TYPE:
-        case GDIObjType_BRUSH_TYPE:
-          return GreDeleteObject((HGDIOBJ) DCHandle);
-
-        default:
-          return FALSE;
-     }
-  }
-  return (DCHandle != NULL);
+    UNIMPLEMENTED;
+    ASSERT(FALSE);
+    return FALSE;
+}
+
+
+HDC FASTCALL
+IntGdiCreateDC(
+    PUNICODE_STRING Driver,
+    PUNICODE_STRING pustrDevice,
+    PVOID pUMdhpdev,
+    CONST PDEVMODEW pdmInit,
+    BOOL CreateAsIC)
+{
+    HDC hdc;
+
+    hdc = GreOpenDCW(pustrDevice,
+                     pdmInit,
+                     NULL,
+                     CreateAsIC ? DCTYPE_INFO : 
+                          (Driver ? DC_TYPE_DIRECT : DC_TYPE_DIRECT),
+                     TRUE,
+                     NULL,
+                     NULL,
+                     pUMdhpdev);
+
+    return hdc;
+}
+
+HDC FASTCALL
+IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
+{
+    HDC hDC;
+    UNIMPLEMENTED;
+    ASSERT(FALSE);
+
+    if (DcType == DC_TYPE_MEMORY)
+        hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
+    else
+        hDC = IntGdiCreateDC(NULL, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
+
+    return hDC;
 }
 
index 44e690d..5644983 100644 (file)
@@ -15,6 +15,8 @@ VOID
 FASTCALL
 DC_vCopyState(PDC pdcSrc, PDC pdcDst)
 {
+    DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr);
+
     /* Copy full DC attribute */
     *pdcDst->pdcattr = *pdcSrc->pdcattr;
 
@@ -93,41 +95,18 @@ NtGdiResetDC(
 }
 
 
-BOOL
-APIENTRY
-NtGdiRestoreDC(
-    HDC hdc,
+VOID
+NTAPI
+DC_vRestoreDC(
+    IN PDC pdc,
     INT iSaveLevel)
 {
-    PDC pdc, pdcSave;
-    HDC hdcSave;
     PEPROCESS pepCurrentProcess;
+    HDC hdcSave;
+    PDC pdcSave;
 
-    DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel);
-
-    /* Lock the original DC */
-    pdc = DC_LockDc(hdc);
-    if (!pdc)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    ASSERT(pdc->dclevel.lSaveDepth > 0);
-
-    /* Negative values are relative to the stack top */
-    if (iSaveLevel < 0)
-        iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel;
-
-    /* Check if we have a valid instance */
-    if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth)
-    {
-        DPRINT("Illegal save level, requested: %ld, current: %ld\n",
-               iSaveLevel, pdc->dclevel.lSaveDepth);
-        DC_UnlockDc(pdc);
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
+    ASSERT(iSaveLevel > 0);
+    DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
 
     /* Get current process */
     pepCurrentProcess = PsGetCurrentProcess();
@@ -136,14 +115,15 @@ NtGdiRestoreDC(
     while (pdc->dclevel.lSaveDepth > iSaveLevel)
     {
         hdcSave = pdc->dclevel.hdcSave;
+        DPRINT("RestoreDC = %p\n", hdcSave);
 
         /* Set us as the owner */
         if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
         {
             /* Could not get ownership. That's bad! */
-            DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n",
-                    hdcSave, hdc);
-            return FALSE;
+            DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
+                    hdcSave, pdc->BaseObject.hHmgr);
+            return;// FALSE;
         }
 
         /* Lock the saved dc */
@@ -152,9 +132,9 @@ NtGdiRestoreDC(
         {
             /* WTF? Internal error! */
             DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
-                    hdcSave, hdc);
+                    hdcSave, pdc->BaseObject.hHmgr);
             DC_UnlockDc(pdc);
-            return FALSE;
+            return;// FALSE;
         }
 
         /* Remove the saved dc from the queue */
@@ -179,13 +159,58 @@ NtGdiRestoreDC(
             }
         }
 
+        /* Prevent save dc from being restored */
+        pdcSave->dclevel.lSaveDepth = 1;
+
         /* Delete the saved dc */
         GreDeleteObject(hdcSave);
     }
 
+    DPRINT("Leave DC_vRestoreDC()\n");
+}
+
+
+
+BOOL
+APIENTRY
+NtGdiRestoreDC(
+    HDC hdc,
+    INT iSaveLevel)
+{
+    PDC pdc;
+
+    DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel);
+
+    /* Lock the original DC */
+    pdc = DC_LockDc(hdc);
+    if (!pdc)
+    {
+        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    ASSERT(pdc->dclevel.lSaveDepth > 0);
+
+    /* Negative values are relative to the stack top */
+    if (iSaveLevel < 0)
+        iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel;
+
+    /* Check if we have a valid instance */
+    if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth)
+    {
+        DPRINT("Illegal save level, requested: %ld, current: %ld\n",
+               iSaveLevel, pdc->dclevel.lSaveDepth);
+        DC_UnlockDc(pdc);
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Call the internal function */
+    DC_vRestoreDC(pdc, iSaveLevel);
+
     DC_UnlockDc(pdc);
 
-    DPRINT("Leaving NtGdiRestoreDC\n");
+    DPRINT("Leave NtGdiRestoreDC\n");
     return TRUE;
 }
 
@@ -199,7 +224,7 @@ NtGdiSaveDC(
     PDC pdc, pdcSave;
     INT lSaveDepth;
 
-    DPRINT("NtGdiSaveDC(%lx)\n", hDC);
+    DPRINT("NtGdiSaveDC(%p)\n", hDC);
 
     /* Lock the original dc */
     pdc = DC_LockDc(hDC);
@@ -211,7 +236,7 @@ NtGdiSaveDC(
     }
 
     /* Allocate a new dc */
-    pdcSave = DC_AllocDC(NULL);
+    pdcSave = DC_AllocDcWithHandle();
     if (pdcSave == NULL)
     {
         DPRINT("Could not allocate a new DC\n");
@@ -220,6 +245,9 @@ NtGdiSaveDC(
     }
     hdcSave = pdcSave->BaseObject.hHmgr;
 
+    InterlockedIncrement(&pdc->ppdev->cPdevRefs);
+    DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev);
+
     /* Make it a kernel handle
        (FIXME: windows handles this different, see wiki)*/
     GDIOBJ_SetOwnership(hdcSave, NULL);
@@ -242,7 +270,7 @@ NtGdiSaveDC(
     DC_UnlockDc(pdcSave);
     DC_UnlockDc(pdc);
 
-    DPRINT("Leave NtGdiSaveDC: %ld\n", lSaveDepth);
+    DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave);
     return lSaveDepth;
 }
 
index 6dfe195..a35bc71 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-// TODO: proper implementation of LDEVOBJ and PDEVOBJ interface
-
-/*static*/ PDEVOBJ PrimarySurface;
-PPDEVOBJ pPrimarySurface = &PrimarySurface;
-static KEVENT VideoDriverNeedsPreparation;
-static KEVENT VideoDriverPrepared;
 PDC defaultDCstate = NULL;
 
-
-NTSTATUS FASTCALL
-InitDcImpl(VOID)
-{
-    KeInitializeEvent(&VideoDriverNeedsPreparation, SynchronizationEvent, TRUE);
-    KeInitializeEvent(&VideoDriverPrepared, NotificationEvent, FALSE);
-    return STATUS_SUCCESS;
-}
-
-
-static BOOLEAN FASTCALL
-GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
-{
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-    WCHAR DeviceNameBuffer[20];
-    NTSTATUS Status;
-
-    swprintf(DeviceNameBuffer, L"\\Device\\Video%lu", DisplayNumber);
-    RtlInitUnicodeString(RegistryPath, NULL);
-    RtlZeroMemory(QueryTable, sizeof(QueryTable));
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
-    QueryTable[0].Name = DeviceNameBuffer;
-    QueryTable[0].EntryContext = RegistryPath;
-
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
-                                    L"VIDEO",
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-    if (! NT_SUCCESS(Status))
-    {
-        DPRINT1("No \\Device\\Video%lu value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
-        return FALSE;
-    }
-
-    DPRINT("RegistryPath %wZ\n", RegistryPath);
-
-    return TRUE;
-}
-
-static BOOL FASTCALL
-FindDriverFileNames(PUNICODE_STRING DriverFileNames, ULONG DisplayNumber)
-{
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-    UNICODE_STRING RegistryPath;
-    NTSTATUS Status;
-
-    if (! GetRegistryPath(&RegistryPath, DisplayNumber))
-    {
-        DPRINT("GetRegistryPath failed\n");
-        return FALSE;
-    }
-
-    RtlZeroMemory(QueryTable, sizeof(QueryTable));
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
-    QueryTable[0].Name = L"InstalledDisplayDrivers";
-    QueryTable[0].EntryContext = DriverFileNames;
-
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
-                                    RegistryPath.Buffer,
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-    ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY);
-    if (! NT_SUCCESS(Status))
-    {
-        DPRINT1("No InstalledDisplayDrivers value in service entry found\n");
-        return FALSE;
-    }
-
-    DPRINT("DriverFileNames %S\n", DriverFileNames->Buffer);
-
-    return TRUE;
-}
-
-
-static NTSTATUS APIENTRY
-DevModeCallback(IN PWSTR ValueName,
-                IN ULONG ValueType,
-                IN PVOID ValueData,
-                IN ULONG ValueLength,
-                IN PVOID Context,
-                IN PVOID EntryContext)
-{
-    PDEVMODEW DevMode = (PDEVMODEW) Context;
-
-    DPRINT("Found registry value for name %S: type %d, length %d\n",
-           ValueName, ValueType, ValueLength);
-
-    if (REG_DWORD == ValueType && sizeof(DWORD) == ValueLength)
-    {
-        if (0 == _wcsicmp(ValueName, L"DefaultSettings.BitsPerPel"))
-        {
-            DevMode->dmBitsPerPel = *((DWORD *) ValueData);
-        }
-        else if (0 == _wcsicmp(ValueName, L"DefaultSettings.Flags"))
-        {
-            DevMode->dmDisplayFlags = *((DWORD *) ValueData);
-        }
-        else if (0 == _wcsicmp(ValueName, L"DefaultSettings.VRefresh"))
-        {
-            DevMode->dmDisplayFrequency = *((DWORD *) ValueData);
-        }
-        else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XPanning"))
-        {
-            DevMode->dmPanningWidth = *((DWORD *) ValueData);
-        }
-        else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XResolution"))
-        {
-            DevMode->dmPelsWidth = *((DWORD *) ValueData);
-        }
-        else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YPanning"))
-        {
-            DevMode->dmPanningHeight = *((DWORD *) ValueData);
-        }
-        else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YResolution"))
-        {
-            DevMode->dmPelsHeight = *((DWORD *) ValueData);
-        }
-    }
-
-    return STATUS_SUCCESS;
-}
-
-
-static BOOL FASTCALL
-SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber)
-{
-    UNICODE_STRING RegistryPath;
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-    NTSTATUS Status;
-    BOOLEAN Valid = TRUE;
-
-    if (!GetRegistryPath(&RegistryPath, DisplayNumber))
-    {
-        DPRINT("GetRegistryPath failed\n");
-        return FALSE;
-    }
-
-    RtlZeroMemory(QueryTable, sizeof(QueryTable));
-    QueryTable[0].QueryRoutine = DevModeCallback;
-    QueryTable[0].Flags = 0;
-    QueryTable[0].Name = NULL;
-    QueryTable[0].EntryContext = NULL;
-    QueryTable[0].DefaultType = REG_NONE;
-    QueryTable[0].DefaultData = NULL;
-    QueryTable[0].DefaultLength = 0;
-
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
-                                    RegistryPath.Buffer,
-                                    QueryTable,
-                                    DevMode,
-                                    NULL);
-    if (! NT_SUCCESS(Status))
-    {
-        DPRINT("RtlQueryRegistryValues for %wZ failed with status 0x%08x\n",
-               &RegistryPath, Status);
-        Valid = FALSE;
-    }
-    else
-    {
-        DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
-               DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
-               DevMode->dmPelsWidth, DevMode->dmPelsHeight);
-        if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
-                || 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
-        {
-            DPRINT("Not all required devmode members are set\n");
-            Valid = FALSE;
-        }
-    }
-
-    ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY);
-
-    if (! Valid)
-    {
-        RtlZeroMemory(DevMode, sizeof(DEVMODEW));
-    }
-
-    return Valid;
-}
-
-static BOOL FASTCALL
-IntPrepareDriver(VOID)
-{
-    PFN_DrvEnableDriver GDEnableDriver;
-    DRVENABLEDATA DED;
-    UNICODE_STRING DriverFileNames;
-    PWSTR CurrentName;
-    BOOL GotDriver;
-    BOOL DoDefault;
-    ULONG DisplayNumber;
-    LARGE_INTEGER Zero;
-    BOOLEAN ret = FALSE;
-
-    Zero.QuadPart = 0;
-    if (STATUS_SUCCESS != KeWaitForSingleObject(&VideoDriverNeedsPreparation, Executive, KernelMode, TRUE, &Zero))
-    {
-        /* Concurrent access. Wait for VideoDriverPrepared event */
-        if (STATUS_SUCCESS == KeWaitForSingleObject(&VideoDriverPrepared, Executive, KernelMode, TRUE, NULL))
-            ret = PrimarySurface.PreparedDriver;
-        goto cleanup;
-    }
-    // HAX! Fixme so I can support more than one! So how many?
-    for (DisplayNumber = 0; ; DisplayNumber++)
-    {
-        DPRINT("Trying to load display driver no. %d\n", DisplayNumber);
-
-        RtlZeroMemory(&PrimarySurface, sizeof(PrimarySurface));
-
-//      if (!pPrimarySurface) pPrimarySurface = ExAllocatePoolWithTag(PagedPool, gdwDirectDrawContext + sizeof(PDEVOBJ), TAG_GDIPDEV);
-
-        PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(DisplayNumber);
-
-        /* Open the miniport driver  */
-        if (PrimarySurface.VideoFileObject == NULL)
-        {
-            DPRINT1("FindMPDriver failed\n");
-            goto cleanup;
-        }
-
-        /* Retrieve DDI driver names from registry */
-        RtlInitUnicodeString(&DriverFileNames, NULL);
-        if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
-        {
-            DPRINT1("FindDriverFileNames failed\n");
-            continue;
-        }
-
-        /*
-         * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
-         * scan all of them until a good one found.
-         */
-        CurrentName = DriverFileNames.Buffer;
-        GotDriver = FALSE;
-        while (!GotDriver &&
-                CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
-        {
-            /* Get the DDI driver's entry point */
-            GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
-            if (NULL == GDEnableDriver)
-            {
-                DPRINT("FindDDIDriver failed for %S\n", CurrentName);
-            }
-            else
-            {
-                /*  Call DDI driver's EnableDriver function  */
-                RtlZeroMemory(&DED, sizeof(DED));
-
-                if (! GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof(DED), &DED))
-                {
-                    DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
-                }
-                else
-                {
-                    GotDriver = TRUE;
-                }
-            }
-
-            if (! GotDriver)
-            {
-                /* Skip to the next name but never get past the Unicode string */
-                while (L'\0' != *CurrentName &&
-                        CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
-                {
-                    CurrentName++;
-                }
-                if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
-                {
-                    CurrentName++;
-                }
-            }
-        }
-
-        if (!GotDriver)
-        {
-            ObDereferenceObject(PrimarySurface.VideoFileObject);
-            ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
-            DPRINT1("No suitable DDI driver found\n");
-            continue;
-        }
-
-        DPRINT("Display driver %S loaded\n", CurrentName);
-
-        ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
-
-        DPRINT("Building DDI Functions\n");
-
-        /* Construct DDI driver function dispatch table */
-        if (!DRIVER_BuildDDIFunctions(&DED, &PrimarySurface.DriverFunctions))
-        {
-            ObDereferenceObject(PrimarySurface.VideoFileObject);
-            DPRINT1("BuildDDIFunctions failed\n");
-            goto cleanup;
-        }
-
-        /* Allocate a phyical device handle from the driver */
-        // Support DMW.dmSize + DMW.dmDriverExtra & Alloc DMW then set prt pdmwDev.
-        PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
-        if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
-        {
-            PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV(
-                                       &PrimarySurface.DMW,
-                                       L"",
-                                       HS_DDI_MAX,
-                                       PrimarySurface.ahsurf,
-                                       sizeof(PrimarySurface.gdiinfo),
-                                       &PrimarySurface.gdiinfo,
-                                       sizeof(PrimarySurface.devinfo),
-                                       &PrimarySurface.devinfo,
-                                       NULL,
-                                       L"",
-                                       (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
-            DoDefault = (NULL == PrimarySurface.dhpdev);
-            if (DoDefault)
-            {
-                DPRINT1("DrvEnablePDev with registry parameters failed\n");
-            }
-        }
-        else
-        {
-            DoDefault = TRUE;
-        }
-
-        if (DoDefault)
-        {
-            RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
-            PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
-            PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV(
-                                       &PrimarySurface.DMW,
-                                       L"",
-                                       HS_DDI_MAX,
-                                       PrimarySurface.ahsurf,
-                                       sizeof(PrimarySurface.gdiinfo),
-                                       &PrimarySurface.gdiinfo,
-                                       sizeof(PrimarySurface.devinfo),
-                                       &PrimarySurface.devinfo,
-                                       NULL,
-                                       L"",
-                                       (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
-
-            if (NULL == PrimarySurface.dhpdev)
-            {
-                ObDereferenceObject(PrimarySurface.VideoFileObject);
-                DPRINT1("DrvEnablePDEV with default parameters failed\n");
-                DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
-                continue;
-            }
-
-            // Update the primary surface with what we really got
-            PrimarySurface.DMW.dmPelsWidth = PrimarySurface.gdiinfo.ulHorzRes;
-            PrimarySurface.DMW.dmPelsHeight = PrimarySurface.gdiinfo.ulVertRes;
-            PrimarySurface.DMW.dmBitsPerPel = PrimarySurface.gdiinfo.cBitsPixel;
-            PrimarySurface.DMW.dmDisplayFrequency = PrimarySurface.gdiinfo.ulVRefresh;
-        }
-
-        if (!PrimarySurface.DMW.dmDriverExtra)
-        {
-            PrimarySurface.pdmwDev = &PrimarySurface.DMW; // HAX!
-        }
-        else
-        {
-            DPRINT1("WARNING!!! Need to Alloc DMW !!!!!!\n");
-        }
-        // Dont remove until we finish testing other drivers.
-        if (PrimarySurface.DMW.dmDriverExtra != 0)
-        {
-            DPRINT1("**** DMW extra = %u bytes. Please report to ros-dev@reactos.org ****\n", PrimarySurface.DMW.dmDriverExtra);
-        }
-
-        if (0 == PrimarySurface.gdiinfo.ulLogPixelsX)
-        {
-            DPRINT("Adjusting gdiinfo.ulLogPixelsX\n");
-            PrimarySurface.gdiinfo.ulLogPixelsX = 96;
-        }
-        if (0 == PrimarySurface.gdiinfo.ulLogPixelsY)
-        {
-            DPRINT("Adjusting gdiinfo.ulLogPixelsY\n");
-            PrimarySurface.gdiinfo.ulLogPixelsY = 96;
-        }
-
-        PrimarySurface.Pointer.Exclude.right = -1;
-
-        DPRINT("calling completePDev\n");
-
-        /* Complete initialization of the physical device */
-        PrimarySurface.DriverFunctions.CompletePDEV(
-            PrimarySurface.dhpdev,
-            (HDEV)&PrimarySurface);
-
-        DPRINT("calling DRIVER_ReferenceDriver\n");
-
-        DRIVER_ReferenceDriver(L"DISPLAY");
-
-        PrimarySurface.PreparedDriver = TRUE;
-        PrimarySurface.DisplayNumber = DisplayNumber;
-        PrimarySurface.flFlags = PDEV_DISPLAY; // Hard set,, add more flags.
-        PrimarySurface.hsemDevLock = (PERESOURCE)EngCreateSemaphore();
-        // Should be null,, but make sure for now.
-        PrimarySurface.pvGammaRamp = NULL;
-        PrimarySurface.ppdevNext = NULL;    // Fixme! We need to support more than display drvs.
-        PrimarySurface.ppdevParent = NULL;  // Always NULL if primary.
-        PrimarySurface.pGraphicsDevice = NULL; // Fixme!
-        PrimarySurface.pEDDgpl = ExAllocatePoolWithTag(PagedPool, sizeof(EDD_DIRECTDRAW_GLOBAL), TAG_EDDGBL);
-        if (PrimarySurface.pEDDgpl)
-        {
-            RtlZeroMemory( PrimarySurface.pEDDgpl ,sizeof(EDD_DIRECTDRAW_GLOBAL));
-            ret = TRUE;
-        }
-        goto cleanup;
-    }
-
-cleanup:
-    KeSetEvent(&VideoDriverPrepared, 1, FALSE);
-    return ret;
-}
-
-BOOL FASTCALL
-IntPrepareDriverIfNeeded(VOID)
+VOID FASTCALL
+IntGdiReferencePdev(PPDEVOBJ ppdev)
 {
-    return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
+    UNIMPLEMENTED;
 }
 
-static BOOL FASTCALL
-PrepareVideoPrt(VOID)
+VOID FASTCALL
+IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType)
 {
-    PIRP Irp;
-    NTSTATUS Status;
-    IO_STATUS_BLOCK Iosb;
-    BOOL Prepare = TRUE;
-    ULONG Length = sizeof(BOOL);
-    PIO_STACK_LOCATION StackPtr;
-    LARGE_INTEGER StartOffset;
-    PFILE_OBJECT FileObject = PrimarySurface.VideoFileObject;
-    PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
-
-    DPRINT("PrepareVideoPrt() called\n");
-
-    KeClearEvent(&PrimarySurface.VideoFileObject->Event);
-
-    ObReferenceObjectByPointer(FileObject, 0, IoFileObjectType, KernelMode);
-
-    StartOffset.QuadPart = 0;
-    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
-                                       DeviceObject,
-                                       (PVOID) &Prepare,
-                                       Length,
-                                       &StartOffset,
-                                       NULL,
-                                       &Iosb);
-    if (NULL == Irp)
-    {
-        return FALSE;
-    }
-
-    /* Set up IRP Data */
-    Irp->Tail.Overlay.OriginalFileObject = FileObject;
-    Irp->RequestorMode = KernelMode;
-    Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
-    Irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
-    Irp->Flags |= IRP_WRITE_OPERATION;
-
-    /* Setup Stack Data */
-    StackPtr = IoGetNextIrpStackLocation(Irp);
-    StackPtr->FileObject = PrimarySurface.VideoFileObject;
-    StackPtr->Parameters.Write.Key = 0;
-
-    Status = IoCallDriver(DeviceObject, Irp);
-
-    if (STATUS_PENDING == Status)
-    {
-        KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, TRUE, 0);
-        Status = Iosb.Status;
-    }
-
-    return NT_SUCCESS(Status);
+    UNIMPLEMENTED;
 }
 
-
 BOOL FASTCALL
-IntCreatePrimarySurface(VOID)
+IntCreatePrimarySurface()
 {
     SIZEL SurfSize;
-    RECTL SurfaceRect;
-    SURFOBJ *SurfObj;
+    SURFOBJ *pso;
     BOOL calledFromUser;
 
-    if (! IntPrepareDriverIfNeeded())
-    {
-        return FALSE;
-    }
-
-    if (! PrepareVideoPrt())
-    {
-        return FALSE;
-    }
-
-    DPRINT("calling EnableSurface\n");
-    /* Enable the drawing surface */
-    PrimarySurface.pSurface =
-        PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.dhpdev);
-    if (NULL == PrimarySurface.pSurface)
-    {
-        /*      PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE);*/
-        PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev);
-        ObDereferenceObject(PrimarySurface.VideoFileObject);
-        DPRINT1("DrvEnableSurface failed\n");
-        return FALSE;
-    }
-
-    PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, TRUE);
-
     calledFromUser = UserIsEntered(); //fixme: possibly upgrade a shared lock
     if (!calledFromUser)
     {
@@ -538,31 +39,22 @@ IntCreatePrimarySurface(VOID)
     }
 
     /* attach monitor */
-    IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
+    IntAttachMonitor(gppdevPrimary, 0);
 
-    SurfObj = EngLockSurface(PrimarySurface.pSurface);
-    SurfObj->dhpdev = PrimarySurface.dhpdev;
-    SurfSize = SurfObj->sizlBitmap;
-    SurfaceRect.left = SurfaceRect.top = 0;
-    SurfaceRect.right = SurfObj->sizlBitmap.cx;
-    SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
-    /* FIXME - why does EngEraseSurface() sometimes crash?
-       EngEraseSurface(SurfObj, &SurfaceRect, 0); */
+DPRINT1("IntCreatePrimarySurface, pPrimarySurface=%p, pPrimarySurface->pSurface = %p\n",
+        pPrimarySurface, pPrimarySurface->pSurface);
 
-    /* Put the pointer in the center of the screen */
-    gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2;
-    gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+    pso = &pPrimarySurface->pSurface->SurfObj;
+    SurfSize = pso->sizlBitmap;
 
-    /* Give the PDEV a MovePointer function */
-    PrimarySurface.pfnMovePointer = PrimarySurface.DriverFunctions.MovePointer;
-    if (!PrimarySurface.pfnMovePointer)
-        PrimarySurface.pfnMovePointer = EngMovePointer;
+    /* Put the pointer in the center of the screen */
+    gpsi->ptCursor.x = pso->sizlBitmap.cx / 2;
+    gpsi->ptCursor.y = pso->sizlBitmap.cy / 2;
 
-    EngUnlockSurface(SurfObj);
     co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
 
     // Init Primary Displays Device Capabilities.
-    IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
+    PDEVOBJ_vGetDeviceCaps(pPrimarySurface, &GdiHandleTable->DevCaps);
 
     if (!calledFromUser)
     {
@@ -573,1140 +65,19 @@ IntCreatePrimarySurface(VOID)
 }
 
 VOID FASTCALL
-IntDestroyPrimarySurface(VOID)
-{
-    BOOL calledFromUser;
-
-    DRIVER_UnreferenceDriver(L"DISPLAY");
-
-    calledFromUser = UserIsEntered();
-    if (!calledFromUser)
-    {
-        UserEnterExclusive();
-    }
-
-    /* detach monitor */
-    IntDetachMonitor(&PrimarySurface);
-
-    if (!calledFromUser)
-    {
-        UserLeave();
-    }
-
-    /*
-     * FIXME: Hide a mouse pointer there. Also because we have to prevent
-     * memory leaks with the Eng* mouse routines.
-     */
-
-    DPRINT("Reseting display\n" );
-    PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE);
-    PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.dhpdev);
-    PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev);
-    PrimarySurface.PreparedDriver = FALSE;
-    KeSetEvent(&VideoDriverNeedsPreparation, 1, FALSE);
-    KeResetEvent(&VideoDriverPrepared);
-
-    DceEmptyCache();
-
-    ObDereferenceObject(PrimarySurface.VideoFileObject);
-}
-
-INT
-FASTCALL
-IntcFonts(PPDEVOBJ pDevObj)
+IntDestroyPrimarySurface()
 {
-    ULONG_PTR Junk;
-// Msdn DrvQueryFont:
-// If the number of fonts in DEVINFO is -1 and iFace is zero, the driver
-// should return the number of fonts it supports.
-    if ( pDevObj->devinfo.cFonts == -1)
-    {
-        if (pDevObj->DriverFunctions.QueryFont)
-            pDevObj->devinfo.cFonts =
-                (ULONG)pDevObj->DriverFunctions.QueryFont(pDevObj->dhpdev, 0, 0, &Junk);
-        else
-            pDevObj->devinfo.cFonts = 0;
-    }
-    return pDevObj->devinfo.cFonts;
-}
-
-//
-// Support multi display/device locks.
-//
-VOID
-FASTCALL
-DC_LockDisplay(HDC hDC)
-{
-    PERESOURCE Resource;
-    PDC dc = DC_LockDc(hDC);
-    if (!dc) return;
-    Resource = dc->ppdev->hsemDevLock;
-    DC_UnlockDc(dc);
-    if (!Resource) return;
-    KeEnterCriticalRegion();
-    ExAcquireResourceExclusiveLite( Resource , TRUE);
-}
-
-VOID
-FASTCALL
-DC_UnlockDisplay(HDC hDC)
-{
-    PERESOURCE Resource;
-    PDC dc = DC_LockDc(hDC);
-    if (!dc) return;
-    Resource = dc->ppdev->hsemDevLock;
-    DC_UnlockDc(dc);
-    if (!Resource) return;
-    ExReleaseResourceLite( Resource );
-    KeLeaveCriticalRegion();
+    UNIMPLEMENTED;
 }
 
-//
-// Enumerate HDev
-//
 PPDEVOBJ FASTCALL
 IntEnumHDev(VOID)
 {
 // I guess we will soon have more than one primary surface.
 // This will do for now.
-    return &PrimarySurface;
-}
-
-
-VOID FASTCALL
-IntGdiReferencePdev(PPDEVOBJ ppdev)
-{
-    if (!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore(); // Hax, should be in dllmain.c
-    IntGdiAcquireSemaphore(hsemDriverMgmt);
-    ppdev->cPdevRefs++;
-    IntGdiReleaseSemaphore(hsemDriverMgmt);
-}
-
-VOID FASTCALL
-IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType)
-{
-    IntGdiAcquireSemaphore(hsemDriverMgmt);
-    ppdev->cPdevRefs--;
-    if (!ppdev->cPdevRefs)
-    {
-        // Handle the destruction of ppdev or PDEVOBJ or PDEVOBJ or PDEV etc.
-    }
-    IntGdiReleaseSemaphore(hsemDriverMgmt);
-}
-
-
-
-INT
-FASTCALL
-IntGetColorManagementCaps(PPDEVOBJ pDevObj)
-{
-    INT ret = CM_NONE;
-
-    if ( pDevObj->flFlags & PDEV_DISPLAY)
-    {
-        if (pDevObj->devinfo.iDitherFormat == BMF_8BPP ||
-            pDevObj->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
-            ret = CM_GAMMA_RAMP;
-    }
-    if (pDevObj->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
-        ret |= CM_CMYK_COLOR;
-    if (pDevObj->devinfo.flGraphicsCaps & GCAPS_ICM)
-        ret |= CM_DEVICE_ICM;
-    return ret;
-}
-
-INT FASTCALL
-IntGdiGetDeviceCaps(PDC dc, INT Index)
-{
-    INT ret = 0;
-    PPDEVOBJ ppdev = dc->ppdev;
-    /* Retrieve capability */
-    switch (Index)
-    {
-        case DRIVERVERSION:
-            ret = ppdev->gdiinfo.ulVersion;
-            break;
-
-        case TECHNOLOGY:
-            ret = ppdev->gdiinfo.ulTechnology;
-            break;
-
-        case HORZSIZE:
-            ret = ppdev->gdiinfo.ulHorzSize;
-            break;
-
-        case VERTSIZE:
-            ret = ppdev->gdiinfo.ulVertSize;
-            break;
-
-        case HORZRES:
-            ret = ppdev->gdiinfo.ulHorzRes;
-            break;
-
-        case VERTRES:
-            ret = ppdev->gdiinfo.ulVertRes;
-            break;
-
-        case LOGPIXELSX:
-            ret = ppdev->gdiinfo.ulLogPixelsX;
-            break;
-
-        case LOGPIXELSY:
-            ret = ppdev->gdiinfo.ulLogPixelsY;
-            break;
-
-        case CAPS1:
-            if ( ppdev->pGraphicsDevice &&
-                    (((PGRAPHICS_DEVICE)ppdev->pGraphicsDevice)->StateFlags &
-                     DISPLAY_DEVICE_MIRRORING_DRIVER))
-                ret = C1_MIRRORING;
-            break;
-
-        case BITSPIXEL:
-            ret = ppdev->gdiinfo.cBitsPixel;
-            break;
-
-        case PLANES:
-            ret = ppdev->gdiinfo.cPlanes;
-            break;
-
-        case NUMBRUSHES:
-            ret = -1;
-            break;
-
-        case NUMPENS:
-            ret = ppdev->gdiinfo.ulNumColors;
-            if ( ret != -1 ) ret *= 5;
-            break;
-
-        case NUMFONTS:
-            ret = IntcFonts(ppdev);
-            break;
-
-        case NUMCOLORS:
-            ret = ppdev->gdiinfo.ulNumColors;
-            break;
-
-        case ASPECTX:
-            ret = ppdev->gdiinfo.ulAspectX;
-            break;
-
-        case ASPECTY:
-            ret = ppdev->gdiinfo.ulAspectY;
-            break;
-
-        case ASPECTXY:
-            ret = ppdev->gdiinfo.ulAspectXY;
-            break;
-
-        case CLIPCAPS:
-            ret = CP_RECTANGLE;
-            break;
-
-        case SIZEPALETTE:
-            ret = ppdev->gdiinfo.ulNumPalReg;
-            break;
-
-        case NUMRESERVED:
-            ret = 20;
-            break;
-
-        case COLORRES:
-            ret = ppdev->gdiinfo.ulDACRed +
-                  ppdev->gdiinfo.ulDACGreen +
-                  ppdev->gdiinfo.ulDACBlue;
-            break;
-
-        case DESKTOPVERTRES:
-            ret = ppdev->gdiinfo.ulVertRes;
-            break;
-
-        case DESKTOPHORZRES:
-            ret = ppdev->gdiinfo.ulHorzRes;
-            break;
-
-        case BLTALIGNMENT:
-            ret = ppdev->gdiinfo.ulBltAlignment;
-            break;
-
-        case SHADEBLENDCAPS:
-            ret = ppdev->gdiinfo.flShadeBlend;
-            break;
-
-        case COLORMGMTCAPS:
-            ret = IntGetColorManagementCaps(ppdev);
-            break;
-
-        case PHYSICALWIDTH:
-            ret = ppdev->gdiinfo.szlPhysSize.cx;
-            break;
-
-        case PHYSICALHEIGHT:
-            ret = ppdev->gdiinfo.szlPhysSize.cy;
-            break;
-
-        case PHYSICALOFFSETX:
-            ret = ppdev->gdiinfo.ptlPhysOffset.x;
-            break;
-
-        case PHYSICALOFFSETY:
-            ret = ppdev->gdiinfo.ptlPhysOffset.y;
-            break;
-
-        case VREFRESH:
-            ret = ppdev->gdiinfo.ulVRefresh;
-            break;
-
-        case RASTERCAPS:
-            ret = ppdev->gdiinfo.flRaster;
-            break;
-
-        case CURVECAPS:
-            ret = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
-                   CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
-            break;
-
-        case LINECAPS:
-            ret = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
-                   LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
-            break;
-
-        case POLYGONALCAPS:
-            ret = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
-                   PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
-            break;
-
-        case TEXTCAPS:
-            ret = ppdev->gdiinfo.flTextCaps;
-            if (ppdev->gdiinfo.ulTechnology) ret |= TC_VA_ABLE;
-            ret |= (TC_SO_ABLE|TC_UA_ABLE);
-            break;
-
-        case PDEVICESIZE:
-        case SCALINGFACTORX:
-        case SCALINGFACTORY:
-        default:
-            ret = 0;
-            break;
-    }
-
-    return ret;
+    return pPrimarySurface;
 }
 
-INT APIENTRY
-NtGdiGetDeviceCaps(HDC  hDC,
-                   INT  Index)
-{
-    PDC  dc;
-    INT  ret;
-
-    dc = DC_LockDc(hDC);
-    if (dc == NULL)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return 0;
-    }
-
-    ret = IntGdiGetDeviceCaps(dc, Index);
-
-    DPRINT("(%04x,%d): returning %d\n", hDC, Index, ret);
-
-    DC_UnlockDc( dc );
-    return ret;
-}
-
-VOID
-FASTCALL
-IntvGetDeviceCaps(
-    PPDEVOBJ pDevObj,
-    PDEVCAPS pDevCaps)
-{
-    ULONG Tmp = 0;
-    PGDIINFO pGdiInfo = &pDevObj->gdiinfo;
-
-    pDevCaps->ulVersion         = pGdiInfo->ulVersion;
-    pDevCaps->ulTechnology      = pGdiInfo->ulTechnology;
-    pDevCaps->ulHorzSizeM       = (pGdiInfo->ulHorzSize + 500) / 1000;
-    pDevCaps->ulVertSizeM       = (pGdiInfo->ulVertSize + 500) / 1000;
-    pDevCaps->ulHorzSize        = pGdiInfo->ulHorzSize;
-    pDevCaps->ulVertSize        = pGdiInfo->ulVertSize;
-    pDevCaps->ulHorzRes         = pGdiInfo->ulHorzRes;
-    pDevCaps->ulVertRes         = pGdiInfo->ulVertRes;
-    pDevCaps->ulVRefresh        = pGdiInfo->ulVRefresh;
-    pDevCaps->ulDesktopHorzRes  = pGdiInfo->ulHorzRes;
-    pDevCaps->ulDesktopVertRes  = pGdiInfo->ulVertRes;
-    pDevCaps->ulBltAlignment    = pGdiInfo->ulBltAlignment;
-    pDevCaps->ulPlanes          = pGdiInfo->cPlanes;
-
-    pDevCaps->ulBitsPixel       = pGdiInfo->cBitsPixel;
-    if (pGdiInfo->cBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
-
-    Tmp = pGdiInfo->ulNumColors;
-    if ( Tmp != -1 ) Tmp *= 5;
-    pDevCaps->ulNumPens = Tmp;
-    pDevCaps->ulNumColors       = pGdiInfo->ulNumColors;
-
-    pDevCaps->ulNumFonts        = IntcFonts(pDevObj);
-
-    pDevCaps->ulRasterCaps      = pGdiInfo->flRaster;
-    pDevCaps->ulShadeBlend      = pGdiInfo->flShadeBlend;
-    pDevCaps->ulAspectX         = pGdiInfo->ulAspectX;
-    pDevCaps->ulAspectY         = pGdiInfo->ulAspectY;
-    pDevCaps->ulAspectXY        = pGdiInfo->ulAspectXY;
-    pDevCaps->ulLogPixelsX      = pGdiInfo->ulLogPixelsX;
-    pDevCaps->ulLogPixelsY      = pGdiInfo->ulLogPixelsY;
-    pDevCaps->ulSizePalette     = pGdiInfo->ulNumPalReg;
-    pDevCaps->ulColorRes        = pGdiInfo->ulDACRed + pGdiInfo->ulDACGreen + pGdiInfo->ulDACBlue;
-    pDevCaps->ulPhysicalWidth   = pGdiInfo->szlPhysSize.cx;
-    pDevCaps->ulPhysicalHeight  = pGdiInfo->szlPhysSize.cy;
-    pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
-    pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
-    pDevCaps->ulPanningHorzRes  = pGdiInfo->ulPanningHorzRes;
-    pDevCaps->ulPanningVertRes  = pGdiInfo->ulPanningVertRes;
-    pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
-    pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
-
-    Tmp = 0;
-    Tmp = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
-
-    pDevCaps->ulTextCaps = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
-
-    if (pGdiInfo->ulTechnology)
-        pDevCaps->ulTextCaps = Tmp | TC_VA_ABLE;
-
-    pDevCaps->ulColorMgmtCaps = IntGetColorManagementCaps(pDevObj);
-
-    return;
-}
-
-/*
-* @implemented
-*/
-BOOL
-APIENTRY
-NtGdiGetDeviceCapsAll (
-    IN HDC hDC,
-    OUT PDEVCAPS pDevCaps)
-{
-    PDC  dc;
-    PDEVCAPS pSafeDevCaps;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    dc = DC_LockDc(hDC);
-    if (!dc)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    pSafeDevCaps = ExAllocatePoolWithTag(PagedPool, sizeof(DEVCAPS), TAG_TEMP);
-
-    if (!pSafeDevCaps)
-    {
-        DC_UnlockDc(dc);
-        return FALSE;
-    }
-
-    IntvGetDeviceCaps(dc->ppdev, pSafeDevCaps);
-
-    _SEH2_TRY
-    {
-        ProbeForWrite(pDevCaps,
-        sizeof(DEVCAPS),
-        1);
-        RtlCopyMemory(pDevCaps, pSafeDevCaps, sizeof(DEVCAPS));
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        Status = _SEH2_GetExceptionCode();
-    }
-    _SEH2_END;
-
-    ExFreePoolWithTag(pSafeDevCaps, TAG_TEMP);
-    DC_UnlockDc(dc);
-
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastNtError(Status);
-        return FALSE;
-    }
-    return TRUE;
-}
-
-
-/*
- * @implemented
- */
-DHPDEV
-APIENTRY
-NtGdiGetDhpdev(
-    IN HDEV hdev)
-{
-    PPDEVOBJ ppdev, pGdiDevice = (PPDEVOBJ) hdev;
-    if (!pGdiDevice) return NULL;
-    if ( pGdiDevice < (PPDEVOBJ)MmSystemRangeStart) return NULL;
-    ppdev = pPrimarySurface;
-    IntGdiAcquireSemaphore(hsemDriverMgmt);
-    do
-    {
-        if (pGdiDevice == ppdev) break;
-        else
-            ppdev = ppdev->ppdevNext;
-    }
-    while (ppdev != NULL);
-    IntGdiReleaseSemaphore(hsemDriverMgmt);
-    if (!ppdev) return NULL;
-    return pGdiDevice->dhpdev;
-}
-
-static NTSTATUS FASTCALL
-GetVideoRegistryKey(
-    OUT PUNICODE_STRING RegistryPath,
-    IN PCUNICODE_STRING DeviceName) /* ex: "\Device\Video0" */
-{
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-    NTSTATUS Status;
-
-    RtlInitUnicodeString(RegistryPath, NULL);
-    RtlZeroMemory(QueryTable, sizeof(QueryTable));
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
-    QueryTable[0].Name = DeviceName->Buffer;
-    QueryTable[0].EntryContext = RegistryPath;
-
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
-                                    L"VIDEO",
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("No %wZ value in DEVICEMAP\\VIDEO found (Status 0x%08lx)\n", DeviceName, Status);
-        return STATUS_NO_SUCH_DEVICE;
-    }
-
-    DPRINT("RegistryPath %wZ\n", RegistryPath);
-    return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS FASTCALL
-GetVideoDeviceName(
-    OUT PUNICODE_STRING VideoDeviceName,
-    IN PCUNICODE_STRING DisplayDevice) /* ex: "\.\DISPLAY1" or "\??\DISPLAY1" */
-{
-    UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\??\\");
-    UNICODE_STRING ObjectName;
-    UNICODE_STRING KernelModeName = { 0, };
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    USHORT LastSlash;
-    ULONG Length;
-    HANDLE LinkHandle = NULL;
-    NTSTATUS Status;
-
-    RtlInitUnicodeString(VideoDeviceName, NULL);
-
-    /* Get device name (DisplayDevice is "\.\xxx") */
-    for (LastSlash = DisplayDevice->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
-    {
-        if (DisplayDevice->Buffer[LastSlash - 1] == L'\\')
-            break;
-    }
-
-    if (LastSlash == 0)
-    {
-        DPRINT1("Invalid device name '%wZ'\n", DisplayDevice);
-        Status = STATUS_OBJECT_NAME_INVALID;
-        goto cleanup;
-    }
-    ObjectName = *DisplayDevice;
-    ObjectName.Length -= LastSlash * sizeof(WCHAR);
-    ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
-    ObjectName.Buffer += LastSlash;
-
-    /* Create "\??\xxx" (ex: "\??\DISPLAY1") */
-    KernelModeName.MaximumLength = Prefix.Length + ObjectName.Length + sizeof(UNICODE_NULL);
-    KernelModeName.Buffer = ExAllocatePoolWithTag(PagedPool,
-                            KernelModeName.MaximumLength,
-                            TAG_DC);
-    if (!KernelModeName.Buffer)
-    {
-        Status = STATUS_NO_MEMORY;
-        goto cleanup;
-    }
-    RtlCopyUnicodeString(&KernelModeName, &Prefix);
-    Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
-    if (!NT_SUCCESS(Status))
-        goto cleanup;
-
-    /* Open \??\xxx (ex: "\??\DISPLAY1") */
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &KernelModeName,
-                               OBJ_KERNEL_HANDLE,
-                               NULL,
-                               NULL);
-    Status = ZwOpenSymbolicLinkObject(&LinkHandle,
-                                      GENERIC_READ,
-                                      &ObjectAttributes);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Unable to open symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
-        Status = STATUS_NO_SUCH_DEVICE;
-        goto cleanup;
-    }
-
-    Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, &Length);
-    if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
-    {
-        DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
-        Status = STATUS_NO_SUCH_DEVICE;
-        goto cleanup;
-    }
-    VideoDeviceName->MaximumLength = Length;
-    VideoDeviceName->Buffer = ExAllocatePoolWithTag(PagedPool,
-                              VideoDeviceName->MaximumLength + sizeof(UNICODE_NULL),
-                              TAG_DC);
-    if (!VideoDeviceName->Buffer)
-    {
-        Status = STATUS_NO_MEMORY;
-        goto cleanup;
-    }
-    Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, NULL);
-    VideoDeviceName->Buffer[VideoDeviceName->MaximumLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
-        Status = STATUS_NO_SUCH_DEVICE;
-        goto cleanup;
-    }
-    Status = STATUS_SUCCESS;
-
-cleanup:
-    if (!NT_SUCCESS(Status) && VideoDeviceName->Buffer)
-        ExFreePoolWithTag(VideoDeviceName->Buffer, TAG_DC);
-    if (KernelModeName.Buffer)
-        ExFreePoolWithTag(KernelModeName.Buffer, TAG_DC);
-    if (LinkHandle)
-        ZwClose(LinkHandle);
-    return Status;
-}
-
-LONG
-FASTCALL
-IntChangeDisplaySettings(
-    IN PUNICODE_STRING pDeviceName  OPTIONAL,
-    IN LPDEVMODEW DevMode,
-    IN DWORD dwflags,
-    IN PVOID lParam  OPTIONAL)
-{
-    BOOLEAN Global = FALSE;
-    BOOLEAN NoReset = FALSE;
-    BOOLEAN Reset = FALSE;
-    BOOLEAN SetPrimary = FALSE;
-    LONG Ret = DISP_CHANGE_SUCCESSFUL;
-    NTSTATUS Status ;
-
-    DPRINT1("display flags : %x\n",dwflags);
-
-    if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
-    {
-        /* Check global, reset and noreset flags */
-        if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL)
-            Global = TRUE;
-        if ((dwflags & CDS_NORESET) == CDS_NORESET)
-            NoReset = TRUE;
-        dwflags &= ~(CDS_GLOBAL | CDS_NORESET);
-    }
-    if ((dwflags & CDS_RESET) == CDS_RESET)
-        Reset = TRUE;
-    if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY)
-        SetPrimary = TRUE;
-    dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY);
-
-    if (Reset && NoReset)
-        return DISP_CHANGE_BADFLAGS;
-
-    if (dwflags == 0)
-    {
-        /* Dynamically change graphics mode */
-        DPRINT1("flag 0 UNIMPLEMENTED\n");
-        SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
-        return DISP_CHANGE_FAILED;
-    }
-
-    if ((dwflags & CDS_TEST) == CDS_TEST)
-    {
-        /* Test resolution */
-        dwflags &= ~CDS_TEST;
-        Status = IntEnumDisplaySettings(pDeviceName, ENUM_REGISTRY_SETTINGS, DevMode, 0);
-        if (!NT_SUCCESS(Status))
-            Ret = DISP_CHANGE_BADMODE;
-        return Ret;
-    }
-
-    if ((dwflags & CDS_FULLSCREEN) == CDS_FULLSCREEN)
-    {
-        DEVMODEW lpDevMode;
-        /* Full Screen */
-        dwflags &= ~CDS_FULLSCREEN;
-        DPRINT1("flag CDS_FULLSCREEN partially implemented\n");
-        Ret = DISP_CHANGE_FAILED;
-
-        RtlZeroMemory(&lpDevMode, sizeof(DEVMODEW));
-        lpDevMode.dmSize = sizeof(DEVMODEW);
-
-        Status = IntEnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &lpDevMode, 0);
-        if (!NT_SUCCESS(Status))
-            return DISP_CHANGE_FAILED;
-
-        DPRINT1("Req Mode     : %d x %d x %d\n", DevMode->dmPelsWidth,DevMode->dmPelsHeight,DevMode->dmBitsPerPel);
-        DPRINT1("Current Mode : %d x %d x %d\n", lpDevMode.dmPelsWidth,lpDevMode.dmPelsHeight, lpDevMode.dmBitsPerPel);
-
-
-        if ((lpDevMode.dmBitsPerPel == DevMode->dmBitsPerPel) &&
-                (lpDevMode.dmPelsWidth  == DevMode->dmPelsWidth) &&
-                (lpDevMode.dmPelsHeight == DevMode->dmPelsHeight))
-            Ret = DISP_CHANGE_SUCCESSFUL;
-    }
-
-    if ((dwflags & CDS_VIDEOPARAMETERS) == CDS_VIDEOPARAMETERS)
-    {
-        dwflags &= ~CDS_VIDEOPARAMETERS;
-        if (lParam == NULL)
-            Ret=DISP_CHANGE_BADPARAM;
-        else
-        {
-            DPRINT1("flag CDS_VIDEOPARAMETERS UNIMPLEMENTED\n");
-            Ret = DISP_CHANGE_FAILED;
-            SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
-        }
-
-    }
-
-    if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
-    {
-
-        UNICODE_STRING DeviceName;
-        UNICODE_STRING RegistryKey;
-        UNICODE_STRING InDeviceName;
-        OBJECT_ATTRIBUTES ObjectAttributes;
-        HANDLE DevInstRegKey;
-        ULONG NewValue;
-
-        DPRINT1("set CDS_UPDATEREGISTRY\n");
-
-        dwflags &= ~CDS_UPDATEREGISTRY;
-
-        /* Check if pDeviceName is NULL, we need to retrieve it */
-        if (pDeviceName == NULL)
-        {
-            WCHAR szBuffer[MAX_DRIVER_NAME];
-            PDC DC;
-            PWINDOW_OBJECT Wnd=NULL;
-            HWND hWnd;
-            HDC hDC;
-
-            hWnd = IntGetDesktopWindow();
-            if (!(Wnd = UserGetWindowObject(hWnd)))
-            {
-                return FALSE;
-            }
-
-            hDC = UserGetWindowDC(Wnd);
-
-            DC = DC_LockDc(hDC);
-            if (NULL == DC)
-            {
-                return FALSE;
-            }
-            swprintf (szBuffer, L"\\\\.\\DISPLAY%lu", DC->ppdev->DisplayNumber);
-            DC_UnlockDc(DC);
-
-            RtlInitUnicodeString(&InDeviceName, szBuffer);
-            pDeviceName = &InDeviceName;
-        }
-
-        Status = GetVideoDeviceName(&DeviceName, pDeviceName);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Unable to get destination of '%wZ' (Status 0x%08lx)\n", pDeviceName, Status);
-            return DISP_CHANGE_FAILED;
-        }
-        Status = GetVideoRegistryKey(&RegistryKey, &DeviceName);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Unable to get registry key for '%wZ' (Status 0x%08lx)\n", &DeviceName, Status);
-            ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
-            return DISP_CHANGE_FAILED;
-        }
-        ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
-
-        InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
-                                   OBJ_CASE_INSENSITIVE, NULL, NULL);
-        Status = ZwOpenKey(&DevInstRegKey, KEY_SET_VALUE, &ObjectAttributes);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Unable to open registry key %wZ (Status 0x%08lx)\n", &RegistryKey, Status);
-            ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY);
-            return DISP_CHANGE_FAILED;
-        }
-        ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY);
-
-        /* Update needed fields */
-        if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
-        {
-            RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel");
-            NewValue = DevMode->dmBitsPerPel;
-            Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
-        }
-
-        if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH)
-        {
-            RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution");
-            NewValue = DevMode->dmPelsWidth;
-            Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
-        }
-
-        if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT)
-        {
-            RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution");
-            NewValue = DevMode->dmPelsHeight;
-            Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
-        }
-
-        if (NT_SUCCESS(Status) && DevMode->dmFields & DM_DISPLAYFREQUENCY)
-        {
-            RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.VRefresh");
-            NewValue = DevMode->dmDisplayFrequency;
-            Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
-        }
-
-        ZwClose(DevInstRegKey);
-        if (NT_SUCCESS(Status))
-            Ret = DISP_CHANGE_RESTART;
-        else
-            /* return DISP_CHANGE_NOTUPDATED when we can save to reg only valid for NT */
-            Ret = DISP_CHANGE_NOTUPDATED;
-    }
-
-    if (dwflags != 0)
-        Ret = DISP_CHANGE_BADFLAGS;
-
-    DPRINT("IntChangeDisplaySettings returning %x\n", Ret);
-    return Ret;
-}
-
-
-
-#define SIZEOF_DEVMODEW_300 188
-#define SIZEOF_DEVMODEW_400 212
-#define SIZEOF_DEVMODEW_500 220
-
-static NTSTATUS FASTCALL
-GetDisplayNumberFromDeviceName(
-    IN PUNICODE_STRING pDeviceName  OPTIONAL,
-    OUT ULONG *DisplayNumber)
-{
-    UNICODE_STRING DisplayString = RTL_CONSTANT_STRING(L"\\\\.\\DISPLAY");
-    NTSTATUS Status = STATUS_SUCCESS;
-    ULONG Length;
-    ULONG Number;
-    ULONG i;
-
-    if (DisplayNumber == NULL)
-        return STATUS_INVALID_PARAMETER_2;
-
-    /* Check if DeviceName is valid */
-    if (pDeviceName &&
-            pDeviceName->Length > 0 && pDeviceName->Length <= DisplayString.Length)
-        return STATUS_OBJECT_NAME_INVALID;
-
-    if (pDeviceName == NULL || pDeviceName->Length == 0)
-    {
-        PWINDOW_OBJECT DesktopObject;
-        HDC DesktopHDC;
-        PDC pDC;
-
-        DesktopObject = UserGetDesktopWindow();
-        DesktopHDC = UserGetWindowDC(DesktopObject);
-        pDC = DC_LockDc(DesktopHDC);
-
-        *DisplayNumber = pDC->ppdev->DisplayNumber;
-
-        DC_UnlockDc(pDC);
-        UserReleaseDC(DesktopObject, DesktopHDC, FALSE);
-
-        return STATUS_SUCCESS;
-    }
-
-    /* Hack to check if the first parts are equal, by faking the device name length */
-    Length = pDeviceName->Length;
-    pDeviceName->Length = DisplayString.Length;
-    if (RtlEqualUnicodeString(&DisplayString, pDeviceName, FALSE) == FALSE)
-        Status = STATUS_OBJECT_NAME_INVALID;
-    pDeviceName->Length = Length;
-
-    if (NT_SUCCESS(Status))
-    {
-        /* Convert the last part of pDeviceName to a number */
-        Number = 0;
-        Length = pDeviceName->Length / sizeof(WCHAR);
-        for (i = DisplayString.Length / sizeof(WCHAR); i < Length; i++)
-        {
-            WCHAR Char = pDeviceName->Buffer[i];
-            if (Char >= L'0' && Char <= L'9')
-                Number = Number * 10 + Char - L'0';
-            else if (Char != L'\0')
-                return STATUS_OBJECT_NAME_INVALID;
-        }
-
-        *DisplayNumber = Number - 1;
-    }
-
-    return Status;
-}
-
-/*! \brief Enumerate possible display settings for the given display...
- *
- * \todo Make thread safe!?
- * \todo Don't ignore pDeviceName
- * \todo Implement non-raw mode (only return settings valid for driver and monitor)
- */
-NTSTATUS
-FASTCALL
-IntEnumDisplaySettings(
-    IN PUNICODE_STRING pDeviceName  OPTIONAL,
-    IN DWORD iModeNum,
-    IN OUT LPDEVMODEW pDevMode,
-    IN DWORD dwFlags)
-{
-    static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
-    static DWORD SizeOfCachedDevModes = 0;
-    static UNICODE_STRING CachedDeviceName;
-    PDEVMODEW CachedMode = NULL;
-    DEVMODEW DevMode;
-    ULONG DisplayNumber;
-    NTSTATUS Status;
-
-    Status = GetDisplayNumberFromDeviceName(pDeviceName, &DisplayNumber);
-    if (!NT_SUCCESS(Status))
-    {
-        return Status;
-    }
-
-    if (pDevMode != NULL)
-    {
-        DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize);
-        DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
-        if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
-                pDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
-                pDevMode->dmSize != SIZEOF_DEVMODEW_500)
-        {
-            return STATUS_BUFFER_TOO_SMALL;
-        }
-    }
-
-    if (iModeNum == ENUM_CURRENT_SETTINGS)
-    {
-        CachedMode = &PrimarySurface.DMW;
-        ASSERT(CachedMode->dmSize > 0);
-    }
-    else if (iModeNum == ENUM_REGISTRY_SETTINGS)
-    {
-        RtlZeroMemory(&DevMode, sizeof (DevMode));
-        DevMode.dmSize = sizeof (DevMode);
-        DevMode.dmDriverExtra = 0;
-        if (SetupDevMode(&DevMode, DisplayNumber))
-            CachedMode = &DevMode;
-        else
-        {
-            return STATUS_UNSUCCESSFUL; // FIXME: what status?
-        }
-        /* FIXME: Maybe look for the matching devmode supplied by the
-         *        driver so we can provide driver private/extra data?
-         */
-    }
-    else
-    {
-        BOOL IsCachedDevice = (CachedDevModes != NULL);
-
-        if (CachedDevModes &&
-                ((pDeviceName == NULL && CachedDeviceName.Length > 0) ||
-                 (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length == 0) ||
-                 (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length > 0 && RtlEqualUnicodeString(pDeviceName, &CachedDeviceName, TRUE) == FALSE)))
-        {
-            IsCachedDevice = FALSE;
-        }
-
-        if (iModeNum == 0 || IsCachedDevice == FALSE) /* query modes from drivers */
-        {
-            UNICODE_STRING DriverFileNames;
-            LPWSTR CurrentName;
-            DRVENABLEDATA DrvEnableData;
-
-            /* Free resources from last driver cache */
-            if (IsCachedDevice == FALSE && CachedDeviceName.Buffer != NULL)
-            {
-                RtlFreeUnicodeString(&CachedDeviceName);
-            }
-
-            /* Retrieve DDI driver names from registry */
-            RtlInitUnicodeString(&DriverFileNames, NULL);
-            if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
-            {
-                DPRINT1("FindDriverFileNames failed\n");
-                return STATUS_UNSUCCESSFUL;
-            }
-
-            if (!IntPrepareDriverIfNeeded())
-            {
-                DPRINT1("IntPrepareDriverIfNeeded failed\n");
-                return STATUS_UNSUCCESSFUL;
-            }
-
-            /*
-             * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
-             * scan all of them until a good one found.
-             */
-            CurrentName = DriverFileNames.Buffer;
-            for (;CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR));
-                    CurrentName += wcslen(CurrentName) + 1)
-            {
-                INT i;
-                PFN_DrvEnableDriver GDEnableDriver;
-                PFN_DrvGetModes GetModes = NULL;
-                INT SizeNeeded, SizeUsed;
-
-                /* Get the DDI driver's entry point */
-                //GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
-                GDEnableDriver = DRIVER_FindExistingDDIDriver(L"DISPLAY");
-                if (NULL == GDEnableDriver)
-                {
-                    DPRINT("FindDDIDriver failed for %S\n", CurrentName);
-                    continue;
-                }
-
-                /*  Call DDI driver's EnableDriver function  */
-                RtlZeroMemory(&DrvEnableData, sizeof(DrvEnableData));
-
-                if (!GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof (DrvEnableData), &DrvEnableData))
-                {
-                    DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
-                    continue;
-                }
-
-                CachedDevModesEnd = CachedDevModes;
-
-                /* find DrvGetModes function */
-                for (i = 0; i < DrvEnableData.c; i++)
-                {
-                    PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
-
-                    if (DrvFn->iFunc == INDEX_DrvGetModes)
-                    {
-                        GetModes = (PFN_DrvGetModes)DrvFn->pfn;
-                        break;
-                    }
-                }
-
-                if (GetModes == NULL)
-                {
-                    DPRINT("DrvGetModes doesn't exist for %S\n", CurrentName);
-                    continue;
-                }
-
-                /* make sure we have enough memory to hold the modes */
-                SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL);
-                if (SizeNeeded <= 0)
-                {
-                    DPRINT("DrvGetModes failed for %S\n", CurrentName);
-                    break;
-                }
-
-                SizeUsed = (PCHAR)CachedDevModesEnd - (PCHAR)CachedDevModes;
-                if (SizeOfCachedDevModes < SizeUsed + SizeNeeded)
-                {
-                    PVOID NewBuffer;
-
-                    SizeOfCachedDevModes += SizeNeeded;
-                    NewBuffer = ExAllocatePool(PagedPool, SizeOfCachedDevModes);
-                    if (NewBuffer == NULL)
-                    {
-                        /* clean up */
-                        ExFreePool(CachedDevModes);
-                        CachedDevModes = NULL;
-                        CachedDevModesEnd = NULL;
-                        SizeOfCachedDevModes = 0;
-
-                        if (CachedDeviceName.Buffer != NULL)
-                            RtlFreeUnicodeString(&CachedDeviceName);
-
-                        return STATUS_NO_MEMORY;
-                    }
-                    if (CachedDevModes != NULL)
-                    {
-                        RtlCopyMemory(NewBuffer, CachedDevModes, SizeUsed);
-                        ExFreePool(CachedDevModes);
-                    }
-                    CachedDevModes = NewBuffer;
-                    CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed);
-                }
-
-                if (!IsCachedDevice)
-                {
-                    if (CachedDeviceName.Buffer != NULL)
-                        RtlFreeUnicodeString(&CachedDeviceName);
-
-                    if (pDeviceName)
-                        IntSafeCopyUnicodeString(&CachedDeviceName, pDeviceName);
-
-                    IsCachedDevice = TRUE;
-                }
-
-                /* query modes */
-                SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject),
-                                      SizeNeeded,
-                                      CachedDevModesEnd);
-                if (SizeNeeded <= 0)
-                {
-                    DPRINT("DrvGetModes failed for %S\n", CurrentName);
-                }
-                else
-                {
-                    CachedDevModesEnd = (DEVMODEW *)((PCHAR)CachedDevModesEnd + SizeNeeded);
-                }
-            }
-
-            ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
-        }
-
-        /* return cached info */
-        CachedMode = CachedDevModes;
-        if (CachedMode >= CachedDevModesEnd)
-        {
-            return STATUS_NO_MORE_ENTRIES;
-        }
-        while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd)
-        {
-            assert(CachedMode->dmSize > 0);
-            CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra);
-        }
-        if (CachedMode >= CachedDevModesEnd)
-        {
-            return STATUS_NO_MORE_ENTRIES;
-        }
-    }
-
-    ASSERT(CachedMode != NULL);
-
-    if (pDevMode != NULL)
-    {
-        RtlCopyMemory(pDevMode, CachedMode, min(pDevMode->dmSize, CachedMode->dmSize));
-        RtlZeroMemory(pDevMode + pDevMode->dmSize, pDevMode->dmDriverExtra);
-        RtlCopyMemory(pDevMode + min(pDevMode->dmSize, CachedMode->dmSize), CachedMode + CachedMode->dmSize, min(pDevMode->dmDriverExtra, CachedMode->dmDriverExtra));
-    }
-
-    return STATUS_SUCCESS;
-}
 
 INT
 APIENTRY
@@ -1720,3 +91,4 @@ NtGdiDrawEscape(
     return 0;
 }
 
+
index cc2a16e..f320f61 100644 (file)
@@ -1258,7 +1258,7 @@ NtGdiCreateDIBitmapInternal(
         else
         {
             if (Dc->dctype != DC_TYPE_MEMORY)
-                bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL);
+                bpp = Dc->ppdev->gdiinfo.cBitsPixel;
             else
             {
                 DIBSECTION dibs;
index bdda9c2..cdec1db 100644 (file)
@@ -2226,7 +2226,7 @@ TextIntGetTextExtentPoint(PDC dc,
 
     Size->cx = (TotalWidth + 32) >> 6;
     Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight);
-    Size->cy = EngMulDiv(Size->cy, IntGdiGetDeviceCaps(dc, LOGPIXELSY), 72);
+    Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72);
 
     return TRUE;
 }
@@ -3425,7 +3425,9 @@ GreExtTextOutW(
     /* Create the xlateobj */
     hDestPalette = psurf->hDIBPalette;
     if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
+    //if (!hDestPalette) hDestPalette = StockObjects[DEFAULT_PALETTE];//pPrimarySurface->devinfo.hpalDefault;
     ppalDst = PALETTE_LockPalette(hDestPalette);
+    ASSERT(ppalDst);
     EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0);
     EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0);
     PALETTE_UnlockPalette(ppalDst);
index 8cb32a7..9bba378 100644 (file)
@@ -51,8 +51,9 @@ SynchonizeDriver(FLONG Flags)
       Flags = DSS_TIMER_EVENT;
 
   Device = IntEnumHDev();
-
-  SurfObj = EngLockSurface( Device->pSurface );
+//  UNIMPLEMENTED;
+//ASSERT(FALSE);
+  SurfObj = 0;// EngLockSurface( Device->pSurface );
   if(!SurfObj) return;
   DoDeviceSync( SurfObj, NULL, Flags);
   EngUnlockSurface(SurfObj);
index a9991ad..88d42ff 100644 (file)
@@ -5,10 +5,10 @@ NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN
 
 static int leak_reported = 0;
 #define GDI_STACK_LEVELS 12
-static ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
-static ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
-static ULONG GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
-static ULONG GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+ ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+ ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+ ULONG GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+ ULONG GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
 struct DbgOpenGDIHandle
 {
     ULONG idx;
index 244c41e..8da4b15 100644 (file)
@@ -8,7 +8,7 @@
 
 /** INCLUDES ******************************************************************/
 
-//#define GDI_DEBUG
+#define GDI_DEBUG
 
 #include <w32k.h>
 #define NDEBUG
@@ -761,7 +761,7 @@ GreDeleteObject(HGDIOBJ hObject)
              break;
 
           case GDI_OBJECT_TYPE_DC:
-             DC_FreeDcAttr(hObject);
+//             DC_FreeDcAttr(hObject);
              break;
        }
 
@@ -894,6 +894,8 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
     POBJ Object = NULL;
     ULONG HandleType, HandleUpper;
 
+    GDIDBG_INITLOOPTRACE();
+
     HandleIndex = GDI_HANDLE_GET_INDEX(hObj);
     HandleType = GDI_HANDLE_GET_TYPE(hObj);
     HandleUpper = GDI_HANDLE_GET_UPPER(hObj);
@@ -973,6 +975,11 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
                 {
                     if (Object->Tid != Thread)
                     {
+                        GDIDBG_TRACELOOP(hObj, Object->Tid, Thread);
+                        GDIDBG_TRACECALLER();
+                        GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj));
+                        GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj));
+
                         /* Unlock the handle table entry. */
                         (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
 
@@ -1001,6 +1008,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
             /*
              * The handle is currently locked, wait some time and try again.
              */
+            GDIDBG_TRACELOOP(hObj, PrevProcId, NULL);
 
             DelayExecution();
             continue;
@@ -1651,10 +1659,9 @@ IntGdiSetDCOwnerEx( HDC hDC, DWORD OwnerMask, BOOL NoSetBrush)
   {
      pDC = DC_LockDc ( hDC );
      MmCopyFromCaller(&pDC->dcattr, pDC->pdcattr, sizeof(DC_ATTR));
+     DC_vFreeDcAttr(pDC);
      DC_UnlockDc( pDC );
 
-     DC_FreeDcAttr( hDC );         // Free the dcattr!
-
      if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible!
         return Ret;
   }
index a1e610b..550ccf1 100644 (file)
@@ -150,18 +150,6 @@ EngFindResource(
   return NULL;
 }
 
-/*
- * @unimplemented
- */
-LPWSTR
-APIENTRY
-EngGetDriverName ( IN HDEV hdev )
-{
-  // www.osr.com/ddk/graphics/gdifncs_2gx3.htm
-  UNIMPLEMENTED;
-  return NULL;
-}
-
 /*
  * @unimplemented
  */
index b5658ba..5685e13 100644 (file)
                        </directory>
                </if>
                <file>gradient.c</file>
+               <file>ldevobj.c</file>
                <file>lineto.c</file>
                <file>mapping.c</file>
                <file>mem.c</file>
                <file>engmisc.c</file>
                <file>mouse.c</file>
                <file>paint.c</file>
+               <file>pdevobj.c</file>
                <file>perfcnt.c</file>
                <file>semaphor.c</file>
                <file>sort.c</file>