File:  [WindowsNT SDKs] / ntddk / src / video / displays / xga / screen.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:31:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntddk-nov-1993, HEAD
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993

/******************************Module*Header*******************************\
* Module Name: screen.c
*
* Initializes the GDIINFO and DEVINFO structures for DrvEnablePDEV.
*
* Copyright (c) 1992 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)
{

    VIDEO_MEMORY             VideoMemory;
    VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
    DWORD         ReturnedDataLength;
    DWORD XGAPixelOp;

    VIDEO_XGA_COPROCESSOR_INFORMATION CoProcessorInfo;

    if (!DeviceIoControl(ppdev->hDriver,
                         IOCTL_VIDEO_SET_CURRENT_MODE,
                         &ppdev->ulMode,        // input buffer
                         sizeof(VIDEO_MODE),
                         NULL,
                         0,
                         &ReturnedDataLength,
                         NULL)) {

        RIP("XGA.DLL: Initialization error-Set mode\n");

    }

    if (bFirst) {

        VideoMemory.RequestedVirtualAddress = NULL;

        if (!DeviceIoControl(ppdev->hDriver,
                             IOCTL_VIDEO_MAP_VIDEO_MEMORY,
                             (PVOID) &VideoMemory, // input buffer
                             sizeof (VIDEO_MEMORY),
                             (PVOID) &VideoMemoryInfo, // output buffer
                             sizeof (VideoMemoryInfo),
                             &ReturnedDataLength,
                             NULL)) {

            RIP("XGA.DLL: Initialization error-Map buffer address\n");

        }

        ppdev->pjScreen = VideoMemoryInfo.FrameBufferBase;
        ppdev->ulScreenSize = VideoMemoryInfo.FrameBufferLength;
        ppdev->ulVideoMemorySize = VideoMemoryInfo.VideoRamLength;

        if (!DeviceIoControl(ppdev->hDriver,
                             IOCTL_VIDEO_XGA_MAP_COPROCESSOR,
                             NULL,    // input buffer
                             0,
                             &CoProcessorInfo, // output buffer
                             sizeof (VIDEO_XGA_COPROCESSOR_INFORMATION),
                             &ReturnedDataLength,
                             NULL)) {

            RIP("XGA.DLL: Initialization error-Map Coprocessor buffer address\n");

        }

        // Set the globals, we will need these almost everywhere.

        ppdev->pXgaCpRegs        = CoProcessorInfo.CoProcessorVirtualAddress;
        ppdev->ulPhysFrameBuffer = (ULONG) CoProcessorInfo.PhysicalVideoMemoryAddress;
        ppdev->ulXgaIoRegsBase   = CoProcessorInfo.XgaIoRegisterBaseAddress;

        // Set the coprocessor defaults (Target pel map).
        // The conventions for this driver will have the Target
        // Pel map as map A.

        ppdev->pXgaCpRegs->XGAPixelMapIndex = PEL_MAP_A;
        ppdev->pXgaCpRegs->XGAPixMapBasePtr = ppdev->ulPhysFrameBuffer;
        ppdev->pXgaCpRegs->XGAPixMapWidth   = (USHORT) ppdev->cxScreen - 1;
        ppdev->pXgaCpRegs->XGAPixMapHeight  = (USHORT) ppdev->cyScreen - 1;
        ppdev->pXgaCpRegs->XGAPixMapFormat  = PEL_MAP_FORMAT;

        ppdev->pXgaCpRegs->XGADestColCompCond = CCCC_FALSE;
        ppdev->pXgaCpRegs->XGAPixelBitMask    = 0xFF;

        //
        // Init the XGA memory manager.
        //

        bCpMmInitHeap(ppdev);

        //
        // Determine if the coprocessor is working properly.
        // Try a solid fill; if it fails, then disable all accelerations.
        //

        ppdev->pXgaCpRegs->XGAOpDim1 = 1;
        ppdev->pXgaCpRegs->XGAOpDim2 = 1;

        ppdev->pXgaCpRegs->XGADestMapX = 0;
        ppdev->pXgaCpRegs->XGADestMapY = 0;

        ppdev->pXgaCpRegs->XGAForeGrMix = XGA_S;
        ppdev->pXgaCpRegs->XGABackGrMix = XGA_S;

        ppdev->pXgaCpRegs->XGAForeGrColorReg = 0x55;

        //
        // Now build the Pel Operation Register Op Code;
        //

        XGAPixelOp = BS_BACK_COLOR   | FS_FORE_COLOR  | STEP_PX_BLT     |
                     SRC_PEL_MAP_A   | DST_PEL_MAP_A  | PATT_FOREGROUND;

        ppdev->pXgaCpRegs->XGAPixelOp = XGAPixelOp;

        //
        // Wait for the coprocessor.
        //

        vWaitForCoProcessor(ppdev, 10) ;

        //
        // Read the byte back to see if it was blit to the screen properly.
        // BUGBUG !!!
        // This is to allow the driver to treat the hardware as a frame buffer
        // in the case where the IBM hardware is broken !
        //

        if (*(ppdev->pjScreen) == 0x55) {

            //
            // private flag used for determining driver capabilities.
            //


            ppdev->ulfAccelerations_debug = CACHED_FONTS;
            ppdev->ulfBlitAccelerations_debug = SCRN_TO_SCRN_CPY | SOLID_PATTERN;

        } else {

            //
            // !!! Turn off all accelerations for broken hardware !
            //

            ppdev->ulfAccelerations_debug = 0;
            ppdev->ulfBlitAccelerations_debug = 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 (!DeviceIoControl(ppdev->hDriver,
                        IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
                        &videoMemory,
                        sizeof(VIDEO_MEMORY),
                        NULL,
                        0,
                        &returnedDataLength,
                        NULL))
    {
        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);
    }

    //
    // Determine if we are looking for a default mode.
    //

    if ( ((pDevMode->dmPelsWidth) ||
          (pDevMode->dmPelsHeight) ||
          (pDevMode->dmBitsPerPel) ||
          (pDevMode->dmDisplayFlags) ||
          (pDevMode->dmDisplayFrequency)) == 0)
    {
        bSelectDefault = TRUE;
    }
    else
    {
        bSelectDefault = FALSE;
    }

    //
    // Now see if the requested mode has a match in that table.
    //

    pVideoModeSelected = NULL;
    pVideoTemp = pVideoBuffer;

    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) ||
                    (pDevMode->dmDisplayFrequency == 0)) &&
                 (((pVideoTemp->AttributeFlags &
                            VIDEO_MODE_INTERLACED) ? 1:0) ==
                    ((pDevMode->dmDisplayFlags & DM_INTERLACED) ? 1:0)) ) )

            {
                pVideoModeSelected = pVideoTemp;
                DISPDBG((3, "XGA: Found a match\n"));
                break;
            }
        }

        pVideoTemp = (PVIDEO_MODE_INFORMATION)
            (((PUCHAR)pVideoTemp) + cbModeSize);
    }

    //
    // If no mode has been found, return an error
    //

    if (pVideoModeSelected == NULL)
    {
        LocalFree(pVideoBuffer);
        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    = 0x1000;    // Our driver is verion 1.000
    pGdiInfo->ulTechnology = DT_RASDISPLAY;
    pGdiInfo->ulHorzSize   = pVideoModeSelected->XMillimeter;
    pGdiInfo->ulVertSize   = pVideoModeSelected->YMillimeter;

    pGdiInfo->ulHorzRes   = ppdev->cxScreen;
    pGdiInfo->ulVertRes   = ppdev->cyScreen;
    pGdiInfo->cBitsPixel  = pVideoModeSelected->BitsPerPlane;
    pGdiInfo->cPlanes     = pVideoModeSelected->NumberOfPlanes;

    pGdiInfo->ulLogPixelsX = 96;
    pGdiInfo->ulLogPixelsY = 96;

    pGdiInfo->flTextCaps = TC_RA_ABLE;
    pGdiInfo->flRaster = 0;           // DDI reserves flRaster

    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 (!DeviceIoControl(ppdev->hDriver,
                         IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
                         NULL,
                         0,
                         &colorCapabilities,
                         sizeof(VIDEO_COLOR_CAPABILITIES),
                         &ulTemp,
                         NULL))
    {
        DISPDBG((1, "XGA DISP 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)
    {

        // BUGBUG check if we have a palette managed device.
        // BUGBUG why is ulNumColors set to 20 ?

        // It is Palette Managed.

        pGdiInfo->ulNumColors = 20;
        pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;

        pGdiInfo->flRaster |= RC_PALETTE;
        pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;

        pDevInfo->iDitherFormat = BMF_8BPP;
        pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);

    }
    else
    {
        pGdiInfo->ulNumColors = 1 << ppdev->ulBitCount;
        pGdiInfo->ulNumPalReg = 0;

        pDevInfo->iDitherFormat = BMF_16BPP;
        pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
    }

    LocalFree(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 (!DeviceIoControl(hDriver,
            IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
            NULL,
            0,
            &modes,
            sizeof(VIDEO_NUM_MODES),
            &ulTemp,
            NULL))
    {
        DISPDBG((0, "xga.dll 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)
                        LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
                                   modes.NumModes *
                                   modes.ModeInformationLength);

    if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
    {
        DISPDBG((0, "xga.dll getAvailableModes failed LocalAlloc\n"));

        return 0;
    }

    //
    // Ask the mini-port to fill in the available modes.
    //

    if (!DeviceIoControl(hDriver,
            IOCTL_VIDEO_QUERY_AVAIL_MODES,
            NULL,
            0,
            *modeInformation,
            modes.NumModes * modes.ModeInformationLength,
            &ulTemp,
            NULL))
    {

        DISPDBG((0, "xga.dll getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));

        LocalFree(*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 bits per pel.
    //

    while (ulTemp--)
    {
        if ((pVideoTemp->NumberOfPlanes != 1 ) ||
            !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
            (pVideoTemp->BitsPerPlane != 8))
        {
            pVideoTemp->Length = 0;
        }

        pVideoTemp = (PVIDEO_MODE_INFORMATION)
            (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
    }

    return modes.NumModes;

}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.