|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: pointer.c ! 3: * ! 4: * This module contains the hardware cursor support for Disp. ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: \**************************************************************************/ ! 8: ! 9: #include "driver.h" ! 10: ! 11: ! 12: ULONG DrvSetColorPointerShape( ! 13: SURFOBJ *pso, ! 14: SURFOBJ *psoMask, ! 15: SURFOBJ *psoColor, ! 16: XLATEOBJ *pxlo, ! 17: LONG xHot, ! 18: LONG yHot, ! 19: LONG x, ! 20: LONG y, ! 21: RECTL *prcl, ! 22: FLONG fl ! 23: ); ! 24: ! 25: ULONG DrvSetMonoHwPointerShape( ! 26: SURFOBJ *pso, ! 27: SURFOBJ *psoMask, ! 28: SURFOBJ *psoColor, ! 29: XLATEOBJ *pxlo, ! 30: LONG xHot, ! 31: LONG yHot, ! 32: LONG x, ! 33: LONG y, ! 34: RECTL *prcl, ! 35: FLONG fl ! 36: ); ! 37: ! 38: ULONG DrvSetBt485PointerShape( ! 39: SURFOBJ *pso, ! 40: SURFOBJ *psoMask, ! 41: SURFOBJ *psoColor, ! 42: XLATEOBJ *pxlo, ! 43: LONG xHot, ! 44: LONG yHot, ! 45: LONG x, ! 46: LONG y, ! 47: RECTL *prcl, ! 48: FLONG fl ! 49: ); ! 50: ! 51: ! 52: ! 53: VOID DrvMoveColorPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl); ! 54: VOID DrvMoveHwPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl); ! 55: VOID DrvMoveBt485Pointer(SURFOBJ *pso, LONG x, LONG y, RECTL *prcl); ! 56: ! 57: ! 58: ! 59: /***************************************************************************** ! 60: * DrvMovePointer - ! 61: ****************************************************************************/ ! 62: VOID DrvMovePointer( ! 63: SURFOBJ *pso, ! 64: LONG x, ! 65: LONG y, ! 66: RECTL *prcl) ! 67: { ! 68: PPDEV ppdev; ! 69: ! 70: ppdev = (PPDEV) pso->dhpdev; ! 71: ! 72: if (ppdev->flPointer & COLOR_POINTER) ! 73: DrvMoveColorPointer(pso, x, y, prcl); ! 74: else ! 75: { ! 76: if (ppdev->bBt485Dac == TRUE) ! 77: { ! 78: DrvMoveBt485Pointer(pso, x, y, prcl); ! 79: } ! 80: else ! 81: { ! 82: DrvMoveHwPointer(pso, x, y, prcl); ! 83: } ! 84: } ! 85: } ! 86: ! 87: ! 88: /***************************************************************************** ! 89: * DrvMoveColorPointer - ! 90: ****************************************************************************/ ! 91: VOID DrvMoveColorPointer( ! 92: SURFOBJ *pso, ! 93: LONG x, ! 94: LONG y, ! 95: RECTL *prcl) ! 96: { ! 97: INT xDest, yDest; ! 98: WORD cmd; ! 99: RECTL rclClip; ! 100: PPDEV ppdev; ! 101: ! 102: ppdev = (PPDEV) pso->dhpdev; ! 103: ! 104: // Sync with the rest of the driver. ! 105: ! 106: GPWAIT(); ! 107: ! 108: // If x is -1 then take down the cursor. ! 109: ! 110: if (x == -1) ! 111: { ! 112: ppdev->flPointer |= TAKE_DOWN_POINTER; ! 113: } ! 114: ! 115: // Adjust the actual position on the screen for the hot spot. ! 116: ! 117: xDest = x - ppdev->ptlHotSpot.x; ! 118: yDest = y - ppdev->ptlHotSpot.y; ! 119: ! 120: // If the save buffer has valid data, copy whats in the save ! 121: // buffer back to the screen. ! 122: ! 123: if (((ppdev->flPointer & VALID_SAVE_BUFFER) && ! 124: (!(ppdev->flPointer & ANIMATEUPDATE))) || ! 125: ((ppdev->flPointer & VALID_SAVE_BUFFER) && ! 126: (ppdev->flPointer & ANIMATEUPDATE) && ! 127: ((ppdev->ptlLastPosition.x != xDest) || ! 128: (ppdev->ptlLastPosition.y != yDest)))) ! 129: { ! 130: // The restore will always take place to the screen, ! 131: // so limit the clip area to the screen. ! 132: ! 133: rclClip.left = 0; ! 134: rclClip.top = 0; ! 135: rclClip.right = ppdev->cxScreen; ! 136: rclClip.bottom = ppdev->cyScreen; ! 137: ! 138: vSetS3ClipRect(ppdev, &rclClip); ! 139: ! 140: cmd = BITBLT | DRAW | DIR_TYPE_XY | ! 141: DRAWING_DIR_TBLRXM | WRITE; ! 142: ! 143: FIFOWAIT(FIFO_2_EMPTY); ! 144: ! 145: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 146: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 147: ! 148: FIFOWAIT(FIFO_7_EMPTY); ! 149: ! 150: OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1); ! 151: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1)); ! 152: OUTPW(CUR_X, COLOR_POINTER_SAVE_X); ! 153: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 154: OUTPW(DEST_X, ppdev->ptlLastPosition.x); ! 155: OUTPW(DEST_Y, ppdev->ptlLastPosition.y); ! 156: ! 157: OUTPW(CMD, cmd); ! 158: ! 159: // Indicate that the save buffer is no longer valid. ! 160: ! 161: ppdev->flPointer &= ~VALID_SAVE_BUFFER; ! 162: ! 163: } ! 164: ! 165: // If we're just taking down the pointer then were done, ! 166: // so this an early exit. ! 167: ! 168: if (ppdev->flPointer & TAKE_DOWN_POINTER ) ! 169: { ! 170: ppdev->flPointer &= ~TAKE_DOWN_POINTER; ! 171: vResetS3Clipping(ppdev); ! 172: return; ! 173: } ! 174: ! 175: ! 176: // Set the clipping for the pointers masks, save, and work area. ! 177: ! 178: rclClip.left = 0; ! 179: rclClip.top = COLOR_POINTER_Y; ! 180: rclClip.right = COLOR_POINTER_SAVE_X + COLOR_POINTER_CX; ! 181: rclClip.bottom = (COLOR_POINTER_Y + COLOR_POINTER_CY); ! 182: ! 183: vSetS3ClipRect(ppdev, &rclClip); ! 184: ! 185: if (!(ppdev->flPointer & ANIMATEUPDATE) || ! 186: !(ppdev->flPointer & VALID_SAVE_BUFFER)) ! 187: { ! 188: // Save the area under where we plan to draw the new cursor. ! 189: ! 190: cmd = BITBLT | DRAW | DIR_TYPE_XY | ! 191: DRAWING_DIR_TBLRXM | WRITE; ! 192: ! 193: FIFOWAIT(FIFO_2_EMPTY); ! 194: ! 195: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 196: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 197: ! 198: FIFOWAIT(FIFO_7_EMPTY); ! 199: ! 200: OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1); ! 201: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1)); ! 202: OUTPW(CUR_X, xDest); ! 203: OUTPW(CUR_Y, yDest); ! 204: OUTPW(DEST_X,COLOR_POINTER_SAVE_X); ! 205: OUTPW(DEST_Y,COLOR_POINTER_Y); ! 206: ! 207: OUTPW(CMD, cmd); ! 208: } ! 209: ! 210: // Validate the save buffer. ! 211: ! 212: ppdev->flPointer |= VALID_SAVE_BUFFER; ! 213: ! 214: // Now copy the saved data to the work buffer. ! 215: ! 216: cmd = BITBLT | DRAW | DIR_TYPE_XY | ! 217: DRAWING_DIR_TBLRXM | WRITE; ! 218: ! 219: FIFOWAIT(FIFO_2_EMPTY); ! 220: ! 221: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 222: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 223: ! 224: FIFOWAIT(FIFO_7_EMPTY); ! 225: ! 226: OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1); ! 227: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1)); ! 228: OUTPW(CUR_X, COLOR_POINTER_SAVE_X); ! 229: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 230: OUTPW(DEST_X,COLOR_POINTER_WORK_X); ! 231: OUTPW(DEST_Y,COLOR_POINTER_Y); ! 232: ! 233: OUTPW(CMD, cmd); ! 234: ! 235: // Record the current position as the last position; ! 236: ! 237: ppdev->ptlLastPosition.x = xDest; ! 238: ppdev->ptlLastPosition.y = yDest; ! 239: ! 240: // AND in the AND mask to the work buffer ! 241: ! 242: cmd = BITBLT | DRAW | DIR_TYPE_XY | ! 243: DRAWING_DIR_TBLRXM | MULTIPLE_PIXELS | WRITE; ! 244: ! 245: FIFOWAIT(FIFO_6_EMPTY); ! 246: ! 247: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | SCREEN_AND_NEW); ! 248: TEST_AND_SET_FRGD_COLOR(0xff); ! 249: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | SCREEN_AND_NEW); ! 250: SET_BKGD_COLOR(0x00); ! 251: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY)); ! 252: TEST_AND_SET_RD_MASK(COLOR_POINTER_AND_PLANE); ! 253: ! 254: ! 255: FIFOWAIT(FIFO_7_EMPTY); ! 256: ! 257: OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1); ! 258: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1)); ! 259: OUTPW(CUR_X, 0); ! 260: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 261: OUTPW(DEST_X,COLOR_POINTER_WORK_X); ! 262: OUTPW(DEST_Y,COLOR_POINTER_Y); ! 263: OUTPW(CMD, cmd); ! 264: ! 265: FIFOWAIT(FIFO_1_EMPTY); ! 266: ! 267: TEST_AND_SET_RD_MASK(0xff); ! 268: ! 269: // Or in the Color data to the work buffer. ! 270: ! 271: cmd = BITBLT | DRAW | DIR_TYPE_XY | ! 272: DRAWING_DIR_TBLRXM | SINGLE_PIXEL | WRITE; ! 273: ! 274: FIFOWAIT(FIFO_3_EMPTY); ! 275: ! 276: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | SCREEN_OR_NEW); ! 277: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 278: ! 279: FIFOWAIT(FIFO_7_EMPTY); ! 280: ! 281: OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1); ! 282: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1)); ! 283: OUTPW(CUR_X, COLOR_POINTER_COLOR_DATA_X); ! 284: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 285: OUTPW(DEST_X,COLOR_POINTER_WORK_X); ! 286: OUTPW(DEST_Y,COLOR_POINTER_Y); ! 287: OUTPW(CMD, cmd); ! 288: ! 289: // Now copy the work buffer to the screen. ! 290: ! 291: rclClip.left = 0; ! 292: rclClip.top = 0; ! 293: rclClip.right = ppdev->cxScreen; ! 294: rclClip.bottom = ppdev->cyScreen; ! 295: ! 296: vSetS3ClipRect(ppdev, &rclClip); ! 297: ! 298: cmd = BITBLT | DRAW | DIR_TYPE_XY | ! 299: DRAWING_DIR_TBLRXM | WRITE; ! 300: ! 301: FIFOWAIT(FIFO_2_EMPTY); ! 302: ! 303: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 304: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 305: ! 306: FIFOWAIT(FIFO_7_EMPTY); ! 307: ! 308: OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1); ! 309: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1)); ! 310: OUTPW(CUR_X, COLOR_POINTER_WORK_X); ! 311: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 312: OUTPW(DEST_X, xDest); ! 313: OUTPW(DEST_Y, yDest); ! 314: OUTPW(CMD, cmd); ! 315: ! 316: FIFOWAIT(FIFO_1_EMPTY); ! 317: ! 318: TEST_AND_SET_RD_MASK(0xff); ! 319: ! 320: // If the GDI requests the bounding box of the pointer, ! 321: // return it. ! 322: ! 323: if (prcl != NULL) ! 324: { ! 325: prcl->left = xDest; ! 326: prcl->top = yDest; ! 327: prcl->right = xDest + ppdev->szlPointer.cx; ! 328: prcl->bottom = yDest + ppdev->szlPointer.cy; ! 329: ! 330: } ! 331: ! 332: // Reset the clipping. This can go when no H/W clipping is done ! 333: // on the color pointer. ! 334: ! 335: vResetS3Clipping(ppdev); ! 336: } ! 337: ! 338: /***************************************************************************** ! 339: * DrvMoveHwPointer - ! 340: ****************************************************************************/ ! 341: VOID DrvMoveHwPointer( ! 342: SURFOBJ *pso, ! 343: LONG x, ! 344: LONG y, ! 345: RECTL *prcl) ! 346: { ! 347: WORD msb, lsb; ! 348: ! 349: PPDEV ppdev; ! 350: ! 351: ppdev = (PPDEV) pso->dhpdev; ! 352: ! 353: // Save the CRTC Index. ! 354: ! 355: ppdev->CrtcIndex = INP(CRTC_INDEX); ! 356: ! 357: // If x is -1 then take down the cursor. ! 358: ! 359: if (x == -1) ! 360: { ! 361: OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8))); ! 362: } ! 363: ! 364: // Adjust the actual pointer position depending upon ! 365: // the hot spot. ! 366: ! 367: x -= ppdev->ptlHotSpot.x; ! 368: y -= ppdev->ptlHotSpot.y; ! 369: ! 370: // Record the current position as the last position; ! 371: ! 372: ppdev->ptlLastPosition.x = x; ! 373: ppdev->ptlLastPosition.y = y; ! 374: ! 375: if (x <= 0) ! 376: { ! 377: OUTPW (CRTC_INDEX, ((-x << 8) | HGC_DX)); ! 378: x = 0; ! 379: } ! 380: else ! 381: { ! 382: OUTPW (CRTC_INDEX, ((0 << 8) | HGC_DX)); ! 383: } ! 384: ! 385: if (y <= 0) ! 386: { ! 387: OUTPW (CRTC_INDEX, ((-y << 8) | HGC_DY)); ! 388: y = 0; ! 389: } ! 390: else ! 391: { ! 392: OUTPW (CRTC_INDEX, ((0 << 8) | HGC_DY)); ! 393: } ! 394: ! 395: // Set the position of the cursor. ! 396: ! 397: msb = HIBYTE (x); ! 398: lsb = LOBYTE (x); ! 399: OUTPW (CRTC_INDEX, ((lsb << 8) | HGC_ORGX_LSB)); ! 400: OUTPW (CRTC_INDEX, ((msb << 8) | HGC_ORGX_MSB)); ! 401: ! 402: msb = HIBYTE (y); ! 403: lsb = LOBYTE (y); ! 404: OUTPW (CRTC_INDEX, ((lsb << 8) | HGC_ORGY_LSB)); ! 405: OUTPW (CRTC_INDEX, ((msb << 8) | HGC_ORGY_MSB)); ! 406: ! 407: // Restore the CRTC index ! 408: ! 409: OUTP(CRTC_INDEX, ppdev->CrtcIndex); ! 410: ! 411: } ! 412: ! 413: /***************************************************************************** ! 414: * DrvMoveBt485Pointer - ! 415: ****************************************************************************/ ! 416: VOID DrvMoveBt485Pointer( ! 417: SURFOBJ *pso, ! 418: LONG x, ! 419: LONG y, ! 420: RECTL *prcl) ! 421: { ! 422: WORD msb, lsb; ! 423: ! 424: PPDEV ppdev; ! 425: ! 426: ppdev = (PPDEV) pso->dhpdev; ! 427: ! 428: // Save the CRTC Index. ! 429: ! 430: ppdev->CrtcIndex = INP(CRTC_INDEX); ! 431: ! 432: // If x is -1 then take down the cursor. ! 433: ! 434: if (x == -1) ! 435: { ! 436: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 437: OUTP (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE); ! 438: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl)); ! 439: ! 440: return; ! 441: } ! 442: ! 443: // Adjust the actual pointer position depending upon ! 444: // the hot spot. ! 445: ! 446: x -= ppdev->ptlHotSpot.x; ! 447: y -= ppdev->ptlHotSpot.y; ! 448: ! 449: // Record the current position as the last position; ! 450: ! 451: ppdev->ptlLastPosition.x = x; ! 452: ppdev->ptlLastPosition.y = y; ! 453: ! 454: // Adjust for the placement in the Bt485 ! 455: ! 456: x += 64; ! 457: y += 64; ! 458: ! 459: // Set the position of the cursor. ! 460: ! 461: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0300)); ! 462: ! 463: msb = HIBYTE (x); ! 464: lsb = LOBYTE (x); ! 465: ! 466: OUTP(BT485_CURSOR_X_LOW, lsb); ! 467: OUTP(BT485_CURSOR_X_HIGH, msb); ! 468: ! 469: msb = HIBYTE (y); ! 470: lsb = LOBYTE (y); ! 471: ! 472: OUTP(BT485_CURSOR_Y_LOW, lsb); ! 473: OUTP(BT485_CURSOR_Y_HIGH, msb); ! 474: ! 475: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl)); ! 476: ! 477: // Restore the CRTC index ! 478: ! 479: OUTP(CRTC_INDEX, ppdev->CrtcIndex); ! 480: ! 481: } ! 482: ! 483: ! 484: ! 485: /***************************************************************************** ! 486: * DrvSetPointerShape - ! 487: ****************************************************************************/ ! 488: ULONG DrvSetPointerShape( ! 489: SURFOBJ *pso, ! 490: SURFOBJ *psoMask, ! 491: SURFOBJ *psoColor, ! 492: XLATEOBJ *pxlo, ! 493: LONG xHot, ! 494: LONG yHot, ! 495: LONG x, ! 496: LONG y, ! 497: RECTL *prcl, ! 498: FLONG fl) ! 499: { ! 500: ULONG ulRet; ! 501: PPDEV ppdev; ! 502: BOOL bResetAnimateFlag; ! 503: ! 504: ppdev = (PPDEV) pso->dhpdev; ! 505: ! 506: // Save the hot spot in the pdev. ! 507: ! 508: ppdev->ptlHotSpot.x = xHot; ! 509: ppdev->ptlHotSpot.y = yHot; ! 510: ! 511: ppdev->szlPointer.cx = psoMask->sizlBitmap.cx; ! 512: ppdev->szlPointer.cy = psoMask->sizlBitmap.cy / 2; ! 513: ! 514: // The pointer may be larger than we can handle. ! 515: // If it is we must cleanup the screen and let the engine ! 516: // take care of it. ! 517: ! 518: if (psoMask->sizlBitmap.cx > 64 || psoMask->sizlBitmap.cy > 64) ! 519: { ! 520: // If it's a color pointer take it down. ! 521: ! 522: if ( (ppdev->flPointer & COLOR_POINTER) ! 523: && (ppdev->flPointer & VALID_SAVE_BUFFER) ! 524: ) ! 525: { ! 526: ulRet = DrvSetColorPointerShape(pso, NULL, NULL, NULL, ! 527: 0, 0, 0, 0, NULL, 0); ! 528: } ! 529: ! 530: // Disable the mono hardware pointer. ! 531: ! 532: if (ppdev->bBt485Dac == TRUE) ! 533: { ! 534: // Disable the H/W cursor on the Bt 485. ! 535: ! 536: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 537: OUTP (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE); ! 538: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl)); ! 539: ! 540: } ! 541: else ! 542: { ! 543: OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8))); ! 544: } ! 545: ! 546: // reset our local pointer flags. ! 547: ! 548: ppdev->flPointer = 0; ! 549: ! 550: return (SPS_DECLINE); ! 551: ! 552: } ! 553: ! 554: // Set the AnimateUpdate flag. ! 555: ! 556: if ((fl & SPS_ANIMATEUPDATE) && ! 557: ((x - xHot) == ppdev->ptlLastPosition.x) && ! 558: ((y - yHot) == ppdev->ptlLastPosition.y)) ! 559: { ! 560: ppdev->flPointer |= ANIMATEUPDATE; ! 561: } ! 562: else ! 563: { ! 564: ppdev->flPointer &= ~ANIMATEUPDATE; ! 565: } ! 566: ! 567: if (psoColor != NULL) ! 568: { ! 569: // Disable the mono hardware pointer. ! 570: ! 571: if (ppdev->bBt485Dac == TRUE) ! 572: { ! 573: // Disable the H/W cursor on the Bt 485. ! 574: ! 575: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 576: OUTP (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE); ! 577: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl)); ! 578: ! 579: } ! 580: else ! 581: { ! 582: OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8))); ! 583: } ! 584: ! 585: ppdev->flPointer |= COLOR_POINTER; ! 586: ulRet = DrvSetColorPointerShape(pso, psoMask, psoColor, pxlo, ! 587: xHot, yHot, x, y, prcl, fl); ! 588: ! 589: } ! 590: else ! 591: { ! 592: // Take down the color pointer if it is visible. ! 593: ! 594: if ( (ppdev->flPointer & COLOR_POINTER) ! 595: && (ppdev->flPointer & VALID_SAVE_BUFFER) ! 596: ) ! 597: { ! 598: // If we are making a transition from a color to a monochrome pointer ! 599: // and we haven't moved the pointer, and we're still in Animate Update mode, ! 600: // then we have to turn off the Animate Update flag for this call to turn off ! 601: // the color pointer. ! 602: ! 603: if (ppdev->flPointer & ANIMATEUPDATE) ! 604: { ! 605: bResetAnimateFlag = TRUE; ! 606: ppdev->flPointer &= ~ANIMATEUPDATE; ! 607: } ! 608: else ! 609: { ! 610: bResetAnimateFlag = FALSE; ! 611: } ! 612: ! 613: ulRet = DrvSetColorPointerShape(pso, NULL, NULL, NULL, ! 614: 0, 0, 0, 0, NULL, 0); ! 615: ! 616: if (bResetAnimateFlag == TRUE) ! 617: { ! 618: ppdev->flPointer |= ANIMATEUPDATE; ! 619: } ! 620: } ! 621: ! 622: // Take care of the monochrome pointer. ! 623: ! 624: ppdev->flPointer &= ~COLOR_POINTER; ! 625: ! 626: if (ppdev->bBt485Dac == TRUE) ! 627: { ! 628: ulRet = DrvSetBt485PointerShape(pso, psoMask, psoColor, pxlo, ! 629: xHot, yHot, x, y, prcl, fl); ! 630: } ! 631: else ! 632: { ! 633: ulRet = DrvSetMonoHwPointerShape(pso, psoMask, psoColor, pxlo, ! 634: xHot, yHot, x, y, prcl, fl); ! 635: } ! 636: } ! 637: ! 638: // Now that we have done an animation update, revert to a normal ! 639: // pointer. ! 640: ! 641: if (ppdev->flPointer & ANIMATEUPDATE) ! 642: { ! 643: ppdev->flPointer &= ~ANIMATEUPDATE; ! 644: } ! 645: ! 646: return (ulRet); ! 647: } ! 648: ! 649: ! 650: /***************************************************************************** ! 651: * DrvSetColorPointerShape - ! 652: ****************************************************************************/ ! 653: ULONG DrvSetColorPointerShape( ! 654: SURFOBJ *pso, ! 655: SURFOBJ *psoMask, ! 656: SURFOBJ *psoColor, ! 657: XLATEOBJ *pxlo, ! 658: LONG xHot, ! 659: LONG yHot, ! 660: LONG x, ! 661: LONG y, ! 662: RECTL *prcl, ! 663: FLONG fl) ! 664: { ! 665: UINT i, j, k; ! 666: PBYTE pb; ! 667: WORD Cmd; ! 668: UINT cxMask, cyMask, cyAND, cyXOR, cxANDBytes, cxXORBytes; ! 669: UINT cxColor, cyColor; ! 670: PBYTE pjAND, pjXOR, pjColor; ! 671: LONG lDelta, lColorDelta; ! 672: PBYTE pb4Bpp; ! 673: UINT nSrcBytes; ! 674: PULONG pulXlate; ! 675: RECTL rclClip; ! 676: PPDEV ppdev; ! 677: BYTE LineBuff8Bpp[64]; ! 678: ! 679: DISPDBG((3, "S3.DLL:DrvSetColorPointerShape - Entry\n")); ! 680: ! 681: ppdev = (PPDEV) pso->dhpdev; ! 682: ! 683: // Sync this operation with the rest of the driver. ! 684: ! 685: GPWAIT(); ! 686: ! 687: // Remove the current pointer, if it is on the screen. ! 688: ! 689: if ((ppdev->flPointer & VALID_SAVE_BUFFER) && (!(ppdev->flPointer & ANIMATEUPDATE))) ! 690: { ! 691: DrvMovePointer(pso, -1, -1, NULL); ! 692: } ! 693: ! 694: // If the pointer is completely transparent, then just return. ! 695: ! 696: if (psoMask == NULL) ! 697: { ! 698: return (SPS_ACCEPT_EXCLUDE); ! 699: } ! 700: ! 701: // If the GDI requests the bounding box of the pointer, ! 702: // return it. ! 703: ! 704: if (prcl != NULL) ! 705: { ! 706: cxMask = psoMask->sizlBitmap.cx; ! 707: cyMask = psoMask->sizlBitmap.cy; ! 708: ! 709: prcl->left = x - xHot; ! 710: prcl->top = y - yHot; ! 711: prcl->right = prcl->left + cxMask; ! 712: prcl->bottom = prcl->top + cyMask; ! 713: ! 714: } ! 715: ! 716: // Set the clipping. ! 717: ! 718: rclClip.left = 0; ! 719: rclClip.top = COLOR_POINTER_Y; ! 720: rclClip.right = COLOR_POINTER_CX * 3; ! 721: rclClip.bottom = COLOR_POINTER_Y + COLOR_POINTER_CY; ! 722: ! 723: vSetS3ClipRect(ppdev, &rclClip); ! 724: ! 725: // Get the bitmap dimensions. ! 726: ! 727: cxMask = psoMask->sizlBitmap.cx; ! 728: cyMask = psoMask->sizlBitmap.cy; ! 729: ! 730: cxColor = psoColor->sizlBitmap.cx; ! 731: cyColor = psoColor->sizlBitmap.cy; ! 732: ! 733: cyAND = cyXOR = cyMask / 2; ! 734: cxANDBytes = cxXORBytes = cxMask / 8; ! 735: ! 736: // Set up pointers to the AND and XOR masks. ! 737: ! 738: pjAND = psoMask->pvScan0; ! 739: lDelta = psoMask->lDelta; ! 740: pjXOR = pjAND + (cyAND * lDelta); ! 741: ! 742: pjColor = psoColor->pvScan0; ! 743: lColorDelta = psoColor->lDelta; ! 744: ! 745: // Zero out coprocessor memory for the masks, color data, ! 746: // and the work area. Be carefull not to wipe out the save area. ! 747: ! 748: Cmd = RECTANGLE_FILL | ! 749: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 750: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE; ! 751: ! 752: FIFOWAIT(FIFO_3_EMPTY); ! 753: ! 754: TEST_AND_SET_FRGD_MIX(LOGICAL_0); ! 755: TEST_AND_SET_WRT_MASK(0xff); ! 756: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 757: ! 758: FIFOWAIT(FIFO_5_EMPTY); ! 759: ! 760: OUTPW(CUR_X, 0); ! 761: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 762: OUTPW(RECT_WIDTH, (COLOR_POINTER_CX * 2) - 1); ! 763: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | COLOR_POINTER_CY - 1)); ! 764: OUTPW(CMD, Cmd); ! 765: ! 766: // Copy the AND mask to the off screen memory. ! 767: ! 768: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT | ! 769: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 770: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE; ! 771: ! 772: ! 773: FIFOWAIT(FIFO_6_EMPTY); ! 774: ! 775: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT); ! 776: TEST_AND_SET_FRGD_COLOR(0xff); ! 777: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT); ! 778: SET_BKGD_COLOR(0x00); ! 779: TEST_AND_SET_WRT_MASK(COLOR_POINTER_AND_PLANE); ! 780: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA)); ! 781: ! 782: FIFOWAIT(FIFO_5_EMPTY); ! 783: ! 784: OUTPW(CUR_X, 0); ! 785: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 786: OUTPW(RECT_WIDTH, cxMask - 1); ! 787: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyAND - 1)); ! 788: ! 789: GPWAIT(); ! 790: ! 791: OUTPW(CMD, Cmd); ! 792: ! 793: CHECK_DATA_READY; ! 794: ! 795: // Now transfer the AND mask data. ! 796: ! 797: FIFOWAIT(FIFO_8_EMPTY); ! 798: ! 799: pb = pjAND; ! 800: for (i = 0; i < cyAND; i++) ! 801: { ! 802: vDataPortOutB(ppdev,(PBYTE) pb, cxANDBytes); ! 803: pb += lDelta; ! 804: } ! 805: ! 806: CHECK_DATA_COMPLETE; ! 807: ! 808: ! 809: // Copy the XOR mask to the off screen memory. ! 810: ! 811: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT | ! 812: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 813: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE; ! 814: ! 815: FIFOWAIT(FIFO_6_EMPTY); ! 816: ! 817: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT); ! 818: TEST_AND_SET_FRGD_COLOR(0xff); ! 819: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT); ! 820: SET_BKGD_COLOR(0x00); ! 821: TEST_AND_SET_WRT_MASK(COLOR_POINTER_XOR_PLANE); ! 822: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA)); ! 823: ! 824: FIFOWAIT(FIFO_5_EMPTY); ! 825: ! 826: OUTPW(CUR_X, 0); ! 827: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 828: OUTPW(RECT_WIDTH, cxMask - 1); ! 829: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyXOR - 1)); ! 830: ! 831: GPWAIT(); ! 832: ! 833: OUTPW(CMD, Cmd); ! 834: ! 835: // Now transfer the XOR mask data. ! 836: ! 837: FIFOWAIT(FIFO_8_EMPTY); ! 838: ! 839: pb = pjXOR; ! 840: for (i = 0; i < cyXOR; i++) ! 841: { ! 842: vDataPortOutB(ppdev,(PBYTE) pb, cxXORBytes); ! 843: pb += lDelta; ! 844: } ! 845: ! 846: FIFOWAIT(FIFO_1_EMPTY); ! 847: ! 848: TEST_AND_SET_WRT_MASK(0xff); ! 849: ! 850: if (psoColor->iBitmapFormat == BMF_8BPP) ! 851: { ! 852: // Copy the Color mask to the off screen memory. ! 853: ! 854: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT | ! 855: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 856: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE; ! 857: ! 858: FIFOWAIT(FIFO_7_EMPTY); ! 859: ! 860: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT); ! 861: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 862: OUTPW(CUR_X, COLOR_POINTER_CX); ! 863: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 864: OUTPW(RECT_WIDTH, cxColor - 1); ! 865: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyColor - 1)); ! 866: ! 867: GPWAIT(); ! 868: ! 869: OUTPW(CMD, Cmd); ! 870: ! 871: CHECK_DATA_READY; ! 872: ! 873: // Now transfer the data. ! 874: ! 875: // Note: It would nice to do the entire bitmap in one ! 876: // fell swoop, but there is no gaurantee source will ! 877: // wrap on a bitmap boundary. ! 878: ! 879: FIFOWAIT(FIFO_8_EMPTY); ! 880: ! 881: pb = pjColor; ! 882: for (i = 0; i < cyColor; i++) ! 883: { ! 884: vDataPortOutB(ppdev,pb, cxColor); ! 885: pb += lColorDelta; ! 886: } ! 887: ! 888: CHECK_DATA_COMPLETE; ! 889: } ! 890: else ! 891: { ! 892: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT | ! 893: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 894: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE; ! 895: ! 896: FIFOWAIT(FIFO_7_EMPTY); ! 897: ! 898: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT); ! 899: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 900: OUTPW(CUR_X, COLOR_POINTER_CX); ! 901: OUTPW(CUR_Y, COLOR_POINTER_Y); ! 902: OUTPW(RECT_WIDTH, cxColor - 1); ! 903: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyColor - 1)); ! 904: ! 905: GPWAIT(); ! 906: ! 907: OUTPW(CMD, Cmd); ! 908: ! 909: CHECK_DATA_READY; ! 910: ! 911: // Now transfer the data. ! 912: ! 913: // Note: It would nice to do the entire bitmap in one ! 914: // fell swoop, but there is no gaurantee source will ! 915: // wrap on a bitmap boundary. ! 916: ! 917: pb4Bpp = pjColor; ! 918: nSrcBytes = (cxColor + 1) / 2; ! 919: ! 920: if (pxlo->flXlate & XO_TABLE) ! 921: { ! 922: pulXlate = pxlo->pulXlate; ! 923: } ! 924: else ! 925: { ! 926: pulXlate = XLATEOBJ_piVector(pxlo); ! 927: } ! 928: ! 929: FIFOWAIT(FIFO_8_EMPTY); ! 930: ! 931: for (i = 0; i < cyColor; i++) ! 932: { ! 933: for (k = 0, j = 0; j < nSrcBytes; j++) ! 934: { ! 935: LineBuff8Bpp[k++] = (BYTE) pulXlate[(pb4Bpp[j] & 0xF0) >> 4]; ! 936: LineBuff8Bpp[k++] = (BYTE) pulXlate[pb4Bpp[j] & 0x0F]; ! 937: } ! 938: ! 939: vDataPortOutB(ppdev,LineBuff8Bpp, cxColor); ! 940: pb4Bpp += lColorDelta; ! 941: } ! 942: ! 943: CHECK_DATA_COMPLETE; ! 944: } ! 945: ! 946: // Set the position of the cursor. ! 947: ! 948: DrvMovePointer(pso, x, y, NULL); ! 949: ! 950: return (SPS_ACCEPT_EXCLUDE); ! 951: } ! 952: ! 953: /***************************************************************************** ! 954: * DrvSetMonoHwPointerShape - ! 955: ****************************************************************************/ ! 956: ULONG DrvSetMonoHwPointerShape( ! 957: SURFOBJ *pso, ! 958: SURFOBJ *psoMask, ! 959: SURFOBJ *psoColor, ! 960: XLATEOBJ *pxlo, ! 961: LONG xHot, ! 962: LONG yHot, ! 963: LONG x, ! 964: LONG y, ! 965: RECTL *prcl, ! 966: FLONG fl) ! 967: { ! 968: UINT i, j, k, cxMask, cyMask, cyAND, cxAND, cyXOR, cxXOR; ! 969: PBYTE pjAND, pjXOR; ! 970: PWORD pwS3AndMask, pwS3XorMask, pInterleavedMasks; ! 971: WORD msb, lsb; ! 972: INT lDelta; ! 973: PPDEV ppdev; ! 974: WORD PointerDataY; ! 975: BYTE s3AndMask[64][8], ! 976: s3XorMask[64][8]; ! 977: WORD s3InterleavedMasks[512]; ! 978: ! 979: DISPDBG((3, "S3.DLL:DrvSetMonoHwPointerShape - Entry\n")); ! 980: ! 981: ppdev = (PPDEV) pso->dhpdev; ! 982: ! 983: // If the mask is NULL this implies the pointer is not ! 984: // visible. ! 985: ! 986: if (psoMask == NULL) ! 987: { ! 988: OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8))); ! 989: return (SPS_ACCEPT_NOEXCLUDE); ! 990: } ! 991: ! 992: // Init the AND and XOR masks. ! 993: ! 994: memset (s3AndMask, 0xFF, 512); ! 995: memset (s3XorMask, 0x00, 512); ! 996: ! 997: // Get the bitmap dimensions. ! 998: ! 999: cxMask = psoMask->sizlBitmap.cx; ! 1000: cyMask = psoMask->sizlBitmap.cy; ! 1001: ! 1002: cyAND = cyXOR = cyMask / 2; ! 1003: cxAND = cxXOR = cxMask / 8; ! 1004: ! 1005: // Set up pointers to the AND and XOR masks. ! 1006: ! 1007: pjAND = psoMask->pvScan0; ! 1008: lDelta = psoMask->lDelta; ! 1009: pjXOR = pjAND + (cyAND * lDelta); ! 1010: ! 1011: // Copy the AND mask. ! 1012: ! 1013: memset (s3AndMask, 0xFFFFFFFF, 512); ! 1014: memset (s3XorMask, 0, 512); ! 1015: ! 1016: for (i = 0; i < cyAND; i++) ! 1017: { ! 1018: // Copy over a line of the AND mask. ! 1019: ! 1020: for (j = 0; j < cxAND; j++) ! 1021: { ! 1022: s3AndMask[i][j] = pjAND[j]; ! 1023: } ! 1024: ! 1025: // point to the next line of the AND mask. ! 1026: ! 1027: pjAND += lDelta; ! 1028: } ! 1029: ! 1030: // Copy the XOR mask. ! 1031: ! 1032: for (i = 0; i < cyXOR; i++) ! 1033: { ! 1034: // Copy over a line of the XOR mask. ! 1035: ! 1036: for (j = 0; j < cxXOR; j++) ! 1037: { ! 1038: s3XorMask[i][j] = pjXOR[j]; ! 1039: } ! 1040: ! 1041: // point to the next line of the XOR mask. ! 1042: ! 1043: pjXOR += lDelta; ! 1044: } ! 1045: ! 1046: // Interleave the S3AND and S3XOR masks. ! 1047: // This will allow an rep stosw instruction to down ! 1048: // load the mask to the card.. ! 1049: ! 1050: pwS3AndMask = (PWORD) s3AndMask; ! 1051: pwS3XorMask = (PWORD) s3XorMask; ! 1052: pInterleavedMasks = s3InterleavedMasks; ! 1053: ! 1054: // Interleave the S3AND and S3XOR masks. ! 1055: // This will allow an rep stosw instruction to down ! 1056: // load the mask to the card.. ! 1057: ! 1058: pwS3AndMask = (PWORD) s3AndMask; ! 1059: pwS3XorMask = (PWORD) s3XorMask; ! 1060: pInterleavedMasks = s3InterleavedMasks; ! 1061: ! 1062: k = 256; ! 1063: ! 1064: for (i = 0; i < k; i++) ! 1065: { ! 1066: *pInterleavedMasks++ = *pwS3AndMask++; ! 1067: *pInterleavedMasks++ = *pwS3XorMask++; ! 1068: } ! 1069: ! 1070: // Down load the pointer shape to the S3 chip. ! 1071: // Determine Which Monochrome pointer buffer is available. ! 1072: ! 1073: if (ppdev->MonoPointerData == 0) ! 1074: { ! 1075: PointerDataY = LOWORD (PTR_DATA_Y); ! 1076: ppdev->MonoPointerData = 1; ! 1077: } ! 1078: else ! 1079: { ! 1080: PointerDataY = LOWORD (PTR_DATA_Y - 1); ! 1081: ppdev->MonoPointerData = 0; ! 1082: } ! 1083: ! 1084: // Set the clipping window to include the last line of offscreen ! 1085: // memory. ! 1086: ! 1087: vResetS3Clipping(ppdev); ! 1088: ! 1089: // Wait for Fifo 7 to empty. ! 1090: ! 1091: FIFOWAIT(FIFO_7_EMPTY); ! 1092: ! 1093: // Now set up for the rectangle. ! 1094: ! 1095: OUTPW (CUR_X, PTR_DATA_X); ! 1096: OUTPW (CUR_Y, PointerDataY); ! 1097: ! 1098: OUTPW (RECT_WIDTH, ppdev->cxMaxRam - 1); ! 1099: OUTPW (MULTIFUNC_CNTL, RECT_HEIGHT); ! 1100: ! 1101: OUTPW (MULTIFUNC_CNTL, DATA_EXTENSION); ! 1102: ! 1103: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT); ! 1104: ! 1105: GPWAIT(); ! 1106: ! 1107: OUTPW (CMD, (RECTANGLE_FILL | BYTE_SWAP | ! 1108: BUS_SIZE_16 | WAIT | ! 1109: DRAWING_DIR_TBLRXM | ! 1110: DRAW | WRITE)); ! 1111: ! 1112: CHECK_DATA_READY; ! 1113: ! 1114: // Now down load the masks. ! 1115: ! 1116: vDataPortOut(ppdev, (PWORD) s3InterleavedMasks, 512); ! 1117: ! 1118: CHECK_DATA_COMPLETE; ! 1119: ! 1120: // This should do it. (the cursor should be downloaded) ! 1121: // Now, wasn't that simple, NOT! ! 1122: ! 1123: // Note: At one point we disabled the pointer before setting the new one. ! 1124: // this caused an excessive flicker of the pointer, so we removed the disable. ! 1125: // At another point, we found the cursor jumped to the left for 1 frame if ! 1126: // we did not disable the cursor for non-animated pointers. So, now ! 1127: // we handle each case separately. ! 1128: ! 1129: ! 1130: if (!(ppdev->flPointer & ANIMATEUPDATE)) ! 1131: { ! 1132: OUTPW (CRTC_INDEX, (ppdev->HgcMode | (HGC_DISABLE << 8))); ! 1133: } ! 1134: ! 1135: // Set the hardware graphics cursor storage area start address for ! 1136: // the new pointer data. ! 1137: ! 1138: msb = HIBYTE (PointerDataY); ! 1139: lsb = LOBYTE (PointerDataY); ! 1140: ! 1141: OUTPW (CRTC_INDEX, ((msb << 8) | CR4C)); ! 1142: OUTPW (CRTC_INDEX, ((lsb << 8) | CR4D)); ! 1143: ! 1144: // Set the position of the cursor. ! 1145: // Need to do this twice, due to shadowing in the 928 and 801/805. ! 1146: ! 1147: DrvMoveHwPointer(pso, x, y, NULL); ! 1148: ! 1149: // On the 928, 801/805 wait for vertical interval then set the ! 1150: // position a second time. ! 1151: ! 1152: if (ppdev->s3ChipID >= 0x90) ! 1153: { ! 1154: while (INP(STATUS_1) & VSY_NOT); ! 1155: DrvMoveHwPointer(pso, x, y, NULL); ! 1156: ! 1157: while (!(INP(STATUS_1) & VSY_NOT)); ! 1158: DrvMoveHwPointer(pso, x, y, NULL); ! 1159: ! 1160: } ! 1161: ! 1162: OUTPW (CRTC_INDEX, (ppdev->HgcMode | (HGC_ENABLE << 8))); ! 1163: ! 1164: // Reset the clipping. This can go when no H/W clipping is done ! 1165: // on the color pointer. ! 1166: ! 1167: vResetS3Clipping(ppdev); ! 1168: ! 1169: return (SPS_ACCEPT_NOEXCLUDE); ! 1170: } ! 1171: ! 1172: ! 1173: ! 1174: /***************************************************************************** ! 1175: * DrvSetBt485PointerShape - ! 1176: ****************************************************************************/ ! 1177: ULONG DrvSetBt485PointerShape( ! 1178: SURFOBJ *pso, ! 1179: SURFOBJ *psoMask, ! 1180: SURFOBJ *psoColor, ! 1181: XLATEOBJ *pxlo, ! 1182: LONG xHot, ! 1183: LONG yHot, ! 1184: LONG x, ! 1185: LONG y, ! 1186: RECTL *prcl, ! 1187: FLONG fl) ! 1188: { ! 1189: UINT i, j, cxMask, cyMask, cyAND, cxAND, cyXOR, cxXOR; ! 1190: PBYTE pjAND, pjXOR; ! 1191: INT lDelta; ! 1192: PPDEV ppdev; ! 1193: BYTE s3AndMask[64][8], ! 1194: s3XorMask[64][8]; ! 1195: ! 1196: DISPDBG((3, "S3.DLL:DrvSetBt485PointerShape - Entry\n")); ! 1197: ! 1198: ppdev = (PPDEV) pso->dhpdev; ! 1199: ! 1200: // If the mask is NULL this implies the pointer is not ! 1201: // visible. ! 1202: ! 1203: if (psoMask == NULL) ! 1204: { ! 1205: // Disable the H/W cursor on the Bt 485. ! 1206: ! 1207: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 1208: OUTP (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE); ! 1209: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl)); ! 1210: ! 1211: return (SPS_ACCEPT_NOEXCLUDE); ! 1212: } ! 1213: ! 1214: // Init the AND and XOR masks. ! 1215: ! 1216: memset (s3AndMask, 0xFF, 512); ! 1217: memset (s3XorMask, 0x00, 512); ! 1218: ! 1219: // Get the bitmap dimensions. ! 1220: ! 1221: cxMask = psoMask->sizlBitmap.cx; ! 1222: cyMask = psoMask->sizlBitmap.cy; ! 1223: ! 1224: cyAND = cyXOR = cyMask / 2; ! 1225: cxAND = cxXOR = cxMask / 8; ! 1226: ! 1227: // Set up pointers to the AND and XOR masks. ! 1228: ! 1229: pjAND = psoMask->pvScan0; ! 1230: lDelta = psoMask->lDelta; ! 1231: pjXOR = pjAND + (cyAND * lDelta); ! 1232: ! 1233: // Copy the AND mask. ! 1234: ! 1235: for (i = 0; i < cyAND; i++) ! 1236: { ! 1237: // Copy over a line of the AND mask. ! 1238: ! 1239: for (j = 0; j < cxAND; j++) ! 1240: { ! 1241: s3AndMask[i][j] = pjAND[j]; ! 1242: } ! 1243: ! 1244: // point to the next line of the AND mask. ! 1245: ! 1246: pjAND += lDelta; ! 1247: } ! 1248: ! 1249: // Copy the XOR mask. ! 1250: ! 1251: for (i = 0; i < cyXOR; i++) ! 1252: { ! 1253: // Copy over a line of the XOR mask. ! 1254: ! 1255: for (j = 0; j < cxXOR; j++) ! 1256: { ! 1257: s3XorMask[i][j] = pjXOR[j]; ! 1258: } ! 1259: ! 1260: // point to the next line of the XOR mask. ! 1261: ! 1262: pjXOR += lDelta; ! 1263: } ! 1264: ! 1265: pjAND = (PBYTE) s3AndMask; ! 1266: pjXOR = (PBYTE) s3XorMask; ! 1267: ! 1268: // Set the cursor for 64 X 64, and set the 2 MSB's for the cursor ! 1269: // RAM addr to 0. ! 1270: // First get access to Command Register 3 ! 1271: ! 1272: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0100)); ! 1273: OUTP (BT485_ADDR_CMD_REG0, ppdev->Bt485CmdReg0 | BT485_CMD_REG_3_ACCESS); ! 1274: ! 1275: OUTPW (CRTC_INDEX, ppdev->ExtDacCtl); ! 1276: OUTP (0x3c8, 0x01); ! 1277: ! 1278: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 1279: OUTP (BT485_ADDR_CMD_REG3, ppdev->Bt485CmdReg3); ! 1280: ! 1281: // Disable the H/W cursor on the Bt 485. ! 1282: ! 1283: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 1284: OUTP (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE); ! 1285: ! 1286: // Down load the AND mask ! 1287: ! 1288: OUTPW (CRTC_INDEX, ppdev->ExtDacCtl); ! 1289: OUTP (BT485_ADDR_CUR_RAM_WRITE, 0x0); ! 1290: ! 1291: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 1292: ! 1293: // Down load the XOR mask ! 1294: ! 1295: for (i = 0 ; i < 512 ; i++) ! 1296: { ! 1297: OUTP (BT485_CUR_RAM_ARRAY_DATA, pjXOR[i]); ! 1298: } ! 1299: ! 1300: // Down load the AND mask ! 1301: ! 1302: for (i = 0 ; i < 512 ; i++) ! 1303: { ! 1304: OUTP (BT485_CUR_RAM_ARRAY_DATA, pjAND[i]); ! 1305: } ! 1306: ! 1307: // Set the position of the cursor. ! 1308: // Need to do this twice, due to shadowing in the 928 and 801/805. ! 1309: ! 1310: DrvMoveBt485Pointer(pso, x, y, NULL); ! 1311: ! 1312: // Enable the H/W cursor ! 1313: ! 1314: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 1315: OUTP (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 | BT485_CURSOR_MODE2); ! 1316: ! 1317: // Reset DAC extended registers. ! 1318: ! 1319: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl)); ! 1320: ! 1321: return (SPS_ACCEPT_NOEXCLUDE); ! 1322: } ! 1323: ! 1324: ! 1325: ! 1326:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.