Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

852 lines
26 KiB

/******************************Module*Header*******************************\
* Module Name: pointer.c *
* *
* This module contains the pointer support for the framebuffer *
* *
* Copyright (c) 1992 Microsoft Corporation *
* Copyright (c) 1995 IBM Corporation *
\**************************************************************************/
#include "driver.h"
#include "hw.h"
// Look-up table for masking the right edge of the given pointer bitmap:
BYTE gajMask[] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
//
// external functions
//
BOOL bIntersect (
RECTL *prcl1,
RECTL *prcl2,
RECTL *prclResult );
//
// function prototypes
//
VOID vShowHwPointer (
BOOL bShow );
BOOL bSetHwPointerShape (
SURFOBJ *pso,
SURFOBJ *psoMask,
SURFOBJ *psoColor,
XLATEOBJ *pxlo,
LONG x,
LONG y,
FLONG fl );
VOID vShowSimPointer (
PPDEV ppdev,
SURFOBJ *pso,
RECTL *prcl,
BOOL bShow );
BOOL bSetSimPointerShape (
SURFOBJ *pso,
SURFOBJ *psoMask,
SURFOBJ *psoColor,
XLATEOBJ *pxlo,
LONG x,
LONG y,
FLONG fl );
VOID vHwSaveScreen (
PPDEV ppdev,
RECTL *prclSrc,
ULONG ulDst );
VOID vHwRestoreScreen (
PPDEV ppdev,
RECTL *prclDst,
ULONG ulSrc );
/******************************Public*Routine******************************\
* VOID vShowHwPointer
*
* Turns on or off the hardware pointer
*
\**************************************************************************/
VOID vShowHwPointer (
BOOL bShow )
{
OUTPW(EPR_INDEX, SELECT_CUR | DISABLE_INC); // select H/W pointer registers
if (bShow) {
OUTPW(EPR_DATA, INPW(EPR_DATA) | CUR_ENABLE); // enable H/W pointer
} else {
OUTPW(EPR_DATA, INPW(EPR_DATA) & ~CUR_ENABLE); // disable H/W pointer
} /* endif */
}
/******************************Public*Routine******************************\
* BOOL bSetHwPointerShape
*
* Changes the shape of the hardware pointer.
*
* Returns: TRUE if successful, FALSE if pointer shape can't be handled.
*
\**************************************************************************/
BOOL bSetHwPointerShape (
SURFOBJ *pso,
SURFOBJ *psoMask,
SURFOBJ *psoColor,
XLATEOBJ *pxlo,
LONG x,
LONG y,
FLONG fl )
{
PPDEV ppdev = (PPDEV) pso->dhpdev;
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
LONG dx, dy;
ULONG cx, cy;
ULONG cxSrc, cySrc, cxSrcBytes, cxSrcFraction;
ULONG cxDst, cyDst, cxDstBytes;
LONG lDeltaSrc, lDeltaDst;
ULONG ulOffset;
PUSHORT pusPointerPattern;
PUSHORT pusDst;
PBYTE pjSrcAnd, pjSrcXor, pjSA, pjSX;
//
// Check if new pointer is monochrome or not
//
if ((psoColor != (SURFOBJ *) NULL) ||
(!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER))) {
return FALSE;
} /* endif */
//
// Check if the size of new pointer is smaller than hardware capability
//
cxSrc = psoMask->sizlBitmap.cx;
cySrc = psoMask->sizlBitmap.cy >> 1;
cxSrcBytes = (cxSrc + 7) / 8;
cxSrcFraction = cxSrc % 8; // Number of fractional pels
cxDst = ppdev->PointerCapabilities.MaxWidth;
cyDst = ppdev->PointerCapabilities.MaxHeight;
cxDstBytes = (cxDst + 7) / 8;
if ((cxSrc > cxDst) ||
(cySrc > cyDst) ||
(!(psoMask->fjBitmap & BMF_TOPDOWN))) {
return FALSE;
} /* endif */
//
// Update the attributes of pointer
//
pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER;
pPointerAttributes->Flags &= ~VIDEO_MODE_COLOR_POINTER;
pPointerAttributes->Width = cxSrc;
pPointerAttributes->Height = cySrc;
pPointerAttributes->WidthInBytes = cxSrcBytes;
//
// Set entire pointer pattern area as transparent
//
// Before accessing to the off-screen memory, wait for a while until on-going
// BITBLT completes.
//
ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen;
ulOffset += 64; // skip over solid color pattern used in bitblt.c
pusPointerPattern = (PUSHORT)(ppdev->pjScreen + ulOffset);
WAIT_BLT_COMPLETE(); // wait for BITBLT completion
pusDst = pusPointerPattern;
for (cy = 0; cy < cyDst; cy++) {
for (cx = 0; cx < cxDstBytes; cx++) {
*pusDst++ = 0x00FF;
} /* endfor */
} /* endfor */
//
// Load new pointer pattern in the off-screen memory
//
pjSrcAnd = psoMask->pvBits;
pjSrcXor = pjSrcAnd + cySrc * (ULONG) psoMask->lDelta;
lDeltaSrc = psoMask->lDelta;
lDeltaDst = cxDstBytes;
for (cy = 0; cy < cySrc; cy++) {
pusDst = pusPointerPattern;
pjSA = pjSrcAnd;
pjSX = pjSrcXor;
//
// Interleave AND and XOR bytes
//
for (cx = 0; cx < (cxSrcBytes - 1); cx++) {
*pusDst++ = ( (*pjSA++ & 0x00ff) |
((*pjSX++ & 0x00ff) << 8));
} /* endfor */
//
// Mask off the right edge if bitmap width is not a multiple of 8
//
*pusDst++ = ( (*pjSA++ | gajMask[cxSrcFraction]) |
((*pjSX++ & ~gajMask[cxSrcFraction]) << 8));
pusPointerPattern += lDeltaDst;
pjSrcAnd += lDeltaSrc;
pjSrcXor += lDeltaSrc;
} /* endfor */
//
// Set hardware cursor registers
//
dx = ppdev->ptlHotSpot.x;
dy = ppdev->ptlHotSpot.y;
OUTPW(EPR_INDEX, SELECT_CUR | DISABLE_INC); // select H/W pointer registers
OUTPW(EPR_DATA, CUR_ORIGIN | (USHORT)((dy << 6) | dx));
OUTPW(EPR_DATA, CUR_PAT_LO | (USHORT)(ulOffset >> 2) & 0x0FFF);
OUTPW(EPR_DATA, CUR_PAT_HI | (USHORT)(ulOffset >> 14) & 0x00FF);
OUTPW(EPR_DATA, CUR_PRI_CLR | 0xFF);
OUTPW(EPR_DATA, CUR_SEC_CLR | 0);
OUTPW(EPR_DATA, INPW(EPR_DATA) | 0x0220);
return TRUE;
}
/******************************Public*Routine******************************\
* VOID vShowSimPointer
*
* Show or hide the simulation pointer
*
\**************************************************************************/
VOID vShowSimPointer (
PPDEV ppdev,
SURFOBJ *pso,
RECTL *prcl,
BOOL bShow )
{
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
RECTL rclScreen, rclPointer;
POINTL ptlPointerOffset;
ULONG ulOffset;
BOOL b;
SURFOBJ *psoMask;
SURFOBJ *psoColor;
ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen;
ulOffset += 64; // skip over solid color pattern used in bitblt.c
ulOffset += 1024; // skip over hardware pointer bitmap
if (bShow) {
rclScreen.top = 0;
rclScreen.bottom = ppdev->cyScreen;
rclScreen.left = 0;
rclScreen.right = ppdev->cxScreen;
rclPointer.top = pPointerAttributes->Row - ppdev->ptlHotSpot.y;
rclPointer.bottom = rclPointer.top + pPointerAttributes->Height;
rclPointer.left = pPointerAttributes->Column - ppdev->ptlHotSpot.x;
rclPointer.right = rclPointer.left + pPointerAttributes->Width;
//
// Trim down the simulation cursor beyond the screen
//
if (bIntersect(&rclScreen, &rclPointer, &ppdev->rclPrevPointer)) {
prcl->top = ppdev->rclPrevPointer.top;
prcl->bottom = ppdev->rclPrevPointer.bottom;
prcl->left = ppdev->rclPrevPointer.left;
prcl->right = ppdev->rclPrevPointer.right;
ptlPointerOffset.x = (rclPointer.left >= 0) ? 0 : (rclPointer.left * (-1));
ptlPointerOffset.y = (rclPointer.top >= 0) ? 0 : (rclPointer.top * (-1));
//
// Save the screen image where the pointer affects
//
vHwSaveScreen(ppdev, &ppdev->rclPrevPointer, ulOffset);
//
// Draw the pointer
//
// Note: Clipping the transparent portion of pointer is required for
// better performance.
//
if ((pso != NULL) && (pso->iType == STYPE_DEVICE))
pso = (SURFOBJ *)(((PPDEV)(pso->dhpdev))->pSurfObj);
psoMask = EngLockSurface(ppdev->hsurfMask);
psoColor = EngLockSurface(ppdev->hsurfColor);
b = EngBitBlt(pso, // Target surface
psoColor, // Source surface
psoMask, // Mask
(CLIPOBJ *) NULL, // Clip through this
(XLATEOBJ *) NULL, // Color translation
prcl, // Target offset and extent
&ptlPointerOffset, // Source offset
&ptlPointerOffset, // Mask offset
(BRUSHOBJ *) NULL, // Brush data (from cbRealizeBrush)
(POINTL *) NULL, // Brush offset (origin)
0x0000CC66); // Raster operation
EngUnlockSurface(psoMask);
EngUnlockSurface(psoColor);
} else {
//
// The entire pointer is outside of screen
//
pPointerAttributes->Enable = 0;
} /* endif */
} else {
//
// Restore the screen image corrupted by the simulation pointer
//
vHwRestoreScreen(ppdev, &ppdev->rclPrevPointer, ulOffset);
} /* endif */
}
/******************************Public*Routine******************************\
* BOOL bSetSimPointerShape
*
* Changes the shape of the simulation pointer.
*
* Returns: TRUE if successful, FALSE if pointer shape can't be simulated.
*
\**************************************************************************/
BOOL bSetSimPointerShape (
SURFOBJ *pso,
SURFOBJ *psoMask,
SURFOBJ *psoColor,
XLATEOBJ *pxlo,
LONG x,
LONG y,
FLONG fl )
{
PPDEV ppdev = (PPDEV) pso->dhpdev;
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
ULONG cxSrc, cySrc, cxSrcBytes;
ULONG ulOffset;
HSURF hsurf;
SIZEL sizl;
ULONG ulBitmapType;
FLONG flBitmap;
SURFOBJ *psoSrc;
SURFOBJ *psoDst;
RECTL prclDst;
POINTL pptlSrc;
XLATEOBJ xlo;
ULONG ulXlate[2];
if (!(ppdev->flCaps & CAPS_NEED_SW_POINTER)) {
return FALSE;
} /* endif */
//
// Check if we have enough off-screen memory to hold the screen image underneath
// the new pointer
//
cxSrc = psoMask->sizlBitmap.cx;
cySrc = psoMask->sizlBitmap.cy >> 1;
cxSrcBytes = (cxSrc + 7) / 8;
ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen;
ulOffset += 64; // skip over solid color pattern used in bitblt.c
ulOffset += 1024; // skip over hardware pointer bitmap
if ((ppdev->cScreenSize < ulOffset + cxSrc * cySrc * (ppdev->ulBitCount/8)) ||
(psoMask->iType & STYPE_BITMAP) ||
(!(psoMask->fjBitmap & BMF_TOPDOWN))) {
return FALSE;
} /* endif */
//
// Update the attributes of pointer
//
pPointerAttributes->Width = cxSrc;
pPointerAttributes->Height = cySrc;
pPointerAttributes->WidthInBytes = cxSrcBytes;
//
// Discard the old pointer
//
if (ppdev->hsurfMask != NULL) {
EngDeleteSurface(ppdev->hsurfMask);
EngDeleteSurface(ppdev->hsurfColor);
} /* endif */
//
// Create a copy of mask bitmap
//
sizl.cx = cxSrc;
sizl.cy = cySrc;
flBitmap = BMF_TOPDOWN;
prclDst.top = 0;
prclDst.bottom = cySrc;
prclDst.left = 0;
prclDst.right = cxSrc;
psoSrc = psoMask;
ulBitmapType = BMF_1BPP;
pptlSrc.x = 0;
pptlSrc.y = 0;
if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl,
0, // Let GDI choose ulWidth
ulBitmapType,
flBitmap,
NULL))) { // Let GDI allocate
return FALSE;
} else {
ppdev->hsurfMask = hsurf;
} /* endif */
psoDst = EngLockSurface(ppdev->hsurfMask);
if (!EngCopyBits(psoDst, // Target surface
psoSrc, // Source surface
(CLIPOBJ *) NULL, // Clip through this
(XLATEOBJ *) NULL, // Color translation
&prclDst, // Target offset and extent
&pptlSrc)) { // Source offset
EngDeleteSurface(ppdev->hsurfMask);
return FALSE;
} /* endif */
EngUnlockSurface(psoDst);
//
// Create a copy of pointer bitmap
//
ulBitmapType = pso->iBitmapFormat;
if (psoColor == (SURFOBJ *) NULL) {
//
// Use second half of mask bitmap if it is monochrome
//
pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER;
pPointerAttributes->Flags &= ~VIDEO_MODE_COLOR_POINTER;
psoSrc = psoMask;
pptlSrc.x = 0;
pptlSrc.y = cySrc;
//
// Create the translation table for monochrome-to-color conversion
//
pxlo = &xlo;
xlo.iUniq = 0;
xlo.flXlate = XO_TABLE;
xlo.iSrcType = PAL_INDEXED;
xlo.iDstType = (ppdev->ulBitCount == 8) ? PAL_INDEXED : PAL_RGB;
xlo.cEntries = 2;
xlo.pulXlate = (ULONG *)ulXlate;
ulXlate[0] = 0x00000000; // Black
ulXlate[1] = (ppdev->ulBitCount == 8) ? 0x000000FF : 0x00FFFFFF; // White
} else {
pPointerAttributes->Flags &= ~VIDEO_MODE_MONO_POINTER;
pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER;
psoSrc = psoColor;
pptlSrc.x = 0;
pptlSrc.y = 0;
} /* endif */
if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl,
0, // Let GDI choose ulWidth
ulBitmapType,
flBitmap,
NULL))) { // Let GDI allocate
EngDeleteSurface(ppdev->hsurfMask);
return FALSE;
} else {
ppdev->hsurfColor = hsurf;
} /* endif */
psoDst = EngLockSurface(ppdev->hsurfColor);
if (!EngCopyBits(psoDst, // Target surface
psoSrc, // Source surface
(CLIPOBJ *) NULL, // Clip through this
pxlo, // Color translation
&prclDst, // Target offset and extent
&pptlSrc)) { // Source offset
EngDeleteSurface(ppdev->hsurfMask);
EngDeleteSurface(ppdev->hsurfColor);
return FALSE;
} /* endif */
EngUnlockSurface(psoDst);
return TRUE;
}
/******************************Public*Routine******************************\
* VOID vHwSaveScreen
*
* Save screen image to off-screen memory using WD hardware accelerator
*
\**************************************************************************/
VOID vHwSaveScreen (
PPDEV ppdev,
RECTL *prclSrc,
ULONG ulDst )
{
ULONG source, target, direction, width, height;
//
// Copy the screen image inside the rectangle to the off-screen memory in linear
//
width = prclSrc->right - prclSrc->left;
height = prclSrc->bottom - prclSrc->top;
direction = 0; // Start BITBLT at top left corner of rectangle
source = prclSrc->top * ppdev->lDeltaScreen + prclSrc->left;
target = ulDst;
//
// Adjust start address if 16bpp mode
//
if (ppdev->ulBitCount == 16) {
source += prclSrc->left;
width *= 2;
} /* endif */
WAIT_BLT_COMPLETE(); // wait for BITBLT completion
OUTPW(EPR_DATA, BLT_CTRL2 | 0);
OUTPW(EPR_DATA, BLT_SRC_LO | (USHORT)( source & 0x0FFF));
OUTPW(EPR_DATA, BLT_SRC_HI | (USHORT)((source >> 12) & 0x01FF));
OUTPW(EPR_DATA, BLT_DST_LO | (USHORT)( target & 0x0FFF));
OUTPW(EPR_DATA, BLT_DST_HI | (USHORT)((target >> 12) & 0x01FF));
OUTPW(EPR_DATA, BLT_SIZE_X | (USHORT)width);
OUTPW(EPR_DATA, BLT_SIZE_Y | (USHORT)height);
OUTPW(EPR_DATA, BLT_DELTA | (USHORT)ppdev->lDeltaScreen);
OUTPW(EPR_DATA, BLT_ROPS | 0x0300); // source copy operation
OUTPW(EPR_DATA, BLT_PLANE | 0x00FF); // enable all planes
OUTPW(EPR_DATA, BLT_CTRL1 | 0x0980 | (USHORT)direction ); // start BITBLT
return;
}
/******************************Public*Routine******************************\
* VOID vHwRestoreScreen
*
* Restore screen image from off-screen memory using WD hardware accelerator
*
\**************************************************************************/
VOID vHwRestoreScreen (
PPDEV ppdev,
RECTL *prclDst,
ULONG ulSrc )
{
ULONG source, target, direction, width, height;
//
// Retrieve the screen image from the off-screen memory
//
width = prclDst->right - prclDst->left;
height = prclDst->bottom - prclDst->top;
direction = 0; // Start BITBLT at top left corner of rectangle
source = ulSrc;
target = prclDst->top * ppdev->lDeltaScreen + prclDst->left;
//
// Adjust start address if 16bpp mode
//
if (ppdev->ulBitCount == 16) {
target += prclDst->left;
width *= 2;
} /* endif */
WAIT_BLT_COMPLETE(); // wait for BITBLT completion
OUTPW(EPR_DATA, BLT_CTRL2 | 0);
OUTPW(EPR_DATA, BLT_SRC_LO | (USHORT)( source & 0x0FFF));
OUTPW(EPR_DATA, BLT_SRC_HI | (USHORT)((source >> 12) & 0x01FF));
OUTPW(EPR_DATA, BLT_DST_LO | (USHORT)( target & 0x0FFF));
OUTPW(EPR_DATA, BLT_DST_HI | (USHORT)((target >> 12) & 0x01FF));
OUTPW(EPR_DATA, BLT_SIZE_X | (USHORT)width);
OUTPW(EPR_DATA, BLT_SIZE_Y | (USHORT)height);
OUTPW(EPR_DATA, BLT_DELTA | (USHORT)ppdev->lDeltaScreen);
OUTPW(EPR_DATA, BLT_ROPS | 0x0300); // source copy operation
OUTPW(EPR_DATA, BLT_PLANE | 0x00FF); // enable all planes
OUTPW(EPR_DATA, BLT_CTRL1 | 0x0940 | (USHORT)direction ); // start BITBLT
return;
}
/******************************Public*Routine******************************\
* VOID DrvMovePointer
*
* Moves the pointer to a new position.
*
\**************************************************************************/
VOID DrvMovePointer (
SURFOBJ *pso,
LONG x,
LONG y,
RECTL *prcl )
{
PPDEV ppdev = (PPDEV) pso->dhpdev;
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
DWORD returnedDataLength;
VIDEO_POINTER_POSITION NewPointerPosition;
if (x == -1) {
//
// A new position of (-1,-1) means hide the pointer.
//
if (ppdev->fHwCursorActive) {
vShowHwPointer(FALSE);
} else {
if (pPointerAttributes->Enable)
vShowSimPointer(ppdev, pso, prcl, FALSE);
} /* endif */
pPointerAttributes->Enable = 0;
} else {
//
// Remove the pointer from the screen
//
if (!ppdev->fHwCursorActive) {
if (pPointerAttributes->Enable)
vShowSimPointer(ppdev, pso, prcl, FALSE);
} /* endif */
pPointerAttributes->Column = (SHORT) x;
pPointerAttributes->Row = (SHORT) y;
pPointerAttributes->Enable = 1;
//
// Draw the pointer at the new location
//
if (ppdev->fHwCursorActive) {
vShowHwPointer(TRUE); // Actually, miniport driver will change the location later
} else {
vShowSimPointer(ppdev, pso, prcl, TRUE);
} /* endif */
//
// Call miniport driver to adjust the visible region of virtual screen
//
NewPointerPosition.Column = (SHORT) x;
NewPointerPosition.Row = (SHORT) y;
if (EngDeviceIoControl(ppdev->hDriver,
IOCTL_VIDEO_SET_POINTER_POSITION,
&NewPointerPosition,
sizeof(VIDEO_POINTER_POSITION),
NULL,
0,
&returnedDataLength))
{
// Not the end of the world, print warning in checked build.
DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_SET_POINTER_POSITION\n"));
}
} /* endif */
}
/******************************Public*Routine******************************\
* ULONG DrvSetPointerShape
*
* Sets the new pointer shape.
*
\**************************************************************************/
ULONG DrvSetPointerShape (
SURFOBJ *pso,
SURFOBJ *psoMask,
SURFOBJ *psoColor,
XLATEOBJ *pxlo,
LONG xHot,
LONG yHot,
LONG x,
LONG y,
RECTL *prcl,
FLONG fl )
{
PPDEV ppdev = (PPDEV) pso->dhpdev;
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
//
// See if we are being asked to hide the pointer
//
if (psoMask == (SURFOBJ *) NULL) {
if (ppdev->fHwCursorActive) {
vShowHwPointer(FALSE);
} else {
if (pPointerAttributes->Enable)
vShowSimPointer(ppdev, pso, prcl, FALSE);
} /* endif */
pPointerAttributes->Enable = 0;
return TRUE;
}
//
// Save the hot spot of the cursor
//
ppdev->ptlHotSpot.x = xHot;
ppdev->ptlHotSpot.y = yHot;
//
// Check if we can handle this pointer in hardware
//
if (bSetHwPointerShape(pso,psoMask,psoColor,pxlo,x,y,fl)) {
//
// Take the old pointer off the screen
//
if (ppdev->fHwCursorActive) {
// do nothing here
} else {
if (pPointerAttributes->Enable)
vShowSimPointer(ppdev, pso, prcl, FALSE);
} /* endif */
ppdev->fHwCursorActive = TRUE;
pPointerAttributes->Enable = 0;
//
// Draw the new pointer
//
DrvMovePointer(pso, x, y, (RECTL *)NULL);
//
// Accept the new pointer
//
return SPS_ACCEPT_NOEXCLUDE;
//
// Try to simulate the pointer in place of the engine simulation to keep track of
// pointer location for the virtual screen
//
} else if (bSetSimPointerShape(pso,psoMask,psoColor,pxlo,x,y,fl)) {
//
// Take the old pointer off the screen
//
if (ppdev->fHwCursorActive) {
vShowHwPointer(FALSE);
} else {
if (pPointerAttributes->Enable)
vShowSimPointer(ppdev, pso, prcl, FALSE);
} /* endif */
ppdev->fHwCursorActive = FALSE;
pPointerAttributes->Enable = 0;
//
// Draw the new pointer
//
DrvMovePointer(pso, x, y, prcl);
//
// Signal GDI to move the pointer before reading from/writting to prcl
//
return SPS_ACCEPT_EXCLUDE;
//
// Give up to handle this pointer. Let GDI simulate it.
//
} else {
//
// Take the old pointer off the screen
//
if (ppdev->fHwCursorActive) {
vShowHwPointer(FALSE);
} else {
if (pPointerAttributes->Enable)
vShowSimPointer(ppdev, pso, prcl, FALSE);
} /* endif */
ppdev->fHwCursorActive = FALSE;
pPointerAttributes->Enable = 0;
//
// Decline to realize the new pointer shape
//
return SPS_DECLINE;
} /* endif */
}
/******************************Public*Routine******************************\
* BOOL bInitPointer
*
* Initialize the Pointer attributes.
*
\**************************************************************************/
BOOL bInitPointer (
PPDEV ppdev,
DEVINFO *pdevinfo )
{
if (ppdev->ulBitCount == 8) {
ppdev->PointerCapabilities.Flags = VIDEO_MODE_MONO_POINTER;
ppdev->PointerCapabilities.MaxWidth = 64;
ppdev->PointerCapabilities.MaxHeight = 64;
ppdev->PointerCapabilities.HWPtrBitmapStart = (ULONG) -1;
ppdev->PointerCapabilities.HWPtrBitmapEnd = (ULONG) -1;
} else {
ppdev->PointerCapabilities.Flags = 0; // no hardware pointer in 16bpp mode
ppdev->PointerCapabilities.MaxWidth = 0;
ppdev->PointerCapabilities.MaxHeight = 0;
ppdev->PointerCapabilities.HWPtrBitmapStart = (ULONG) -1;
ppdev->PointerCapabilities.HWPtrBitmapEnd = (ULONG) -1;
} /* endif */
ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL;
ppdev->cjPointerAttributes = 0; // initialized in screen.c
// Note: The buffer itself is allocated after we set the
// mode. At that time we know the pixel depth and we can
// allocate the correct size for the color pointer if supported.
// Set the asynchronous support status (async means miniport is capable of
// drawing the Pointer at any time, with no interference with any ongoing
// drawing operation)
pdevinfo->flGraphicsCaps &= ~GCAPS_ASYNCMOVE; // drawing must be synchronized by GDI
ppdev->hsurfMask = (HSURF) NULL;
ppdev->hsurfColor = (HSURF) NULL;
return TRUE;
}