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.

1060 lines
30 KiB

  1. /***************************************************************************
  2. *
  3. * ******************************************
  4. * * Copyright (c) 1995, Cirrus Logic, Inc. *
  5. * * All Rights Reserved *
  6. * ******************************************
  7. *
  8. * PROJECT: Laguna I (CL-GD5462) -
  9. *
  10. * FILE: pointer.c
  11. *
  12. * AUTHOR: Benny Ng
  13. *
  14. * DESCRIPTION:
  15. * This module contains the SW & HW curosr support for the
  16. * Laguna NT driver.
  17. *
  18. * MODULES:
  19. * DrvMovePointer()
  20. * DrvSetPointerShape()
  21. *
  22. * REVISION HISTORY:
  23. * 6/20/95 Benny Ng Initial version
  24. *
  25. * $Log: X:/log/laguna/nt35/displays/cl546x/POINTER.C $
  26. *
  27. * Rev 1.39 Mar 04 1998 15:30:24 frido
  28. * Added new shadow macros.
  29. *
  30. * Rev 1.38 Jan 19 1998 10:26:26 frido
  31. * HP#86 (no PDR yet). Removed hardware cursor for 1600x1200 >=65Hz.
  32. *
  33. * Rev 1.37 Nov 03 1997 11:30:16 frido
  34. * Added REQUIRE macros.
  35. *
  36. * Rev 1.36 23 Sep 1997 10:48:22 bennyn
  37. * Not use HW cursor if the resolution is below 640x480
  38. *
  39. * Rev 1.35 11 Jun 1997 15:13:14 bennyn
  40. * Fixed PDR 9747 Punt to SW cursor in 1600x1200x8 & x16 at 65,70,75 Hz
  41. *
  42. * Rev 1.34 11 Jun 1997 14:02:30 bennyn
  43. * Fixed PDR 9741 (animated cursor turns back)
  44. *
  45. * Rev 1.33 28 May 1997 14:17:58 bennyn
  46. * Fixed PDR 9741 and eliminated dead code
  47. *
  48. * Rev 1.32 01 May 1997 15:02:12 bennyn
  49. * Punt the cursor if it is in interlace modes
  50. *
  51. * Rev 1.31 09 Apr 1997 10:53:36 SueS
  52. * Changed type of pointer_switch to eliminate compiler warning.
  53. *
  54. * Rev 1.30 08 Apr 1997 15:22:50 SueS
  55. * Don't use color for monochrome animated cursors - otherwise we'll
  56. * reference a NULL pointer.
  57. *
  58. * Rev 1.29 07 Apr 1997 12:44:50 BENNYN
  59. * Added the checking ptrmaskhandle equal to NULL
  60. *
  61. * Rev 1.28 02 Apr 1997 14:24:14 noelv
  62. * NT 35.1 wass accessing a NULL pointer in DrvMovePointer
  63. * Removed SW cursor and chainblt cursor code
  64. *
  65. * Rev 1.27 21 Mar 1997 13:37:44 noelv
  66. *
  67. * Combined do_flag and sw_test_flag into pointer_switch
  68. *
  69. * Rev 1.26 03 Feb 1997 13:35:22 bennyn
  70. * Modified the 5465 cursor algorithm
  71. *
  72. * Rev 1.25 30 Jan 1997 17:15:02 bennyn
  73. * Added cursor algorithm for 5465
  74. *
  75. * Rev 1.24 17 Dec 1996 17:01:10 SueS
  76. * Added test for writing to log file based on cursor at (0,0).
  77. *
  78. * Rev 1.23 10 Dec 1996 14:32:46 bennyn
  79. *
  80. * Fixed cursor mask from device bitmap problem
  81. *
  82. * Rev 1.22 26 Nov 1996 10:43:04 SueS
  83. * Changed WriteLogFile parameters for buffering.
  84. *
  85. * Rev 1.21 13 Nov 1996 17:00:52 SueS
  86. * Changed WriteFile calls to WriteLogFile.
  87. *
  88. * Rev 1.20 01 Nov 1996 09:26:46 BENNYN
  89. *
  90. * Cleanup unused code
  91. *
  92. * Rev 1.19 23 Oct 1996 14:44:44 BENNYN
  93. *
  94. * Fixed the YUV cursor problems
  95. *
  96. * Rev 1.18 06 Sep 1996 09:07:02 noelv
  97. *
  98. * Cleaned up NULL driver code.
  99. *
  100. * Rev 1.17 26 Aug 1996 17:35:08 bennyn
  101. *
  102. * Restore the changes for the losed version
  103. *
  104. * Rev 1.16 20 Aug 1996 11:04:20 noelv
  105. * Bugfix release from Frido 8-19-96
  106. *
  107. * Rev 1.3 17 Aug 1996 19:39:20 frido
  108. * Fixed DirectDraw cursor problem.
  109. *
  110. * Rev 1.2 17 Aug 1996 13:34:56 frido
  111. * New release from Bellevue.
  112. *
  113. * Rev 1.1 15 Aug 1996 11:40:18 frido
  114. * Added precompiled header.
  115. *
  116. * Rev 1.0 14 Aug 1996 17:16:30 frido
  117. * Initial revision.
  118. *
  119. * Rev 1.13 25 Jul 1996 15:56:00 bennyn
  120. *
  121. * Modified to support DirectDraw
  122. *
  123. * Rev 1.12 18 Jun 1996 12:44:18 noelv
  124. * Fixed the way interleave is calculated.
  125. *
  126. * Rev 1.11 28 May 1996 15:11:28 noelv
  127. * Updated data logging.
  128. *
  129. * Rev 1.10 01 May 1996 12:23:30 bennyn
  130. *
  131. * Rev 1.9 01 May 1996 12:05:36 bennyn
  132. * Fixed resolution change bug for NT4.0
  133. *
  134. * Rev 1.8 01 May 1996 11:00:48 bennyn
  135. *
  136. * Modified for NT4.0
  137. *
  138. * Rev 1.7 04 Apr 1996 13:20:24 noelv
  139. * Frido release 26
  140. *
  141. * Rev 1.4 28 Mar 1996 20:22:28 frido
  142. * Removed warning messages from new Bellevue release.
  143. *
  144. * Rev 1.6 25 Mar 1996 18:55:30 noelv
  145. * Fixed bouncing screeen when cursor is disabled.
  146. *
  147. * Rev 1.5 08 Mar 1996 17:27:38 noelv
  148. *
  149. * Added NULL_POINTER flag
  150. *
  151. * Rev 1.4 07 Mar 1996 18:22:46 bennyn
  152. *
  153. * Removed read/modify/write on CONTROL reg
  154. *
  155. * Rev 1.3 05 Mar 1996 11:58:26 noelv
  156. * Frido version 19
  157. *
  158. * Rev 1.1 20 Jan 1996 01:22:00 frido
  159. *
  160. *
  161. * Rev 1.10 15 Jan 1996 16:59:58 NOELV
  162. * AB workaround reductions
  163. *
  164. * Rev 1.9 11 Jan 1996 09:22:04 NOELV
  165. * Removed al 16 bit writes to X,Y,and BLTEXT registers.
  166. *
  167. * Rev 1.8 10 Jan 1996 16:20:56 NOELV
  168. * Added increased logging capabilities.
  169. * Added null driver capabilities.
  170. *
  171. * Rev 1.7 29 Nov 1995 12:11:42 noelv
  172. *
  173. * Coded a workaround for HW bug. The screen corrupts sometimes when the curs
  174. * I changed the code to turn the cursor off as little as possible.
  175. *
  176. * Rev 1.6 29 Sep 1995 10:26:20 bennyn
  177. *
  178. * Punt the cursor to GDI for 1600x1200 modes
  179. *
  180. * Rev 1.5 29 Sep 1995 09:54:58 bennyn
  181. *
  182. * Rev 1.4 27 Sep 1995 16:45:40 bennyn
  183. * Fixed the HW cursor AND mask
  184. *
  185. * Rev 1.3 26 Sep 1995 16:27:50 bennyn
  186. *
  187. * Rev 1.2 26 Sep 1995 09:35:16 bennyn
  188. * Enable HW cursor
  189. *
  190. * Rev 1.1 21 Aug 1995 13:52:16 NOELV
  191. * Initial port to real hardware.
  192. * Converted all 32 bit register writes to 2 16 bit regiser writes.
  193. *
  194. * Rev 1.0 25 Jul 1995 11:19:28 NOELV
  195. * Initial revision.
  196. *
  197. * Rev 1.6 06 Jul 1995 09:57:10 BENNYN
  198. *
  199. * Fixed the problem switching between full-screen & Windowed DOS box
  200. *
  201. * Rev 1.5 29 Jun 1995 09:50:54 BENNYN
  202. * Fixed the unsupport cursor request problem
  203. *
  204. * Rev 1.4 29 Jun 1995 09:01:30 BENNYN
  205. *
  206. * Rev 1.3 28 Jun 1995 11:13:32 BENNYN
  207. * Fixed 16-bit/pixel problem
  208. *
  209. * Rev 1.2 22 Jun 1995 13:33:32 BENNYN
  210. *
  211. * Added SW cursor auto BLT
  212. *
  213. * Rev 1.1 20 Jun 1995 16:09:30 BENNYN
  214. *
  215. *
  216. ****************************************************************************
  217. ****************************************************************************/
  218. /*----------------------------- INCLUDES ----------------------------------*/
  219. #include "precomp.h"
  220. /*----------------------------- DEFINES -----------------------------------*/
  221. //#define DBGBRK
  222. //#define DBGDISP
  223. #define CURSOR_DBG_LEVEL 1
  224. #define MAX_CNT 0x7FFF
  225. #define BLT_FLAG_BIT 0x2L
  226. #define BYTES_PER_TILE 0x800 // 2048
  227. /*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/
  228. /*--------------------------- ENUMERATIONS --------------------------------*/
  229. /*----------------------------- TYPEDEFS ----------------------------------*/
  230. typedef union _HOST_DATA {
  231. BYTE bData[4];
  232. DWORD dwData;
  233. } HOST_DATA;
  234. /*-------------------------- STATIC VARIABLES -----------------------------*/
  235. /*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
  236. VOID CopyLgHWPtrMaskData(PPDEV ppdev,
  237. LONG Ycord,
  238. LONG lSrcDelta,
  239. LONG cy,
  240. ULONG tileszx,
  241. BYTE *pANDSrcScan,
  242. BYTE *pXORSrcScan);
  243. ULONG ConvertMaskBufToLinearAddr(PPDEV ppdev);
  244. VOID RestoreSaveShowCursor(PPDEV ppdev,
  245. LONG x,
  246. LONG y);
  247. #if POINTER_SWITCH_ENABLED
  248. int pointer_switch=0;
  249. #endif
  250. #if LOG_QFREE
  251. unsigned long QfreeData[32];
  252. #endif
  253. /****************************************************************************
  254. * FUNCTION NAME: InitPointerHW()
  255. *
  256. * DESCRIPTION: Initialization the cursor palette colors.
  257. *
  258. ****************************************************************************/
  259. VOID InitPointerHW (PPDEV ppdev)
  260. {
  261. ULONG ultmp;
  262. // Enable HW cursor color access
  263. ultmp = LLDR_SZ (grPalette_State);
  264. ultmp |= 0x8;
  265. LL8 (grPalette_State, ultmp);
  266. // Write HW cursor BK & FG color
  267. ultmp = 0;
  268. LL8 (grPalette_Write_Address, ultmp);
  269. LL8 (grPalette_Data, ultmp);
  270. LL8 (grPalette_Data, ultmp);
  271. LL8 (grPalette_Data, ultmp);
  272. ultmp = 0xF;
  273. LL8 (grPalette_Write_Address, ultmp);
  274. ultmp = 0xFF;
  275. LL8 (grPalette_Data, ultmp);
  276. LL8 (grPalette_Data, ultmp);
  277. LL8 (grPalette_Data, ultmp);
  278. // Disable HW cursor color access
  279. ultmp = LLDR_SZ (grPalette_State);
  280. ultmp &= 0xFFF7;
  281. LL8 (grPalette_State, ultmp);
  282. }
  283. /****************************************************************************
  284. * FUNCTION NAME: InitPointer()
  285. *
  286. * DESCRIPTION: Initialization the variables used by the pointer.
  287. *
  288. * REVISION HISTORY:
  289. * 6/20/95 Benny Ng Initial version
  290. ****************************************************************************/
  291. VOID InitPointer(PPDEV ppdev)
  292. {
  293. ULONG ultmp;
  294. SIZEL reqsz;
  295. ppdev->PointerUsage = HW_CURSOR;
  296. DISPDBG((CURSOR_DBG_LEVEL, "HW cursor\n"));
  297. ppdev->bYUVuseSWPtr = FALSE;
  298. ppdev->PtrImageHandle = NULL;
  299. ppdev->PtrABltHandle = NULL;
  300. // Get the current tile size
  301. if (ppdev->lTileSize == (LONG) 128)
  302. {
  303. reqsz.cx = 128;
  304. reqsz.cy = 8;
  305. }
  306. else if (ppdev->lTileSize == (LONG) 256)
  307. {
  308. reqsz.cx = 256;
  309. reqsz.cy = 4;
  310. }
  311. else
  312. {
  313. reqsz.cx = 1024;
  314. reqsz.cy = 1;
  315. };
  316. InitPointerHW (ppdev);
  317. // Allocate the mask buffer from offscreen memory
  318. DISPDBG((CURSOR_DBG_LEVEL, "Allocating Pointer Mask\n"));
  319. ppdev->PtrMaskHandle = AllocOffScnMem(ppdev, &reqsz, 0, NULL);
  320. #ifdef WINNT_VER40
  321. ppdev->CShsem = NULL;
  322. #endif
  323. }
  324. /****************************************************************************
  325. * FUNCTION NAME: DrvMovePointer()
  326. *
  327. * DESCRIPTION: This function Moves the hardware pointer to a new position.
  328. *
  329. * REVISION HISTORY:
  330. * 6/20/95 Benny Ng Initial version
  331. ****************************************************************************/
  332. VOID DrvMovePointer(SURFOBJ *pso,
  333. LONG x,
  334. LONG y,
  335. RECTL *prcl)
  336. {
  337. LONG adjx, adjy;
  338. LONG delaycnt = 0;
  339. PPDEV ppdev = (PPDEV) pso->dhpdev;
  340. if (x==0 && y==0)
  341. {
  342. //
  343. // This isn't used in the released code. This is test code for setting
  344. // the sw_test_flag to different values by pointing the cursor to
  345. // 'special' places. Used to turn different test features on and off.
  346. //
  347. #if (POINTER_SWITCH_ENABLED)
  348. if (pointer_switch)
  349. pointer_switch = 0;
  350. else
  351. pointer_switch = 1;
  352. #endif
  353. #if ENABLE_LOG_SWITCH && POINTER_SWITCH_ENABLED
  354. if (pointer_switch)
  355. {
  356. CreateLogFile(ppdev->hDriver, &ppdev->TxtBuffIndex);
  357. ppdev->pmfile = ppdev->hDriver; // handle to the miniport
  358. lg_i = sprintf(lg_buf, "Log file opened\r\n");
  359. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  360. }
  361. else
  362. CloseLogFile(ppdev->pmfile, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  363. #endif
  364. #if NULL_HW
  365. //
  366. // Enables and disables the "infinitly fast hardware" feature.
  367. // then "on" all register writes go to a chunk of blank memory
  368. // on the host. Register reads proceed normally.
  369. //
  370. if (ppdev->pLgREGS == ppdev->pLgREGS_real)
  371. ppdev->pLgREGS = (GAR *)ppdev->buffer;
  372. else
  373. ppdev->pLgREGS = ppdev->pLgREGS_real;
  374. #endif
  375. #if LOG_QFREE
  376. {
  377. int i;
  378. DISPDBG((CURSOR_DBG_LEVEL,"Dumping QFREE log.\n"));
  379. lg_i = sprintf(lg_buf,"\r\n\r\n");
  380. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  381. for (i=0; i<32; ++i)
  382. {
  383. lg_i = sprintf(lg_buf,"QFREE %d: %d times.\r\n", i, QfreeData[i]);
  384. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  385. QfreeData[i] = 0;
  386. }
  387. }
  388. #endif
  389. } // End if x==0 and y==0
  390. #if LOG_CALLS
  391. #if ENABLE_LOG_SWITCH
  392. if (pointer_switch)
  393. #endif
  394. {
  395. lg_i = sprintf(lg_buf,"DrvMovePointer: x=%d, y=%d \r\n", x, y);
  396. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  397. }
  398. #endif
  399. #if NULL_POINTER
  400. if (pointer_switch) return;
  401. #endif
  402. if ((ppdev->PointerUsage == DEF_CURSOR) ||
  403. (ppdev->PtrMaskHandle == NULL))
  404. return;
  405. adjx = x;
  406. adjy = y;
  407. // Check whether want to hide the pointer.
  408. if (x == -1)
  409. {
  410. #if HW_PRESET_BUG
  411. LL16 (grCursor_X, (WORD)0xFFFF);
  412. LL16 (grCursor_Y, (WORD)0xFFFF);
  413. #else
  414. // Disable the Hw cursor by clearing the hw cursor enable
  415. // bit in CURSOR_CONTROL reg
  416. ultmp = LLDR_SZ (grCursor_Control);
  417. if (ultmp & 1)
  418. {
  419. ultmp &= 0xFFFE;
  420. LL16 (grCursor_Control, ultmp);
  421. }
  422. #endif
  423. }
  424. else if ((adjx >= 0) && (adjy >= 0))
  425. {
  426. // Restore the current pointer area screen image from offscreen memory.
  427. // Save the new pointer area screen image to offscreen memory.
  428. // Show the curosr using both AND and XOR masks
  429. RestoreSaveShowCursor(ppdev, adjx, adjy);
  430. ppdev->PtrX = adjx;
  431. ppdev->PtrY = adjy;
  432. if (prcl != NULL)
  433. {
  434. prcl->left = ppdev->PtrX;
  435. prcl->top = ppdev->PtrY;
  436. prcl->right = prcl->left + ppdev->PtrSzX;
  437. prcl->bottom = prcl->top + ppdev->PtrSzY;
  438. ppdev->prcl.left = prcl->left;
  439. ppdev->prcl.top = prcl->top;
  440. ppdev->prcl.right = prcl->right;
  441. ppdev->prcl.bottom = prcl->bottom;
  442. }
  443. }
  444. return;
  445. }
  446. /****************************************************************************
  447. * FUNCTION NAME: DrvSetPointerShape()
  448. *
  449. * DESCRIPTION: This function sets the new pointer shape.
  450. *
  451. * REVISION HISTORY:
  452. * 6/20/95 Benny Ng Initial version
  453. ****************************************************************************/
  454. ULONG DrvSetPointerShape(SURFOBJ *pso,
  455. SURFOBJ *psoMask,
  456. SURFOBJ *psoColor,
  457. XLATEOBJ *pxlo,
  458. LONG xHot,
  459. LONG yHot,
  460. LONG x,
  461. LONG y,
  462. RECTL *prcl,
  463. FLONG fl)
  464. {
  465. BOOL bAnimatedCursor = FALSE;
  466. LONG lSrcDelta;
  467. ULONG retul;
  468. ULONG cx, cy;
  469. LONG bpp;
  470. SIZEL tilesz;
  471. SIZEL reqsz;
  472. BYTE *pANDSrcScan;
  473. BYTE *pXORSrcScan;
  474. LONG Ycord;
  475. ULONG curloc;
  476. ULONG ultmp;
  477. PPDEV ppdev = (PPDEV) pso->dhpdev;
  478. #if NULL_POINTER
  479. if (pointer_switch)
  480. return SPS_ACCEPT_NOEXCLUDE;
  481. #endif
  482. DISPDBG((CURSOR_DBG_LEVEL, "DrvSetPointerShape %d, x=%d, y=%d, xHot=%d, yHot=%d\n",
  483. ppdev->PointerUsage, x, y, xHot, yHot));
  484. // If no HW cursor mask buffer allocated from offscreen memory,
  485. // or If in intrelace mode, Use SW cursor
  486. // Use SW cursor
  487. if ((ppdev->PtrMaskHandle == NULL) || (ppdev->ulFreq < 50))
  488. return (SPS_DECLINE);
  489. // HW cursor bug in 1600x1200-8bpp & 16bpp with refresh rate 65,
  490. // 70 or 75Hz. Use SW cursor
  491. if ((ppdev->cxScreen == 1600) && (ppdev->cyScreen == 1200) &&
  492. ((ppdev->ulBitCount == 8) || (ppdev->ulBitCount == 16)))
  493. {
  494. if (ppdev->ulFreq >= 65)
  495. return (SPS_DECLINE);
  496. };
  497. // Don't use HW cursor if resolution below 640x480
  498. if ((ppdev->cxScreen < 640) || (ppdev->cyScreen < 480))
  499. return (SPS_DECLINE);
  500. // Get dimensions of the pointer
  501. cx = psoMask->sizlBitmap.cx ;
  502. cy = psoMask->sizlBitmap.cy >> 1;
  503. // Calculate bytes per pixel
  504. bpp = ppdev->iBytesPerPixel;
  505. // Get the current tile size
  506. if (ppdev->lTileSize == (LONG) 128)
  507. {
  508. tilesz.cx = 128;
  509. tilesz.cy = 16;
  510. }
  511. else if (ppdev->lTileSize == (LONG) 256)
  512. {
  513. tilesz.cx = 256;
  514. tilesz.cy = 8;
  515. }
  516. else
  517. {
  518. tilesz.cx = 2048;
  519. tilesz.cy = 1;
  520. };
  521. lSrcDelta = psoMask->lDelta;
  522. retul = SPS_ACCEPT_NOEXCLUDE; // We can still draw while HW cursor is on the screen.
  523. // Check whether we should let the GDI handle the pointer
  524. if ((ppdev->PointerUsage == DEF_CURSOR) ||
  525. (psoMask == (SURFOBJ *) NULL) ||
  526. (cx > HW_POINTER_DIMENSION) ||
  527. (cy > (HW_POINTER_DIMENSION - 1)) ||
  528. (psoColor != NULL) ||
  529. (fl & SPS_ASYNCCHANGE) || // We can't change the cursor shape while drawing.
  530. (fl & SPS_ANIMATESTART) || // We don't do animated cursors
  531. (fl & SPS_ANIMATEUPDATE) || // We don't do animated cursors
  532. !(fl & SPS_CHANGE))
  533. {
  534. bAnimatedCursor = TRUE;
  535. #if HW_PRESET_BUG
  536. LL16 (grCursor_X, (WORD)0xFFFF);
  537. LL16 (grCursor_Y, (WORD)0xFFFF);
  538. #else
  539. // Disable the Hw cursor by clearing the hw cursor enable
  540. // bit in CURSOR_CONTROL reg
  541. ultmp = LLDR_SZ (grCursor_Control);
  542. if (ultmp & 1)
  543. {
  544. ultmp &= 0xFFFE;
  545. LL16 (grCursor_Control, ultmp);
  546. }
  547. #endif
  548. };
  549. // Save the position informations
  550. //
  551. ppdev->PtrXHotSpot = xHot;
  552. ppdev->PtrYHotSpot = yHot;
  553. ppdev->PtrSzX = cx;
  554. ppdev->PtrSzY = cy;
  555. // Setup the AND and XOR mask data pointer
  556. pANDSrcScan = psoMask->pvScan0;
  557. pXORSrcScan = psoMask->pvScan0;
  558. pXORSrcScan += (cy * lSrcDelta);
  559. // If animated cursor generate the XOR mask from psoColor->pvScan0
  560. // data
  561. if ((bAnimatedCursor) && (psoColor != NULL))
  562. {
  563. PDSURF pDSURF;
  564. POFMHDL pOFMHDL;
  565. SURFOBJ* pDsurfSo;
  566. BYTE XorMaskBuf[130];
  567. BYTE *pColorSrcScan;
  568. BYTE maskval;
  569. LONG ii, jj, kk, mm;
  570. BOOL bCalc;
  571. bCalc = FALSE;
  572. pColorSrcScan = NULL;
  573. if (psoColor->pvScan0 != NULL)
  574. {
  575. // From host memory
  576. pColorSrcScan = psoColor->pvScan0;
  577. }
  578. else
  579. {
  580. // From device bitmap
  581. pDSURF = (DSURF *) psoColor->dhsurf;
  582. pDsurfSo = (SURFOBJ*) pDSURF->pso;
  583. if (pDsurfSo != NULL)
  584. {
  585. pColorSrcScan = pDsurfSo->pvScan0;
  586. }
  587. else
  588. {
  589. pOFMHDL = (OFMHDL *) pDSURF->pofm;
  590. if (pOFMHDL != NULL)
  591. {
  592. bCalc = TRUE;
  593. pColorSrcScan = (BYTE *)((pOFMHDL->aligned_y * ppdev->lDeltaScreen) +
  594. pOFMHDL->aligned_x + (ULONG) ppdev->pjScreen);
  595. }; // endif (pOFMHDL != NULL)
  596. }; // endif (pDsurfSo != NULL)
  597. }; // endif (psoColor->pvScan0 != NULL)
  598. if (pColorSrcScan != NULL)
  599. {
  600. mm = 0;
  601. for (ii=0; ii < 0x20; ii++)
  602. {
  603. for (jj=0; jj < 0x4; jj++)
  604. {
  605. maskval = 0;
  606. for (kk=0; kk < 0x8; kk++)
  607. {
  608. maskval = maskval << 1;
  609. if ((*pColorSrcScan & 1) != 0)
  610. maskval |= 0x1;
  611. pColorSrcScan += ppdev->iBytesPerPixel;
  612. }; // endfor kk
  613. XorMaskBuf[mm++] = maskval;
  614. }; // endfor jj
  615. if (bCalc)
  616. {
  617. pColorSrcScan = (BYTE *)(((pOFMHDL->aligned_y+ii) * ppdev->lDeltaScreen) +
  618. pOFMHDL->aligned_x + (ULONG) ppdev->pjScreen);
  619. };
  620. }; // endfor ii
  621. pXORSrcScan = &XorMaskBuf[0];
  622. }; // endif (pColorSrcScan != NULL)
  623. }; // endif (bAnimatedCursor)
  624. // Set Laguna Command Control Register SWIZ_CNTL bit
  625. ppdev->grCONTROL |= SWIZ_CNTL;
  626. LL16(grCONTROL, ppdev->grCONTROL);
  627. // Setup the laguna registers for byte to byte BLT extents
  628. REQUIRE(6);
  629. LL_DRAWBLTDEF(0x102000CC, 0);
  630. LL_OP1 (0,0);
  631. Ycord = ppdev->PtrMaskHandle->aligned_y;
  632. LL_OP0_MONO (ppdev->PtrMaskHandle->aligned_x, Ycord);
  633. // Use the AND and XOR mask to create the mask buffer for Laguna HW.
  634. CopyLgHWPtrMaskData(ppdev, Ycord, lSrcDelta, cy, tilesz.cx, pANDSrcScan, pXORSrcScan);
  635. // Set the HW cursor mask location register
  636. curloc = ConvertMaskBufToLinearAddr(ppdev);
  637. curloc = (curloc >> 8) & 0xFFFC;
  638. LL16 (grCursor_Location, curloc);
  639. // Clear Laguna Command Control Register SWIZ_CNTL bit
  640. ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
  641. LL16(grCONTROL, ppdev->grCONTROL);
  642. // Specific the exclude rectange
  643. if (prcl != NULL)
  644. {
  645. prcl->left = x - xHot;
  646. prcl->top = y - yHot;
  647. prcl->right = prcl->left + cx;
  648. prcl->bottom = prcl->top + cy;
  649. ppdev->prcl.left = prcl->left;
  650. ppdev->prcl.top = prcl->top;
  651. ppdev->prcl.right = prcl->right;
  652. ppdev->prcl.bottom = prcl->bottom;
  653. };
  654. if (bAnimatedCursor)
  655. {
  656. DISPDBG((CURSOR_DBG_LEVEL, "DrvSetPointerShape - SPS_DECLINE\n"));
  657. // Indicate use animiated cursor
  658. ppdev->bYUVuseSWPtr = TRUE;
  659. if (!ppdev->bYUVSurfaceOn)
  660. return (SPS_DECLINE);
  661. };
  662. if ((ppdev->bYUVuseSWPtr) && (x == -1) && (y == -1))
  663. {
  664. #if HW_PRESET_BUG
  665. LL16 (grCursor_X, (WORD)0xFFFF);
  666. LL16 (grCursor_Y, (WORD)0xFFFF);
  667. #else
  668. // Disable the Hw cursor by clearing the hw cursor enable
  669. // bit in CURSOR_CONTROL reg
  670. ultmp = LLDR_SZ (grCursor_Control);
  671. if (ultmp & 1)
  672. {
  673. ultmp &= 0xFFFE;
  674. LL16 (grCursor_Control, ultmp);
  675. }
  676. #endif
  677. ppdev->bYUVuseSWPtr = FALSE;
  678. return (SPS_DECLINE);
  679. };
  680. // Enable the Hw cursor by setting the hw cursor enable
  681. // bit in CURSOR_CONTROL reg
  682. ultmp = LLDR_SZ (grCursor_Control);
  683. if ((ultmp & 1) == 0)
  684. {
  685. ultmp |= 0x0001;
  686. LL16 (grCursor_Control, ultmp);
  687. };
  688. // Indicate use HW cursor
  689. ppdev->bYUVuseSWPtr = FALSE;
  690. // Show the pointer by using the mask buffer
  691. DrvMovePointer(pso, x, y, prcl);
  692. return (retul);
  693. }
  694. /****************************************************************************
  695. * FUNCTION NAME: CopyLgHWPtrMaskData()
  696. *
  697. * DESCRIPTION: Using the AND & XOR source mask data to generate
  698. * a 64x64 bits pointer size mask buffer in the offscreen
  699. * memory for Laguna HW.
  700. *
  701. * REVISION HISTORY:
  702. * 6/20/95 Benny Ng Initial version
  703. ****************************************************************************/
  704. VOID CopyLgHWPtrMaskData(PPDEV ppdev,
  705. LONG Ycord,
  706. LONG lSrcDelta,
  707. LONG cy,
  708. ULONG tileszx,
  709. BYTE *pANDSrcScan,
  710. BYTE *pXORSrcScan)
  711. {
  712. LONG i, j, k;
  713. LONG cnt;
  714. LONG DWcnt;
  715. PDWORD pPattern;
  716. LONG TileSize;
  717. HOST_DATA MaskPattern;
  718. pPattern = &MaskPattern.dwData;
  719. TileSize = ppdev->lTileSize;
  720. REQUIRE(3);
  721. LL_MBLTEXT (TileSize, (1024/TileSize));
  722. DWcnt = tileszx / sizeof(DWORD);
  723. // Copy the mask data into the 64x64 space with unused portion
  724. // fill with AND or XOR default mask value.
  725. cnt = DWcnt;
  726. k = 0;
  727. for (i=0; i < 64; i++)
  728. {
  729. // Copy XOR mask
  730. for (j=0; j < 8; j++)
  731. {
  732. // Copy one screen line mask data from source to destination
  733. if ((j < lSrcDelta) && (i < cy))
  734. {
  735. MaskPattern.bData[k++] = *pXORSrcScan;
  736. pXORSrcScan++;
  737. }
  738. else
  739. {
  740. MaskPattern.bData[k++] = 0x0;
  741. };
  742. if (k > 3)
  743. {
  744. REQUIRE(1);
  745. LL32 (grHOSTDATA[0], *pPattern);
  746. k = 0;
  747. cnt--;
  748. }; // endif (k > 3)
  749. }; // endfor j
  750. // Copy AND mask
  751. for (j=0; j < 8; j++)
  752. {
  753. // Copy one screen line mask data from source to destination
  754. if ((j < lSrcDelta) && (i < cy))
  755. {
  756. MaskPattern.bData[k++] = *pANDSrcScan;
  757. pANDSrcScan++;
  758. }
  759. else
  760. {
  761. MaskPattern.bData[k++] = 0xFF;
  762. };
  763. if (k > 3)
  764. {
  765. *pPattern = ~ *pPattern;
  766. REQUIRE(1);
  767. LL32 (grHOSTDATA[0], *pPattern);
  768. k = 0;
  769. cnt--;
  770. }; // endif (k > 3)
  771. }; // endfor j
  772. // Check whether one tile row size of host data is written to the
  773. // HOSTDATA register.
  774. if (cnt == 0)
  775. {
  776. // Reset the row data count
  777. cnt = DWcnt;
  778. }; // endif (cnt == 0)
  779. }; // end for i
  780. };
  781. /****************************************************************************
  782. * FUNCTION NAME: RestoreSaveShowCursor()
  783. *
  784. * DESCRIPTION: Restore the screen image (if needed), save the new
  785. * cursor location the image to offscreen memory and
  786. * show the cursor in the new location
  787. *
  788. * REVISION HISTORY:
  789. * 6/20/95 Benny Ng Initial version
  790. ****************************************************************************/
  791. VOID RestoreSaveShowCursor(PPDEV ppdev,
  792. LONG x,
  793. LONG y)
  794. {
  795. ULONG curloc;
  796. LONG ltmpX, ltmpY;
  797. DISPDBG((CURSOR_DBG_LEVEL, "DrvMovePointer - RestoreSaveShowCursor\n"));
  798. ltmpX = x;
  799. ltmpY = y;
  800. // Set Hw cursor preset register
  801. curloc = 0;
  802. if ((ltmpY = (y - ppdev->PtrYHotSpot)) < 0)
  803. {
  804. curloc = (-ltmpY) & 0x7F;
  805. ltmpY = 0;
  806. }
  807. if ((ltmpX = (x - ppdev->PtrXHotSpot)) < 0)
  808. {
  809. curloc = curloc | (((-ltmpX) << 8) & 0x7F00);
  810. ltmpX = 0;
  811. }
  812. LL16 (grCursor_Preset, curloc);
  813. // Set Hw cursor X & Y registers
  814. LL16 (grCursor_X, (WORD)ltmpX);
  815. LL16 (grCursor_Y, (WORD)ltmpY);
  816. return;
  817. };
  818. /****************************************************************************
  819. * FUNCTION NAME: ConvertMaskBufToLinearAddr()
  820. *
  821. * DESCRIPTION: Convert the HW cursor mask buffer address to linear offset
  822. * address.
  823. *
  824. * Input: Pointer to the OFMHDL structure.
  825. *
  826. * Output: 32-bits Linear address pointer.
  827. *
  828. * REVISION HISTORY:
  829. * 6/12/95 Benny Ng Initial version
  830. ****************************************************************************/
  831. ULONG ConvertMaskBufToLinearAddr(PPDEV ppdev)
  832. {
  833. #if DRIVER_5465
  834. ULONG Page;
  835. ULONG Bank;
  836. ULONG CurLoc;
  837. ULONG DP;
  838. #endif // DRIVER_5465
  839. ULONG retaddr;
  840. ULONG xtile, ytile;
  841. ULONG tileszx, tileszy;
  842. ULONG tileno;
  843. ULONG xByteOffset, yByteOffset;
  844. ULONG bpp;
  845. ULONG TilesPerLine, Interleave;
  846. #ifdef DBGDISP
  847. DISPDBG((CURSOR_DBG_LEVEL, "ConvertMaskBufToLinearAddr\n"));
  848. #endif
  849. // Calculate the linear address from the X & Y coordinate
  850. if ((ppdev->lTileSize == (LONG) 128) || (ppdev->lTileSize == (LONG) 256))
  851. {
  852. if (ppdev->lTileSize == (LONG) 128)
  853. {
  854. tileszx = 128;
  855. tileszy = 16;
  856. }
  857. else if (ppdev->lTileSize == (LONG) 256)
  858. {
  859. tileszx = 256;
  860. tileszy = 8;
  861. };
  862. Interleave = LLDR_SZ(grTILE_CTRL);
  863. TilesPerLine = Interleave & 0x3F;
  864. Interleave = ((Interleave >> 6) & 0x3);
  865. Interleave = 1 << Interleave;
  866. bpp = ppdev->ulBitCount/8;
  867. #if DRIVER_5465
  868. DP = TilesPerLine * tileszx;
  869. Page = (ppdev->PtrMaskHandle->aligned_y) /
  870. (tileszy * Interleave) * TilesPerLine +
  871. (ppdev->PtrMaskHandle->aligned_x/tileszx);
  872. Bank = (((ppdev->PtrMaskHandle->aligned_x / tileszx) +
  873. (ppdev->PtrMaskHandle->aligned_y / tileszy)) % Interleave) +
  874. ((Page/512) << (Interleave >> 1));
  875. Page = Page & 0x1FF;
  876. CurLoc = (Bank<<20) + (Page<<11) +
  877. (ppdev->PtrMaskHandle->aligned_y % tileszy) * tileszx;
  878. retaddr = CurLoc;
  879. #else
  880. // calculate x tile coordinate and byte offset into tile due to x
  881. // xTileCoord = x / TileWidth
  882. // xByteOffset = x % TileWidth
  883. xtile = ppdev->PtrMaskHandle->aligned_x / tileszx;
  884. xByteOffset = ppdev->PtrMaskHandle->aligned_x % tileszx;
  885. // calculate y tile coordinate and byte offset into tile due to y
  886. // yTileCoord = y / TileHeight
  887. // yByteOffset = (y % TileHeight) * TileWidth
  888. // byteOffset = yByteOffset + xByteOffset
  889. ytile = ppdev->PtrMaskHandle->aligned_y / tileszy;
  890. yByteOffset = (ppdev->PtrMaskHandle->aligned_y % tileszy) * tileszx;
  891. // calculate tile number from start of RDRAM
  892. // (the LS 0,1,or 2 bits of this will become the bank selects based
  893. // on interleave of 1,2,or 4)
  894. //
  895. // tileNo = ((yTile / Interleave) * TilesPerLine) * Interleave
  896. // + xTile * Interleave
  897. // + (yTile + xTile) % Interleave
  898. // (the "+xTile" takes care of interleave rotation)
  899. tileno = (((ytile / Interleave) * TilesPerLine) * Interleave)
  900. + (xtile * Interleave)
  901. + ((ytile + xtile) % Interleave);
  902. // calculate linear offset
  903. // LinOffset = tileNo * BYTES_PER_TILE + xByteOffset + yByteOffset
  904. retaddr = (tileno * BYTES_PER_TILE) + xByteOffset + yByteOffset;
  905. #endif // DRIVER_5465
  906. }
  907. else
  908. {
  909. // Calculate the linear address from the X & Y coordinate
  910. retaddr = (ULONG) ppdev->PtrMaskHandle->aligned_x +
  911. (ULONG) ppdev->lDeltaScreen * ppdev->PtrMaskHandle->aligned_y;
  912. };
  913. return (retaddr);
  914. };
  915.