|
|
/******************************Module*Header*******************************\
* * ******************* * * GDI SAMPLE CODE * * ******************* * * Module Name: screen.c * * Initializes the GDIINFO and DEVINFO structures for DrvEnablePDEV. * * Copyright (c) 1992-1998 Microsoft Corporation \**************************************************************************/
#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; ULONG RemappingNeeded = 0;
//
// Set the current mode into the hardware.
//
if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_SET_CURRENT_MODE, &(ppdev->ulMode), sizeof(ULONG), &RemappingNeeded, sizeof(ULONG), &returnedDataLength)) { DISPDBG((1, "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.
//
if (bFirst || RemappingNeeded) { videoMemory.RequestedVirtualAddress = NULL;
if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_MAP_VIDEO_MEMORY, &videoMemory, sizeof(VIDEO_MEMORY), &videoMemoryInformation, sizeof(VIDEO_MEMORY_INFORMATION), &returnedDataLength)) { DISPDBG((1, "DISP bInitSURF failed IOCTL_VIDEO_MAP\n")); return(FALSE); }
ppdev->pjScreen = (PBYTE)(videoMemoryInformation.FrameBufferBase);
if (videoMemoryInformation.FrameBufferBase != videoMemoryInformation.VideoRamBase) { DISPDBG((0, "VideoRamBase does not correspond to FrameBufferBase\n")); }
//
// 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); }
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)) { DISPDBG((0, "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 { 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));
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;
// Note: this should be modified later 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) || (pVideoTemp->AttributeFlags & VIDEO_MODE_BANKED) || ((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;
}
|