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.
456 lines
11 KiB
456 lines
11 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: pointer.c
|
|
*
|
|
* This module contains the hardware pointer support for the XGA dispaly driver.
|
|
*
|
|
*
|
|
* Copyright (c) 1992 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "driver.h"
|
|
|
|
ULONG DrvSetColorPointerShape(
|
|
SURFOBJ *pso,
|
|
SURFOBJ *psoMask,
|
|
SURFOBJ *psoColor,
|
|
XLATEOBJ *pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl,
|
|
FLONG fl
|
|
) ;
|
|
|
|
ULONG DrvSetMonoHwPointerShape(
|
|
SURFOBJ *pso,
|
|
SURFOBJ *psoMask,
|
|
SURFOBJ *psoColor,
|
|
XLATEOBJ *pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl,
|
|
FLONG fl
|
|
) ;
|
|
|
|
|
|
VOID DrvMoveColorPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl) ;
|
|
VOID DrvMoveHwPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl) ;
|
|
|
|
|
|
#define VALID_SAVE_BUFFER 0x1
|
|
#define COLOR_POINTER 0x2
|
|
#define TAKE_DOWN_POINTER 0X4
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
* DrvMovePointer -
|
|
****************************************************************************/
|
|
VOID DrvMovePointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl)
|
|
{
|
|
PPDEV ppdev ;
|
|
|
|
ppdev = (PPDEV) pso->dhpdev ;
|
|
|
|
if (ppdev->gPointerFlags & COLOR_POINTER)
|
|
DrvMoveColorPointer(pso, x, y, prcl) ;
|
|
else
|
|
DrvMoveHwPointer(pso, x, y, prcl) ;
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* DrvMoveColorPointer -
|
|
****************************************************************************/
|
|
VOID DrvMoveColorPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl)
|
|
{
|
|
return ;
|
|
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* DrvMoveHwPointer -
|
|
****************************************************************************/
|
|
VOID DrvMoveHwPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl)
|
|
{
|
|
WORD msb,
|
|
lsb ;
|
|
|
|
PPDEV ppdev ;
|
|
INT XgaIndexReg ;
|
|
|
|
// get a local pointer to the pdev and all the registers we plan
|
|
// to use.
|
|
|
|
ppdev = (PPDEV) pso->dhpdev ;
|
|
XgaIndexReg = ppdev->ulXgaIoRegsBase + INDEX_REG ;
|
|
|
|
// If x is -1 then take down the cursor.
|
|
|
|
if (x == -1)
|
|
{
|
|
outpw (XgaIndexReg, SPRITE_CONTROL) ;
|
|
return ;
|
|
}
|
|
|
|
// Adjust the actual pointer position depending upon
|
|
// the hot spot.
|
|
|
|
x -= ppdev->gxHot ;
|
|
y -= ppdev->gyHot ;
|
|
|
|
if (x <= 0)
|
|
{
|
|
outpw (XgaIndexReg, ((-x << 8) | SPRITE_HORZ_PRESET)) ;
|
|
x = 0 ;
|
|
}
|
|
else
|
|
{
|
|
outpw (XgaIndexReg, ((0 << 8) | SPRITE_HORZ_PRESET)) ;
|
|
}
|
|
|
|
if (y <= 0)
|
|
{
|
|
outpw (XgaIndexReg, ((-y << 8) | SPRITE_VERT_PRESET)) ;
|
|
y = 0 ;
|
|
}
|
|
else
|
|
{
|
|
outpw (XgaIndexReg, ((0 << 8) | SPRITE_VERT_PRESET)) ;
|
|
}
|
|
|
|
// Set the position of the cursor.
|
|
|
|
msb = HIBYTE (x) ;
|
|
lsb = LOBYTE (x) ;
|
|
outpw (XgaIndexReg, ((lsb << 8) | SPRITE_HORZ_START_LOW)) ;
|
|
outpw (XgaIndexReg, ((msb << 8) | SPRITE_HORZ_START_HIGH)) ;
|
|
|
|
msb = HIBYTE (y) ;
|
|
lsb = LOBYTE (y) ;
|
|
outpw (XgaIndexReg, ((lsb << 8) | SPRITE_VERT_START_LOW)) ;
|
|
outpw (XgaIndexReg, ((msb << 8) | SPRITE_VERT_START_HIGH)) ;
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* DrvSetPointerShape -
|
|
****************************************************************************/
|
|
ULONG DrvSetPointerShape(
|
|
SURFOBJ *pso,
|
|
SURFOBJ *psoMask,
|
|
SURFOBJ *psoColor,
|
|
XLATEOBJ *pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl,
|
|
FLONG fl)
|
|
{
|
|
ULONG ulRet ;
|
|
|
|
PPDEV ppdev ;
|
|
INT XgaIndexReg ;
|
|
|
|
DISPDBG((3, "Change hardware pointer shape\n"));
|
|
|
|
// get a local pointer to the pdev and all the registers we plan
|
|
// to use.
|
|
|
|
ppdev = (PPDEV) pso->dhpdev ;
|
|
XgaIndexReg = ppdev->ulXgaIoRegsBase + INDEX_REG ;
|
|
|
|
// Save the position and hot spot in globals.
|
|
|
|
ppdev->gxHot = xHot ;
|
|
ppdev->gyHot = yHot ;
|
|
|
|
if (psoColor != NULL)
|
|
{
|
|
// Disable the mono hardware pointer.
|
|
|
|
outpw (XgaIndexReg, SPRITE_CONTROL) ;
|
|
|
|
ppdev->gPointerFlags |= COLOR_POINTER ;
|
|
ulRet = DrvSetColorPointerShape(pso, psoMask, psoColor, pxlo,
|
|
xHot, yHot, x, y, prcl, fl) ;
|
|
|
|
}
|
|
else
|
|
{
|
|
// Take down the color pointer if it is visible.
|
|
|
|
if ( (ppdev->gPointerFlags & COLOR_POINTER)
|
|
&& (ppdev->gPointerFlags & VALID_SAVE_BUFFER)
|
|
)
|
|
{
|
|
ulRet = DrvSetColorPointerShape(NULL, NULL, NULL, NULL,
|
|
0, 0, 0, 0, NULL, 0) ;
|
|
}
|
|
|
|
// Take care of the monochrome pointer.
|
|
|
|
ppdev->gPointerFlags &= ~COLOR_POINTER ;
|
|
ulRet = DrvSetMonoHwPointerShape(pso, psoMask, psoColor, pxlo,
|
|
xHot, yHot, x, y, prcl, fl) ;
|
|
}
|
|
|
|
|
|
return (ulRet) ;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* DrvSetColorPointerShape -
|
|
****************************************************************************/
|
|
ULONG DrvSetColorPointerShape(
|
|
SURFOBJ *pso,
|
|
SURFOBJ *psoMask,
|
|
SURFOBJ *psoColor,
|
|
XLATEOBJ *pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl,
|
|
FLONG fl)
|
|
{
|
|
return (SPS_DECLINE) ;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* DrvSetMonoHwPointerShape -
|
|
****************************************************************************/
|
|
ULONG DrvSetMonoHwPointerShape(
|
|
SURFOBJ *pso,
|
|
SURFOBJ *psoMask,
|
|
SURFOBJ *psoColor,
|
|
XLATEOBJ *pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl,
|
|
FLONG fl)
|
|
{
|
|
|
|
UINT i,
|
|
j,
|
|
cxMask,
|
|
cyMask,
|
|
cyAND,
|
|
cxAND,
|
|
cyXOR,
|
|
cxXOR ;
|
|
|
|
PBYTE pjAND,
|
|
pjXOR ;
|
|
|
|
INT lDelta ;
|
|
|
|
PPDEV ppdev ;
|
|
INT XgaIndexReg ;
|
|
|
|
INT ix,
|
|
iy,
|
|
is,
|
|
ip,
|
|
iBit,
|
|
jAndByte,
|
|
jXorByte,
|
|
jSpriteBits,
|
|
jSpriteByte ;
|
|
|
|
BYTE ajAndMask[64][8],
|
|
ajXorMask[64][8] ;
|
|
|
|
BYTE ajXgaSprite[1024] ;
|
|
|
|
|
|
DISPDBG((3, "XGA.DLL:DrvSetPointerShape - Entry\n")) ;
|
|
DISPDBG((3, "\txHot: %d\n", xHot)) ;
|
|
DISPDBG((3, "\tyHot: %d\n", yHot)) ;
|
|
|
|
// get a local pointer to the pdev and all the registers we plan
|
|
// to use.
|
|
|
|
ppdev = (PPDEV) pso->dhpdev ;
|
|
XgaIndexReg = ppdev->ulXgaIoRegsBase + INDEX_REG ;
|
|
|
|
// If the mask is NULL this implies the pointer is not
|
|
// visible.
|
|
|
|
if (psoMask == NULL)
|
|
{
|
|
outpw (XgaIndexReg, SPRITE_CONTROL) ;
|
|
return (SPS_ACCEPT_NOEXCLUDE) ;
|
|
}
|
|
|
|
// Init the AND and XOR masks.
|
|
|
|
memset (ajAndMask, 0xFFFFFFFF, 512) ;
|
|
memset (ajXorMask, 0, 512) ;
|
|
|
|
// Get the bitmap dimensions.
|
|
|
|
cxMask = psoMask->sizlBitmap.cx ;
|
|
cyMask = psoMask->sizlBitmap.cy ;
|
|
|
|
cyAND = cyXOR = cyMask / 2 ;
|
|
cxAND = cxXOR = cxMask / 8 ;
|
|
|
|
// Set up pointers to the AND and XOR masks.
|
|
|
|
pjAND = psoMask->pvScan0 ;
|
|
lDelta = psoMask->lDelta ;
|
|
pjXOR = pjAND + (cyAND * lDelta) ;
|
|
|
|
// Copy the AND mask.
|
|
|
|
for (i = 0 ; i < cyAND ; i++)
|
|
{
|
|
// Copy over a line of the AND mask.
|
|
|
|
for (j = 0 ; j < cxAND ; j++)
|
|
{
|
|
ajAndMask[i][j] = pjAND[j] ;
|
|
}
|
|
|
|
// point to the next line of the AND mask.
|
|
|
|
pjAND += lDelta ;
|
|
}
|
|
|
|
// Copy the XOR mask.
|
|
|
|
for (i = 0 ; i < cyXOR ; i++)
|
|
{
|
|
// Copy over a line of the XOR mask.
|
|
|
|
for (j = 0 ; j < cxXOR ; j++)
|
|
{
|
|
ajXorMask[i][j] = pjXOR[j] ;
|
|
}
|
|
|
|
// point to the next line of the XOR mask.
|
|
|
|
pjXOR += lDelta ;
|
|
}
|
|
|
|
// Build up the XGA sprite from NT's And and Xor masks.
|
|
|
|
// Init the indexes into the sprite buffer (is) and the
|
|
// index for the bit pairs (ip).
|
|
|
|
is = 0 ;
|
|
ip = 0 ;
|
|
|
|
// Outer most loop goes over NT's And and Xor rows.
|
|
|
|
for (iy = 0 ; iy < 64 ; iy++)
|
|
{
|
|
// loop over Nt's columns.
|
|
|
|
for (ix = 0 ; ix < 8 ; ix++)
|
|
{
|
|
// pickup a source byte for each mask.
|
|
|
|
jAndByte = ajAndMask[iy][ix] ;
|
|
jXorByte = ajXorMask[iy][ix] ;
|
|
|
|
// loop over the bits in the byte.
|
|
|
|
for (iBit = 0x80 ; iBit != 0 ; iBit >>= 1)
|
|
{
|
|
// init the sprite bitpair.
|
|
|
|
jSpriteBits = 0x0 ;
|
|
|
|
// Set the sprite bit pairs.
|
|
|
|
if (jAndByte & iBit)
|
|
jSpriteBits |= 0x02 ;
|
|
|
|
if (jXorByte & iBit)
|
|
jSpriteBits |= 0x01 ;
|
|
|
|
// If all 4 bit pairs in this byte are filled in
|
|
// flush the sprite byte to the sprite byte array.
|
|
// and set the first bit pair.
|
|
|
|
if ((ip % 4) == 0)
|
|
{
|
|
if (ip != 0)
|
|
{
|
|
ajXgaSprite[is++] = jSpriteByte ;
|
|
}
|
|
jSpriteByte = jSpriteBits ;
|
|
}
|
|
|
|
// If the sprite byte is not full, shift the bit pair
|
|
// into position, and or it into the sprite byte.
|
|
|
|
else
|
|
{
|
|
jSpriteBits <<= (ip % 4) * 2 ;
|
|
jSpriteByte |= jSpriteBits ;
|
|
}
|
|
|
|
// bump the bit pair counter.
|
|
|
|
ip++ ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Flush the last byte.
|
|
|
|
ajXgaSprite[is++] = jSpriteByte ;
|
|
|
|
|
|
// Disable the pointer.
|
|
|
|
outpw (XgaIndexReg, SPRITE_CONTROL) ;
|
|
|
|
// Set the sprite index to 0.
|
|
|
|
outpw (XgaIndexReg, SPRITE_INDEX_LOW) ;
|
|
outpw (XgaIndexReg, SPRITE_INDEX_HIGH) ;
|
|
|
|
// Down load the sprite data to the XGA.
|
|
|
|
for (i = 0 ; i < 1024 ; i++)
|
|
{
|
|
jSpriteByte = ajXgaSprite[i] ;
|
|
outpw (XgaIndexReg, ((jSpriteByte << 8) | SPRITE_DATA)) ;
|
|
}
|
|
|
|
// Set the pointer colors.
|
|
|
|
outpw (XgaIndexReg, SPRITE_COLOR_REG0_RED) ;
|
|
outpw (XgaIndexReg, SPRITE_COLOR_REG0_GREEN) ;
|
|
outpw (XgaIndexReg, SPRITE_COLOR_REG0_BLUE) ;
|
|
|
|
outpw (XgaIndexReg, ((0xff << 8) | SPRITE_COLOR_REG1_RED)) ;
|
|
outpw (XgaIndexReg, ((0xff << 8) | SPRITE_COLOR_REG1_GREEN)) ;
|
|
outpw (XgaIndexReg, ((0xff << 8) | SPRITE_COLOR_REG1_BLUE)) ;
|
|
|
|
// Set the position of the cursor.
|
|
|
|
DrvMovePointer(pso, x, y, NULL) ;
|
|
|
|
outpw (XgaIndexReg, ((SC << 8) | SPRITE_CONTROL)) ;
|
|
|
|
return (SPS_ACCEPT_NOEXCLUDE) ;
|
|
}
|
|
|