|
|
/******************************Module*Header*******************************\
* Module Name: driver.h * * Contains prototypes for the display driver. * * Copyright (c) 1992-1994 Microsoft Corporation \**************************************************************************/
//////////////////////////////////////////////////////////////////////
// Put all the conditional-compile constants here. There had better
// not be many!
// Set this bit when GDI's HOOK_SYNCHRONIZEACCESS works so that we don't
// have to worry about synchronizing device-bitmap access. Note that
// this wasn't an option in the first release of NT:
#define SYNCHRONIZEACCESS_WORKS 1
// We have no hardware patterns:
#define FASTFILL_PATTERNS 0
#define SLOWFILL_PATTERNS 1
// This is the maximum number of boards we'll support in a single
// virtual driver:
#define MAX_BOARDS 1
// We don't do any banking with the 8514/A:
#define GDI_BANKING 0
// Useful for visualizing the 2-d heap:
#define DEBUG_HEAP 0
//////////////////////////////////////////////////////////////////////
// Miscellaneous shared stuff
#define DLL_NAME L"8514a" // Name of the DLL in UNICODE
#define STANDARD_DEBUG_PREFIX "8514/A: " // All debug output is prefixed
// by this string
#define ALLOC_TAG '158D' // D851
// Four byte tag (characters in
// reverse order) used for memory
// allocations
#define CLIP_LIMIT 50 // We'll be taking 800 bytes of stack space
#define DRIVER_EXTRA_SIZE 0 // Size of the DriverExtra information in the
// DEVMODE structure
#define TMP_BUFFER_SIZE 8192 // Size in bytes of 'pvTmpBuffer'. Has to
// be at least enough to store an entire
// scan line
typedef struct _CLIPENUM { LONG c; RECTL arcl[CLIP_LIMIT]; // Space for enumerating complex clipping
} CLIPENUM; /* ce, pce */
typedef struct _PDEV PDEV; // Handy forward declaration
extern BYTE gaRop3FromMix[];
VOID vSetClipping(PDEV*, RECTL*); VOID vResetClipping(PDEV*); VOID vDataPortOut(PDEV*, VOID*, ULONG); VOID vDataPortOutB(PDEV*, VOID*, ULONG); VOID vDataPortIn(PDEV*, VOID*, ULONG);
//////////////////////////////////////////////////////////////////////
// Text stuff
typedef struct _XLATECOLORS { // Specifies foreground and background
ULONG iBackColor; // colours for faking a 1bpp XLATEOBJ
ULONG iForeColor; } XLATECOLORS; /* xlc, pxlc */
BOOL bEnableText(PDEV*); VOID vDisableText(PDEV*); VOID vAssertModeText(PDEV*, BOOL);
VOID vFastText(GLYPHPOS*, ULONG, BYTE*, ULONG, ULONG, RECTL*, RECTL*, FLONG, RECTL*, RECTL*); VOID vClearMemDword(ULONG*, ULONG);
//////////////////////////////////////////////////////////////////////
// Dither stuff
// Describes a single colour tetrahedron vertex for dithering:
typedef struct _VERTEX_DATA { ULONG ulCount; // Number of pixels in this vertex
ULONG ulVertex; // Vertex number
} VERTEX_DATA; /* vd, pv */
VERTEX_DATA* vComputeSubspaces(ULONG, VERTEX_DATA*); VOID vDitherColor(ULONG*, VERTEX_DATA*, VERTEX_DATA*, ULONG);
//////////////////////////////////////////////////////////////////////
// Brush stuff
// 'Slow' brushes are used when we don't have hardware pattern capability,
// and we have to handle patterns using screen-to-screen blts:
#define SLOW_BRUSH_CACHE_DIM 3 // Controls the number of brushes cached
// in off-screen memory, when we don't
// have the S3 hardware pattern support.
// We allocate 3 x 3 brushes, so we can
// cache a total of 9 brushes:
#define SLOW_BRUSH_COUNT (SLOW_BRUSH_CACHE_DIM * SLOW_BRUSH_CACHE_DIM)
#define SLOW_BRUSH_DIMENSION 64 // After alignment is taken care of,
// every off-screen brush cache entry
// will be 64 pels in both dimensions
#define SLOW_BRUSH_ALLOCATION (SLOW_BRUSH_DIMENSION + 8)
// Actually allocate 72x72 pels for each
// pattern, using the 8 extra for brush
// alignment
// 'Fast' brushes are used when we have hardware pattern capability:
#define FAST_BRUSH_COUNT 16 // Total number of non-hardware brushes
// cached off-screen
#define FAST_BRUSH_DIMENSION 8 // Every off-screen brush cache entry
// is 8 pels in both dimensions
#define FAST_BRUSH_ALLOCATION 8 // We have to align ourselves, so this is
// the dimension of each brush allocation
// Common to both implementations:
#define RBRUSH_2COLOR 1 // For RBRUSH flags
#define TOTAL_BRUSH_COUNT max(FAST_BRUSH_COUNT, SLOW_BRUSH_COUNT)
// This is the maximum number of brushes
// we can possibly have cached off-screen
#define TOTAL_BRUSH_SIZE 64 // We'll only ever handle 8x8 patterns,
// and this is the number of pels
typedef struct _BRUSHENTRY BRUSHENTRY;
// NOTE: Changes to the RBRUSH or BRUSHENTRY structures must be reflected
// in strucs.inc!
typedef struct _RBRUSH { FLONG fl; // Type flags
BOOL bTransparent; // TRUE if brush was realized for a transparent
// blt (meaning colours are white and black),
// FALSE if not (meaning it's already been
// colour-expanded to the correct colours).
// Value is undefined if the brush isn't
// 2 colour.
BRUSHENTRY* pbe; // Points to brush-entry that keeps track
// of the cached off-screen brush bits
ULONG ulForeColor; // Foreground colour if 1bpp
ULONG ulBackColor; // Background colour if 1bpp
POINTL ptlBrushOrg; // Brush origin of cached pattern. Initial
// value should be -1
ULONG aulPattern[1]; // Open-ended array for keeping copy of the
// Don't put anything // actual pattern bits in case the brush
// after here, or // origin changes, or someone else steals
// you'll be sorry! // our brush entry (declared as a ULONG
// for proper dword alignment)
} RBRUSH; /* rb, prb */
typedef struct _BRUSHENTRY { RBRUSH* prbVerify; // We never dereference this pointer to
// find a brush realization; it is only
// ever used in a compare to verify
// that for a given realized brush, our
// off-screen brush entry is still valid.
LONG x; // x-position of cached pattern
LONG y; // y-position of cached pattern
} BRUSHENTRY; /* be, pbe */
typedef union _RBRUSH_COLOR { RBRUSH* prb; ULONG iSolidColor; } RBRUSH_COLOR; /* rbc, prbc */
BOOL bEnableBrushCache(PDEV*); VOID vDisableBrushCache(PDEV*); VOID vAssertModeBrushCache(PDEV*, BOOL);
/////////////////////////////////////////////////////////////////////////
// Heap stuff
typedef enum { OFL_INUSE = 1, // The device bitmap is no longer located in
// off-screen memory; it's been converted to
// a DIB
OFL_AVAILABLE = 2, // Space is in-use
OFL_PERMANENT = 4 // Space is available
} OHFLAGS; // Space is permanently allocated; never free it
typedef struct _DSURF DSURF; typedef struct _OH OH; typedef struct _OH { OHFLAGS ofl; // OH_ flags
LONG x; // x-coordinate of left edge of allocation
LONG y; // y-coordinate of top edge of allocation
LONG cx; // Width in pixels of allocation
LONG cy; // Height in pixels of allocation
OH* pohNext; // When OFL_AVAILABLE, points to the next free node,
// in ascending cxcy value. This is kept as a
// circular doubly-linked list with a sentinel
// at the end.
// When OFL_INUSE, points to the next most recently
// blitted allocation. This is kept as a circular
// doubly-linked list so that the list can be
// quickly be updated on every blt.
OH* pohPrev; // Opposite of 'pohNext'
ULONG cxcy; // Width and height in a dword for searching
OH* pohLeft; // Adjacent allocation when in-use or available
OH* pohUp; OH* pohRight; OH* pohDown; DSURF* pdsurf; // Points to our DSURF structure
}; /* oh, poh */
// This is the smallest structure used for memory allocations:
typedef struct _OHALLOC OHALLOC; typedef struct _OHALLOC { OHALLOC* pohaNext; OH aoh[1]; } OHALLOC; /* oha, poha */
typedef struct _HEAP { LONG cxMax; // Largest possible free space by area
LONG cyMax; OH ohAvailable; // Head of available list (pohNext points to
// smallest available rectangle, pohPrev
// points to largest available rectangle,
// sorted by cxcy)
OH ohDfb; // Head of the list of all DFBs currently in
// offscreen memory that are eligible to be
// tossed out of the heap (pohNext points to
// the most recently blitted; pohPrev points
// to least recently blitted)
OH* pohFreeList; // List of OH node data structures available
OHALLOC* pohaChain; // Chain of allocations
} HEAP; /* heap, pheap */
typedef enum { DT_SCREEN, // Surface is kept in screen memory
DT_DIB // Surface is kept as a DIB
} DSURFTYPE; /* dt, pdt */
typedef struct _DSURF { DSURFTYPE dt; // DSURF status (whether off-screen or in a DIB)
SIZEL sizl; // Size of the original bitmap (could be smaller
// than poh->sizl)
PDEV* ppdev; // Need this for deleting the bitmap
union { OH* poh; // If DT_SCREEN, points to off-screen heap node
SURFOBJ* pso; // If DT_DIB, points to locked GDI surface
};
// The following are used for DT_DIB only...
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
// this DIB
} DSURF; /* dsurf, pdsurf */
// Off-screen heap allocations have no 'x' alignment:
#define HEAP_X_ALIGNMENT 1
// Number of blts necessary before we'll consider putting a DIB DFB back
// into off-screen memory:
#define HEAP_COUNT_DOWN 6
// Flags for 'pohAllocate':
typedef enum { FLOH_ONLY_IF_ROOM = 0x00000001, // Don't kick stuff out of off-
// screen memory to make room
} FLOH;
BOOL bEnableOffscreenHeap(PDEV*); VOID vDisableOffscreenHeap(PDEV*); BOOL bAssertModeOffscreenHeap(PDEV*, BOOL);
OH* pohMoveOffscreenDfbToDib(PDEV*, OH*); BOOL bMoveDibToOffscreenDfbIfRoom(PDEV*, DSURF*); OH* pohAllocatePermanent(PDEV*, LONG, LONG); BOOL bMoveAllDfbsFromOffscreenToDibs(PDEV* ppdev);
/////////////////////////////////////////////////////////////////////////
// Pointer stuff
BOOL bEnablePointer(PDEV*); VOID vDisablePointer(PDEV*); VOID vAssertModePointer(PDEV*, BOOL);
/////////////////////////////////////////////////////////////////////////
// Palette stuff
BOOL bEnablePalette(PDEV*); VOID vDisablePalette(); VOID vAssertModePalette(PDEV*, BOOL);
BOOL bInitializePalette(PDEV*, DEVINFO*); VOID vUninitializePalette(PDEV*);
#define MAX_CLUT_SIZE (sizeof(VIDEO_CLUT) + (sizeof(ULONG) * 256))
//////////////////////////////////////////////////////////////////////
// Low-level blt function prototypes
typedef VOID (FNFILL)(PDEV*, LONG, RECTL*, ULONG, ULONG, RBRUSH_COLOR, POINTL*); typedef VOID (FNXFER)(PDEV*, LONG, RECTL*, ULONG, ULONG, SURFOBJ*, POINTL*, RECTL*, XLATEOBJ*); typedef VOID (FNCOPY)(PDEV*, LONG, RECTL*, ULONG, POINTL*, RECTL*); typedef VOID (FNMASK)(PDEV*, LONG, RECTL*, ULONG, ULONG, SURFOBJ*, POINTL*, SURFOBJ*, POINTL*, RECTL*, ULONG, RBRUSH*, POINTL*, XLATEOBJ*); typedef VOID (FNFASTLINE)(PDEV*, PATHOBJ*, RECTL*, PFNSTRIP*, LONG, ULONG, ULONG); typedef BOOL (FNFASTFILL)(PDEV*, LONG, POINTFIX*, ULONG, ULONG, ULONG, RBRUSH*);
FNFILL vIoFillPatFast; FNFILL vIoFillPatSlow; FNFILL vIoFillSolid; FNXFER vIoXfer1bpp; FNXFER vIoXfer1bppPacked; FNXFER vIoXfer4bpp; FNXFER vIoXferNative; FNCOPY vIoCopyBlt; FNMASK vIoMaskCopy; FNFASTLINE vIoFastLine; FNFASTFILL bIoFastFill;
VOID vPutBits(PDEV*, SURFOBJ*, RECTL*, POINTL*); VOID vGetBits(PDEV*, SURFOBJ*, RECTL*, POINTL*); VOID vIoSlowPatRealize(PDEV*, RBRUSH*, BOOL);
////////////////////////////////////////////////////////////////////////
// Capabilities flags
typedef enum { CAPS_MASKBLT_CAPABLE = 0x0001, // Hardware is capable of maskblts
CAPS_SW_POINTER = 0x0002, // No hardware pointer; use software
// simulation
CAPS_MINIPORT_POINTER = 0x0004, // Use miniport hardware pointer
} CAPS;
// Status flags
typedef enum { STAT_GLYPH_CACHE = 0x0001, // Glyph cache successfully allocated
STAT_BRUSH_CACHE = 0x0002, // Brush cache successfully allocated
} STATUS;
////////////////////////////////////////////////////////////////////////
// The Physical Device data structure
typedef struct _PDEV { LONG xOffset; LONG yOffset; ULONG iBitmapFormat; // BMF_8BPP or BMF_16BPP or BMF_32BPP
// (our current colour depth)
// Enhanced mode register addresses.
ULONG ioCur_y; ULONG ioCur_x; ULONG ioDesty_axstp; ULONG ioDestx_diastp; ULONG ioErr_term; ULONG ioMaj_axis_pcnt; ULONG ioGp_stat_cmd; ULONG ioShort_stroke; ULONG ioBkgd_color; ULONG ioFrgd_color; ULONG ioWrt_mask; ULONG ioRd_mask; ULONG ioColor_cmp; ULONG ioBkgd_mix; ULONG ioFrgd_mix; ULONG ioMulti_function; ULONG ioPix_trans;
CAPS flCaps; // CAPS_ capabilities flags
STATUS flStatus; // STAT_ status flags
BOOL bEnabled; // In graphics mode (not full-screen)
// -------------------------------------------------------------------
// NOTE: Changes up to here in the PDEV structure must be reflected in
// i386\strucs.inc (assuming you're on an x86, of course)!
LONG iBoard; // Logical multi-board identifier
HANDLE hDriver; // Handle to \Device\Screen
HDEV hdevEng; // Engine's handle to PDEV
HSURF hsurfScreen; // Engine's handle to screen surface
DSURF* pdsurfScreen; // Our private DSURF for the screen
BYTE* pjScreen; // Points to base screen address
BYTE* pjMmBase; // Start of memory mapped I/O
LONG cxScreen; // Visible screen width
LONG cyScreen; // Visible screen height
LONG cxMemory; // Width of Video RAM
LONG cyMemory; // Height of Video RAM
ULONG ulMode; // Mode the mini-port driver is in.
LONG lDelta; // Distance from one scan to the next.
FLONG flHooks; // What we're hooking from GDI
LONG cPelSize; // 0 if 8bpp, 1 if 16bpp, 2 if 32bpp
ULONG ulWhite; // 0xff if 8bpp, 0xffff if 16bpp,
// 0xffffffff if 32bpp
VOID* pvTmpBuffer; // General purpose temporary buffer,
// TMP_BUFFER_SIZE bytes in size
// (Remember to synchronize if you
// use this for device bitmaps or
// async pointers)
////////// Low-level blt function pointers:
FNFILL* pfnFillSolid; FNFILL* pfnFillPat; FNXFER* pfnXfer1bpp; FNXFER* pfnXfer4bpp; FNXFER* pfnXferNative; FNCOPY* pfnCopyBlt; FNMASK* pfnMaskCopy; FNFASTLINE* pfnFastLine; FNFASTFILL* pfnFastFill;
////////// Palette stuff:
PALETTEENTRY* pPal; // The palette if palette managed
HPALETTE hpalDefault; // GDI handle to the default palette.
FLONG flRed; // Red mask for 16/32bpp bitfields
FLONG flGreen; // Green mask for 16/32bpp bitfields
FLONG flBlue; // Blue mask for 16/32bpp bitfields
ULONG cPaletteShift; // number of bits the 8-8-8 palette must
// be shifted by to fit in the hardware
// palette.
////////// Heap stuff:
HEAP heap; // All our off-screen heap data
ULONG iHeapUniq; // Incremented every time room is freed
// in the off-screen heap
////////// Brush stuff:
BOOL bRealizeTransparent; // Hint to DrvRealizeBrush for whether
// the brush should be realized as
// transparent or not
LONG iBrushCache; // Index for next brush to be allocated
LONG cBrushCache; // Total number of brushes cached
BRUSHENTRY abe[TOTAL_BRUSH_COUNT]; // Keeps track of brush cache
////////// Font Stuff
#define GLYPH_CACHE_X (ppdev->ptlGlyphCache.x)
#define GLYPH_CACHE_Y (ppdev->ptlGlyphCache.y)
#define GLYPH_CACHE_CX 32
#define GLYPH_CACHE_CY 32
#define CACHED_GLYPHS_ROWS 4
#define GLYPHS_PER_ROW (512 / GLYPH_CACHE_CX)
BYTE ajGlyphAllocBitVector[CACHED_GLYPHS_ROWS][GLYPHS_PER_ROW]; CLIPOBJ *pcoDefault; // ptr to a default clip obj
POINTL ptlGlyphCache; } PDEV, *PPDEV;
/////////////////////////////////////////////////////////////////////////
// Miscellaneous prototypes:
BOOL bIntersect(RECTL*, RECTL*, RECTL*); LONG cIntersect(RECTL*, RECTL*, LONG); BOOL bFastFill(PDEV*, LONG, POINTFIX*, ULONG, ULONG); DWORD getAvailableModes(HANDLE, PVIDEO_MODE_INFORMATION*, DWORD*);
BOOL bInitializeModeFields(PDEV*, GDIINFO*, DEVINFO*, DEVMODEW*);
BOOL bEnableHardware(PDEV*); VOID vDisableHardware(PDEV*); BOOL bAssertModeHardware(PDEV*, BOOL);
extern BYTE gajHwMixFromMix[];
/////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////
// OVERLAP - Returns TRUE if the same-size lower-right exclusive
// rectangles defined by 'pptl' and 'prcl' overlap:
#define OVERLAP(prcl, pptl) \
(((prcl)->right > (pptl)->x) && \ ((prcl)->bottom > (pptl)->y) && \ ((prcl)->left < ((pptl)->x + (prcl)->right - (prcl)->left)) && \ ((prcl)->top < ((pptl)->y + (prcl)->bottom - (prcl)->top)))
// These Dbg prototypes are thunks for debugging:
VOID DbgDisableDriver(VOID); ULONG DbgGetModes(HANDLE, ULONG, DEVMODEW*); DHPDEV DbgEnablePDEV(DEVMODEW*, PWSTR, ULONG, HSURF*, ULONG, ULONG*, ULONG, DEVINFO*, HDEV, PWSTR, HANDLE); VOID DbgCompletePDEV(DHPDEV, HDEV); HSURF DbgEnableSurface(DHPDEV); BOOL DbgStrokePath(SURFOBJ*, PATHOBJ*, CLIPOBJ*, XFORMOBJ*, BRUSHOBJ*, POINTL*, LINEATTRS*, MIX); BOOL DbgFillPath(SURFOBJ*, PATHOBJ*, CLIPOBJ*, BRUSHOBJ*, POINTL*, MIX, FLONG); BOOL DbgBitBlt(SURFOBJ*, SURFOBJ*, SURFOBJ*, CLIPOBJ*, XLATEOBJ*, RECTL*, POINTL*, POINTL*, BRUSHOBJ*, POINTL*, ROP4); VOID DbgDisablePDEV(DHPDEV); VOID DbgDisableSurface(DHPDEV); BOOL DbgAssertMode(DHPDEV, BOOL); VOID DbgMovePointer(SURFOBJ*, LONG, LONG, RECTL*); ULONG DbgSetPointerShape(SURFOBJ*, SURFOBJ*, SURFOBJ*, XLATEOBJ*, LONG, LONG, LONG, LONG, RECTL*, FLONG); ULONG DbgDitherColor(DHPDEV, ULONG, ULONG, ULONG*); BOOL DbgSetPalette(DHPDEV, PALOBJ*, FLONG, ULONG, ULONG); BOOL DbgCopyBits(SURFOBJ*, SURFOBJ*, CLIPOBJ*, XLATEOBJ*, RECTL*, POINTL*); BOOL DbgTextOut(SURFOBJ*, STROBJ*, FONTOBJ*, CLIPOBJ*, RECTL*, RECTL*, BRUSHOBJ*, BRUSHOBJ*, POINTL*, MIX); VOID DbgDestroyFont(FONTOBJ*); BOOL DbgPaint(SURFOBJ*, CLIPOBJ*, BRUSHOBJ*, POINTL*, MIX); BOOL DbgRealizeBrush(BRUSHOBJ*, SURFOBJ*, SURFOBJ*, SURFOBJ*, XLATEOBJ*, ULONG); HBITMAP DbgCreateDeviceBitmap(DHPDEV, SIZEL, ULONG); VOID DbgDeleteDeviceBitmap(DHSURF); BOOL DbgStretchBlt(SURFOBJ*, SURFOBJ*, SURFOBJ*, CLIPOBJ*, XLATEOBJ*, COLORADJUSTMENT*, POINTL*, RECTL*, RECTL*, POINTL*, ULONG);
//////////////////////////////////////////////////////////////////////////
typedef struct { LONG x; LONG y; LONG z; } XYZPOINTL;
typedef XYZPOINTL *PXYZPOINTL; typedef XYZPOINTL XYZPOINT; typedef XYZPOINT *PXYZPOINT;
// Font & Text stuff
typedef struct _cachedGlyph { HGLYPH hg; struct _cachedGlyph *pcgCollisionLink; ULONG fl; POINTL ptlOrigin; SIZEL sizlBitmap; ULONG BmPitchInPels; ULONG BmPitchInBytes; XYZPOINTL xyzGlyph; } CACHEDGLYPH, *PCACHEDGLYPH;
#define VALID_GLYPH 0x01
#define END_COLLISIONS 0
typedef struct _cachedFont { struct _cachedFont *pcfNext; ULONG iUniq; ULONG cGlyphs; ULONG cjMaxGlyph1; PCACHEDGLYPH pCachedGlyphs; } CACHEDFONT, *PCACHEDFONT;
// Clipping Control Stuff
typedef struct { ULONG c; RECTL arcl[8]; } ENUMRECTS8;
typedef ENUMRECTS8 *PENUMRECTS8;
|