Leaked source code of windows server 2003
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.
 
 
 
 
 
 

532 lines
19 KiB

/******************************Module*Header**********************************\
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: gdi.h
*
* Contains all the gdi related stuff
*
* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#ifndef __GDI__H__
#define __GDI__H__
typedef struct _PDev PDev;
#define CLIP_LIMIT 50 // We'll take 800 bytes of stack space
typedef struct _ClipEnum
{
LONG c;
RECTL arcl[CLIP_LIMIT]; // Space for enumerating complex clipping
} ClipEnum; /* ce, pce */
//
// Text stuff. Specifies foreground and background colours for faking a 1bpp
// XLATEOBJ
//
typedef struct _XlateColors
{
ULONG iBackColor;
ULONG iForeColor;
} XlateColors;
#define SF_VM 0x01 // kept in video memory
#define SF_SM 0x02 // kept in system memory
#define SF_AGP 0x04 // kept in AGP memory
#define SF_LIST 0x08 // in surface list
#define SF_ALLOCATED 0x10 // surface memory allocated by us
#define SF_DIRECTDRAW 0x20 // wrapper of a Direct Draw surface
typedef ULONG SurfFlags;
typedef struct _Surf
{
SurfFlags flags; // Type (video memory or system memory)
PDev* ppdev; // Need this for deleting the bitmap
struct _Surf* psurfNext;
struct _Surf* psurfPrev;
ULONG cBlt; // Counts down the number of blts necessary
// at the current uniqueness before we'll
// consider putting the DIB back into
// off-screen memory
ULONG iUniq; // Tells us whether there have been any
// heap 'free's since the last time we
// looked at
LONG cx; // Bitmap width in pixels
LONG cy; // Bitmap height in pixels
union
{
ULONG ulByteOffset; // Offset from start of video memory if
// DT_VM
VOID* pvScan0; // pointer to system memory if DT_SM
};
LONG lDelta; // Stride in bytes for this bitmap
VIDEOMEMORY* pvmHeap; // DirectDraw heap this was allocated from
HSURF hsurf; // Handle to associated GDI surface (if any)
// this DIB
// New fields to support linear heap allocation of surface
// Only valid if dt == DT_VM
ULONG ulPackedPP; // padcked partial products needed by
// Permedia hardware for given surface
// lDelta
ULONG ulPixOffset; // Pixel Offset from start of video memory
ULONG ulPixDelta; // stride in pixels
ULONG ulChecksum;
} Surf; // dsurf, pdsurf
#define NUM_BUFFER_POINTS 96 // Maximum number of points in a path
// for which we'll attempt to join
// all the path records so that the
// path may still be drawn by FastFill
#define FIX_SHIFT 4L
#define FIX_MASK (- (1 << FIX_SHIFT))
//
// Maximum number of rects we'll fill per call to the fill code
//
#define MAX_PATH_RECTS 50
#define RECT_BYTES (MAX_PATH_RECTS * sizeof(RECTL))
#define EDGE_BYTES (TMP_BUFFER_SIZE - RECT_BYTES)
#define MAX_EDGES (EDGE_BYTES/sizeof(EDGE))
#define RIGHT 0
#define LEFT 1
#define NEARLY_ONE 0x0000FFFF
//
// Describe a single non-horizontal edge of a path to fill.
//
typedef struct _EDGE
{
PVOID pNext;
INT iScansLeft;
INT X;
INT Y;
INT iErrorTerm;
INT iErrorAdjustUp;
INT iErrorAdjustDown;
INT iXWhole;
INT iXDirection;
INT iWindingDirection;
} EDGE, *PEDGE;
typedef struct _EDGEDATA
{
LONG lCurrentXPos; // Current x position
LONG lXAdvance; // Number of pixels to advance x on each scan
LONG lError; // Current DDA error
LONG lErrorUp; // DDA error increment on each scan
LONG lErrorDown; // DDA error adjustment
POINTFIX* pptfx; // Points to start of current edge
LONG lPtfxDelta; // Delta (in bytes) from pptfx to next point
LONG lNumOfScanToGo; // Number of scans to go for this edge
} EDGEDATA; // Ed, pEd
//
//
// The x86 C compiler insists on making a divide and modulus operation
// into two DIVs, when it can in fact be done in one. So we use this
// macro.
//
// Note: QUOTIENT_REMAINDER implicitly takes unsigned arguments.
#if defined(i386)
#define QUOTIENT_REMAINDER(ulNumerator, ulDenominator, ulQuotient, ulRemainder) \
{ \
__asm mov eax, ulNumerator \
__asm sub edx, edx \
__asm div ulDenominator \
__asm mov ulQuotient, eax \
__asm mov ulRemainder, edx \
}
#else
#define QUOTIENT_REMAINDER(ulNumerator, ulDenominator, ulQuotient, ulRemainder) \
{ \
ulQuotient = (ULONG) ulNumerator / (ULONG) ulDenominator; \
ulRemainder = (ULONG) ulNumerator % (ULONG) ulDenominator; \
}
#endif
//
// Rendering constant definition
//
#define __RENDER_TEXTURE_ENABLE (1 << 13)
#define __FX_TEXREADMODE_SWRAP_REPEAT (1 << 1)
#define __FX_TEXREADMODE_TWRAP_REPEAT (1 << 3)
#define __FX_TEXREADMODE_8HIGH (3 << 13)
#define __FX_TEXREADMODE_8WIDE (3 << 9)
#define __FX_TEXREADMODE_2048HIGH (11 << 13)
#define __FX_TEXREADMODE_2048WIDE (11 << 9)
#define __FX_TEXTUREREADMODE_PACKED_DATA (1 << 24)
#define __FX_8x8REPEAT_TEXTUREREADMODE ( __PERMEDIA_ENABLE \
| __FX_TEXREADMODE_TWRAP_REPEAT \
| __FX_TEXREADMODE_SWRAP_REPEAT \
| __FX_TEXREADMODE_8HIGH \
| __FX_TEXREADMODE_8WIDE)
#define __FX_TEXTUREDATAFORMAT_32BIT_RGBA 0x00
#define __FX_TEXTUREDATAFORMAT_32BIT 0x10
#define __FX_TEXTUREDATAFORMAT_8BIT 0xe
#define __FX_TEXTUREDATAFORMAT_16BIT 0x11
#define __FX_TEXTUREDATAFORMAT_4BIT 0xf
#define __P2_TEXTURE_DATAFORMAT_FLIP (1 << 9)
#define __FX_TEXLUTMODE_DIRECT_ENTRY (1 << 1)
#define __FX_TEXLUTMODE_4PIXELS_PER_ENTRY (2 << 10) //log2
#define __FX_TEXLUTMODE_2PIXELS_PER_ENTRY (1 << 10) //log2
#define __FX_TEXLUTMODE_1PIXEL_PER_ENTRY 0 //log2
#define STRETCH_MAX_EXTENT 32767
//
//-----------------------Function***Prototypes--------------------------------
//
// Low-level blt function prototypes
//
//----------------------------------------------------------------------------
typedef struct _GFNPB
{
VOID (*pgfn)(struct _GFNPB *); // pointer to graphics function
PDev * ppdev; // driver ppdev
Surf * psurfDst; // destination surface
RECTL * prclDst; // original unclipped destination rectangle
Surf * psurfSrc; // source surface
RECTL * prclSrc; // original unclipped source rectangle
POINTL * pptlSrc; // original unclipped source point
// NOTE: pdsurfSrc must be null if
// there is no source. If there is
// a source either (pptlSrc must be
// valid) or (pptlSrc is NULL and prclSrc
// is valid).
RECTL * pRects; // rectangle list
LONG lNumRects; // number of rectangles in list
ULONG colorKey; // colorKey for transparent operations
ULONG solidColor; // solid color used in fills
RBrush * prbrush; // pointer to brush
POINTL * pptlBrush; // brush origin
CLIPOBJ * pco; // clipping object
XLATEOBJ * pxlo; // color translatoin object
POINTL * pptlMask; // original uncliped mask origin
ULONG ulRop4; // original rop4
UCHAR ucAlpha; // alpha value for constant blends
TRIVERTEX * ptvrt; // verticies used for gradient fills
ULONG ulNumTvrt; // number of verticies
PVOID pvMesh; // connectivity for gradient fills
ULONG ulNumMesh; // number of connectivity elements
ULONG ulMode; // drawing mode
SURFOBJ * psoSrc; // GDI managed surface source
SURFOBJ * psoDst; // GDI managed surface destination
} GFNPB;
long flt_to_fix_1_30(float f);
BOOL bConstructGET(EDGE* pGETHead,
EDGE* pFreeEdges,
PATHOBJ* ppo,
PATHDATA* pd,
BOOL bMore,
RECTL* pClipRect);
EDGE* pAddEdgeToGET(EDGE* pGETHead,
EDGE* pFreeEdge,
POINTFIX* ppfxEdgeStart,
POINTFIX* ppfxEdgeEnd,
RECTL* pClipRect);
void vAdjustErrorTerm(INT* pErrorTerm,
INT iErrorAdjustUp,
INT iErrorAdjustDown,
INT yJump,
INT* pXStart,
INT iXDirection);
VOID vAdvanceAETEdges(EDGE* pAETHead);
VOID vMoveNewEdges(EDGE* pGETHead,
EDGE* pAETHead,
INT iCurrentY);
VOID vXSortAETEdges(EDGE* pAETHead);
//
// Prototypes for lower level rendering functions
//
BOOL bFillPolygon(PDev* ppdev,
Surf* pSurfDst,
LONG lEdges,
POINTFIX* pptfxFirst,
ULONG ulSolidColor,
ULONG ulRop4,
CLIPOBJ* pco,
RBrush* prb,
POINTL* pptlBrush);
BOOL bFillSpans(PDev* ppdev,
Surf* pSurfDst,
LONG lEdges,
POINTFIX* pptfxFirst,
POINTFIX* pptfxTop,
POINTFIX* pptfxLast,
ULONG ulSolidColor,
ULONG ulRop4,
CLIPOBJ* pco,
RBrush* prb,
POINTL* pptlBrush);
BOOL bInitializeStrips(PDev* ppdev,
ULONG iSolidColor,
DWORD logicop,
RECTL* prclClip);
void vAlphaBlend(GFNPB * ppb);
void vAlphaBlendDownload(GFNPB * ppb);
void vConstantAlphaBlend(GFNPB * ppb);
void vConstantAlphaBlendDownload(GFNPB * ppb);
void vCopyBlt(GFNPB * ppb);
void vCopyBltNative(GFNPB * ppb);
void vGradientFillRect(GFNPB * ppb);
void vGradientFillTri(GFNPB * ppb);
void vImageDownload(GFNPB * ppb);
void vInvert(GFNPB * ppb);
void vMonoDownload(GFNPB * ppb);
void vMonoOffset(GFNPB * ppb);
void vMonoPatFill(GFNPB * ppb);
void vPatFill(GFNPB * ppb);
void vPatternFillRects(GFNPB * ppb);
void vPatRealize(GFNPB * ppb);
void vResetStrips(PDev* ppdev);
void vRop2Blt(GFNPB * ppb);
void vSolidFill(GFNPB * ppb);
void vSolidFillWithRop(GFNPB * ppb);
void vTransparentBlt(GFNPB * ppb);
//
// Text stuff
//
BOOL bEnableText(PDev* ppdev);
VOID vDisableText(PDev* ppdev);
VOID vAssertModeText(PDev* ppdev, BOOL bEnable);
//
// Palette stuff
//
BOOL bEnablePalette(PDev* ppdev);
BOOL bInitializePalette(PDev* ppdev, DEVINFO* pdi);
VOID vDisablePalette(PDev* ppdev);
VOID vUninitializePalette(PDev* ppdev);
//
// Upload and download functions
//
VOID vDownloadNative(GFNPB* ppb);
VOID vUploadNative(GFNPB* ppb);
//
// StretchBlt stuff
//
DWORD dwGetPixelSize(ULONG ulBitmapFormat,
DWORD* pdwFormatBits,
DWORD* pdwFormatExtention);
BOOL bStretchInit(SURFOBJ* psoDst,
SURFOBJ* psoSrc);
VOID vStretchBlt(SURFOBJ* psoDst,
SURFOBJ* psoSrc,
RECTL* rDest,
RECTL* rSrc,
RECTL* prclClip);
VOID vStretchReset(PDev* ppdev);
//
// Work in progress
//
VOID vCheckGdiContext(PPDev ppdev);
VOID vOldStyleDMA(PPDev ppdev);
VOID vNewStyleDMA(PPDev ppdev);
// Input buffer access methods
//
// InputBufferStart/InputBufferContinue/InputBufferCommit
//
// This method is used when the caller does not know
// the upper limit of the amount of space that needs to be reserved
// or needs to reserve space that exceeds that maximum allowed to
// be reserved MAX_FIFO_RESERVATION.
//
// InputBufferStart() is used to get a pointer to the first available entry in
// the input fifo, a pointer to the end of the reservation and
// a pointer to the end of the usable area of the buffer.
//
// InputBufferContinue() is called to extend the current reservation.
//
// InputBufferCommit() is called when the caller is done using the reserved space.
//
// Please see textout.c for an example usage of these methods.
//
// InputBufferReserve/InputBufferCommit
//
// This method is used when the caller needs to make only one
// reservation of some small known quantity.
//
// InputBufferReserve() is called to establish the reservation.
//
// InputBufferCommit() is called when the caller is done using the reserved space.
//
// Please see textout.c for the usage of InputBufferReserve/InputBufferCommit.
//
// A caller is free to use these access methods at any time. Once either
// InputBufferStart or InputBufferReserve is called, the caller must pair the
// call with either a InputBufferFinish or a InputBufferCommit before making
// another reservation.
//
// A caller is free to use either of these methods at any time.
//
// Before calling any of the CPermedia class access methods, the caller
// must call InputBufferFlush (see below). Because of this, a caller must
// call InputBufferFlush or InputBufferExecute before returning to GDI.
//
// When the caller is done and wishes to initial the transmission of what
// has been placed in the input fifo, the caller can call InputBufferExecute
// (see below).
//
// InputBufferFlush
//
// InputBufferFlush is a neccessary evil only as long as these macros are not
// part of the official input buffer access schemes. Flush is really
// the means we sync up our copy of the input buffer state to the
// CPermedia class. If these methods were instead part of the fundamental
// input fifo mechanism, then we could do away with the need for Flush.
//
// InputBufferExecute
//
// Flush is a neccessary evil only as long as these macros are not
// part of the official input buffer access schemes. If and when these
// new access schemes are made part of the official input fifo buffer
// mechanism, then it can be replaced by that mechanism's input fifo
// execute method.
//
//
// InputBufferMakeSpace
//
// This is a private call and no one should find need to call it directly.
//
//
// Other Notes:
//
// We will play with making the access routines inline functions instead
// of macros taking a look at the code generated. If acceptable,
// these macros may turn into function calls in the non-Debug build.
//
// The InputBufferStart/InputBufferContinue mechansism keeps state on the stack
// to avoid the dereferences to ppdev freeing up a register in cases where ppdev
// references are not needed in the inner loop that contains InputBufferContinue.
//
// MAX_IN_FIFO_RESERVATION should be bumped up considerably when we add an
// emulation buffer for the non-DMA case
#define MAX_INPUT_BUFFER_RESERVATION (INPUT_BUFFER_SIZE>>3) // in longs
#if DBG
extern
void InputBufferStart(
PPDev ppdev,
ULONG ulLongs,
PULONG* ppulBuffer,
PULONG* ppulBufferEnd,
PULONG* ppulReservationEnd);
extern
void InputBufferContinue(
PPDev ppdev,
ULONG ulLongs,
PULONG* ppulBuffer,
PULONG* ppulBufferEnd,
PULONG* ppulReservationEnd);
extern
void InputBufferReserve(
PPDev ppdev,
ULONG ulLongs,
PULONG* ppulBuffer);
extern
void InputBufferCommit(
PPDev ppdev,
PULONG pulBuffer);
#else
#define InputBufferStart(ppdev, ulLongs, ppulBuffer, ppulBufferEnd, ppulReservationEnd) \
{ \
*(ppulBuffer) = ppdev->pulInFifoPtr; \
*(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \
*(ppulBufferEnd) = ppdev->pulInFifoEnd; \
if(*(ppulReservationEnd) > *(ppulBufferEnd)) \
{ \
InputBufferSwap(ppdev); \
*(ppulBuffer) = ppdev->pulInFifoPtr; \
*(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \
*(ppulBufferEnd) = ppdev->pulInFifoEnd; \
} \
}
#define InputBufferContinue(ppdev, ulLongs, ppulBuffer, ppulBufferEnd, ppulReservationEnd) \
{ \
*(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \
if(*(ppulReservationEnd) > *(ppulBufferEnd)) \
{ \
ppdev->pulInFifoPtr = *(ppulBuffer); \
InputBufferSwap(ppdev); \
*(ppulBuffer) = ppdev->pulInFifoPtr; \
*(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \
*(ppulBufferEnd) = ppdev->pulInFifoEnd; \
} \
}
#define InputBufferReserve(ppdev, ulLongs, ppulBuffer) \
{ \
if(ppdev->pulInFifoPtr + ulLongs > ppdev->pulInFifoEnd) \
{ \
InputBufferSwap(ppdev); \
} \
*(ppulBuffer) = ppdev->pulInFifoPtr; \
}
#define InputBufferCommit(ppdev, pulBuffer) ppdev->pulInFifoPtr = pulBuffer
#endif
void FASTCALL InputBufferFlush(PPDev ppdev);
void FASTCALL InputBufferSwap(PPDev ppdev);
void InputBufferSync(PPDev ppdev);
extern BOOL bGdiContext;
#endif // __GDI__H__