diff --git a/reactos/drivers/video/displays/directory.rbuild b/reactos/drivers/video/displays/directory.rbuild index eb650854819..16801792653 100644 --- a/reactos/drivers/video/displays/directory.rbuild +++ b/reactos/drivers/video/displays/directory.rbuild @@ -1,10 +1,7 @@ - - - - - + + diff --git a/reactos/drivers/video/displays/framebuf_new/debug.c b/reactos/drivers/video/displays/framebuf_new/debug.c new file mode 100755 index 00000000000..ada125df7ec --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/debug.c @@ -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 index 00000000000..d73a223baaf --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/debug.h @@ -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 index 00000000000..77306ca5ba6 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/driver.h @@ -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 +#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 index 00000000000..8031da8a173 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/enable.c @@ -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 index 00000000000..c334ac9ac4a --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/framebuf_new.rbuild @@ -0,0 +1,18 @@ + + + + + . + win32k + debug.c + enable.c + palette.c + pointer.c + screen.c + framebuf_new.rc + + -mrtd + -fno-builtin + -Wno-unused-variable + + 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 index 00000000000..98ba2627f11 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/framebuf_new.rc @@ -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 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 index 00000000000..aec115e4ef7 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/framebuf_new.spec @@ -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 index 00000000000..c8cff990e2b --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/palette.c @@ -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 index 00000000000..d3752a2763c --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/pointer.c @@ -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 index 00000000000..1973c580866 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_new/screen.c @@ -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; + +}