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.
1060 lines
30 KiB
1060 lines
30 KiB
/***************************************************************************
|
|
*
|
|
* ******************************************
|
|
* * Copyright (c) 1995, Cirrus Logic, Inc. *
|
|
* * All Rights Reserved *
|
|
* ******************************************
|
|
*
|
|
* PROJECT: Laguna I (CL-GD5462) -
|
|
*
|
|
* FILE: pointer.c
|
|
*
|
|
* AUTHOR: Benny Ng
|
|
*
|
|
* DESCRIPTION:
|
|
* This module contains the SW & HW curosr support for the
|
|
* Laguna NT driver.
|
|
*
|
|
* MODULES:
|
|
* DrvMovePointer()
|
|
* DrvSetPointerShape()
|
|
*
|
|
* REVISION HISTORY:
|
|
* 6/20/95 Benny Ng Initial version
|
|
*
|
|
* $Log: X:/log/laguna/nt35/displays/cl546x/POINTER.C $
|
|
*
|
|
* Rev 1.39 Mar 04 1998 15:30:24 frido
|
|
* Added new shadow macros.
|
|
*
|
|
* Rev 1.38 Jan 19 1998 10:26:26 frido
|
|
* HP#86 (no PDR yet). Removed hardware cursor for 1600x1200 >=65Hz.
|
|
*
|
|
* Rev 1.37 Nov 03 1997 11:30:16 frido
|
|
* Added REQUIRE macros.
|
|
*
|
|
* Rev 1.36 23 Sep 1997 10:48:22 bennyn
|
|
* Not use HW cursor if the resolution is below 640x480
|
|
*
|
|
* Rev 1.35 11 Jun 1997 15:13:14 bennyn
|
|
* Fixed PDR 9747 Punt to SW cursor in 1600x1200x8 & x16 at 65,70,75 Hz
|
|
*
|
|
* Rev 1.34 11 Jun 1997 14:02:30 bennyn
|
|
* Fixed PDR 9741 (animated cursor turns back)
|
|
*
|
|
* Rev 1.33 28 May 1997 14:17:58 bennyn
|
|
* Fixed PDR 9741 and eliminated dead code
|
|
*
|
|
* Rev 1.32 01 May 1997 15:02:12 bennyn
|
|
* Punt the cursor if it is in interlace modes
|
|
*
|
|
* Rev 1.31 09 Apr 1997 10:53:36 SueS
|
|
* Changed type of pointer_switch to eliminate compiler warning.
|
|
*
|
|
* Rev 1.30 08 Apr 1997 15:22:50 SueS
|
|
* Don't use color for monochrome animated cursors - otherwise we'll
|
|
* reference a NULL pointer.
|
|
*
|
|
* Rev 1.29 07 Apr 1997 12:44:50 BENNYN
|
|
* Added the checking ptrmaskhandle equal to NULL
|
|
*
|
|
* Rev 1.28 02 Apr 1997 14:24:14 noelv
|
|
* NT 35.1 wass accessing a NULL pointer in DrvMovePointer
|
|
* Removed SW cursor and chainblt cursor code
|
|
*
|
|
* Rev 1.27 21 Mar 1997 13:37:44 noelv
|
|
*
|
|
* Combined do_flag and sw_test_flag into pointer_switch
|
|
*
|
|
* Rev 1.26 03 Feb 1997 13:35:22 bennyn
|
|
* Modified the 5465 cursor algorithm
|
|
*
|
|
* Rev 1.25 30 Jan 1997 17:15:02 bennyn
|
|
* Added cursor algorithm for 5465
|
|
*
|
|
* Rev 1.24 17 Dec 1996 17:01:10 SueS
|
|
* Added test for writing to log file based on cursor at (0,0).
|
|
*
|
|
* Rev 1.23 10 Dec 1996 14:32:46 bennyn
|
|
*
|
|
* Fixed cursor mask from device bitmap problem
|
|
*
|
|
* Rev 1.22 26 Nov 1996 10:43:04 SueS
|
|
* Changed WriteLogFile parameters for buffering.
|
|
*
|
|
* Rev 1.21 13 Nov 1996 17:00:52 SueS
|
|
* Changed WriteFile calls to WriteLogFile.
|
|
*
|
|
* Rev 1.20 01 Nov 1996 09:26:46 BENNYN
|
|
*
|
|
* Cleanup unused code
|
|
*
|
|
* Rev 1.19 23 Oct 1996 14:44:44 BENNYN
|
|
*
|
|
* Fixed the YUV cursor problems
|
|
*
|
|
* Rev 1.18 06 Sep 1996 09:07:02 noelv
|
|
*
|
|
* Cleaned up NULL driver code.
|
|
*
|
|
* Rev 1.17 26 Aug 1996 17:35:08 bennyn
|
|
*
|
|
* Restore the changes for the losed version
|
|
*
|
|
* Rev 1.16 20 Aug 1996 11:04:20 noelv
|
|
* Bugfix release from Frido 8-19-96
|
|
*
|
|
* Rev 1.3 17 Aug 1996 19:39:20 frido
|
|
* Fixed DirectDraw cursor problem.
|
|
*
|
|
* Rev 1.2 17 Aug 1996 13:34:56 frido
|
|
* New release from Bellevue.
|
|
*
|
|
* Rev 1.1 15 Aug 1996 11:40:18 frido
|
|
* Added precompiled header.
|
|
*
|
|
* Rev 1.0 14 Aug 1996 17:16:30 frido
|
|
* Initial revision.
|
|
*
|
|
* Rev 1.13 25 Jul 1996 15:56:00 bennyn
|
|
*
|
|
* Modified to support DirectDraw
|
|
*
|
|
* Rev 1.12 18 Jun 1996 12:44:18 noelv
|
|
* Fixed the way interleave is calculated.
|
|
*
|
|
* Rev 1.11 28 May 1996 15:11:28 noelv
|
|
* Updated data logging.
|
|
*
|
|
* Rev 1.10 01 May 1996 12:23:30 bennyn
|
|
*
|
|
* Rev 1.9 01 May 1996 12:05:36 bennyn
|
|
* Fixed resolution change bug for NT4.0
|
|
*
|
|
* Rev 1.8 01 May 1996 11:00:48 bennyn
|
|
*
|
|
* Modified for NT4.0
|
|
*
|
|
* Rev 1.7 04 Apr 1996 13:20:24 noelv
|
|
* Frido release 26
|
|
*
|
|
* Rev 1.4 28 Mar 1996 20:22:28 frido
|
|
* Removed warning messages from new Bellevue release.
|
|
*
|
|
* Rev 1.6 25 Mar 1996 18:55:30 noelv
|
|
* Fixed bouncing screeen when cursor is disabled.
|
|
*
|
|
* Rev 1.5 08 Mar 1996 17:27:38 noelv
|
|
*
|
|
* Added NULL_POINTER flag
|
|
*
|
|
* Rev 1.4 07 Mar 1996 18:22:46 bennyn
|
|
*
|
|
* Removed read/modify/write on CONTROL reg
|
|
*
|
|
* Rev 1.3 05 Mar 1996 11:58:26 noelv
|
|
* Frido version 19
|
|
*
|
|
* Rev 1.1 20 Jan 1996 01:22:00 frido
|
|
*
|
|
*
|
|
* Rev 1.10 15 Jan 1996 16:59:58 NOELV
|
|
* AB workaround reductions
|
|
*
|
|
* Rev 1.9 11 Jan 1996 09:22:04 NOELV
|
|
* Removed al 16 bit writes to X,Y,and BLTEXT registers.
|
|
*
|
|
* Rev 1.8 10 Jan 1996 16:20:56 NOELV
|
|
* Added increased logging capabilities.
|
|
* Added null driver capabilities.
|
|
*
|
|
* Rev 1.7 29 Nov 1995 12:11:42 noelv
|
|
*
|
|
* Coded a workaround for HW bug. The screen corrupts sometimes when the curs
|
|
* I changed the code to turn the cursor off as little as possible.
|
|
*
|
|
* Rev 1.6 29 Sep 1995 10:26:20 bennyn
|
|
*
|
|
* Punt the cursor to GDI for 1600x1200 modes
|
|
*
|
|
* Rev 1.5 29 Sep 1995 09:54:58 bennyn
|
|
*
|
|
* Rev 1.4 27 Sep 1995 16:45:40 bennyn
|
|
* Fixed the HW cursor AND mask
|
|
*
|
|
* Rev 1.3 26 Sep 1995 16:27:50 bennyn
|
|
*
|
|
* Rev 1.2 26 Sep 1995 09:35:16 bennyn
|
|
* Enable HW cursor
|
|
*
|
|
* Rev 1.1 21 Aug 1995 13:52:16 NOELV
|
|
* Initial port to real hardware.
|
|
* Converted all 32 bit register writes to 2 16 bit regiser writes.
|
|
*
|
|
* Rev 1.0 25 Jul 1995 11:19:28 NOELV
|
|
* Initial revision.
|
|
*
|
|
* Rev 1.6 06 Jul 1995 09:57:10 BENNYN
|
|
*
|
|
* Fixed the problem switching between full-screen & Windowed DOS box
|
|
*
|
|
* Rev 1.5 29 Jun 1995 09:50:54 BENNYN
|
|
* Fixed the unsupport cursor request problem
|
|
*
|
|
* Rev 1.4 29 Jun 1995 09:01:30 BENNYN
|
|
*
|
|
* Rev 1.3 28 Jun 1995 11:13:32 BENNYN
|
|
* Fixed 16-bit/pixel problem
|
|
*
|
|
* Rev 1.2 22 Jun 1995 13:33:32 BENNYN
|
|
*
|
|
* Added SW cursor auto BLT
|
|
*
|
|
* Rev 1.1 20 Jun 1995 16:09:30 BENNYN
|
|
*
|
|
*
|
|
****************************************************************************
|
|
****************************************************************************/
|
|
|
|
/*----------------------------- INCLUDES ----------------------------------*/
|
|
#include "precomp.h"
|
|
|
|
/*----------------------------- DEFINES -----------------------------------*/
|
|
//#define DBGBRK
|
|
//#define DBGDISP
|
|
#define CURSOR_DBG_LEVEL 1
|
|
|
|
#define MAX_CNT 0x7FFF
|
|
#define BLT_FLAG_BIT 0x2L
|
|
#define BYTES_PER_TILE 0x800 // 2048
|
|
|
|
|
|
/*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/
|
|
|
|
/*--------------------------- ENUMERATIONS --------------------------------*/
|
|
|
|
/*----------------------------- TYPEDEFS ----------------------------------*/
|
|
typedef union _HOST_DATA {
|
|
BYTE bData[4];
|
|
DWORD dwData;
|
|
} HOST_DATA;
|
|
|
|
|
|
/*-------------------------- STATIC VARIABLES -----------------------------*/
|
|
|
|
/*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
|
|
VOID CopyLgHWPtrMaskData(PPDEV ppdev,
|
|
LONG Ycord,
|
|
LONG lSrcDelta,
|
|
LONG cy,
|
|
ULONG tileszx,
|
|
BYTE *pANDSrcScan,
|
|
BYTE *pXORSrcScan);
|
|
|
|
ULONG ConvertMaskBufToLinearAddr(PPDEV ppdev);
|
|
|
|
VOID RestoreSaveShowCursor(PPDEV ppdev,
|
|
LONG x,
|
|
LONG y);
|
|
|
|
#if POINTER_SWITCH_ENABLED
|
|
int pointer_switch=0;
|
|
#endif
|
|
|
|
#if LOG_QFREE
|
|
unsigned long QfreeData[32];
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* FUNCTION NAME: InitPointerHW()
|
|
*
|
|
* DESCRIPTION: Initialization the cursor palette colors.
|
|
*
|
|
****************************************************************************/
|
|
VOID InitPointerHW (PPDEV ppdev)
|
|
{
|
|
ULONG ultmp;
|
|
|
|
// Enable HW cursor color access
|
|
ultmp = LLDR_SZ (grPalette_State);
|
|
ultmp |= 0x8;
|
|
LL8 (grPalette_State, ultmp);
|
|
|
|
// Write HW cursor BK & FG color
|
|
ultmp = 0;
|
|
LL8 (grPalette_Write_Address, ultmp);
|
|
LL8 (grPalette_Data, ultmp);
|
|
LL8 (grPalette_Data, ultmp);
|
|
LL8 (grPalette_Data, ultmp);
|
|
|
|
ultmp = 0xF;
|
|
LL8 (grPalette_Write_Address, ultmp);
|
|
|
|
ultmp = 0xFF;
|
|
LL8 (grPalette_Data, ultmp);
|
|
LL8 (grPalette_Data, ultmp);
|
|
LL8 (grPalette_Data, ultmp);
|
|
|
|
// Disable HW cursor color access
|
|
ultmp = LLDR_SZ (grPalette_State);
|
|
ultmp &= 0xFFF7;
|
|
LL8 (grPalette_State, ultmp);
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* FUNCTION NAME: InitPointer()
|
|
*
|
|
* DESCRIPTION: Initialization the variables used by the pointer.
|
|
*
|
|
* REVISION HISTORY:
|
|
* 6/20/95 Benny Ng Initial version
|
|
****************************************************************************/
|
|
VOID InitPointer(PPDEV ppdev)
|
|
{
|
|
ULONG ultmp;
|
|
SIZEL reqsz;
|
|
|
|
ppdev->PointerUsage = HW_CURSOR;
|
|
DISPDBG((CURSOR_DBG_LEVEL, "HW cursor\n"));
|
|
|
|
ppdev->bYUVuseSWPtr = FALSE;
|
|
ppdev->PtrImageHandle = NULL;
|
|
ppdev->PtrABltHandle = NULL;
|
|
|
|
// Get the current tile size
|
|
if (ppdev->lTileSize == (LONG) 128)
|
|
{
|
|
reqsz.cx = 128;
|
|
reqsz.cy = 8;
|
|
}
|
|
else if (ppdev->lTileSize == (LONG) 256)
|
|
{
|
|
reqsz.cx = 256;
|
|
reqsz.cy = 4;
|
|
}
|
|
else
|
|
{
|
|
reqsz.cx = 1024;
|
|
reqsz.cy = 1;
|
|
};
|
|
|
|
InitPointerHW (ppdev);
|
|
|
|
// Allocate the mask buffer from offscreen memory
|
|
DISPDBG((CURSOR_DBG_LEVEL, "Allocating Pointer Mask\n"));
|
|
ppdev->PtrMaskHandle = AllocOffScnMem(ppdev, &reqsz, 0, NULL);
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->CShsem = NULL;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* FUNCTION NAME: DrvMovePointer()
|
|
*
|
|
* DESCRIPTION: This function Moves the hardware pointer to a new position.
|
|
*
|
|
* REVISION HISTORY:
|
|
* 6/20/95 Benny Ng Initial version
|
|
****************************************************************************/
|
|
VOID DrvMovePointer(SURFOBJ *pso,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl)
|
|
{
|
|
LONG adjx, adjy;
|
|
LONG delaycnt = 0;
|
|
|
|
PPDEV ppdev = (PPDEV) pso->dhpdev;
|
|
|
|
if (x==0 && y==0)
|
|
{
|
|
//
|
|
// This isn't used in the released code. This is test code for setting
|
|
// the sw_test_flag to different values by pointing the cursor to
|
|
// 'special' places. Used to turn different test features on and off.
|
|
//
|
|
#if (POINTER_SWITCH_ENABLED)
|
|
if (pointer_switch)
|
|
pointer_switch = 0;
|
|
else
|
|
pointer_switch = 1;
|
|
#endif
|
|
|
|
#if ENABLE_LOG_SWITCH && POINTER_SWITCH_ENABLED
|
|
if (pointer_switch)
|
|
{
|
|
CreateLogFile(ppdev->hDriver, &ppdev->TxtBuffIndex);
|
|
ppdev->pmfile = ppdev->hDriver; // handle to the miniport
|
|
lg_i = sprintf(lg_buf, "Log file opened\r\n");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
}
|
|
else
|
|
CloseLogFile(ppdev->pmfile, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
#endif
|
|
|
|
#if NULL_HW
|
|
//
|
|
// Enables and disables the "infinitly fast hardware" feature.
|
|
// then "on" all register writes go to a chunk of blank memory
|
|
// on the host. Register reads proceed normally.
|
|
//
|
|
if (ppdev->pLgREGS == ppdev->pLgREGS_real)
|
|
ppdev->pLgREGS = (GAR *)ppdev->buffer;
|
|
else
|
|
ppdev->pLgREGS = ppdev->pLgREGS_real;
|
|
#endif
|
|
|
|
#if LOG_QFREE
|
|
{
|
|
int i;
|
|
|
|
DISPDBG((CURSOR_DBG_LEVEL,"Dumping QFREE log.\n"));
|
|
lg_i = sprintf(lg_buf,"\r\n\r\n");
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
|
|
for (i=0; i<32; ++i)
|
|
{
|
|
lg_i = sprintf(lg_buf,"QFREE %d: %d times.\r\n", i, QfreeData[i]);
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
QfreeData[i] = 0;
|
|
}
|
|
}
|
|
#endif
|
|
} // End if x==0 and y==0
|
|
|
|
|
|
#if LOG_CALLS
|
|
#if ENABLE_LOG_SWITCH
|
|
if (pointer_switch)
|
|
#endif
|
|
{
|
|
lg_i = sprintf(lg_buf,"DrvMovePointer: x=%d, y=%d \r\n", x, y);
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
|
|
}
|
|
#endif
|
|
|
|
|
|
#if NULL_POINTER
|
|
if (pointer_switch) return;
|
|
#endif
|
|
|
|
if ((ppdev->PointerUsage == DEF_CURSOR) ||
|
|
(ppdev->PtrMaskHandle == NULL))
|
|
return;
|
|
|
|
adjx = x;
|
|
adjy = y;
|
|
|
|
// Check whether want to hide the pointer.
|
|
if (x == -1)
|
|
{
|
|
#if HW_PRESET_BUG
|
|
LL16 (grCursor_X, (WORD)0xFFFF);
|
|
LL16 (grCursor_Y, (WORD)0xFFFF);
|
|
#else
|
|
// Disable the Hw cursor by clearing the hw cursor enable
|
|
// bit in CURSOR_CONTROL reg
|
|
ultmp = LLDR_SZ (grCursor_Control);
|
|
if (ultmp & 1)
|
|
{
|
|
ultmp &= 0xFFFE;
|
|
LL16 (grCursor_Control, ultmp);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
else if ((adjx >= 0) && (adjy >= 0))
|
|
{
|
|
// Restore the current pointer area screen image from offscreen memory.
|
|
// Save the new pointer area screen image to offscreen memory.
|
|
// Show the curosr using both AND and XOR masks
|
|
RestoreSaveShowCursor(ppdev, adjx, adjy);
|
|
|
|
ppdev->PtrX = adjx;
|
|
ppdev->PtrY = adjy;
|
|
|
|
if (prcl != NULL)
|
|
{
|
|
prcl->left = ppdev->PtrX;
|
|
prcl->top = ppdev->PtrY;
|
|
prcl->right = prcl->left + ppdev->PtrSzX;
|
|
prcl->bottom = prcl->top + ppdev->PtrSzY;
|
|
|
|
ppdev->prcl.left = prcl->left;
|
|
ppdev->prcl.top = prcl->top;
|
|
ppdev->prcl.right = prcl->right;
|
|
ppdev->prcl.bottom = prcl->bottom;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* FUNCTION NAME: DrvSetPointerShape()
|
|
*
|
|
* DESCRIPTION: This function sets the new pointer shape.
|
|
*
|
|
* REVISION HISTORY:
|
|
* 6/20/95 Benny Ng Initial version
|
|
****************************************************************************/
|
|
ULONG DrvSetPointerShape(SURFOBJ *pso,
|
|
SURFOBJ *psoMask,
|
|
SURFOBJ *psoColor,
|
|
XLATEOBJ *pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl,
|
|
FLONG fl)
|
|
{
|
|
|
|
BOOL bAnimatedCursor = FALSE;
|
|
LONG lSrcDelta;
|
|
ULONG retul;
|
|
ULONG cx, cy;
|
|
LONG bpp;
|
|
SIZEL tilesz;
|
|
SIZEL reqsz;
|
|
BYTE *pANDSrcScan;
|
|
BYTE *pXORSrcScan;
|
|
LONG Ycord;
|
|
ULONG curloc;
|
|
ULONG ultmp;
|
|
PPDEV ppdev = (PPDEV) pso->dhpdev;
|
|
|
|
#if NULL_POINTER
|
|
if (pointer_switch)
|
|
return SPS_ACCEPT_NOEXCLUDE;
|
|
#endif
|
|
|
|
DISPDBG((CURSOR_DBG_LEVEL, "DrvSetPointerShape %d, x=%d, y=%d, xHot=%d, yHot=%d\n",
|
|
ppdev->PointerUsage, x, y, xHot, yHot));
|
|
|
|
// If no HW cursor mask buffer allocated from offscreen memory,
|
|
// or If in intrelace mode, Use SW cursor
|
|
// Use SW cursor
|
|
if ((ppdev->PtrMaskHandle == NULL) || (ppdev->ulFreq < 50))
|
|
return (SPS_DECLINE);
|
|
|
|
// HW cursor bug in 1600x1200-8bpp & 16bpp with refresh rate 65,
|
|
// 70 or 75Hz. Use SW cursor
|
|
if ((ppdev->cxScreen == 1600) && (ppdev->cyScreen == 1200) &&
|
|
((ppdev->ulBitCount == 8) || (ppdev->ulBitCount == 16)))
|
|
{
|
|
if (ppdev->ulFreq >= 65)
|
|
return (SPS_DECLINE);
|
|
};
|
|
|
|
// Don't use HW cursor if resolution below 640x480
|
|
if ((ppdev->cxScreen < 640) || (ppdev->cyScreen < 480))
|
|
return (SPS_DECLINE);
|
|
|
|
// Get dimensions of the pointer
|
|
cx = psoMask->sizlBitmap.cx ;
|
|
cy = psoMask->sizlBitmap.cy >> 1;
|
|
|
|
// Calculate bytes per pixel
|
|
bpp = ppdev->iBytesPerPixel;
|
|
|
|
// Get the current tile size
|
|
if (ppdev->lTileSize == (LONG) 128)
|
|
{
|
|
tilesz.cx = 128;
|
|
tilesz.cy = 16;
|
|
}
|
|
else if (ppdev->lTileSize == (LONG) 256)
|
|
{
|
|
tilesz.cx = 256;
|
|
tilesz.cy = 8;
|
|
}
|
|
else
|
|
{
|
|
tilesz.cx = 2048;
|
|
tilesz.cy = 1;
|
|
};
|
|
|
|
lSrcDelta = psoMask->lDelta;
|
|
retul = SPS_ACCEPT_NOEXCLUDE; // We can still draw while HW cursor is on the screen.
|
|
|
|
// Check whether we should let the GDI handle the pointer
|
|
if ((ppdev->PointerUsage == DEF_CURSOR) ||
|
|
(psoMask == (SURFOBJ *) NULL) ||
|
|
(cx > HW_POINTER_DIMENSION) ||
|
|
(cy > (HW_POINTER_DIMENSION - 1)) ||
|
|
(psoColor != NULL) ||
|
|
(fl & SPS_ASYNCCHANGE) || // We can't change the cursor shape while drawing.
|
|
(fl & SPS_ANIMATESTART) || // We don't do animated cursors
|
|
(fl & SPS_ANIMATEUPDATE) || // We don't do animated cursors
|
|
!(fl & SPS_CHANGE))
|
|
{
|
|
bAnimatedCursor = TRUE;
|
|
|
|
#if HW_PRESET_BUG
|
|
LL16 (grCursor_X, (WORD)0xFFFF);
|
|
LL16 (grCursor_Y, (WORD)0xFFFF);
|
|
#else
|
|
// Disable the Hw cursor by clearing the hw cursor enable
|
|
// bit in CURSOR_CONTROL reg
|
|
ultmp = LLDR_SZ (grCursor_Control);
|
|
if (ultmp & 1)
|
|
{
|
|
ultmp &= 0xFFFE;
|
|
LL16 (grCursor_Control, ultmp);
|
|
}
|
|
#endif
|
|
};
|
|
|
|
// Save the position informations
|
|
//
|
|
ppdev->PtrXHotSpot = xHot;
|
|
ppdev->PtrYHotSpot = yHot;
|
|
ppdev->PtrSzX = cx;
|
|
ppdev->PtrSzY = cy;
|
|
|
|
// Setup the AND and XOR mask data pointer
|
|
pANDSrcScan = psoMask->pvScan0;
|
|
pXORSrcScan = psoMask->pvScan0;
|
|
pXORSrcScan += (cy * lSrcDelta);
|
|
|
|
// If animated cursor generate the XOR mask from psoColor->pvScan0
|
|
// data
|
|
if ((bAnimatedCursor) && (psoColor != NULL))
|
|
{
|
|
PDSURF pDSURF;
|
|
POFMHDL pOFMHDL;
|
|
SURFOBJ* pDsurfSo;
|
|
BYTE XorMaskBuf[130];
|
|
BYTE *pColorSrcScan;
|
|
BYTE maskval;
|
|
LONG ii, jj, kk, mm;
|
|
BOOL bCalc;
|
|
|
|
bCalc = FALSE;
|
|
pColorSrcScan = NULL;
|
|
if (psoColor->pvScan0 != NULL)
|
|
{
|
|
// From host memory
|
|
pColorSrcScan = psoColor->pvScan0;
|
|
}
|
|
else
|
|
{
|
|
// From device bitmap
|
|
pDSURF = (DSURF *) psoColor->dhsurf;
|
|
pDsurfSo = (SURFOBJ*) pDSURF->pso;
|
|
|
|
if (pDsurfSo != NULL)
|
|
{
|
|
pColorSrcScan = pDsurfSo->pvScan0;
|
|
}
|
|
else
|
|
{
|
|
pOFMHDL = (OFMHDL *) pDSURF->pofm;
|
|
if (pOFMHDL != NULL)
|
|
{
|
|
bCalc = TRUE;
|
|
pColorSrcScan = (BYTE *)((pOFMHDL->aligned_y * ppdev->lDeltaScreen) +
|
|
pOFMHDL->aligned_x + (ULONG) ppdev->pjScreen);
|
|
}; // endif (pOFMHDL != NULL)
|
|
}; // endif (pDsurfSo != NULL)
|
|
}; // endif (psoColor->pvScan0 != NULL)
|
|
|
|
if (pColorSrcScan != NULL)
|
|
{
|
|
mm = 0;
|
|
for (ii=0; ii < 0x20; ii++)
|
|
{
|
|
for (jj=0; jj < 0x4; jj++)
|
|
{
|
|
maskval = 0;
|
|
for (kk=0; kk < 0x8; kk++)
|
|
{
|
|
maskval = maskval << 1;
|
|
|
|
if ((*pColorSrcScan & 1) != 0)
|
|
maskval |= 0x1;
|
|
|
|
pColorSrcScan += ppdev->iBytesPerPixel;
|
|
|
|
}; // endfor kk
|
|
|
|
XorMaskBuf[mm++] = maskval;
|
|
|
|
}; // endfor jj
|
|
|
|
if (bCalc)
|
|
{
|
|
pColorSrcScan = (BYTE *)(((pOFMHDL->aligned_y+ii) * ppdev->lDeltaScreen) +
|
|
pOFMHDL->aligned_x + (ULONG) ppdev->pjScreen);
|
|
};
|
|
|
|
}; // endfor ii
|
|
|
|
pXORSrcScan = &XorMaskBuf[0];
|
|
|
|
}; // endif (pColorSrcScan != NULL)
|
|
}; // endif (bAnimatedCursor)
|
|
|
|
// Set Laguna Command Control Register SWIZ_CNTL bit
|
|
ppdev->grCONTROL |= SWIZ_CNTL;
|
|
LL16(grCONTROL, ppdev->grCONTROL);
|
|
|
|
// Setup the laguna registers for byte to byte BLT extents
|
|
REQUIRE(6);
|
|
LL_DRAWBLTDEF(0x102000CC, 0);
|
|
LL_OP1 (0,0);
|
|
Ycord = ppdev->PtrMaskHandle->aligned_y;
|
|
LL_OP0_MONO (ppdev->PtrMaskHandle->aligned_x, Ycord);
|
|
|
|
// Use the AND and XOR mask to create the mask buffer for Laguna HW.
|
|
CopyLgHWPtrMaskData(ppdev, Ycord, lSrcDelta, cy, tilesz.cx, pANDSrcScan, pXORSrcScan);
|
|
|
|
// Set the HW cursor mask location register
|
|
curloc = ConvertMaskBufToLinearAddr(ppdev);
|
|
curloc = (curloc >> 8) & 0xFFFC;
|
|
LL16 (grCursor_Location, curloc);
|
|
|
|
// Clear Laguna Command Control Register SWIZ_CNTL bit
|
|
ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
|
|
LL16(grCONTROL, ppdev->grCONTROL);
|
|
|
|
// Specific the exclude rectange
|
|
if (prcl != NULL)
|
|
{
|
|
prcl->left = x - xHot;
|
|
prcl->top = y - yHot;
|
|
prcl->right = prcl->left + cx;
|
|
prcl->bottom = prcl->top + cy;
|
|
|
|
ppdev->prcl.left = prcl->left;
|
|
ppdev->prcl.top = prcl->top;
|
|
ppdev->prcl.right = prcl->right;
|
|
ppdev->prcl.bottom = prcl->bottom;
|
|
};
|
|
|
|
if (bAnimatedCursor)
|
|
{
|
|
DISPDBG((CURSOR_DBG_LEVEL, "DrvSetPointerShape - SPS_DECLINE\n"));
|
|
|
|
// Indicate use animiated cursor
|
|
ppdev->bYUVuseSWPtr = TRUE;
|
|
|
|
if (!ppdev->bYUVSurfaceOn)
|
|
return (SPS_DECLINE);
|
|
};
|
|
|
|
if ((ppdev->bYUVuseSWPtr) && (x == -1) && (y == -1))
|
|
{
|
|
#if HW_PRESET_BUG
|
|
LL16 (grCursor_X, (WORD)0xFFFF);
|
|
LL16 (grCursor_Y, (WORD)0xFFFF);
|
|
#else
|
|
// Disable the Hw cursor by clearing the hw cursor enable
|
|
// bit in CURSOR_CONTROL reg
|
|
ultmp = LLDR_SZ (grCursor_Control);
|
|
if (ultmp & 1)
|
|
{
|
|
ultmp &= 0xFFFE;
|
|
LL16 (grCursor_Control, ultmp);
|
|
}
|
|
#endif
|
|
|
|
ppdev->bYUVuseSWPtr = FALSE;
|
|
|
|
return (SPS_DECLINE);
|
|
};
|
|
|
|
// Enable the Hw cursor by setting the hw cursor enable
|
|
// bit in CURSOR_CONTROL reg
|
|
ultmp = LLDR_SZ (grCursor_Control);
|
|
if ((ultmp & 1) == 0)
|
|
{
|
|
ultmp |= 0x0001;
|
|
LL16 (grCursor_Control, ultmp);
|
|
};
|
|
|
|
// Indicate use HW cursor
|
|
ppdev->bYUVuseSWPtr = FALSE;
|
|
|
|
// Show the pointer by using the mask buffer
|
|
DrvMovePointer(pso, x, y, prcl);
|
|
|
|
return (retul);
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* FUNCTION NAME: CopyLgHWPtrMaskData()
|
|
*
|
|
* DESCRIPTION: Using the AND & XOR source mask data to generate
|
|
* a 64x64 bits pointer size mask buffer in the offscreen
|
|
* memory for Laguna HW.
|
|
*
|
|
* REVISION HISTORY:
|
|
* 6/20/95 Benny Ng Initial version
|
|
****************************************************************************/
|
|
VOID CopyLgHWPtrMaskData(PPDEV ppdev,
|
|
LONG Ycord,
|
|
LONG lSrcDelta,
|
|
LONG cy,
|
|
ULONG tileszx,
|
|
BYTE *pANDSrcScan,
|
|
BYTE *pXORSrcScan)
|
|
{
|
|
LONG i, j, k;
|
|
LONG cnt;
|
|
LONG DWcnt;
|
|
PDWORD pPattern;
|
|
LONG TileSize;
|
|
HOST_DATA MaskPattern;
|
|
|
|
pPattern = &MaskPattern.dwData;
|
|
|
|
TileSize = ppdev->lTileSize;
|
|
REQUIRE(3);
|
|
LL_MBLTEXT (TileSize, (1024/TileSize));
|
|
|
|
DWcnt = tileszx / sizeof(DWORD);
|
|
|
|
// Copy the mask data into the 64x64 space with unused portion
|
|
// fill with AND or XOR default mask value.
|
|
cnt = DWcnt;
|
|
k = 0;
|
|
for (i=0; i < 64; i++)
|
|
{
|
|
// Copy XOR mask
|
|
for (j=0; j < 8; j++)
|
|
{
|
|
// Copy one screen line mask data from source to destination
|
|
if ((j < lSrcDelta) && (i < cy))
|
|
{
|
|
MaskPattern.bData[k++] = *pXORSrcScan;
|
|
pXORSrcScan++;
|
|
}
|
|
else
|
|
{
|
|
MaskPattern.bData[k++] = 0x0;
|
|
};
|
|
|
|
if (k > 3)
|
|
{
|
|
REQUIRE(1);
|
|
LL32 (grHOSTDATA[0], *pPattern);
|
|
|
|
k = 0;
|
|
cnt--;
|
|
}; // endif (k > 3)
|
|
}; // endfor j
|
|
|
|
// Copy AND mask
|
|
for (j=0; j < 8; j++)
|
|
{
|
|
// Copy one screen line mask data from source to destination
|
|
if ((j < lSrcDelta) && (i < cy))
|
|
{
|
|
MaskPattern.bData[k++] = *pANDSrcScan;
|
|
pANDSrcScan++;
|
|
}
|
|
else
|
|
{
|
|
MaskPattern.bData[k++] = 0xFF;
|
|
};
|
|
|
|
if (k > 3)
|
|
{
|
|
*pPattern = ~ *pPattern;
|
|
REQUIRE(1);
|
|
LL32 (grHOSTDATA[0], *pPattern);
|
|
|
|
k = 0;
|
|
cnt--;
|
|
}; // endif (k > 3)
|
|
}; // endfor j
|
|
|
|
// Check whether one tile row size of host data is written to the
|
|
// HOSTDATA register.
|
|
if (cnt == 0)
|
|
{
|
|
// Reset the row data count
|
|
cnt = DWcnt;
|
|
}; // endif (cnt == 0)
|
|
}; // end for i
|
|
};
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* FUNCTION NAME: RestoreSaveShowCursor()
|
|
*
|
|
* DESCRIPTION: Restore the screen image (if needed), save the new
|
|
* cursor location the image to offscreen memory and
|
|
* show the cursor in the new location
|
|
*
|
|
* REVISION HISTORY:
|
|
* 6/20/95 Benny Ng Initial version
|
|
****************************************************************************/
|
|
VOID RestoreSaveShowCursor(PPDEV ppdev,
|
|
LONG x,
|
|
LONG y)
|
|
{
|
|
ULONG curloc;
|
|
LONG ltmpX, ltmpY;
|
|
|
|
DISPDBG((CURSOR_DBG_LEVEL, "DrvMovePointer - RestoreSaveShowCursor\n"));
|
|
|
|
ltmpX = x;
|
|
ltmpY = y;
|
|
|
|
// Set Hw cursor preset register
|
|
curloc = 0;
|
|
|
|
if ((ltmpY = (y - ppdev->PtrYHotSpot)) < 0)
|
|
{
|
|
curloc = (-ltmpY) & 0x7F;
|
|
ltmpY = 0;
|
|
}
|
|
|
|
if ((ltmpX = (x - ppdev->PtrXHotSpot)) < 0)
|
|
{
|
|
curloc = curloc | (((-ltmpX) << 8) & 0x7F00);
|
|
ltmpX = 0;
|
|
}
|
|
|
|
LL16 (grCursor_Preset, curloc);
|
|
|
|
// Set Hw cursor X & Y registers
|
|
LL16 (grCursor_X, (WORD)ltmpX);
|
|
LL16 (grCursor_Y, (WORD)ltmpY);
|
|
|
|
return;
|
|
};
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* FUNCTION NAME: ConvertMaskBufToLinearAddr()
|
|
*
|
|
* DESCRIPTION: Convert the HW cursor mask buffer address to linear offset
|
|
* address.
|
|
*
|
|
* Input: Pointer to the OFMHDL structure.
|
|
*
|
|
* Output: 32-bits Linear address pointer.
|
|
*
|
|
* REVISION HISTORY:
|
|
* 6/12/95 Benny Ng Initial version
|
|
****************************************************************************/
|
|
ULONG ConvertMaskBufToLinearAddr(PPDEV ppdev)
|
|
{
|
|
#if DRIVER_5465
|
|
ULONG Page;
|
|
ULONG Bank;
|
|
ULONG CurLoc;
|
|
ULONG DP;
|
|
#endif // DRIVER_5465
|
|
|
|
ULONG retaddr;
|
|
ULONG xtile, ytile;
|
|
ULONG tileszx, tileszy;
|
|
ULONG tileno;
|
|
ULONG xByteOffset, yByteOffset;
|
|
ULONG bpp;
|
|
ULONG TilesPerLine, Interleave;
|
|
|
|
#ifdef DBGDISP
|
|
DISPDBG((CURSOR_DBG_LEVEL, "ConvertMaskBufToLinearAddr\n"));
|
|
#endif
|
|
|
|
// Calculate the linear address from the X & Y coordinate
|
|
if ((ppdev->lTileSize == (LONG) 128) || (ppdev->lTileSize == (LONG) 256))
|
|
{
|
|
if (ppdev->lTileSize == (LONG) 128)
|
|
{
|
|
tileszx = 128;
|
|
tileszy = 16;
|
|
}
|
|
else if (ppdev->lTileSize == (LONG) 256)
|
|
{
|
|
tileszx = 256;
|
|
tileszy = 8;
|
|
};
|
|
|
|
Interleave = LLDR_SZ(grTILE_CTRL);
|
|
TilesPerLine = Interleave & 0x3F;
|
|
Interleave = ((Interleave >> 6) & 0x3);
|
|
Interleave = 1 << Interleave;
|
|
|
|
bpp = ppdev->ulBitCount/8;
|
|
|
|
#if DRIVER_5465
|
|
DP = TilesPerLine * tileszx;
|
|
Page = (ppdev->PtrMaskHandle->aligned_y) /
|
|
(tileszy * Interleave) * TilesPerLine +
|
|
(ppdev->PtrMaskHandle->aligned_x/tileszx);
|
|
|
|
Bank = (((ppdev->PtrMaskHandle->aligned_x / tileszx) +
|
|
(ppdev->PtrMaskHandle->aligned_y / tileszy)) % Interleave) +
|
|
((Page/512) << (Interleave >> 1));
|
|
|
|
Page = Page & 0x1FF;
|
|
|
|
CurLoc = (Bank<<20) + (Page<<11) +
|
|
(ppdev->PtrMaskHandle->aligned_y % tileszy) * tileszx;
|
|
|
|
retaddr = CurLoc;
|
|
#else
|
|
// calculate x tile coordinate and byte offset into tile due to x
|
|
// xTileCoord = x / TileWidth
|
|
// xByteOffset = x % TileWidth
|
|
|
|
xtile = ppdev->PtrMaskHandle->aligned_x / tileszx;
|
|
xByteOffset = ppdev->PtrMaskHandle->aligned_x % tileszx;
|
|
|
|
// calculate y tile coordinate and byte offset into tile due to y
|
|
// yTileCoord = y / TileHeight
|
|
// yByteOffset = (y % TileHeight) * TileWidth
|
|
// byteOffset = yByteOffset + xByteOffset
|
|
|
|
ytile = ppdev->PtrMaskHandle->aligned_y / tileszy;
|
|
yByteOffset = (ppdev->PtrMaskHandle->aligned_y % tileszy) * tileszx;
|
|
|
|
// calculate tile number from start of RDRAM
|
|
// (the LS 0,1,or 2 bits of this will become the bank selects based
|
|
// on interleave of 1,2,or 4)
|
|
//
|
|
// tileNo = ((yTile / Interleave) * TilesPerLine) * Interleave
|
|
// + xTile * Interleave
|
|
// + (yTile + xTile) % Interleave
|
|
// (the "+xTile" takes care of interleave rotation)
|
|
|
|
tileno = (((ytile / Interleave) * TilesPerLine) * Interleave)
|
|
+ (xtile * Interleave)
|
|
+ ((ytile + xtile) % Interleave);
|
|
|
|
// calculate linear offset
|
|
// LinOffset = tileNo * BYTES_PER_TILE + xByteOffset + yByteOffset
|
|
retaddr = (tileno * BYTES_PER_TILE) + xByteOffset + yByteOffset;
|
|
#endif // DRIVER_5465
|
|
}
|
|
else
|
|
{
|
|
// Calculate the linear address from the X & Y coordinate
|
|
retaddr = (ULONG) ppdev->PtrMaskHandle->aligned_x +
|
|
(ULONG) ppdev->lDeltaScreen * ppdev->PtrMaskHandle->aligned_y;
|
|
};
|
|
|
|
return (retaddr);
|
|
};
|
|
|
|
|