Revert tree-restructure attempt: r66583, r66582, r66581, r66578, sauf ntdll changes...
[reactos.git] / reactos / win32ss / drivers / displays / vga_new / enable.c
diff --git a/reactos/win32ss/drivers/displays/vga_new/enable.c b/reactos/win32ss/drivers/displays/vga_new/enable.c
new file mode 100644 (file)
index 0000000..cae6b37
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * PROJECT:         ReactOS Framebuffer Display Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/displays/framebuf/enable.c
+ * PURPOSE:         Main Driver Initialization and PDEV Enabling
+ * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
+ *                  ReactOS Portable Systems Group
+ */
+
+#include "driver.h"
+
+// The driver function table with all function index/address pairs
+
+static DRVFN gadrvfn[] =
+{
+    {   INDEX_DrvEnablePDEV,            (PFN) DrvEnablePDEV         },
+    {   INDEX_DrvCompletePDEV,          (PFN) DrvCompletePDEV       },
+    {   INDEX_DrvDisablePDEV,           (PFN) DrvDisablePDEV        },
+    {   INDEX_DrvEnableSurface,         (PFN) DrvEnableSurface      },
+    {   INDEX_DrvDisableSurface,        (PFN) DrvDisableSurface     },
+    {   INDEX_DrvAssertMode,            (PFN) DrvAssertMode         },
+// eVb: 1.2 [VGARISC Change] - Disable hardware palette support
+    {   INDEX_DrvSetPalette,            (PFN) DrvSetPalette         },
+// eVb: 1.2 [END]
+// eVb: 1.1 [VGARISC Change] - Disable hardware pointer support
+#if 0
+    {   INDEX_DrvMovePointer,           (PFN) DrvMovePointer        },
+    {   INDEX_DrvSetPointerShape,       (PFN) DrvSetPointerShape    },
+#endif
+// eVb: 1.1 [END]
+    {   INDEX_DrvGetModes,              (PFN) DrvGetModes           }
+};
+
+// Define the functions you want to hook for 8/16/24/32 pel formats
+
+#define HOOKS_BMF8BPP 0
+
+#define HOOKS_BMF16BPP 0
+
+#define HOOKS_BMF24BPP 0
+
+#define HOOKS_BMF32BPP 0
+
+/******************************Public*Routine******************************\
+* DrvEnableDriver
+*
+* Enables the driver by retrieving the drivers function table and version.
+*
+\**************************************************************************/
+
+BOOL DrvEnableDriver(
+ULONG iEngineVersion,
+ULONG cj,
+PDRVENABLEDATA pded)
+{
+// Engine Version is passed down so future drivers can support previous
+// engine versions.  A next generation driver can support both the old
+// and new engine conventions if told what version of engine it is
+// working with.  For the first version the driver does nothing with it.
+// eVb: 1.1 [DDK Change] - Remove bogus statement
+    //iEngineVersion;
+// eVb: 1.1 [END]
+// Fill in as much as we can.
+
+    if (cj >= sizeof(DRVENABLEDATA))
+        pded->pdrvfn = gadrvfn;
+
+    if (cj >= (sizeof(ULONG) * 2))
+        pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
+
+// DDI version this driver was targeted for is passed back to engine.
+// Future graphic's engine may break calls down to old driver format.
+
+    if (cj >= sizeof(ULONG))
+// eVb: 1.2 [DDK Change] - Use DDI_DRIVER_VERSION_NT4 instead of DDI_DRIVER_VERSION
+        pded->iDriverVersion = DDI_DRIVER_VERSION_NT4;
+// eVb: 1.2 [END]
+
+    return(TRUE);
+}
+
+/******************************Public*Routine******************************\
+* DrvEnablePDEV
+*
+* DDI function, Enables the Physical Device.
+*
+* Return Value: device handle to pdev.
+*
+\**************************************************************************/
+
+DHPDEV DrvEnablePDEV(
+DEVMODEW   *pDevmode,       // Pointer to DEVMODE
+PWSTR       pwszLogAddress, // Logical address
+ULONG       cPatterns,      // number of patterns
+HSURF      *ahsurfPatterns, // return standard patterns
+ULONG       cjGdiInfo,      // Length of memory pointed to by pGdiInfo
+ULONG      *pGdiInfo,       // Pointer to GdiInfo structure
+ULONG       cjDevInfo,      // Length of following PDEVINFO structure
+DEVINFO    *pDevInfo,       // physical device information structure
+HDEV        hdev,           // HDEV, used for callbacks
+PWSTR       pwszDeviceName, // DeviceName - not used
+HANDLE      hDriver)        // Handle to base driver
+{
+    GDIINFO GdiInfo;
+    DEVINFO DevInfo;
+    PPDEV   ppdev = (PPDEV) NULL;
+
+    UNREFERENCED_PARAMETER(pwszLogAddress);
+    UNREFERENCED_PARAMETER(pwszDeviceName);
+
+    // Allocate a physical device structure.
+
+    ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG);
+
+    if (ppdev == (PPDEV) NULL)
+    {
+        RIP("DISP DrvEnablePDEV failed EngAllocMem\n");
+        return((DHPDEV) 0);
+    }
+
+    memset(ppdev, 0, sizeof(PDEV));
+
+    // Save the screen handle in the PDEV.
+
+    ppdev->hDriver = hDriver;
+
+    // Get the current screen mode information.  Set up device caps and devinfo.
+
+    if (!bInitPDEV(ppdev, pDevmode, &GdiInfo, &DevInfo))
+    {
+        DISPDBG((0,"DISP DrvEnablePDEV failed\n"));
+        goto error_free;
+    }
+
+// eVb: 1.2 [VGARISC Change] - Disable hardware pointer support
+#if 0
+    // Initialize the cursor information.
+
+    if (!bInitPointer(ppdev, &DevInfo))
+    {
+        // Not a fatal error...
+        DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
+    }
+
+#endif
+// eVb: 1.2 [END]
+    // Initialize palette information.
+
+    if (!bInitPaletteInfo(ppdev, &DevInfo))
+    {
+        RIP("DrvEnablePDEV failed bInitPalette\n");
+        goto error_free;
+    }
+
+    // Copy the devinfo into the engine buffer.
+
+    memcpy(pDevInfo, &DevInfo, min(sizeof(DEVINFO), cjDevInfo));
+
+    // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
+    // pdev.
+
+    memcpy(pGdiInfo, &GdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
+
+    return((DHPDEV) ppdev);
+
+    // Error case for failure.
+error_free:
+    EngFreeMem(ppdev);
+    return((DHPDEV) 0);
+}
+
+/******************************Public*Routine******************************\
+* DrvCompletePDEV
+*
+* Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
+*
+\**************************************************************************/
+
+VOID DrvCompletePDEV(
+DHPDEV dhpdev,
+HDEV  hdev)
+{
+    ((PPDEV) dhpdev)->hdevEng = hdev;
+}
+
+/******************************Public*Routine******************************\
+* DrvDisablePDEV
+*
+* Release the resources allocated in DrvEnablePDEV.  If a surface has been
+* enabled DrvDisableSurface will have already been called.
+*
+\**************************************************************************/
+
+VOID DrvDisablePDEV(
+DHPDEV dhpdev)
+{
+    vDisablePalette((PPDEV) dhpdev);
+    EngFreeMem(dhpdev);
+}
+
+/******************************Public*Routine******************************\
+* DrvEnableSurface
+*
+* Enable the surface for the device.  Hook the calls this driver supports.
+*
+* Return: Handle to the surface if successful, 0 for failure.
+*
+\**************************************************************************/
+
+HSURF DrvEnableSurface(
+DHPDEV dhpdev)
+{
+    PPDEV ppdev;
+    HSURF hsurf;
+    SIZEL sizl;
+    ULONG ulBitmapType;
+    FLONG flHooks;
+
+    // Create engine bitmap around frame buffer.
+
+    ppdev = (PPDEV) dhpdev;
+
+    if (!bInitSURF(ppdev, TRUE))
+    {
+        RIP("DISP DrvEnableSurface failed bInitSURF\n");
+        return(FALSE);
+    }
+
+    sizl.cx = ppdev->cxScreen;
+    sizl.cy = ppdev->cyScreen;
+
+// eVb: 1.3 [VGARISC Change] - Disable dynamic palette and > 4BPP support
+#if 0
+    if (ppdev->ulBitCount == 8)
+    {
+        if (!bInit256ColorPalette(ppdev)) {
+            RIP("DISP DrvEnableSurface failed to init the 8bpp palette\n");
+            return(FALSE);
+        }
+        ulBitmapType = BMF_8BPP;
+        flHooks = HOOKS_BMF8BPP;
+    }
+    else if (ppdev->ulBitCount == 16)
+    {
+        ulBitmapType = BMF_16BPP;
+        flHooks = HOOKS_BMF16BPP;
+    }
+    else if (ppdev->ulBitCount == 24)
+    {
+        ulBitmapType = BMF_24BPP;
+        flHooks = HOOKS_BMF24BPP;
+    }
+    else
+    {
+        ulBitmapType = BMF_32BPP;
+        flHooks = HOOKS_BMF32BPP;
+    }
+// eVb: 1.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
+    ppdev->flHooks = flHooks;
+// eVb: 1.3 [END]
+#else
+    ulBitmapType = BMF_4BPP;
+#endif
+// eVb: 1.3 [END]
+// eVb: 1.4 [DDK Change] - Use EngCreateDeviceSurface instead of EngCreateBitmap
+    hsurf = (HSURF)EngCreateDeviceSurface((DHSURF)ppdev, 
+                                           sizl,
+                                           ulBitmapType);
+
+    if (hsurf == (HSURF) 0)
+    {
+        RIP("DISP DrvEnableSurface failed EngCreateDeviceSurface\n");
+        return(FALSE);
+    }
+// eVb: 1.4 [END]
+
+// eVb: 1.5 [DDK Change] - Use EngModifySurface instead of EngAssociateSurface
+    if ( !EngModifySurface(hsurf,
+                           ppdev->hdevEng,
+                           ppdev->flHooks | HOOK_SYNCHRONIZE,
+                           MS_NOTSYSTEMMEMORY,
+                           (DHSURF)ppdev,
+                           ppdev->pjScreen,
+                           ppdev->lDeltaScreen,
+                           NULL))
+    {
+        RIP("DISP DrvEnableSurface failed EngModifySurface\n");
+        return(FALSE);
+    }
+// eVb: 1.5 [END]
+    ppdev->hsurfEng = hsurf;
+// eVb: 1.4 [VGARISC Change] - Allocate 4BPP DIB that will store GDI drawing
+    HSURF hSurfBitmap;
+    hSurfBitmap = (HSURF)EngCreateBitmap(sizl, 0, ulBitmapType, 0, NULL);
+    if (hSurfBitmap == (HSURF) 0)
+    {
+        RIP("DISP DrvEnableSurface failed EngCreateBitmap\n");
+        return(FALSE);
+    }
+
+    if ( !EngModifySurface(hSurfBitmap,
+                           ppdev->hdevEng,
+                           ppdev->flHooks | HOOK_SYNCHRONIZE,
+                           MS_NOTSYSTEMMEMORY,
+                           (DHSURF)ppdev,
+                           ppdev->pjScreen,
+                           ppdev->lDeltaScreen,
+                           NULL))
+    {
+        RIP("DISP DrvEnableSurface failed second EngModifySurface\n");
+        return(FALSE);
+    }
+
+    ppdev->pso = EngLockSurface(hSurfBitmap);
+    if (ppdev->pso == NULL)
+    {
+        RIP("DISP DrvEnableSurface failed EngLockSurface\n");
+        return(FALSE);
+    }
+// eVb: 1.4 [END]
+    return(hsurf);
+}
+
+/******************************Public*Routine******************************\
+* DrvDisableSurface
+*
+* Free resources allocated by DrvEnableSurface.  Release the surface.
+*
+\**************************************************************************/
+
+VOID DrvDisableSurface(
+DHPDEV dhpdev)
+{
+    EngDeleteSurface(((PPDEV) dhpdev)->hsurfEng);
+    vDisableSURF((PPDEV) dhpdev);
+    ((PPDEV) dhpdev)->hsurfEng = (HSURF) 0;
+}
+
+/******************************Public*Routine******************************\
+* DrvAssertMode
+*
+* This asks the device to reset itself to the mode of the pdev passed in.
+*
+\**************************************************************************/
+
+BOOL DrvAssertMode(
+DHPDEV dhpdev,
+BOOL bEnable)
+{
+    PPDEV   ppdev = (PPDEV) dhpdev;
+    ULONG   ulReturn;
+    PBYTE   pjScreen;
+
+    if (bEnable)
+    {
+        //
+        // The screen must be reenabled, reinitialize the device to clean state.
+        //
+// eVb: 1.6 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
+        pjScreen = ppdev->pjScreen;
+
+        if (!bInitSURF(ppdev, FALSE))
+        {
+            DISPDBG((0, "DISP DrvAssertMode failed bInitSURF\n"));
+            return (FALSE);
+        }
+
+        if (pjScreen != ppdev->pjScreen) {
+
+            if ( !EngModifySurface(ppdev->hsurfEng,
+                                   ppdev->hdevEng,
+                                   ppdev->flHooks | HOOK_SYNCHRONIZE,
+                                   MS_NOTSYSTEMMEMORY,
+                                   (DHSURF)ppdev,
+                                   ppdev->pjScreen,
+                                   ppdev->lDeltaScreen,
+                                   NULL))
+            {
+                DISPDBG((0, "DISP DrvAssertMode failed EngModifySurface\n"));
+                return (FALSE);
+            }
+        }
+// eVb: 1.6 [END]
+        return (TRUE);
+    }
+    else
+    {
+        //
+        // We must give up the display.
+        // Call the kernel driver to reset the device to a known state.
+        //
+
+        if (EngDeviceIoControl(ppdev->hDriver,
+                               IOCTL_VIDEO_RESET_DEVICE,
+                               NULL,
+                               0,
+                               NULL,
+                               0,
+                               &ulReturn))
+        {
+            RIP("DISP DrvAssertMode failed IOCTL");
+            return FALSE;
+        }
+        else
+        {
+            return TRUE;
+        }
+    }
+}
+
+/******************************Public*Routine******************************\
+* DrvGetModes
+*
+* Returns the list of available modes for the device.
+*
+\**************************************************************************/
+
+ULONG DrvGetModes(
+HANDLE hDriver,
+ULONG cjSize,
+DEVMODEW *pdm)
+
+{
+
+    DWORD cModes;
+    DWORD cbOutputSize;
+    PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
+    DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
+    DWORD cbModeSize;
+
+    DISPDBG((3, "DrvGetModes\n"));
+
+    cModes = getAvailableModes(hDriver,
+                               (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
+                               &cbModeSize);
+
+    if (cModes == 0)
+    {
+        DISPDBG((0, "DrvGetModes failed to get mode information"));
+        return 0;
+    }
+
+    if (pdm == NULL)
+    {
+        cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
+    }
+    else
+    {
+        //
+        // Now copy the information for the supported modes back into the output
+        // buffer
+        //
+
+        cbOutputSize = 0;
+
+        pVideoTemp = pVideoModeInformation;
+
+        do
+        {
+            if (pVideoTemp->Length != 0)
+            {
+                if (cOutputModes == 0)
+                {
+                    break;
+                }
+
+                //
+                // Zero the entire structure to start off with.
+                //
+
+                memset(pdm, 0, sizeof(DEVMODEW));
+
+                //
+                // Set the name of the device to the name of the DLL.
+                //
+
+                memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
+
+                pdm->dmSpecVersion      = DM_SPECVERSION;
+                pdm->dmDriverVersion    = DM_SPECVERSION;
+                pdm->dmSize             = sizeof(DEVMODEW);
+                pdm->dmDriverExtra      = DRIVER_EXTRA_SIZE;
+
+                pdm->dmBitsPerPel       = pVideoTemp->NumberOfPlanes *
+                                          pVideoTemp->BitsPerPlane;
+                pdm->dmPelsWidth        = pVideoTemp->VisScreenWidth;
+                pdm->dmPelsHeight       = pVideoTemp->VisScreenHeight;
+                pdm->dmDisplayFrequency = pVideoTemp->Frequency;
+                pdm->dmDisplayFlags     = 0;
+
+                pdm->dmFields           = DM_BITSPERPEL       |
+                                          DM_PELSWIDTH        |
+                                          DM_PELSHEIGHT       |
+                                          DM_DISPLAYFREQUENCY |
+                                          DM_DISPLAYFLAGS     ;
+
+                //
+                // Go to the next DEVMODE entry in the buffer.
+                //
+
+                cOutputModes--;
+
+                pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) +
+                                                   DRIVER_EXTRA_SIZE);
+
+                cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
+
+            }
+
+            pVideoTemp = (PVIDEO_MODE_INFORMATION)
+                (((PUCHAR)pVideoTemp) + cbModeSize);
+
+        } while (--cModes);
+    }
+
+    EngFreeMem(pVideoModeInformation);
+
+    return cbOutputSize;
+
+}