mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1030 lines
36 KiB
1030 lines
36 KiB
/*
|
|
*
|
|
* Copyright (C) 1993-1995 by
|
|
* DIGITAL EQUIPMENT CORPORATION, Maynard, MA.
|
|
*
|
|
* This software is furnished under a license and may be used and copied
|
|
* only in accordance with the terms of such license and with the inclusion
|
|
* of the above copyright notice. This software or any other copies there-
|
|
* of may not be provided or otherwise made available to any other person.
|
|
* No title to and ownership of the software is hereby transferred.
|
|
*
|
|
* The information in this software is subject to change without notice
|
|
* and should not be construed as a commitment by DIGITAL EQUIPMENT COR-
|
|
* PORATION.
|
|
*
|
|
* DIGITAL assumes no responsibility for the use or reliability of its
|
|
* software on equipment which is not supplied by DIGITAL.
|
|
*
|
|
*******************************************************************************
|
|
*
|
|
* Module: screen.c
|
|
*
|
|
* Abstract: Contains a lot of the screen initialization code, etc.,
|
|
* like initializing the GDIINFO and DEVINFO structures for
|
|
* DrvEnablePDEV.
|
|
*
|
|
* HISTORY
|
|
*
|
|
* 1-Nov-1993 Bob Seitsinger
|
|
* Original version.
|
|
*
|
|
* 1-Nov-1993 Bob Seitsinger
|
|
* Initialize lBrushUnique in 'init surface'.
|
|
*
|
|
* 1-Nov-1993 Barry Tannenbaum
|
|
* Initialize PDEV elements for addresses in the TGA address space.
|
|
*
|
|
* 1-Nov-1993 Barry Tannenbaum
|
|
* Offset the base address of the screen from the start of the framebuffer
|
|
* by one page (4096 bytes). This allows the BitBlt code to make
|
|
* optimizations which require it to be able to write up to 7 pixels
|
|
* before the start of the screen.
|
|
*
|
|
* 2-Nov-1993 Barry Tannenbaum
|
|
* Initialize pFrameBufferBase and ulFrameBufferLen - The base address of
|
|
* the framebuffer and the size in bytes.
|
|
*
|
|
* 03-Nov-1993 Bob Seitsinger
|
|
* Initialize pjFrameBufferEnd (this replaces ulFrameBufferLen).
|
|
*
|
|
* 8-Nov-1993 Barry Tannenbaum
|
|
* Rework pointers that we keep to TGA space to allow for aliasing the
|
|
* frame buffer.
|
|
*
|
|
* 12-Nov-1993 Barry Tannenbaum
|
|
* Initialize global variables pjFrameBufferStart and pjFrameBufferEnd.
|
|
*
|
|
* 3-Dec-1993 Barry Tannenbaum
|
|
* Add call to initailize off-screen memory management routines
|
|
*
|
|
* 2-Jan-1994 Barry Tannenbaum
|
|
* Added flush and sync before reading DEEP register.
|
|
*
|
|
* 13-Feb-1994 Barry Tannenbaum
|
|
* Added code to initialize ppdev->iFormat based on ppdev->ulBitCount
|
|
*
|
|
* 25-Feb-1994 Barry Tannenbaum
|
|
* Added code to initialize ppdev->ulBytesPerPixel based on
|
|
* ppdev->ulBitCount
|
|
*
|
|
* 07-Mar-1994 Bob Seitsinger
|
|
* Add code in bInitPDEV to initialize ulMainPageBytes and
|
|
* ulMainPageBytesMask.
|
|
*
|
|
* 08-Mar-1994 Bob Seitsinger
|
|
* Delete allocation of DMA Table. No longer needed. DMA pass 4.
|
|
*
|
|
* 07-Apr-1994 Bob Seitsinger
|
|
* Modify ulMainPageBytes to get the page size from the SYSTEM_INFO
|
|
* structure.
|
|
*
|
|
* 14-Apr-1994 Barry Tannenbaum
|
|
* Merged in changes from Daytona QV driver so that we can support the
|
|
* Display applet.
|
|
*
|
|
* 30-May-1994 Barry Tannnebaum
|
|
* Set GCAPS_ALTERNATEFILL and GCAPS_WINDINGFILL in
|
|
* DevInfo->flGraphicsCaps to allow GDI to call DrvFillPath.
|
|
*
|
|
* 31-May-1994 Barry Tannenbaum
|
|
* Daytona Beta-2 requires us to fill in GdiInfo->ulDesktopHorzRes and
|
|
* GdiInfo->ulDesktopVertRes or the driver dies.
|
|
*
|
|
* 01-Jun-1994 Bob Seitsinger
|
|
* Initialize ppdev->pcoDefault to DC_TRIVIAL instead of DC_RECT. No one
|
|
* is currently using it, but bitblt.c will.
|
|
*
|
|
* Nope, back this out. Keep it DC_RECT. Initialize ppdev->pcoTrivial -
|
|
* a new trivial clipping object we can use when GDI passes us a NULL
|
|
* pco.
|
|
*
|
|
* 21-Jun-1994 Barry Tannenbaum
|
|
* Initialize ppdev->pjTGAStart from VideoRamBase instead of
|
|
* FrameBufferBase. Ritu has made a corresponding change. This allows
|
|
* us to skip mapping the memory between the registers and the frame
|
|
* buffer
|
|
*
|
|
* 24-Jun-1994 Bob Seitsinger
|
|
* ifdef DAYTONA_BETA_2 around some code that uses new fields returned
|
|
* by the kernel driver. Also, add back in code that uses the 'old'
|
|
* fields to init frame buffer address pointers. Using the new code
|
|
* causes a problem when you don't have a kernel driver that passes back
|
|
* these new fields!
|
|
*
|
|
* 29-Jun-1994 Barry Tannenbaum
|
|
* Microsoft has removed BMF_DEVICE, so default to BMF_8BPP instead.
|
|
*
|
|
* 14-Jul-1994 Bob Seitsinger
|
|
* Add code in support of 24 plane boards.
|
|
*
|
|
* 11-Aug-1994 Barry Tannenbaum
|
|
* Use GetRegistryInfo instead of GetBitsPerPixel
|
|
*
|
|
* 1-Sep-1994 Bob Seitsinger
|
|
* Dynamically allocate space for the Color Translation buffer
|
|
* and load the ppdev->pjColorXlateBuffer pointer.
|
|
*
|
|
* 20-Oct-1994 Barry Tannenbaum
|
|
* AND frame buffer base address with 0xffff8000 to mask off the low 7
|
|
* bits of the frame buffer address. Due to a bug in the firmware which
|
|
* is setting the VIDEO BASE register to 1, the kernel driver must add
|
|
* 16KB to the frame buffer base address to make NT installation work
|
|
* correctly.
|
|
*
|
|
* 25-Oct-1994 Kathleen Langone
|
|
* Changed the setting of pGdiInfo->ulNumColors to be (ULONG) -1 for
|
|
* the 24-plane board in routine bInitPDEV.
|
|
* The previous code set it to 0. This is the same as the S3 driver and
|
|
* allows passage of the DEC VET video test.
|
|
*
|
|
* 3-Nov-1994 Bob Seitsinger
|
|
* In bInitPDEV - Allocate space for the 'merged' cursor buffer - used only by
|
|
* 24 plane boards.
|
|
* In bInitSURF - do some 24plane hardware cursor setup stuff.
|
|
*
|
|
* 5-Dec-1994 Bob Seitsinger
|
|
* Set GdiInfo->ulHTOutputFormat appropriately. This fixes the HCT SBMODE*
|
|
* failures for 24 plane boards.
|
|
*
|
|
* 3-Jan-1995 Barry Tannenbaum
|
|
* Restored use of "BitsPerPel" instead of "FrameBuffer Depth" to fetch
|
|
* bits per pixel
|
|
*
|
|
* 2-Mar-1995 Barry Tannenbaum
|
|
* Removed use of the registry.
|
|
* Fetch PCI Class/Revision register and processor type from kernel
|
|
* driver.
|
|
*/
|
|
|
|
#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;
|
|
VIDEO_PUBLIC_ACCESS_RANGES VideoAccessRange;
|
|
|
|
DISPDBG ((1, "TGA.DLL!bInitSURF - Entry\n"));
|
|
|
|
// Set the current mode into the hardware.
|
|
|
|
if (EngDeviceIoControl (ppdev->hDriver,
|
|
IOCTL_VIDEO_SET_CURRENT_MODE,
|
|
&(ppdev->ulMode),
|
|
sizeof(ULONG),
|
|
NULL,
|
|
0,
|
|
&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.
|
|
|
|
if (bFirst)
|
|
{
|
|
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;
|
|
}
|
|
|
|
DISPDBG ((1, "FrameBuffer Base: %08x, Length %08x\n",
|
|
videoMemoryInformation.FrameBufferBase,
|
|
videoMemoryInformation.FrameBufferLength));
|
|
|
|
DISPDBG ((1, "VideoRam Base: %08x, Length %08x\n",
|
|
videoMemoryInformation.VideoRamBase,
|
|
videoMemoryInformation.VideoRamLength));
|
|
|
|
if (EngDeviceIoControl(ppdev->hDriver,
|
|
IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES,
|
|
NULL,
|
|
0,
|
|
&VideoAccessRange, // output buffer
|
|
sizeof(VideoAccessRange),
|
|
&returnedDataLength))
|
|
{
|
|
RIP ("DISP bInitSURF failed IOCTL_VIDEO_QUERY_PUBLIC\n");
|
|
return FALSE;
|
|
}
|
|
|
|
// Save the extent of the TGA address space in our address space
|
|
|
|
ppdev->pjTGARegStart = (PTGARegisters)(VideoAccessRange.VirtualAddress);
|
|
|
|
DISPDBG ((1, "ppdev: pjTGARegStart = %08x\n", ppdev->pjTGARegStart));
|
|
|
|
// Initialize the pointer to the TGA registers to the first alias
|
|
|
|
ppdev->TGAReg = ppdev->pjTGARegStart;
|
|
|
|
DISPDBG ((1, "ppdev->TGAReg = %08x\n", ppdev->TGAReg));
|
|
|
|
// Initialize the pointers to the framebuffer
|
|
|
|
ppdev->pjVideoMemory = videoMemoryInformation.VideoRamBase;
|
|
ppdev->pjFrameBufferStart = videoMemoryInformation.FrameBufferBase;
|
|
ppdev->ulFrameBufferLen = videoMemoryInformation.FrameBufferLength;
|
|
|
|
DISPDBG ((1, "ppdev: pjVideoMemory = %08x\n", ppdev->pjVideoMemory));
|
|
DISPDBG ((1, "ppdev: pjFrameBufferStart = %08x, ulFrameBufferLen = %08x\n",
|
|
ppdev->pjFrameBufferStart,
|
|
ppdev->ulFrameBufferLen));
|
|
|
|
ppdev->ulFrameBufferOffsetStatic = 0;
|
|
ppdev->ulFrameBufferOffset = 0;
|
|
|
|
// Set the framebuffer address in the PDEV.
|
|
|
|
ppdev->pjFrameBuffer = ppdev->pjFrameBufferStart;
|
|
|
|
DISPDBG ((1, "TGA.DLL!bInitSURF - ppdev: pjFrameBuffer [%x]\n",
|
|
ppdev->pjFrameBuffer));
|
|
|
|
WBFLUSH (ppdev);
|
|
TGASYNC (ppdev);
|
|
|
|
// Initialize elements that are used for Frame Buffer aliasing.
|
|
|
|
if (8 == ppdev->ulBitCount)
|
|
ppdev->ulCycleFBInc = CYCLE_FB_INC_8;
|
|
else
|
|
ppdev->ulCycleFBInc = CYCLE_FB_INC_24;
|
|
|
|
#if CPU_WB_WORDS == 0
|
|
ppdev->ulCycleFBReset = 0xffffffff;
|
|
ppdev->ulCycleFBMask = 0xffffffff;
|
|
#else
|
|
ppdev->ulCycleFBReset = ~(4 * ppdev->ulCycleFBInc);
|
|
ppdev->ulCycleFBMask = ~(3 * ppdev->ulCycleFBInc);
|
|
#endif
|
|
|
|
DISPDBG ((1, "TGA.DLL!bInitSURF - ppdev: ulCycleFBInc [%x], ulCycleFBReset [%x], ulCycleFBMask [%x]\n",
|
|
ppdev->ulCycleFBInc, ppdev->ulCycleFBReset, ppdev->ulCycleFBMask));
|
|
|
|
// Initialize the off-screen memory management routines
|
|
|
|
vTgaOffScreenInit (ppdev);
|
|
|
|
// 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);
|
|
|
|
DISPDBG ((2, "TGA.DLL!bInitSURF - ppdev-ptr: Sizof [%d], mW [%d], mW2 [%d], mH [%d], cj [%d]\n",
|
|
sizeof(VIDEO_POINTER_ATTRIBUTES),
|
|
ppdev->PointerCapabilities.MaxWidth,
|
|
MaxWidth,
|
|
ppdev->PointerCapabilities.MaxHeight,
|
|
ppdev->cjPointerAttributes));
|
|
|
|
ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)
|
|
EngAllocMem (FL_ZERO_MEMORY,
|
|
ppdev->cjPointerAttributes,
|
|
ALLOC_TAG);
|
|
|
|
if (ppdev->pPointerAttributes == NULL)
|
|
{
|
|
DISPDBG ((0, "TGA.DLL!bInitSURF - PointerAttributes EngAllocMem failed\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
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;
|
|
|
|
// Do some 24 plane hardware cursor-specific stuff.
|
|
|
|
if (32 == ppdev->ulBitCount)
|
|
{
|
|
HORIZONTAL HorCtlReg;
|
|
VERTICAL VerCtlReg;
|
|
CURSORBASEREG CursorBaseReg;
|
|
VVALIDREG VideoValidReg;
|
|
|
|
// Initialize the cursor base address to zero and
|
|
// the number of rows to 63. These two values could
|
|
// change in DrvMovePointer. See that code for details.
|
|
//
|
|
// The TGA doc states you need to put in # rows - 1, so,
|
|
// the row value that goes into this register will be 63,
|
|
// since the bt463 (which is on the 24 plane board) expects
|
|
// a 64x64 cursor.
|
|
|
|
CursorBaseReg.u32 = 0;
|
|
CursorBaseReg.reg.rowsMinusOne = 63;
|
|
|
|
CYCLE_REGS (ppdev);
|
|
TGACURSORBASE (ppdev, CursorBaseReg.u32);
|
|
|
|
// Keep track of the number of rows, so DrvMovePointer can
|
|
// adjust the Cursor base address register if it needs to.
|
|
|
|
ppdev->ulCursorPreviousRows = 64;
|
|
|
|
// Enable TGA-based cursor management.
|
|
|
|
VideoValidReg.u32 = 0;
|
|
VideoValidReg.reg.cursor_enable = 1;
|
|
|
|
TGAVIDEOVALID (ppdev, (ppdev->TGAReg->video_valid | VideoValidReg.u32));
|
|
|
|
// Calculate the X and Y offsets needed when setting the
|
|
// cursor position in DrvMovePointer.
|
|
//
|
|
// Don't expect me to explain this, since I stole the 'how to
|
|
// calculate the offsets' code from the OSF TGA driver and
|
|
// there weren't any comments in that code to explain why they
|
|
// had to do it this way.
|
|
//
|
|
// The calculations are:
|
|
// X offset = 4 * (horiz_control.sync + horiz_control.backporch)
|
|
// Y offset = vert_control.sync + ver_control.backporch
|
|
//
|
|
// Why? I don't have a clue.
|
|
//
|
|
|
|
TGAHORIZCTLREAD (ppdev, HorCtlReg.u32);
|
|
TGAVERTCTLREAD (ppdev, VerCtlReg.u32);
|
|
|
|
// Calculate the X and Y offsets, for later use by the
|
|
// DrvMovePointer routine.
|
|
|
|
ppdev->ulCursorXOffset = 4 * (HorCtlReg.reg.sync + HorCtlReg.reg.bp);
|
|
ppdev->ulCursorYOffset = VerCtlReg.reg.sync + VerCtlReg.reg.bp;
|
|
|
|
}
|
|
}
|
|
|
|
DISPDBG ((1, "TGA.DLL!bInitSURF - Exit\n"));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vDisableSURF
|
|
*
|
|
* Disable the surface. Un-Maps the frame in memory.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vDisableSURF (PPDEV ppdev)
|
|
{
|
|
DWORD returnedDataLength;
|
|
VIDEO_MEMORY videoMemory;
|
|
|
|
// Unmap the frame buffer memory
|
|
|
|
videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjVideoMemory;
|
|
|
|
if (EngDeviceIoControl (ppdev->hDriver,
|
|
IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
|
|
&videoMemory,
|
|
sizeof(VIDEO_MEMORY),
|
|
NULL,
|
|
0,
|
|
&returnedDataLength))
|
|
{
|
|
RIP ("DISP vDisableSURF failed IOCTL_VIDEO_UNMAP\n");
|
|
}
|
|
|
|
// Unmap the register memory
|
|
|
|
videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjTGARegStart;
|
|
|
|
if (EngDeviceIoControl (ppdev->hDriver,
|
|
IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES,
|
|
&videoMemory,
|
|
sizeof(VIDEO_MEMORY),
|
|
NULL,
|
|
0,
|
|
&returnedDataLength))
|
|
{
|
|
RIP ("DISP vDisableSURF failed IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES\n");
|
|
}
|
|
|
|
// Free the pointer attributes memory we allocated in bInitSURF
|
|
|
|
if (NULL != ppdev->pPointerAttributes)
|
|
EngFreeMem (ppdev->pPointerAttributes);
|
|
|
|
// Free up the offscreen memory allocated in bInitSURF
|
|
|
|
vTgaOffScreenFreeAll (ppdev);
|
|
|
|
// We must give up the display.
|
|
// Call the kernel driver to reset the device to a known state.
|
|
|
|
#if 0
|
|
// This is a NOOP in the miniport driver - so we shouldn't
|
|
// have to do this.
|
|
|
|
if (EngDeviceIoControl (ppdev->hDriver,
|
|
IOCTL_VIDEO_RESET_DEVICE,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&returnedDataLength))
|
|
{
|
|
RIP ("DISP vDisableSurf failed IOCTL_VIDEO_RESET_DEVICE");
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
/******************************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;
|
|
VIDEO_MODE_INFORMATION VideoModeInformation;
|
|
ULONG pcrr;
|
|
|
|
DISPDBG ((1, "TGA.DLL!bInitPDEV - Entry\n"));
|
|
|
|
// Call the miniport to get mode information for the current pixel depth.
|
|
|
|
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;
|
|
|
|
DISPDBG((1, " pDevMode X Y %d %d BPP %d Freq %d\n",
|
|
pDevMode->dmPelsWidth,
|
|
pDevMode->dmPelsHeight,
|
|
pDevMode->dmBitsPerPel,
|
|
pDevMode->dmDisplayFrequency));
|
|
|
|
while (cModes--)
|
|
{
|
|
DISPDBG((1, " ModeIndex %d X Y %d %d BPP %d Freq %d\n",
|
|
pVideoTemp->ModeIndex,
|
|
pVideoTemp->VisScreenWidth,
|
|
pVideoTemp->VisScreenHeight,
|
|
pVideoTemp->BitsPerPlane * pVideoTemp->NumberOfPlanes,
|
|
pVideoTemp->Frequency));
|
|
|
|
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, "framebuf: Found a match\n")) ;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pVideoTemp = (PVIDEO_MODE_INFORMATION)
|
|
(((PUCHAR)pVideoTemp) + cbModeSize);
|
|
}
|
|
|
|
// If no mode has been found.
|
|
|
|
if (pVideoModeSelected == NULL)
|
|
{
|
|
EngFreeMem (pVideoBuffer);
|
|
return FALSE;
|
|
}
|
|
|
|
// We have chosen the one we want. Save it in a stack buffer and
|
|
// get rid of allocated memory before we forget to free it.
|
|
|
|
VideoModeInformation = *pVideoModeSelected;
|
|
EngFreeMem (pVideoBuffer);
|
|
|
|
// Setup screen information from the video mode info
|
|
|
|
// Fill in the GDIINFO data structure with the information returned from
|
|
// the kernel driver.
|
|
|
|
ppdev->ulMode = VideoModeInformation.ModeIndex;
|
|
ppdev->cxScreen = VideoModeInformation.VisScreenWidth;
|
|
ppdev->cyScreen = VideoModeInformation.VisScreenHeight;
|
|
|
|
ppdev->ulBitCount = VideoModeInformation.BitsPerPlane *
|
|
VideoModeInformation.NumberOfPlanes;
|
|
ppdev->ulBytesPerPixel = (ppdev->ulBitCount + 7) / 8;
|
|
switch (ppdev->ulBitCount)
|
|
{
|
|
case 8: ppdev->iFormat = BMF_8BPP; break;
|
|
case 16: ppdev->iFormat = BMF_16BPP; break;
|
|
case 24: ppdev->iFormat = BMF_24BPP; break;
|
|
case 32: ppdev->iFormat = BMF_32BPP; break;
|
|
default:
|
|
ppdev->iFormat = BMF_8BPP;
|
|
DISPDBG ((0, "Unrecognized value for ulBitCount: %d\n",
|
|
ppdev->ulBitCount));
|
|
return FALSE;
|
|
}
|
|
ppdev->lDeltaScreen = VideoModeInformation.ScreenStride;
|
|
ppdev->lScreenStride = VideoModeInformation.ScreenStride;
|
|
|
|
ppdev->flRed = VideoModeInformation.RedMask;
|
|
ppdev->flGreen = VideoModeInformation.GreenMask;
|
|
ppdev->flBlue = VideoModeInformation.BlueMask;
|
|
|
|
// Create a default Clip Object. This will/can be used
|
|
// when a NULL clip object is passed to us.
|
|
|
|
ppdev->pcoDefault = EngCreateClip();
|
|
ppdev->pcoDefault->iDComplexity = DC_RECT;
|
|
ppdev->pcoDefault->iMode = TC_RECTANGLES;
|
|
|
|
ppdev->pcoDefault->rclBounds.left = 0;
|
|
ppdev->pcoDefault->rclBounds.top = 0;
|
|
ppdev->pcoDefault->rclBounds.right = ppdev->cxScreen;
|
|
ppdev->pcoDefault->rclBounds.bottom = ppdev->cyScreen;
|
|
|
|
// Create a Trivial Clip Object. This will/can be used
|
|
// when a NULL clip object is passed to us.
|
|
|
|
ppdev->pcoTrivial = EngCreateClip();
|
|
ppdev->pcoTrivial->iDComplexity = DC_TRIVIAL;
|
|
ppdev->pcoTrivial->iMode = TC_RECTANGLES;
|
|
|
|
ppdev->pcoTrivial->rclBounds.left = 0;
|
|
ppdev->pcoTrivial->rclBounds.top = 0;
|
|
ppdev->pcoTrivial->rclBounds.right = ppdev->cxScreen;
|
|
ppdev->pcoTrivial->rclBounds.bottom = ppdev->cyScreen;
|
|
|
|
// Initialize the Unique Brush Counter,
|
|
|
|
ppdev->ulBrushUnique = 1;
|
|
|
|
// Initialize elements that define the target platform
|
|
// memory physical page size. Used in DMA code.
|
|
|
|
// Hard code it, because it's fairly certain that the DMA won't
|
|
// work on any platform other than the Alpha:
|
|
|
|
ppdev->ulMainPageBytes = 0x2000;
|
|
ppdev->ulMainPageBytesMask = ppdev->ulMainPageBytes - 1;
|
|
|
|
DISPDBG ((1, "TGA.DLL!bInitPDEV - PageSize [%d][0x%x]\n",
|
|
ppdev->ulMainPageBytes, ppdev->ulMainPageBytes));
|
|
|
|
// Fill in the GDIINFO data structure with the information returned from the
|
|
// kernel driver
|
|
|
|
pGdiInfo->ulVersion = GDI_DRIVER_VERSION | // Microsoft major/minor version
|
|
TGA_VERSION; // TGA version number (low byte)
|
|
|
|
pGdiInfo->ulTechnology = DT_RASDISPLAY;
|
|
pGdiInfo->ulHorzSize = VideoModeInformation.XMillimeter;
|
|
pGdiInfo->ulVertSize = VideoModeInformation.YMillimeter;
|
|
|
|
pGdiInfo->ulHorzRes = ppdev->cxScreen;
|
|
pGdiInfo->ulVertRes = ppdev->cyScreen;
|
|
|
|
pGdiInfo->ulPanningHorzRes = ppdev->cxScreen;
|
|
pGdiInfo->ulPanningVertRes = ppdev->cyScreen;
|
|
|
|
pGdiInfo->cBitsPixel = VideoModeInformation.BitsPerPlane;
|
|
pGdiInfo->cPlanes = VideoModeInformation.NumberOfPlanes;
|
|
pGdiInfo->ulVRefresh = VideoModeInformation.Frequency;
|
|
|
|
if (ppdev->ulBitCount == 8)
|
|
{
|
|
// It is Palette Managed.
|
|
|
|
pGdiInfo->ulNumColors = 20;
|
|
pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;
|
|
|
|
pGdiInfo->flRaster = 0; // DDI reserved field
|
|
}
|
|
else
|
|
{
|
|
pGdiInfo->ulNumColors = (ULONG)-1;
|
|
pGdiInfo->ulNumPalReg = 0;
|
|
|
|
pGdiInfo->flRaster = 0; // DDI reserved field
|
|
|
|
}
|
|
|
|
pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
|
|
pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
|
|
|
|
pGdiInfo->flTextCaps = TC_RA_ABLE;
|
|
|
|
pGdiInfo->ulDACRed = VideoModeInformation.NumberRedBits;
|
|
pGdiInfo->ulDACGreen = VideoModeInformation.NumberGreenBits;
|
|
pGdiInfo->ulDACBlue = VideoModeInformation.NumberBlueBits;
|
|
|
|
pGdiInfo->xStyleStep = 1; // A style unit is 3 pels
|
|
pGdiInfo->yStyleStep = 1;
|
|
pGdiInfo->denStyleStep = 3;
|
|
|
|
pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio
|
|
pGdiInfo->ulAspectY = 0x24;
|
|
pGdiInfo->ulAspectXY = 0x33;
|
|
|
|
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, "FRAMEBUF 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;
|
|
|
|
if (32 == ppdev->ulBitCount)
|
|
pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
|
|
else
|
|
pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
|
|
|
|
pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
|
|
|
|
// Fill in the basic devinfo structure
|
|
|
|
*pDevInfo = gDevInfoFrameBuffer;
|
|
|
|
|
|
if (ppdev->ulBitCount == 8)
|
|
{
|
|
// It is a palette managed device
|
|
|
|
pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED |
|
|
GCAPS_COLOR_DITHER |
|
|
GCAPS_OPAQUERECT); // New for Daytona?
|
|
|
|
pDevInfo->flGraphicsCaps |= (GCAPS_ALTERNATEFILL | GCAPS_WINDINGFILL);
|
|
|
|
// We dither on this, non-zero cxDither and cyDither
|
|
|
|
pDevInfo->iDitherFormat = BMF_8BPP;
|
|
}
|
|
else if (ppdev->ulBitCount == 16)
|
|
{
|
|
pDevInfo->iDitherFormat = BMF_16BPP;
|
|
}
|
|
else
|
|
{
|
|
pDevInfo->iDitherFormat = BMF_32BPP;
|
|
}
|
|
|
|
//
|
|
// Disable 64 bit access if the hardware does not support it.
|
|
//
|
|
|
|
if (VideoModeInformation.AttributeFlags & VIDEO_MODE_NO_64_BIT_ACCESS)
|
|
{
|
|
DISPDBG((0, "Disable 64 bit access on this device !\n"));
|
|
pDevInfo->flGraphicsCaps |= GCAPS_NO64BITMEMACCESS;
|
|
}
|
|
|
|
// Allocate space for the color translation buffer.
|
|
// Allocate enough space to handle the current X resolution.
|
|
|
|
ppdev->pjColorXlateBuffer = (PBYTE) EngAllocMem (0, ppdev->lDeltaScreen, ALLOC_TAG);
|
|
|
|
if ((PBYTE) NULL == ppdev->pjColorXlateBuffer)
|
|
{
|
|
DISPDBG ((0, "TGA.DLL!bInitPDEV - Unable to allocate space for ColorXlateBuffer\n"));
|
|
DISPDBG ((0, "TGA.DLL!bInitPDEV - Bytes attempting to allocate [%d]\n",
|
|
ppdev->lDeltaScreen));
|
|
return FALSE;
|
|
}
|
|
|
|
// Allocate space for the 'merged' cursor buffer.
|
|
//
|
|
// This buffer is used only for 24 plane boards that have
|
|
// TGA-based cursor management enabled.
|
|
|
|
ppdev->pjCursorBuffer = (PBYTE) EngAllocMem (0, TGA_CURSOR_BUFFER_SIZE, ALLOC_TAG);
|
|
|
|
DISPDBG ((2, "TGA.DLL!bInitPDEV - pjCursorBuffer [%08x], size [%d]\n",
|
|
ppdev->pjCursorBuffer, TGA_CURSOR_BUFFER_SIZE));
|
|
|
|
if ((PBYTE) NULL == ppdev->pjCursorBuffer)
|
|
{
|
|
DISPDBG ((0, "TGA.DLL!bInitPDEV - Unable to allocate space for CursurBuffer\n"));
|
|
DISPDBG ((0, "TGA.DLL!bInitPDEV - Bytes attempting to allocate [%d]\n",
|
|
TGA_CURSOR_BUFFER_SIZE));
|
|
return FALSE;
|
|
}
|
|
|
|
// Fetch the PCI Class/Revision Register
|
|
|
|
if (EngDeviceIoControl (ppdev->hDriver, // Device handle
|
|
IOCTL_VIDEO_FETCH_PCRR, // IOCTL code
|
|
NULL, // Input buffer
|
|
0, // Input buffer bytes
|
|
&pcrr, // Output buffer
|
|
sizeof (ULONG), // Output buffer bytes
|
|
&ulTemp)) // Bytes returned
|
|
{
|
|
DISPDBG ((0, "TGA: FETCH_PCRR failed - Defaulting to TGA Pass 3\n"));
|
|
ppdev->ulTgaVersion = TGA_PASS_3;
|
|
}
|
|
else
|
|
ppdev->ulTgaVersion = pcrr & 0x000000ff;
|
|
|
|
// Fetch the processor generation
|
|
|
|
#if 0
|
|
//
|
|
// This is no longer used.
|
|
//
|
|
|
|
if (EngDeviceIoControl(ppdev->hDriver,
|
|
IOCTL_VIDEO_TEST_EV4,
|
|
NULL,
|
|
0,
|
|
&ppdev->bEV4,
|
|
sizeof (ULONG),
|
|
&ulTemp))
|
|
{
|
|
DISPDBG ((0, "TGA: TEST_EV4 failed - Defaulting to EV5 processor\n"));
|
|
ppdev->bEV4 = FALSE;
|
|
}
|
|
|
|
DISPDBG ((0, "TGA: Is machine EV4 ? %d\n", ppdev->bEV4));
|
|
#endif
|
|
|
|
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, "tga.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)
|
|
EngAllocMem (FL_ZERO_MEMORY,
|
|
modes.NumModes * modes.ModeInformationLength,
|
|
ALLOC_TAG);
|
|
|
|
if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
|
|
{
|
|
DISPDBG ((0, "tga.dll 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, "tga.dll 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 not
|
|
// the passed in pixel depth.
|
|
|
|
while (ulTemp--)
|
|
{
|
|
if ((pVideoTemp->NumberOfPlanes != 1) ||
|
|
(! (pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS)))
|
|
{
|
|
pVideoTemp->Length = 0;
|
|
}
|
|
|
|
pVideoTemp = (PVIDEO_MODE_INFORMATION)
|
|
(((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
|
|
}
|
|
|
|
return modes.NumModes;
|
|
|
|
}
|