- New Framebuffer (Linear) Display Driver to support new unified VGA/VBE miniport...
authorevb <evb@svn.reactos.org>
Fri, 5 Mar 2010 17:29:51 +0000 (17:29 +0000)
committerevb <evb@svn.reactos.org>
Fri, 5 Mar 2010 17:29:51 +0000 (17:29 +0000)
- Also used Virtual Box Display Driver as sample, which is based on "GPL" Windows 2003 DDK sample driver. Could not use 2003 DDK sample directly because of licensing issues, and feel unsafe about VirtualBox "GPL" driver that says "PATENTED AND ONLY FOR USE IN MICROSOFT PRODUCTS".
- Note that old driver was based off DDK sample too, but with variables renamed (some comments identical!) and code reformatted, then marked as "GPL". This is not very good way to share/use code... one day someone can teach you lesson.

svn path=/trunk/; revision=45874

reactos/drivers/video/displays/directory.rbuild
reactos/drivers/video/displays/framebuf_new/debug.c [new file with mode: 0755]
reactos/drivers/video/displays/framebuf_new/debug.h [new file with mode: 0755]
reactos/drivers/video/displays/framebuf_new/driver.h [new file with mode: 0755]
reactos/drivers/video/displays/framebuf_new/enable.c [new file with mode: 0644]
reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild [new file with mode: 0644]
reactos/drivers/video/displays/framebuf_new/framebuf_new.rc [new file with mode: 0644]
reactos/drivers/video/displays/framebuf_new/framebuf_new.spec [new file with mode: 0644]
reactos/drivers/video/displays/framebuf_new/palette.c [new file with mode: 0755]
reactos/drivers/video/displays/framebuf_new/pointer.c [new file with mode: 0755]
reactos/drivers/video/displays/framebuf_new/screen.c [new file with mode: 0755]

index eb65085..1680179 100644 (file)
@@ -1,10 +1,7 @@
 <?xml version="1.0"?>
 <!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
 <group xmlns:xi="http://www.w3.org/2001/XInclude">
-       <directory name="framebuf">
-               <xi:include href="framebuf/framebuf.rbuild" />
-       </directory>
-       <directory name="vga">
-               <xi:include href="vga/vgaddi.rbuild" />
+       <directory name="framebuf_new">
+               <xi:include href="framebuf_new/framebuf_new.rbuild" />
        </directory>
 </group>
diff --git a/reactos/drivers/video/displays/framebuf_new/debug.c b/reactos/drivers/video/displays/framebuf_new/debug.c
new file mode 100755 (executable)
index 0000000..ada125d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * PROJECT:         ReactOS Framebuffer Display Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/displays/framebuf/debug.c
+ * PURPOSE:         Debug Support
+ * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
+ */
+
+#include "driver.h"
+
+#if DBG
+
+ULONG DebugLevel = 0xFFFFFFFF;
+
+/*****************************************************************************
+ *
+ *   Routine Description:
+ *
+ *      This function is variable-argument, level-sensitive debug print
+ *      routine.
+ *      If the specified debug level for the print statement is lower or equal
+ *      to the current debug level, the message will be printed.
+ *
+ *   Arguments:
+ *
+ *      DebugPrintLevel - Specifies at which debugging level the string should
+ *          be printed
+ *
+ *      DebugMessage - Variable argument ascii c string
+ *
+ *   Return Value:
+ *
+ *      None.
+ *
+ ***************************************************************************/
+
+VOID
+DebugPrint(
+    ULONG DebugPrintLevel,
+    PCHAR DebugMessage,
+    ...
+    )
+
+{
+
+    va_list ap;
+
+    va_start(ap, DebugMessage);
+
+    if (DebugPrintLevel <= DebugLevel)
+    {
+        EngDebugPrint(STANDARD_DEBUG_PREFIX, DebugMessage, ap);
+    }
+
+    va_end(ap);
+
+}
+
+#endif
diff --git a/reactos/drivers/video/displays/framebuf_new/debug.h b/reactos/drivers/video/displays/framebuf_new/debug.h
new file mode 100755 (executable)
index 0000000..d73a223
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * PROJECT:         ReactOS Framebuffer Display Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/displays/framebuf/debug.h
+ * PURPOSE:         Debug Support Header
+ * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
+ */
+
+#if DBG
+
+VOID
+DebugPrint(
+    ULONG DebugPrintLevel,
+    PCHAR DebugMessage,
+    ...
+    );
+
+#define DISPDBG(arg) DebugPrint arg
+#define RIP(x) { DebugPrint(0, x); EngDebugBreak();}
+
+#else
+
+#define DISPDBG(arg)
+#define RIP(x)
+
+#endif
diff --git a/reactos/drivers/video/displays/framebuf_new/driver.h b/reactos/drivers/video/displays/framebuf_new/driver.h
new file mode 100755 (executable)
index 0000000..77306ca
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * PROJECT:         ReactOS Framebuffer Display Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/displays/framebuf/driver.h
+ * PURPOSE:         Main Driver Header File
+ * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
+ *                  ReactOS Portable Systems Group
+ */
+#define DBG 1
+#include "stddef.h"
+#include <stdarg.h>
+#include "windef.h"
+#include "wingdi.h"
+#include "winddi.h"
+#include "devioctl.h"
+#include "ntddvdeo.h"
+#include "debug.h"
+
+typedef struct  _PDEV
+{
+    HANDLE  hDriver;                    // Handle to \Device\Screen
+    HDEV    hdevEng;                    // Engine's handle to PDEV
+    HSURF   hsurfEng;                   // Engine's handle to surface
+    HPALETTE hpalDefault;               // Handle to the default palette for device.
+    PBYTE   pjScreen;                   // This is pointer to base screen address
+    ULONG   cxScreen;                   // Visible screen width
+    ULONG   cyScreen;                   // Visible screen height
+    ULONG   ulMode;                     // Mode the mini-port driver is in.
+    LONG    lDeltaScreen;               // Distance from one scan to the next.
+    ULONG   cScreenSize;                // size of video memory, including
+                                        // offscreen memory.
+    PVOID   pOffscreenList;             // linked list of DCI offscreen surfaces.
+    FLONG   flRed;                      // For bitfields device, Red Mask
+    FLONG   flGreen;                    // For bitfields device, Green Mask
+    FLONG   flBlue;                     // For bitfields device, Blue Mask
+    ULONG   cPaletteShift;              // number of bits the 8-8-8 palette must
+                                        // be shifted by to fit in the hardware
+                                        // palette.
+    ULONG   ulBitCount;                 // # of bits per pel 8,16,24,32 are only supported.
+    POINTL  ptlHotSpot;                 // adjustment for pointer hot spot
+    VIDEO_POINTER_CAPABILITIES PointerCapabilities; // HW pointer abilities
+    PVIDEO_POINTER_ATTRIBUTES pPointerAttributes; // hardware pointer attributes
+    DWORD   cjPointerAttributes;        // Size of buffer allocated
+    BOOL    fHwCursorActive;            // Are we currently using the hw cursor
+    PALETTEENTRY *pPal;                 // If this is pal managed, this is the pal
+    BOOL    bSupportDCI;                // Does the miniport support DCI?
+// eVb: 3.1 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
+    LONG flHooks;
+// eVb: 3.1 [END]
+} PDEV, *PPDEV;
+
+DWORD getAvailableModes(HANDLE, PVIDEO_MODE_INFORMATION *, DWORD *);
+BOOL bInitPDEV(PPDEV, PDEVMODEW, GDIINFO *, DEVINFO *);
+BOOL bInitSURF(PPDEV, BOOL);
+BOOL bInitPaletteInfo(PPDEV, DEVINFO *);
+BOOL bInitPointer(PPDEV, DEVINFO *);
+BOOL bInit256ColorPalette(PPDEV);
+VOID vDisablePalette(PPDEV);
+VOID vDisableSURF(PPDEV);
+
+#define MAX_CLUT_SIZE (sizeof(VIDEO_CLUT) + (sizeof(ULONG) * 256))
+
+//
+// Determines the size of the DriverExtra information in the DEVMODE
+// structure passed to and from the display driver.
+//
+
+#define DRIVER_EXTRA_SIZE 0
+
+#define DLL_NAME                L"framebuf"   // Name of the DLL in UNICODE
+#define STANDARD_DEBUG_PREFIX   "FRAMEBUF: "  // All debug output is prefixed
+#define ALLOC_TAG               'bfDD'        // Four byte tag (characters in
+                                              // reverse order) used for memory
+                                              // allocations
diff --git a/reactos/drivers/video/displays/framebuf_new/enable.c b/reactos/drivers/video/displays/framebuf_new/enable.c
new file mode 100644 (file)
index 0000000..8031da8
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * 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         },
+    {   INDEX_DrvSetPalette,            (PFN) DrvSetPalette         },
+    {   INDEX_DrvMovePointer,           (PFN) DrvMovePointer        },
+    {   INDEX_DrvSetPointerShape,       (PFN) DrvSetPointerShape    },
+    {   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;
+    }
+
+    // Initialize the cursor information.
+
+    if (!bInitPointer(ppdev, &DevInfo))
+    {
+        // Not a fatal error...
+        DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
+    }
+
+    // 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;
+
+    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]
+// 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;
+
+    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;
+
+}
diff --git a/reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild b/reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild
new file mode 100644 (file)
index 0000000..c334ac9
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
+<module name="framebuf_new" type="kernelmodedll" entrypoint="DrvEnableDriver@12" installbase="system32" installname="framebuf_new.dll" crt="libcntpr">
+       <importlibrary definition="framebuf_new.spec" />
+       <include base="framebuf_new">.</include>
+       <library>win32k</library>
+       <file>debug.c</file>
+       <file>enable.c</file>
+       <file>palette.c</file>
+       <file>pointer.c</file>
+       <file>screen.c</file>
+       <file>framebuf_new.rc</file>
+       <group compilerset="gcc">
+        <compilerflag>-mrtd</compilerflag>
+        <compilerflag>-fno-builtin</compilerflag>
+               <compilerflag>-Wno-unused-variable</compilerflag>
+       </group>
+</module>
diff --git a/reactos/drivers/video/displays/framebuf_new/framebuf_new.rc b/reactos/drivers/video/displays/framebuf_new/framebuf_new.rc
new file mode 100644 (file)
index 0000000..98ba262
--- /dev/null
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION   "Framebuffer Display Driver\0"
+#define REACTOS_STR_INTERNAL_NAME          "framebuf\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "framebuf.dll\0"
+#include <reactos/version.rc>
diff --git a/reactos/drivers/video/displays/framebuf_new/framebuf_new.spec b/reactos/drivers/video/displays/framebuf_new/framebuf_new.spec
new file mode 100644 (file)
index 0000000..aec115e
--- /dev/null
@@ -0,0 +1 @@
+@ stdcall DrvEnableDriver(long long ptr)
diff --git a/reactos/drivers/video/displays/framebuf_new/palette.c b/reactos/drivers/video/displays/framebuf_new/palette.c
new file mode 100755 (executable)
index 0000000..c8cff99
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * PROJECT:         ReactOS Framebuffer Display Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/displays/framebuf/palette.c
+ * PURPOSE:         Palette Support
+ * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
+ */
+
+#include "driver.h"
+
+// Global Table defining the 20 Window Default Colors.        For 256 color
+// palettes the first 10 must be put at the beginning of the palette
+// and the last 10 at the end of the palette.
+
+const PALETTEENTRY BASEPALETTE[20] =
+{
+    { 0,   0,   0,   0 },       // 0
+    { 0x80,0,   0,   0 },       // 1
+    { 0,   0x80,0,   0 },       // 2
+    { 0x80,0x80,0,   0 },       // 3
+    { 0,   0,   0x80,0 },       // 4
+    { 0x80,0,   0x80,0 },       // 5
+    { 0,   0x80,0x80,0 },       // 6
+    { 0xC0,0xC0,0xC0,0 },       // 7
+    { 192, 220, 192, 0 },       // 8
+    { 166, 202, 240, 0 },       // 9
+    { 255, 251, 240, 0 },       // 10
+    { 160, 160, 164, 0 },       // 11
+    { 0x80,0x80,0x80,0 },       // 12
+    { 0xFF,0,   0   ,0 },       // 13
+    { 0,   0xFF,0   ,0 },       // 14
+    { 0xFF,0xFF,0   ,0 },       // 15
+    { 0   ,0,   0xFF,0 },       // 16
+    { 0xFF,0,   0xFF,0 },       // 17
+    { 0,   0xFF,0xFF,0 },       // 18
+    { 0xFF,0xFF,0xFF,0 },       // 19
+};
+
+BOOL bInitDefaultPalette(PPDEV ppdev, DEVINFO *pDevInfo);
+
+/******************************Public*Routine******************************\
+* bInitPaletteInfo
+*
+* Initializes the palette information for this PDEV.
+*
+* Called by DrvEnablePDEV.
+*
+\**************************************************************************/
+
+BOOL bInitPaletteInfo(PPDEV ppdev, DEVINFO *pDevInfo)
+{
+    if (!bInitDefaultPalette(ppdev, pDevInfo))
+        return(FALSE);
+
+    return(TRUE);
+}
+
+/******************************Public*Routine******************************\
+* vDisablePalette
+*
+* Frees resources allocated by bInitPaletteInfo.
+*
+\**************************************************************************/
+
+VOID vDisablePalette(PPDEV ppdev)
+{
+// Delete the default palette if we created one.
+
+    if (ppdev->hpalDefault)
+    {
+        EngDeletePalette(ppdev->hpalDefault);
+        ppdev->hpalDefault = (HPALETTE) 0;
+    }
+
+    if (ppdev->pPal != (PPALETTEENTRY)NULL)
+        EngFreeMem((PVOID)ppdev->pPal);
+}
+
+/******************************Public*Routine******************************\
+* bInitDefaultPalette
+*
+* Initializes default palette for PDEV.
+*
+\**************************************************************************/
+
+BOOL bInitDefaultPalette(PPDEV ppdev, DEVINFO *pDevInfo)
+{
+    if (ppdev->ulBitCount == 8)
+    {
+        ULONG ulLoop;
+        BYTE jRed,jGre,jBlu;
+
+        //
+        // Allocate our palette
+        //
+
+        ppdev->pPal = (PPALETTEENTRY)EngAllocMem(0, sizeof(PALETTEENTRY) * 256,
+                                                 ALLOC_TAG);
+
+        if ((ppdev->pPal) == NULL) {
+            RIP("DISP bInitDefaultPalette() failed EngAllocMem\n");
+            return(FALSE);
+        }
+
+        //
+        // Generate 256 (8*4*4) RGB combinations to fill the palette
+        //
+
+        jRed = jGre = jBlu = 0;
+
+        for (ulLoop = 0; ulLoop < 256; ulLoop++)
+        {
+            ppdev->pPal[ulLoop].peRed   = jRed;
+            ppdev->pPal[ulLoop].peGreen = jGre;
+            ppdev->pPal[ulLoop].peBlue  = jBlu;
+            ppdev->pPal[ulLoop].peFlags = (BYTE)0;
+
+            if (!(jRed += 32))
+            if (!(jGre += 32))
+            jBlu += 64;
+        }
+
+        //
+        // Fill in Windows Reserved Colors from the WIN 3.0 DDK
+        // The Window Manager reserved the first and last 10 colors for
+        // painting windows borders and for non-palette managed applications.
+        //
+
+        for (ulLoop = 0; ulLoop < 10; ulLoop++)
+        {
+            //
+            // First 10
+            //
+
+            ppdev->pPal[ulLoop] = BASEPALETTE[ulLoop];
+
+            //
+            // Last 10
+            //
+
+            ppdev->pPal[246 + ulLoop] = BASEPALETTE[ulLoop+10];
+        }
+
+        //
+        // Create handle for palette.
+        //
+
+        ppdev->hpalDefault =
+        pDevInfo->hpalDefault = EngCreatePalette(PAL_INDEXED,
+                                                   256,
+                                                   (PULONG) ppdev->pPal,
+                                                   0,0,0);
+
+        if (ppdev->hpalDefault == (HPALETTE) 0)
+        {
+            RIP("DISP bInitDefaultPalette failed EngCreatePalette\n");
+            EngFreeMem(ppdev->pPal);
+            return(FALSE);
+        }
+
+        //
+        // Initialize the hardware with the initial palette.
+        //
+
+        return(TRUE);
+
+    } else {
+
+        ppdev->hpalDefault =
+        pDevInfo->hpalDefault = EngCreatePalette(PAL_BITFIELDS,
+                                                   0,(PULONG) NULL,
+                                                   ppdev->flRed,
+                                                   ppdev->flGreen,
+                                                   ppdev->flBlue);
+
+        if (ppdev->hpalDefault == (HPALETTE) 0)
+        {
+            RIP("DISP bInitDefaultPalette failed EngCreatePalette\n");
+            return(FALSE);
+        }
+    }
+
+    return(TRUE);
+}
+
+/******************************Public*Routine******************************\
+* bInit256ColorPalette
+*
+* Initialize the hardware's palette registers.
+*
+\**************************************************************************/
+
+BOOL bInit256ColorPalette(PPDEV ppdev)
+{
+    BYTE        ajClutSpace[MAX_CLUT_SIZE];
+    PVIDEO_CLUT pScreenClut;
+    ULONG       ulReturnedDataLength;
+    ULONG       cColors;
+    PVIDEO_CLUTDATA pScreenClutData;
+
+    if (ppdev->ulBitCount == 8)
+    {
+        //
+        // Fill in pScreenClut header info:
+        //
+
+        pScreenClut             = (PVIDEO_CLUT) ajClutSpace;
+        pScreenClut->NumEntries = 256;
+        pScreenClut->FirstEntry = 0;
+
+        //
+        // Copy colours in:
+        //
+
+        cColors = 256;
+        pScreenClutData = (PVIDEO_CLUTDATA) (&(pScreenClut->LookupTable[0]));
+
+        while(cColors--)
+        {
+            pScreenClutData[cColors].Red =    ppdev->pPal[cColors].peRed >>
+                                              ppdev->cPaletteShift;
+            pScreenClutData[cColors].Green =  ppdev->pPal[cColors].peGreen >>
+                                              ppdev->cPaletteShift;
+            pScreenClutData[cColors].Blue =   ppdev->pPal[cColors].peBlue >>
+                                              ppdev->cPaletteShift;
+            pScreenClutData[cColors].Unused = 0;
+        }
+
+        //
+        // Set palette registers:
+        //
+
+        if (EngDeviceIoControl(ppdev->hDriver,
+                               IOCTL_VIDEO_SET_COLOR_REGISTERS,
+                               pScreenClut,
+                               MAX_CLUT_SIZE,
+                               NULL,
+                               0,
+                               &ulReturnedDataLength))
+        {
+            DISPDBG((0, "Failed bEnablePalette"));
+            return(FALSE);
+        }
+    }
+
+    DISPDBG((5, "Passed bEnablePalette"));
+
+    return(TRUE);
+}
+
+/******************************Public*Routine******************************\
+* DrvSetPalette
+*
+* DDI entry point for manipulating the palette.
+*
+\**************************************************************************/
+
+BOOL DrvSetPalette(
+DHPDEV  dhpdev,
+PALOBJ* ppalo,
+FLONG   fl,
+ULONG   iStart,
+ULONG   cColors)
+{
+    BYTE            ajClutSpace[MAX_CLUT_SIZE];
+    PVIDEO_CLUT     pScreenClut;
+    PVIDEO_CLUTDATA pScreenClutData;
+    PDEV*           ppdev;
+
+    UNREFERENCED_PARAMETER(fl);
+
+    ppdev = (PDEV*) dhpdev;
+
+    //
+    // Fill in pScreenClut header info:
+    //
+
+    pScreenClut             = (PVIDEO_CLUT) ajClutSpace;
+    pScreenClut->NumEntries = (USHORT) cColors;
+    pScreenClut->FirstEntry = (USHORT) iStart;
+
+    pScreenClutData = (PVIDEO_CLUTDATA) (&(pScreenClut->LookupTable[0]));
+
+    if (cColors != PALOBJ_cGetColors(ppalo, iStart, cColors,
+                                     (ULONG*) pScreenClutData))
+    {
+        DISPDBG((0, "DrvSetPalette failed PALOBJ_cGetColors\n"));
+        return (FALSE);
+    }
+
+    //
+    // Set the high reserved byte in each palette entry to 0.
+    // Do the appropriate palette shifting to fit in the DAC.
+    //
+
+    if (ppdev->cPaletteShift)
+    {
+        while(cColors--)
+        {
+            pScreenClutData[cColors].Red >>= ppdev->cPaletteShift;
+            pScreenClutData[cColors].Green >>= ppdev->cPaletteShift;
+            pScreenClutData[cColors].Blue >>= ppdev->cPaletteShift;
+            pScreenClutData[cColors].Unused = 0;
+        }
+    }
+    else
+    {
+        while(cColors--)
+        {
+            pScreenClutData[cColors].Unused = 0;
+        }
+    }
+
+    //
+    // Set palette registers
+    //
+
+    if (EngDeviceIoControl(ppdev->hDriver,
+                           IOCTL_VIDEO_SET_COLOR_REGISTERS,
+                           pScreenClut,
+                           MAX_CLUT_SIZE,
+                           NULL,
+                           0,
+                           &cColors))
+    {
+        DISPDBG((0, "DrvSetPalette failed EngDeviceIoControl\n"));
+        return (FALSE);
+    }
+
+    return(TRUE);
+
+}
diff --git a/reactos/drivers/video/displays/framebuf_new/pointer.c b/reactos/drivers/video/displays/framebuf_new/pointer.c
new file mode 100755 (executable)
index 0000000..d3752a2
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * PROJECT:         ReactOS Framebuffer Display Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/displays/framebuf/pointer.c
+ * PURPOSE:         Hardware Pointer Support
+ * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
+ */
+
+#include "driver.h"
+
+BOOL bCopyColorPointer(
+PPDEV ppdev,
+SURFOBJ *psoMask,
+SURFOBJ *psoColor,
+XLATEOBJ *pxlo);
+
+BOOL bCopyMonoPointer(
+PPDEV ppdev,
+SURFOBJ *psoMask);
+
+BOOL bSetHardwarePointerShape(
+SURFOBJ  *pso,
+SURFOBJ  *psoMask,
+SURFOBJ  *psoColor,
+XLATEOBJ *pxlo,
+LONG      x,
+LONG      y,
+FLONG     fl);
+
+/******************************Public*Routine******************************\
+* DrvMovePointer
+*
+* Moves the hardware pointer to a new position.
+*
+\**************************************************************************/
+
+VOID DrvMovePointer
+(
+    SURFOBJ *pso,
+    LONG     x,
+    LONG     y,
+    RECTL   *prcl
+)
+{
+    PPDEV ppdev = (PPDEV) pso->dhpdev;
+    DWORD returnedDataLength;
+    VIDEO_POINTER_POSITION NewPointerPosition;
+
+    // We don't use the exclusion rectangle because we only support
+    // hardware Pointers. If we were doing our own Pointer simulations
+    // we would want to update prcl so that the engine would call us
+    // to exclude out pointer before drawing to the pixels in prcl.
+
+    UNREFERENCED_PARAMETER(prcl);
+
+    if (x == -1)
+    {
+        //
+        // A new position of (-1,-1) means hide the pointer.
+        //
+
+        if (EngDeviceIoControl(ppdev->hDriver,
+                               IOCTL_VIDEO_DISABLE_POINTER,
+                               NULL,
+                               0,
+                               NULL,
+                               0,
+                               &returnedDataLength))
+        {
+            //
+            // Not the end of the world, print warning in checked build.
+            //
+
+            DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_DISABLE_POINTER\n"));
+        }
+    }
+    else
+    {
+        NewPointerPosition.Column = (SHORT) x - (SHORT) (ppdev->ptlHotSpot.x);
+        NewPointerPosition.Row    = (SHORT) y - (SHORT) (ppdev->ptlHotSpot.y);
+
+        //
+        // Call miniport driver to move Pointer.
+        //
+
+        if (EngDeviceIoControl(ppdev->hDriver,
+                               IOCTL_VIDEO_SET_POINTER_POSITION,
+                               &NewPointerPosition,
+                               sizeof(VIDEO_POINTER_POSITION),
+                               NULL,
+                               0,
+                               &returnedDataLength))
+        {
+            //
+            // Not the end of the world, print warning in checked build.
+            //
+
+            DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_SET_POINTER_POSITION\n"));
+        }
+    }
+}
+
+/******************************Public*Routine******************************\
+* DrvSetPointerShape
+*
+* Sets the new pointer shape.
+*
+\**************************************************************************/
+
+ULONG DrvSetPointerShape
+(
+    SURFOBJ  *pso,
+    SURFOBJ  *psoMask,
+    SURFOBJ  *psoColor,
+    XLATEOBJ *pxlo,
+    LONG      xHot,
+    LONG      yHot,
+    LONG      x,
+    LONG      y,
+    RECTL    *prcl,
+    FLONG     fl
+)
+{
+    PPDEV   ppdev = (PPDEV) pso->dhpdev;
+    DWORD   returnedDataLength;
+
+    // We don't use the exclusion rectangle because we only support
+    // hardware Pointers. If we were doing our own Pointer simulations
+    // we would want to update prcl so that the engine would call us
+    // to exclude out pointer before drawing to the pixels in prcl.
+    UNREFERENCED_PARAMETER(prcl);
+
+    if (ppdev->pPointerAttributes == (PVIDEO_POINTER_ATTRIBUTES) NULL)
+    {
+        // Mini-port has no hardware Pointer support.
+        return(SPS_ERROR);
+    }
+
+    // See if we are being asked to hide the pointer
+
+    if (psoMask == (SURFOBJ *) NULL)
+    {
+        if (EngDeviceIoControl(ppdev->hDriver,
+                               IOCTL_VIDEO_DISABLE_POINTER,
+                               NULL,
+                               0,
+                               NULL,
+                               0,
+                               &returnedDataLength))
+        {
+            //
+            // It should never be possible to fail.
+            // Message supplied for debugging.
+            //
+
+            DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n"));
+        }
+
+        return(TRUE);
+    }
+
+    ppdev->ptlHotSpot.x = xHot;
+    ppdev->ptlHotSpot.y = yHot;
+
+    if (!bSetHardwarePointerShape(pso,psoMask,psoColor,pxlo,x,y,fl))
+    {
+            if (ppdev->fHwCursorActive) {
+                ppdev->fHwCursorActive = FALSE;
+
+                if (EngDeviceIoControl(ppdev->hDriver,
+                                       IOCTL_VIDEO_DISABLE_POINTER,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       0,
+                                       &returnedDataLength)) {
+
+                    DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n"));
+                }
+            }
+
+            //
+            // Mini-port declines to realize this Pointer
+            //
+
+            return(SPS_DECLINE);
+    }
+    else
+    {
+        ppdev->fHwCursorActive = TRUE;
+    }
+
+    return(SPS_ACCEPT_NOEXCLUDE);
+}
+
+/******************************Public*Routine******************************\
+* bSetHardwarePointerShape
+*
+* Changes the shape of the Hardware Pointer.
+*
+* Returns: True if successful, False if Pointer shape can't be hardware.
+*
+\**************************************************************************/
+
+BOOL bSetHardwarePointerShape(
+SURFOBJ  *pso,
+SURFOBJ  *psoMask,
+SURFOBJ  *psoColor,
+XLATEOBJ *pxlo,
+LONG      x,
+LONG      y,
+FLONG     fl)
+{
+    PPDEV     ppdev = (PPDEV) pso->dhpdev;
+    PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
+    DWORD     returnedDataLength;
+
+    if (psoColor != (SURFOBJ *) NULL)
+    {
+        if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER) &&
+                bCopyColorPointer(ppdev, psoMask, psoColor, pxlo))
+        {
+            pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER;
+        } else {
+            return(FALSE);
+        }
+
+    } else {
+
+        if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER) &&
+                bCopyMonoPointer(ppdev, psoMask))
+        {
+            pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER;
+        } else {
+            return(FALSE);
+        }
+    }
+
+    //
+    // Initialize Pointer attributes and position
+    //
+
+    pPointerAttributes->Enable = 1;
+
+    //
+    // if x,y = -1,-1 then pass them directly to the miniport so that
+    // the cursor will be disabled
+
+    pPointerAttributes->Column = (SHORT)(x);
+    pPointerAttributes->Row    = (SHORT)(y);
+
+    if ((x != -1) || (y != -1)) {
+        pPointerAttributes->Column -= (SHORT)(ppdev->ptlHotSpot.x);
+        pPointerAttributes->Row    -= (SHORT)(ppdev->ptlHotSpot.y);
+    }
+
+    //
+    // set animate flags
+    //
+
+    if (fl & SPS_ANIMATESTART) {
+        pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START;
+    } else if (fl & SPS_ANIMATEUPDATE) {
+        pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE;
+    }
+
+    //
+    // Set the new Pointer shape.
+    //
+
+    if (EngDeviceIoControl(ppdev->hDriver,
+                           IOCTL_VIDEO_SET_POINTER_ATTR,
+                           pPointerAttributes,
+                           ppdev->cjPointerAttributes,
+                           NULL,
+                           0,
+                           &returnedDataLength)) {
+
+        DISPDBG((1, "DISP:Failed IOCTL_VIDEO_SET_POINTER_ATTR call\n"));
+        return(FALSE);
+    }
+
+    return(TRUE);
+}
+
+/******************************Public*Routine******************************\
+* bCopyMonoPointer
+*
+* Copies two monochrome masks into a buffer of the maximum size handled by the
+* miniport, with any extra bits set to 0.  The masks are converted to topdown
+* form if they aren't already.  Returns TRUE if we can handle this pointer in
+* hardware, FALSE if not.
+*
+\**************************************************************************/
+
+BOOL bCopyMonoPointer(
+    PPDEV    ppdev,
+    SURFOBJ *pso)
+{
+    ULONG cy;
+    PBYTE pjSrcAnd, pjSrcXor;
+    LONG  lDeltaSrc, lDeltaDst;
+    LONG  lSrcWidthInBytes;
+    ULONG cxSrc = pso->sizlBitmap.cx;
+    ULONG cySrc = pso->sizlBitmap.cy;
+    ULONG cxSrcBytes;
+    PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
+    PBYTE pjDstAnd = pPointerAttributes->Pixels;
+    PBYTE pjDstXor = pPointerAttributes->Pixels;
+
+    // Make sure the new pointer isn't too big to handle
+    // (*2 because both masks are in there)
+    if ((cxSrc > ppdev->PointerCapabilities.MaxWidth) ||
+        (cySrc > (ppdev->PointerCapabilities.MaxHeight * 2)))
+    {
+        return(FALSE);
+    }
+
+    pjDstXor += ((ppdev->PointerCapabilities.MaxWidth + 7) / 8) *
+            ppdev->pPointerAttributes->Height;
+
+    // set the desk and mask to 0xff
+    RtlFillMemory(pjDstAnd, ppdev->pPointerAttributes->WidthInBytes *
+            ppdev->pPointerAttributes->Height, 0xFF);
+
+    // Zero the dest XOR mask
+    RtlZeroMemory(pjDstXor, ppdev->pPointerAttributes->WidthInBytes *
+            ppdev->pPointerAttributes->Height);
+
+    cxSrcBytes = (cxSrc + 7) / 8;
+
+    if ((lDeltaSrc = pso->lDelta) < 0)
+    {
+        lSrcWidthInBytes = -lDeltaSrc;
+    } else {
+        lSrcWidthInBytes = lDeltaSrc;
+    }
+
+    pjSrcAnd = (PBYTE) pso->pvBits;
+
+    // If the incoming pointer bitmap is bottomup, we'll flip it to topdown to
+    // save the miniport some work
+    if (!(pso->fjBitmap & BMF_TOPDOWN))
+    {
+        // Copy from the bottom
+        pjSrcAnd += lSrcWidthInBytes * (cySrc - 1);
+    }
+
+    // Height of just AND mask
+    cySrc = cySrc / 2;
+
+    // Point to XOR mask
+    pjSrcXor = pjSrcAnd + (cySrc * lDeltaSrc);
+
+    // Offset from end of one dest scan to start of next
+    lDeltaDst = ppdev->pPointerAttributes->WidthInBytes;
+
+    for (cy = 0; cy < cySrc; ++cy)
+    {
+        RtlCopyMemory(pjDstAnd, pjSrcAnd, cxSrcBytes);
+        RtlCopyMemory(pjDstXor, pjSrcXor, cxSrcBytes);
+
+        // Point to next source and dest scans
+        pjSrcAnd += lDeltaSrc;
+        pjSrcXor += lDeltaSrc;
+        pjDstAnd += lDeltaDst;
+        pjDstXor += lDeltaDst;
+    }
+
+    return(TRUE);
+}
+
+/******************************Public*Routine******************************\
+* bCopyColorPointer
+*
+* Copies the mono and color masks into the buffer of maximum size
+* handled by the miniport with any extra bits set to 0. Color translation
+* is handled at this time. The masks are converted to topdown form if they
+* aren't already.  Returns TRUE if we can handle this pointer in  hardware,
+* FALSE if not.
+*
+\**************************************************************************/
+BOOL bCopyColorPointer(
+PPDEV ppdev,
+SURFOBJ *psoMask,
+SURFOBJ *psoColor,
+XLATEOBJ *pxlo)
+{
+    return(FALSE);
+}
+
+
+/******************************Public*Routine******************************\
+* bInitPointer
+*
+* Initialize the Pointer attributes.
+*
+\**************************************************************************/
+
+BOOL bInitPointer(PPDEV ppdev, DEVINFO *pdevinfo)
+{
+    DWORD    returnedDataLength;
+
+    ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL;
+    ppdev->cjPointerAttributes = 0; // initialized in screen.c
+
+    //
+    // Ask the miniport whether it provides pointer support.
+    //
+
+    if (EngDeviceIoControl(ppdev->hDriver,
+                           IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES,
+                           &ppdev->ulMode,
+                           sizeof(PVIDEO_MODE),
+                           &ppdev->PointerCapabilities,
+                           sizeof(ppdev->PointerCapabilities),
+                           &returnedDataLength))
+    {
+         return(FALSE);
+    }
+
+    //
+    // If neither mono nor color hardware pointer is supported, there's no
+    // hardware pointer support and we're done.
+    //
+
+    if ((!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER)) &&
+        (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER)))
+    {
+        return(TRUE);
+    }
+
+    //
+    // Note: The buffer itself is allocated after we set the
+    // mode. At that time we know the pixel depth and we can
+    // allocate the correct size for the color pointer if supported.
+    //
+
+    //
+    // Set the asynchronous support status (async means miniport is capable of
+    // drawing the Pointer at any time, with no interference with any ongoing
+    // drawing operation)
+    //
+
+    if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_ASYNC_POINTER)
+    {
+       pdevinfo->flGraphicsCaps |= GCAPS_ASYNCMOVE;
+    }
+    else
+    {
+       pdevinfo->flGraphicsCaps &= ~GCAPS_ASYNCMOVE;
+    }
+
+    return(TRUE);
+}
diff --git a/reactos/drivers/video/displays/framebuf_new/screen.c b/reactos/drivers/video/displays/framebuf_new/screen.c
new file mode 100755 (executable)
index 0000000..1973c58
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+ * PROJECT:         ReactOS Framebuffer Display Driver
+ * LICENSE:         Microsoft NT4 DDK Sample Code License
+ * FILE:            boot/drivers/video/displays/framebuf/screen.c
+ * PURPOSE:         Surface, Screen and PDEV support/initialization
+ * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
+ *                  ReactOS Portable Systems Group
+ */
+#include "driver.h"
+
+#define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | FF_DONTCARE,L"System"}
+#define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | FF_DONTCARE,L"MS Sans Serif"}
+#define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_DONTCARE, L"Courier"}
+
+// This is the basic devinfo for a default driver.  This is used as a base and customized based
+// on information passed back from the miniport driver.
+
+const DEVINFO gDevInfoFrameBuffer = {
+    ( GCAPS_OPAQUERECT
+    | GCAPS_MONO_DITHER
+                   ), /* Graphics capabilities         */
+    SYSTM_LOGFONT,    /* Default font description */
+    HELVE_LOGFONT,    /* ANSI variable font description   */
+    COURI_LOGFONT,    /* ANSI fixed font description          */
+    0,                /* Count of device fonts          */
+    0,                /* Preferred DIB format          */
+    8,                /* Width of color dither          */
+    8,                /* Height of color dither   */
+    0                 /* Default palette to use for this device */
+};
+
+/******************************Public*Routine******************************\
+* bInitSURF
+*
+* Enables the surface.        Maps the frame buffer into memory.
+*
+\**************************************************************************/
+
+BOOL bInitSURF(PPDEV ppdev, BOOL bFirst)
+{
+    DWORD returnedDataLength;
+    DWORD MaxWidth, MaxHeight;
+    VIDEO_MEMORY videoMemory;
+    VIDEO_MEMORY_INFORMATION videoMemoryInformation;
+// eVb: 2.1 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
+    ULONG RemappingNeeded = 0;  
+// eVb: 2.1 [END]
+    //
+    // Set the current mode into the hardware.
+    //
+
+    if (EngDeviceIoControl(ppdev->hDriver,
+                           IOCTL_VIDEO_SET_CURRENT_MODE,
+                           &(ppdev->ulMode),
+                           sizeof(ULONG),
+// eVb: 2.2 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
+                           &RemappingNeeded,
+                           sizeof(ULONG),
+// eVb: 2.2 [END]
+                           &returnedDataLength))
+    {
+        RIP("DISP bInitSURF failed IOCTL_SET_MODE\n");
+        return(FALSE);
+    }
+
+    //
+    // If this is the first time we enable the surface we need to map in the
+    // memory also.
+    //
+// eVb: 2.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
+    if (bFirst || RemappingNeeded)
+    {
+// eVb: 2.3 [END]
+        videoMemory.RequestedVirtualAddress = NULL;
+
+        if (EngDeviceIoControl(ppdev->hDriver,
+                               IOCTL_VIDEO_MAP_VIDEO_MEMORY,
+                               &videoMemory,
+                               sizeof(VIDEO_MEMORY),
+                               &videoMemoryInformation,
+                               sizeof(VIDEO_MEMORY_INFORMATION),
+                               &returnedDataLength))
+        {
+            RIP("DISP bInitSURF failed IOCTL_VIDEO_MAP\n");
+            return(FALSE);
+        }
+
+        ppdev->pjScreen = (PBYTE)(videoMemoryInformation.FrameBufferBase);
+
+        if (videoMemoryInformation.FrameBufferBase !=
+            videoMemoryInformation.VideoRamBase)
+        {
+            RIP("VideoRamBase does not correspond to FrameBufferBase\n");
+        }
+// eVb: 2.4 [DDK Change] - Make sure frame buffer mapping worked
+        //
+        // Make sure we can access this video memory
+        //
+
+        *(PULONG)(ppdev->pjScreen) = 0xaa55aa55;
+
+        if (*(PULONG)(ppdev->pjScreen) != 0xaa55aa55) {
+
+            DISPDBG((1, "Frame buffer memory is not accessible.\n"));
+            return(FALSE);
+        }
+// eVb: 2.4 [END]
+        ppdev->cScreenSize = videoMemoryInformation.VideoRamLength;
+
+        //
+        // Initialize the head of the offscreen list to NULL.
+        //
+
+        ppdev->pOffscreenList = NULL;
+
+        // It's a hardware pointer; set up pointer attributes.
+
+        MaxHeight = ppdev->PointerCapabilities.MaxHeight;
+
+        // Allocate space for two DIBs (data/mask) for the pointer. If this
+        // device supports a color Pointer, we will allocate a larger bitmap.
+        // If this is a color bitmap we allocate for the largest possible
+        // bitmap because we have no idea of what the pixel depth might be.
+
+        // Width rounded up to nearest byte multiple
+
+        if (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))
+        {
+            MaxWidth = (ppdev->PointerCapabilities.MaxWidth + 7) / 8;
+        }
+        else
+        {
+            MaxWidth = ppdev->PointerCapabilities.MaxWidth * sizeof(DWORD);
+        }
+
+        ppdev->cjPointerAttributes =
+                sizeof(VIDEO_POINTER_ATTRIBUTES) +
+                ((sizeof(UCHAR) * MaxWidth * MaxHeight) * 2);
+
+        ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)
+                EngAllocMem(0, ppdev->cjPointerAttributes, ALLOC_TAG);
+
+        if (ppdev->pPointerAttributes == NULL) {
+
+            DISPDBG((0, "bInitPointer EngAllocMem failed\n"));
+            return(FALSE);
+        }
+
+        ppdev->pPointerAttributes->Flags = ppdev->PointerCapabilities.Flags;
+        ppdev->pPointerAttributes->WidthInBytes = MaxWidth;
+        ppdev->pPointerAttributes->Width = ppdev->PointerCapabilities.MaxWidth;
+        ppdev->pPointerAttributes->Height = MaxHeight;
+        ppdev->pPointerAttributes->Column = 0;
+        ppdev->pPointerAttributes->Row = 0;
+        ppdev->pPointerAttributes->Enable = 0;
+    }
+
+    return(TRUE);
+}
+
+/******************************Public*Routine******************************\
+* vDisableSURF
+*
+* Disable the surface. Un-Maps the frame in memory.
+*
+\**************************************************************************/
+
+VOID vDisableSURF(PPDEV ppdev)
+{
+    DWORD returnedDataLength;
+    VIDEO_MEMORY videoMemory;
+
+    videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen;
+
+    if (EngDeviceIoControl(ppdev->hDriver,
+                           IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
+                           &videoMemory,
+                           sizeof(VIDEO_MEMORY),
+                           NULL,
+                           0,
+                           &returnedDataLength))
+    {
+        RIP("DISP vDisableSURF failed IOCTL_VIDEO_UNMAP\n");
+    }
+}
+
+
+/******************************Public*Routine******************************\
+* bInitPDEV
+*
+* Determine the mode we should be in based on the DEVMODE passed in.
+* Query mini-port to get information needed to fill in the DevInfo and the
+* GdiInfo .
+*
+\**************************************************************************/
+
+BOOL bInitPDEV(
+PPDEV ppdev,
+DEVMODEW *pDevMode,
+GDIINFO *pGdiInfo,
+DEVINFO *pDevInfo)
+{
+    ULONG cModes;
+    PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
+    VIDEO_COLOR_CAPABILITIES colorCapabilities;
+    ULONG ulTemp;
+    BOOL bSelectDefault;
+    ULONG cbModeSize;
+
+    //
+    // calls the miniport to get mode information.
+    //
+
+    cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
+
+    if (cModes == 0)
+    {
+        return(FALSE);
+    }
+
+    //
+    // Now see if the requested mode has a match in that table.
+    //
+
+    pVideoModeSelected = NULL;
+    pVideoTemp = pVideoBuffer;
+
+    if ((pDevMode->dmPelsWidth        == 0) &&
+        (pDevMode->dmPelsHeight       == 0) &&
+        (pDevMode->dmBitsPerPel       == 0) &&
+        (pDevMode->dmDisplayFrequency == 0))
+    {
+        DISPDBG((2, "Default mode requested"));
+        bSelectDefault = TRUE;
+    }
+    else
+    {
+// eVb: 2.5 [DDK Change] - Add missing newlines to debug output
+        DISPDBG((2, "Requested mode...\n"));
+        DISPDBG((2, "   Screen width  -- %li\n", pDevMode->dmPelsWidth));
+        DISPDBG((2, "   Screen height -- %li\n", pDevMode->dmPelsHeight));
+        DISPDBG((2, "   Bits per pel  -- %li\n", pDevMode->dmBitsPerPel));
+        DISPDBG((2, "   Frequency     -- %li\n", pDevMode->dmDisplayFrequency));
+// eVb: 2.5 [END]
+        bSelectDefault = FALSE;
+    }
+
+    while (cModes--)
+    {
+        if (pVideoTemp->Length != 0)
+        {
+            if (bSelectDefault ||
+                ((pVideoTemp->VisScreenWidth  == pDevMode->dmPelsWidth) &&
+                 (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
+                 (pVideoTemp->BitsPerPlane *
+                  pVideoTemp->NumberOfPlanes  == pDevMode->dmBitsPerPel) &&
+                 (pVideoTemp->Frequency  == pDevMode->dmDisplayFrequency)))
+            {
+                pVideoModeSelected = pVideoTemp;
+                DISPDBG((3, "Found a match\n")) ;
+                break;
+            }
+        }
+
+        pVideoTemp = (PVIDEO_MODE_INFORMATION)
+            (((PUCHAR)pVideoTemp) + cbModeSize);
+    }
+
+    //
+    // If no mode has been found, return an error
+    //
+
+    if (pVideoModeSelected == NULL)
+    {
+        EngFreeMem(pVideoBuffer);
+        DISPDBG((0,"DISP bInitPDEV failed - no valid modes\n"));
+        return(FALSE);
+    }
+
+    //
+    // Fill in the GDIINFO data structure with the information returned from
+    // the kernel driver.
+    //
+
+    ppdev->ulMode = pVideoModeSelected->ModeIndex;
+    ppdev->cxScreen = pVideoModeSelected->VisScreenWidth;
+    ppdev->cyScreen = pVideoModeSelected->VisScreenHeight;
+    ppdev->ulBitCount = pVideoModeSelected->BitsPerPlane *
+                        pVideoModeSelected->NumberOfPlanes;
+    ppdev->lDeltaScreen = pVideoModeSelected->ScreenStride;
+
+    ppdev->flRed = pVideoModeSelected->RedMask;
+    ppdev->flGreen = pVideoModeSelected->GreenMask;
+    ppdev->flBlue = pVideoModeSelected->BlueMask;
+
+
+    pGdiInfo->ulVersion    = GDI_DRIVER_VERSION;
+    pGdiInfo->ulTechnology = DT_RASDISPLAY;
+    pGdiInfo->ulHorzSize   = pVideoModeSelected->XMillimeter;
+    pGdiInfo->ulVertSize   = pVideoModeSelected->YMillimeter;
+
+    pGdiInfo->ulHorzRes        = ppdev->cxScreen;
+    pGdiInfo->ulVertRes        = ppdev->cyScreen;
+    pGdiInfo->ulPanningHorzRes = ppdev->cxScreen;
+    pGdiInfo->ulPanningVertRes = ppdev->cyScreen;
+    pGdiInfo->cBitsPixel       = pVideoModeSelected->BitsPerPlane;
+    pGdiInfo->cPlanes          = pVideoModeSelected->NumberOfPlanes;
+    pGdiInfo->ulVRefresh       = pVideoModeSelected->Frequency;
+    pGdiInfo->ulBltAlignment   = 1;     // We don't have accelerated screen-
+                                        //   to-screen blts, and any
+                                        //   window alignment is okay
+
+    pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
+    pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
+
+#ifdef MIPS
+    if (ppdev->ulBitCount == 8)
+        pGdiInfo->flTextCaps = (TC_RA_ABLE | TC_SCROLLBLT);
+    else
+#endif
+    pGdiInfo->flTextCaps = TC_RA_ABLE;
+
+    pGdiInfo->flRaster = 0;           // flRaster is reserved by DDI
+
+    pGdiInfo->ulDACRed   = pVideoModeSelected->NumberRedBits;
+    pGdiInfo->ulDACGreen = pVideoModeSelected->NumberGreenBits;
+    pGdiInfo->ulDACBlue  = pVideoModeSelected->NumberBlueBits;
+
+    pGdiInfo->ulAspectX    = 0x24;    // One-to-one aspect ratio
+    pGdiInfo->ulAspectY    = 0x24;
+    pGdiInfo->ulAspectXY   = 0x33;
+
+    pGdiInfo->xStyleStep   = 1;       // A style unit is 3 pels
+    pGdiInfo->yStyleStep   = 1;
+    pGdiInfo->denStyleStep = 3;
+
+    pGdiInfo->ptlPhysOffset.x = 0;
+    pGdiInfo->ptlPhysOffset.y = 0;
+    pGdiInfo->szlPhysSize.cx  = 0;
+    pGdiInfo->szlPhysSize.cy  = 0;
+
+    // RGB and CMY color info.
+
+    //
+    // try to get it from the miniport.
+    // if the miniport doesn ot support this feature, use defaults.
+    //
+
+    if (EngDeviceIoControl(ppdev->hDriver,
+                           IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
+                           NULL,
+                           0,
+                           &colorCapabilities,
+                           sizeof(VIDEO_COLOR_CAPABILITIES),
+                           &ulTemp))
+    {
+
+        DISPDBG((2, "getcolorCapabilities failed \n"));
+
+        pGdiInfo->ciDevice.Red.x = 6700;
+        pGdiInfo->ciDevice.Red.y = 3300;
+        pGdiInfo->ciDevice.Red.Y = 0;
+        pGdiInfo->ciDevice.Green.x = 2100;
+        pGdiInfo->ciDevice.Green.y = 7100;
+        pGdiInfo->ciDevice.Green.Y = 0;
+        pGdiInfo->ciDevice.Blue.x = 1400;
+        pGdiInfo->ciDevice.Blue.y = 800;
+        pGdiInfo->ciDevice.Blue.Y = 0;
+        pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
+        pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
+        pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
+
+        pGdiInfo->ciDevice.RedGamma = 20000;
+        pGdiInfo->ciDevice.GreenGamma = 20000;
+        pGdiInfo->ciDevice.BlueGamma = 20000;
+
+    }
+    else
+    {
+        pGdiInfo->ciDevice.Red.x = colorCapabilities.RedChromaticity_x;
+        pGdiInfo->ciDevice.Red.y = colorCapabilities.RedChromaticity_y;
+        pGdiInfo->ciDevice.Red.Y = 0;
+        pGdiInfo->ciDevice.Green.x = colorCapabilities.GreenChromaticity_x;
+        pGdiInfo->ciDevice.Green.y = colorCapabilities.GreenChromaticity_y;
+        pGdiInfo->ciDevice.Green.Y = 0;
+        pGdiInfo->ciDevice.Blue.x = colorCapabilities.BlueChromaticity_x;
+        pGdiInfo->ciDevice.Blue.y = colorCapabilities.BlueChromaticity_y;
+        pGdiInfo->ciDevice.Blue.Y = 0;
+        pGdiInfo->ciDevice.AlignmentWhite.x = colorCapabilities.WhiteChromaticity_x;
+        pGdiInfo->ciDevice.AlignmentWhite.y = colorCapabilities.WhiteChromaticity_y;
+        pGdiInfo->ciDevice.AlignmentWhite.Y = colorCapabilities.WhiteChromaticity_Y;
+
+        // if we have a color device store the three color gamma values,
+        // otherwise store the unique gamma value in all three.
+
+        if (colorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
+        {
+            pGdiInfo->ciDevice.RedGamma = colorCapabilities.RedGamma;
+            pGdiInfo->ciDevice.GreenGamma = colorCapabilities.GreenGamma;
+            pGdiInfo->ciDevice.BlueGamma = colorCapabilities.BlueGamma;
+        }
+        else
+        {
+            pGdiInfo->ciDevice.RedGamma = colorCapabilities.WhiteGamma;
+            pGdiInfo->ciDevice.GreenGamma = colorCapabilities.WhiteGamma;
+            pGdiInfo->ciDevice.BlueGamma = colorCapabilities.WhiteGamma;
+        }
+
+    };
+
+    pGdiInfo->ciDevice.Cyan.x = 0;
+    pGdiInfo->ciDevice.Cyan.y = 0;
+    pGdiInfo->ciDevice.Cyan.Y = 0;
+    pGdiInfo->ciDevice.Magenta.x = 0;
+    pGdiInfo->ciDevice.Magenta.y = 0;
+    pGdiInfo->ciDevice.Magenta.Y = 0;
+    pGdiInfo->ciDevice.Yellow.x = 0;
+    pGdiInfo->ciDevice.Yellow.y = 0;
+    pGdiInfo->ciDevice.Yellow.Y = 0;
+
+    // No dye correction for raster displays.
+
+    pGdiInfo->ciDevice.MagentaInCyanDye = 0;
+    pGdiInfo->ciDevice.YellowInCyanDye = 0;
+    pGdiInfo->ciDevice.CyanInMagentaDye = 0;
+    pGdiInfo->ciDevice.YellowInMagentaDye = 0;
+    pGdiInfo->ciDevice.CyanInYellowDye = 0;
+    pGdiInfo->ciDevice.MagentaInYellowDye = 0;
+
+    pGdiInfo->ulDevicePelsDPI = 0;   // For printers only
+    pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
+
+    // BUGBUG this should be modified to take into account the size
+    // of the display and the resolution.
+
+    pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
+
+    pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
+
+    // Fill in the basic devinfo structure
+
+    *pDevInfo = gDevInfoFrameBuffer;
+
+    // Fill in the rest of the devinfo and GdiInfo structures.
+
+    if (ppdev->ulBitCount == 8)
+    {
+        // It is Palette Managed.
+
+        pGdiInfo->ulNumColors = 20;
+        pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;
+
+        pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
+
+        pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
+        pDevInfo->iDitherFormat = BMF_8BPP;
+
+        // Assuming palette is orthogonal - all colors are same size.
+
+        ppdev->cPaletteShift   = 8 - pGdiInfo->ulDACRed;
+    }
+    else
+    {
+        pGdiInfo->ulNumColors = (ULONG) (-1);
+        pGdiInfo->ulNumPalReg = 0;
+
+        if (ppdev->ulBitCount == 16)
+        {
+            pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
+            pDevInfo->iDitherFormat = BMF_16BPP;
+        }
+        else if (ppdev->ulBitCount == 24)
+        {
+            pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP;
+            pDevInfo->iDitherFormat = BMF_24BPP;
+        }
+        else
+        {
+            pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
+            pDevInfo->iDitherFormat = BMF_32BPP;
+        }
+    }
+
+    EngFreeMem(pVideoBuffer);
+
+    return(TRUE);
+}
+
+
+/******************************Public*Routine******************************\
+* getAvailableModes
+*
+* Calls the miniport to get the list of modes supported by the kernel driver,
+* and returns the list of modes supported by the diplay driver among those
+*
+* returns the number of entries in the videomode buffer.
+* 0 means no modes are supported by the miniport or that an error occured.
+*
+* NOTE: the buffer must be freed up by the caller.
+*
+\**************************************************************************/
+
+DWORD getAvailableModes(
+HANDLE hDriver,
+PVIDEO_MODE_INFORMATION *modeInformation,
+DWORD *cbModeSize)
+{
+    ULONG ulTemp;
+    VIDEO_NUM_MODES modes;
+    PVIDEO_MODE_INFORMATION pVideoTemp;
+
+    //
+    // Get the number of modes supported by the mini-port
+    //
+
+    if (EngDeviceIoControl(hDriver,
+                           IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
+                           NULL,
+                           0,
+                           &modes,
+                           sizeof(VIDEO_NUM_MODES),
+                           &ulTemp))
+    {
+        DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
+        return(0);
+    }
+
+    *cbModeSize = modes.ModeInformationLength;
+
+    //
+    // Allocate the buffer for the mini-port to write the modes in.
+    //
+
+    *modeInformation = (PVIDEO_MODE_INFORMATION)
+                        EngAllocMem(0, modes.NumModes *
+                                    modes.ModeInformationLength, ALLOC_TAG);
+
+    if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
+    {
+        DISPDBG((0, "getAvailableModes failed EngAllocMem\n"));
+
+        return 0;
+    }
+
+    //
+    // Ask the mini-port to fill in the available modes.
+    //
+
+    if (EngDeviceIoControl(hDriver,
+                           IOCTL_VIDEO_QUERY_AVAIL_MODES,
+                           NULL,
+                           0,
+                           *modeInformation,
+                           modes.NumModes * modes.ModeInformationLength,
+                           &ulTemp))
+    {
+
+        DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
+
+        EngFreeMem(*modeInformation);
+        *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
+
+        return(0);
+    }
+
+    //
+    // Now see which of these modes are supported by the display driver.
+    // As an internal mechanism, set the length to 0 for the modes we
+    // DO NOT support.
+    //
+
+    ulTemp = modes.NumModes;
+    pVideoTemp = *modeInformation;
+
+    //
+    // Mode is rejected if it is not one plane, or not graphics, or is not
+    // one of 8, 16 or 32 bits per pel.
+    //
+
+    while (ulTemp--)
+    {
+        if ((pVideoTemp->NumberOfPlanes != 1 ) ||
+            !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
+// eVb: 2.6 [DDK CHANGE] - Do not process banked video modes
+             (pVideoTemp->AttributeFlags & VIDEO_MODE_BANKED) ||
+// eVb: 2.6 [END]
+            ((pVideoTemp->BitsPerPlane != 8) &&
+             (pVideoTemp->BitsPerPlane != 16) &&
+             (pVideoTemp->BitsPerPlane != 24) &&
+             (pVideoTemp->BitsPerPlane != 32)))
+        {
+            pVideoTemp->Length = 0;
+        }
+
+        pVideoTemp = (PVIDEO_MODE_INFORMATION)
+            (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
+    }
+
+    return modes.NumModes;
+
+}