|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: cursor.c * ! 3: * * ! 4: * Cursor management. * ! 5: * * ! 6: * Copyright (c) 1992 Microsoft Corporation * ! 7: \**************************************************************************/ ! 8: ! 9: ! 10: #include "driver.h" ! 11: ! 12: ! 13: VOID vShowCursor(PPDEV ppdev); ! 14: VOID vHideCursor(PPDEV ppdev); ! 15: VOID vComputePointerRect(PPDEV ppdev,RECTL *prcl); ! 16: ! 17: VOID vYankPointer(PPDEV,BOOL); // POINTER.ASM ! 18: VOID vDrawPointer(PPDEV,LONG,LONG,BOOL); // POINTER.ASM ! 19: ! 20: ULONG xyCreateMasks // POINTER.ASM ! 21: ( ! 22: PPDEV ppdev, ! 23: PVOID pvMask, ! 24: PVOID pvColor, ! 25: LONG cy, ! 26: ULONG *pulXlate, ! 27: FSHORT fs ! 28: ); ! 29: ! 30: BOOL bSetHardwarePointerShape ! 31: ( ! 32: SURFOBJ *pso, ! 33: SURFOBJ *psoMask, ! 34: SURFOBJ *psoColor, ! 35: FLONG fl); ! 36: ! 37: BOOL bCopyInNewCursor( ! 38: PPDEV ppdev, ! 39: SURFOBJ *pso); ! 40: ! 41: /******************************Public*Routine******************************\ ! 42: * DrvMovePointer (pso,x,y,prcl) * ! 43: * * ! 44: * Move the cursor to the specified location. * ! 45: * * ! 46: \**************************************************************************/ ! 47: ! 48: VOID DrvMovePointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl) ! 49: { ! 50: PPDEV ppdev = (PPDEV) pso->dhpdev; ! 51: ! 52: // (-1,-1) indicates that the cursor should be torn down. ! 53: ! 54: if (x == -1) ! 55: { ! 56: vHideCursor(ppdev); ! 57: return; ! 58: } ! 59: ! 60: // Note where we want it to be drawn and do it. ! 61: ! 62: ppdev->xyCursor.x = (USHORT) x; ! 63: ppdev->xyCursor.y = (USHORT) y; ! 64: vShowCursor(ppdev); ! 65: ! 66: // Return the new rectangle occupied by the pointer. ! 67: ! 68: if (prcl != (RECTL *) NULL) ! 69: vComputePointerRect(ppdev,prcl); ! 70: return; ! 71: } ! 72: ! 73: /******************************Public*Routine******************************\ ! 74: * DrvSetPointerShape (pso,psoMask,psoColor,pxlo,xHot,yHot,x,y,prcl,fl) * ! 75: * * ! 76: * Set a new pointer shape. * ! 77: * * ! 78: \**************************************************************************/ ! 79: ! 80: ULONG DrvSetPointerShape ! 81: ( ! 82: SURFOBJ *pso, ! 83: SURFOBJ *psoMask, ! 84: SURFOBJ *psoColor, ! 85: XLATEOBJ *pxlo, ! 86: LONG xHot, ! 87: LONG yHot, ! 88: LONG x, ! 89: LONG y, ! 90: RECTL *prcl, ! 91: FLONG fl ! 92: ) ! 93: { ! 94: PPDEV ppdev = (PPDEV) pso->dhpdev; ! 95: PDEVSURF pdsurf = (PDEVSURF) ppdev->pdsurf; ! 96: XYPAIR xy; ! 97: PVOID pvMask; ! 98: PVOID pvColor; ! 99: FSHORT fsFlags; ! 100: ULONG ulTmp; ! 101: ULONG *pulXlate = (PULONG) NULL; // Assume no color translation. ! 102: LONG cy; ! 103: ! 104: // Set the new cursor position ! 105: ppdev->xyCursor.x = (USHORT) x; ! 106: ppdev->xyCursor.y = (USHORT) y; ! 107: ! 108: // Set the hot spot information ! 109: ppdev->xyHotSpot.x = (USHORT) xHot; ! 110: ppdev->xyHotSpot.y = (USHORT) yHot; ! 111: ! 112: if (x == -1) ! 113: vHideCursor(ppdev); ! 114: ! 115: // If we have a hardware cursor, let the miniport try to realize it ! 116: if (ppdev->flCursor & CURSOR_HW) ! 117: { ! 118: if (bSetHardwarePointerShape(pso,psoMask,psoColor,fl)) ! 119: { ! 120: // We are using the HW cursor and it is enabled. ! 121: // Mark out state flag and leave. ! 122: ppdev->flCursor |= CURSOR_HW_ACTIVE; ! 123: ppdev->flCursor &= ~(CURSOR_DOWN|CURSOR_ANIMATE); ! 124: ! 125: if (fl & SPS_ANIMATEUPDATE) ! 126: ppdev->flCursor |= CURSOR_ANIMATE; ! 127: ! 128: return(SPS_ACCEPT_NOEXCLUDE); ! 129: } ! 130: } ! 131: ! 132: // If we are not in an animation sequence, hide the pointer. Also, ! 133: // if we are coming from a hw pointer to a sw pointer, hide the ! 134: // hw pointer regardless of animation state. ! 135: ! 136: if ((!(ppdev->flCursor & CURSOR_ANIMATE)) || ! 137: (ppdev->flCursor & CURSOR_HW_ACTIVE)) { ! 138: vHideCursor(ppdev); ! 139: } ! 140: ! 141: fsFlags = 0; ! 142: ! 143: if (fl & SPS_ANIMATEUPDATE) { ! 144: fsFlags |= PTRI_ANIMATE; ! 145: ppdev->flCursor |= CURSOR_ANIMATE; ! 146: } else { ! 147: ppdev->flCursor &= ~CURSOR_ANIMATE; ! 148: ! 149: // Hide the pointer again just in case we are ending an ! 150: // animation sequence. ! 151: ! 152: vHideCursor(ppdev); ! 153: } ! 154: ! 155: ppdev->flCursor &= ~CURSOR_HW_ACTIVE; ! 156: ! 157: // We can't handle software pointers on 1 R/W adapters. ! 158: if (pdsurf->vbtBankingType == VideoBanked1RW) { ! 159: goto DeclineCursor; ! 160: } ! 161: ! 162: // If the VGA doesn't support usable offscreen memory, we can't use our ! 163: // nifty cursor code, which uses offscreen memory for saving under the ! 164: // cursor, so we'll have to let the engine handle it. ! 165: ! 166: if (!(ppdev->fl & DRIVER_USE_OFFSCREEN)) { ! 167: goto DeclineCursor; ! 168: } ! 169: ! 170: // If the mask is too big, we just can't handle it on the VGA. ! 171: ! 172: if ((psoMask->sizlBitmap.cx > 32) || (psoMask->sizlBitmap.cy > 64)) { ! 173: vHideCursor(ppdev); // get the old software cursor off the screen, if ! 174: // there is one ! 175: goto DeclineCursor; ! 176: } ! 177: ! 178: // Since there is a mask, get its data for xyCreateMasks(). ! 179: ! 180: pvMask = psoMask->pvBits; ! 181: cy = psoMask->sizlBitmap.cy / 2; ! 182: if (!(psoMask->fjBitmap & BMF_TOPDOWN)) ! 183: fsFlags |= PTRI_INVERT; ! 184: ! 185: // There may be some color. Get the pointer or NULL and set the ! 186: // color cursor flag in the PDEV accordingly. ! 187: ! 188: if (psoColor == (SURFOBJ *) NULL) ! 189: { ! 190: pvColor = (PVOID) NULL; ! 191: ppdev->flCursor &= ~CURSOR_COLOR; ! 192: } ! 193: else ! 194: { ! 195: pvColor = psoColor->pvBits; ! 196: ppdev->flCursor |= CURSOR_COLOR; ! 197: cy = psoColor->sizlBitmap.cy; ! 198: ! 199: // flag for both pointers coming in TOP_DOWN. ! 200: ! 201: if ((psoMask->fjBitmap & BMF_TOPDOWN) && ! 202: (psoColor->fjBitmap & BMF_TOPDOWN)) ! 203: fsFlags |= 0x80; ! 204: ! 205: // flag for mask coming in TOP_DOWN, but color coming in ! 206: // BOTTOM_UP ! 207: ! 208: if ((psoMask->fjBitmap & BMF_TOPDOWN) && ! 209: !(psoColor->fjBitmap & BMF_TOPDOWN)) ! 210: fsFlags |= 0x40; ! 211: ! 212: // bitmaps currently may come in 2x high, so we might have to ! 213: // compute where the AND mask really starts in an inverted ! 214: // bitmap. ! 215: ! 216: if (fsFlags & PTRI_INVERT) ! 217: pvMask = (BYTE *)psoMask->pvScan0 + (psoMask->lDelta * (cy - 1)); ! 218: ! 219: if (pxlo->flXlate & XO_TABLE) ! 220: pulXlate = pxlo->pulXlate; ! 221: } ! 222: ! 223: // Create the masks for the cursor ! 224: ! 225: ulTmp = xyCreateMasks(ppdev,pvMask,pvColor,cy,pulXlate,fsFlags); ! 226: ! 227: // It is valid for ulTmp to be zero. Some applications set the ! 228: // pointer shape to be blank and our pointer code optimizes this ! 229: // down to the smallest possible drawing area which in this case ! 230: // is an empty rect. But this is still a valid pointer. ! 231: ! 232: if (ulTmp == 0) { ! 233: xy.x = 32; ! 234: xy.y = 32; ! 235: } else ! 236: xy = *((XYPAIR *)&ulTmp); ! 237: ! 238: // Set up hit testing information in the PDEV ! 239: ! 240: ppdev->ptlExtent.x = xy.x; ! 241: ppdev->ptlExtent.y = xy.y; ! 242: ! 243: // This tells us how many aligned pels we need to exclude. ! 244: // If POINTER_ROUNDING_SIZE is 8, then a common extent of xy.x=16 will ! 245: // give cExtent=24, i.e. we always have to protect 3 bytes. ! 246: ! 247: ppdev->cExtent = (xy.x + 2 * POINTER_ROUNDING_SIZE - 2) & POINTER_MASK; ! 248: ! 249: ! 250: // Enable drawing functions and mark cursor as down ! 251: ! 252: ppdev->flCursor |= CURSOR_DOWN; ! 253: ! 254: // Draw the cursor. ! 255: if (x != -1) ! 256: vShowCursor(ppdev); ! 257: ! 258: // Set the new rectangle occupied by the pointer, and return the exclusion ! 259: // status ! 260: ! 261: vComputePointerRect(ppdev,prcl); ! 262: return(SPS_ACCEPT_EXCLUDE); ! 263: ! 264: // ! 265: // We choose not to handle this particular cursor bitmap. ! 266: // ! 267: ! 268: DeclineCursor: ! 269: return(SPS_DECLINE); ! 270: ! 271: } ! 272: ! 273: /******************************Public*Routine******************************\ ! 274: * vComputePointerRect (ppdev,prcl) * ! 275: * * ! 276: * Computes the boundary around the pointer that GDI should avoid writing * ! 277: * on. * ! 278: * * ! 279: \**************************************************************************/ ! 280: ! 281: VOID vComputePointerRect(PPDEV ppdev,RECTL *prcl) ! 282: { ! 283: XYPAIR xy; ! 284: XYPAIR xyHotSpot; ! 285: ! 286: xy = ppdev->xyCursor; ! 287: xyHotSpot = ppdev->xyHotSpot; ! 288: ! 289: prcl->left = (xy.x - xyHotSpot.x) & POINTER_MASK; ! 290: prcl->right = prcl->left + ppdev->cExtent; ! 291: prcl->top = xy.y - xyHotSpot.y; ! 292: prcl->bottom = prcl->top + ppdev->ptlExtent.y; ! 293: } ! 294: ! 295: /*****************************Private*Routine******************************\ ! 296: * VOID vShowCursor(ppdev) * ! 297: * * ! 298: * Try to draw the cursor. * ! 299: * * ! 300: \**************************************************************************/ ! 301: ! 302: VOID vShowCursor(PPDEV ppdev) ! 303: { ! 304: XYPAIR xy; ! 305: XYPAIR xyHotSpot; ! 306: ! 307: xy = ppdev->xyCursor; ! 308: xyHotSpot = ppdev->xyHotSpot; ! 309: ! 310: if (ppdev->flCursor & CURSOR_HW_ACTIVE) ! 311: { ! 312: DWORD returnedDataLength; ! 313: VIDEO_POINTER_POSITION PointerPosition; ! 314: ! 315: PointerPosition.Column = ppdev->pPointerAttributes->Column = ! 316: (SHORT)(xy.x - xyHotSpot.x); ! 317: PointerPosition.Row = ppdev->pPointerAttributes->Row = ! 318: (SHORT)(xy.y - xyHotSpot.y); ! 319: ! 320: // ! 321: // Call miniport to move pointer. ! 322: // ! 323: if (!DeviceIoControl(ppdev->hDriver, ! 324: IOCTL_VIDEO_SET_POINTER_POSITION, ! 325: &PointerPosition, ! 326: sizeof(VIDEO_POINTER_POSITION), ! 327: NULL, ! 328: 0, ! 329: &returnedDataLength, ! 330: NULL)) ! 331: ! 332: { ! 333: DISPDBG((0, "VGA:vShowCursor fail IOCTL_VIDEO_SET_POINTER_POSITION\n")); ! 334: } ! 335: } ! 336: else ! 337: { ! 338: vDrawPointer(ppdev, (LONG) (xy.x - xyHotSpot.x), ! 339: (LONG) (xy.y - xyHotSpot.y), ! 340: ppdev->flCursor & CURSOR_COLOR); ! 341: } ! 342: ! 343: ppdev->flCursor &= ~CURSOR_DOWN; ! 344: } ! 345: ! 346: /*****************************Private*Routine******************************\ ! 347: * VOID vHideCursor(ppdev) * ! 348: * * ! 349: * Try to hide the cursor * ! 350: * * ! 351: \**************************************************************************/ ! 352: ! 353: VOID vHideCursor(PPDEV ppdev) ! 354: { ! 355: if (ppdev->flCursor & CURSOR_DOWN) ! 356: return; ! 357: ! 358: // ! 359: // if this is a hardware cursor, hide it by moving it off the ! 360: // screen. ! 361: // ! 362: if (ppdev->flCursor & CURSOR_HW_ACTIVE) ! 363: { ! 364: DWORD returnedDataLength; ! 365: ! 366: if (!DeviceIoControl(ppdev->hDriver, ! 367: IOCTL_VIDEO_DISABLE_POINTER, ! 368: NULL, ! 369: 0, ! 370: NULL, ! 371: 0, ! 372: &returnedDataLength, ! 373: NULL)) ! 374: ! 375: { ! 376: // ! 377: // It should never be possible to fail. ! 378: // ! 379: ! 380: DISPDBG((0, "VGA vHideCursor failed IOCTL_VIDEO_DISABLE_POINTER\n")); ! 381: } ! 382: } ! 383: else ! 384: { ! 385: vYankPointer(ppdev, ppdev->flCursor & CURSOR_COLOR); ! 386: } ! 387: ! 388: ppdev->flCursor |= CURSOR_DOWN; ! 389: } ! 390: ! 391: /******************************Public*Routine******************************\ ! 392: * bSetHardwarePointerShape ! 393: * ! 394: * Changes the shape of the Hardware Pointer. ! 395: * ! 396: * Returns: True if successful, False if Pointer shape can't be hardware. ! 397: * ! 398: \**************************************************************************/ ! 399: ! 400: BOOL bSetHardwarePointerShape( ! 401: SURFOBJ *pso, ! 402: SURFOBJ *psoMask, ! 403: SURFOBJ *psoColor, ! 404: FLONG fl) ! 405: { ! 406: PPDEV ppdev = (PPDEV) pso->dhpdev; ! 407: PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; ! 408: DWORD returnedDataLength; ! 409: ! 410: pPointerAttributes->Flags = 0; ! 411: ! 412: // BUGBUG only supports monochrome cursor for now ! 413: if (psoColor != (SURFOBJ *) NULL) ! 414: { ! 415: return(FALSE); ! 416: } else { ! 417: pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER; ! 418: } ! 419: ! 420: if (fl & SPS_ANIMATESTART) { ! 421: pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START; ! 422: } else if (fl & SPS_ANIMATEUPDATE) { ! 423: pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE; ! 424: } ! 425: ! 426: // Copy the pixels into the buffer. ! 427: ! 428: if (!bCopyInNewCursor(ppdev, psoMask)) ! 429: { ! 430: return(FALSE); ! 431: } ! 432: ! 433: // Initialize cursor attributes and position ! 434: ! 435: pPointerAttributes->Column = ppdev->xyCursor.x - ppdev->xyHotSpot.x; ! 436: pPointerAttributes->Row = ppdev->xyCursor.y - ppdev->xyHotSpot.y; ! 437: pPointerAttributes->Enable = 1; ! 438: ! 439: ! 440: if (!(ppdev->flCursor & CURSOR_HW_ACTIVE)) { ! 441: vHideCursor(ppdev); ! 442: } ! 443: ! 444: ! 445: // Set the new cursor shape. ! 446: ! 447: if (!DeviceIoControl(ppdev->hDriver, ! 448: IOCTL_VIDEO_SET_POINTER_ATTR, ! 449: pPointerAttributes, ! 450: ppdev->cjPointerAttributes, ! 451: NULL, ! 452: 0, ! 453: &returnedDataLength, ! 454: NULL)) { ! 455: ! 456: return(FALSE); ! 457: } ! 458: ! 459: return(TRUE); ! 460: } ! 461: ! 462: /******************************Public*Routine******************************\ ! 463: * bCopyInNewCursor ! 464: * ! 465: * Copies two monochrome masks into a buffer of the maximum size handled by the ! 466: * miniport, with any extra bits set to 0. The masks are converted to topdown ! 467: * form if they aren't already. Returns TRUE if we can handle this pointer in ! 468: * hardware, FALSE if not. ! 469: * ! 470: \**************************************************************************/ ! 471: ! 472: BOOL bCopyInNewCursor( ! 473: PPDEV ppdev, ! 474: SURFOBJ *pso) ! 475: { ! 476: ULONG cx; ! 477: ULONG cy; ! 478: PBYTE pjSrcAnd, pjSrcXor; ! 479: LONG lDeltaSrc, lDeltaDst; ! 480: LONG lSrcWidthInBytes; ! 481: ULONG cxSrc = pso->sizlBitmap.cx; ! 482: ULONG cySrc = pso->sizlBitmap.cy; ! 483: ULONG cxSrcBytes; ! 484: PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; ! 485: PBYTE pjDstAnd = pPointerAttributes->Pixels; ! 486: PBYTE pjDstXor = pPointerAttributes->Pixels + ppdev->XorMaskStartOffset; ! 487: ! 488: // Make sure the new pointer isn't too big to handle ! 489: // (*2 because both masks are in there) ! 490: if ((cxSrc > ppdev->PointerCapabilities.MaxWidth) || ! 491: (cySrc > (ppdev->PointerCapabilities.MaxHeight * 2))) ! 492: { ! 493: return(FALSE); ! 494: } ! 495: ! 496: // Pad the XOR mask with -1's ! 497: memset(pjDstXor, 0xFFFFFFFF, ppdev->pPointerAttributes->WidthInBytes * ! 498: ppdev->pPointerAttributes->Height); ! 499: ! 500: // Pad the AND mask with 0's ! 501: memset(pjDstAnd, 0, ppdev->pPointerAttributes->WidthInBytes * ! 502: ppdev->pPointerAttributes->Height); ! 503: ! 504: cxSrcBytes = (cxSrc + 7) / 8; ! 505: ! 506: if ((lDeltaSrc = pso->lDelta) < 0) ! 507: { ! 508: lSrcWidthInBytes = -lDeltaSrc; ! 509: } ! 510: else ! 511: { ! 512: lSrcWidthInBytes = lDeltaSrc; ! 513: } ! 514: ! 515: pjSrcAnd = (PBYTE) pso->pvBits; ! 516: ! 517: // If the incoming pointer bitmap is bottomup, we'll flip it to topdown to ! 518: // save the miniport some work ! 519: if (!(pso->fjBitmap & BMF_TOPDOWN)) ! 520: { ! 521: // Copy from the bottom ! 522: pjSrcAnd += lSrcWidthInBytes * (cySrc - 1); ! 523: } ! 524: ! 525: // Height of just AND mask ! 526: cySrc = cySrc / 2; ! 527: ! 528: // Point to XOR mask ! 529: pjSrcXor = pjSrcAnd + (cySrc * lDeltaSrc); ! 530: ! 531: // Offset to next source scan line ! 532: lDeltaSrc -= cxSrcBytes; ! 533: ! 534: // Offset from end of one dest scan to start of next ! 535: lDeltaDst = ppdev->pPointerAttributes->WidthInBytes - cxSrcBytes; ! 536: ! 537: for (cy = 0; cy < cySrc; ++cy) ! 538: { ! 539: // Copy however many mask bytes are on this scan line ! 540: for (cx = 0; cx < cxSrcBytes; ++cx) ! 541: { ! 542: *pjDstAnd++ = *pjSrcAnd++; ! 543: *pjDstXor++ = *pjSrcXor++; ! 544: } ! 545: ! 546: // Point to next source and dest scans ! 547: pjSrcAnd += lDeltaSrc; ! 548: pjSrcXor += lDeltaSrc; ! 549: pjDstAnd += lDeltaDst; ! 550: pjDstXor += lDeltaDst; ! 551: } ! 552: ! 553: return(TRUE); ! 554: } ! 555: ! 556: /******************************Public*Routine******************************\ ! 557: * bInitPointer ! 558: * ! 559: * Initialize the Cursor attributes. ! 560: * ! 561: \**************************************************************************/ ! 562: ! 563: BOOL bInitPointer(PPDEV ppdev) ! 564: { ! 565: DWORD returnedDataLength; ! 566: ULONG MaxWidthB, MaxHeight; ! 567: ! 568: ppdev->flCursor &= ~CURSOR_HW; // assume there's no hardware pointer ! 569: ! 570: ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL; ! 571: ! 572: // Ask the miniport whether it provides pointer support. ! 573: // If it fails assume there is no hardware pointer. ! 574: ! 575: if (!DeviceIoControl(ppdev->hDriver, ! 576: IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES, ! 577: NULL, ! 578: 0, ! 579: &ppdev->PointerCapabilities, ! 580: sizeof(ppdev->PointerCapabilities), ! 581: &returnedDataLength, ! 582: NULL)) ! 583: { ! 584: // miniport does not support a hardware pointer. ! 585: ! 586: ppdev->PointerCapabilities.Flags = 0; ! 587: ppdev->PointerCapabilities.MaxWidth = 0; ! 588: ppdev->PointerCapabilities.MaxHeight = 0; ! 589: ppdev->PointerCapabilities.HWPtrBitmapStart = 0; ! 590: ppdev->PointerCapabilities.HWPtrBitmapEnd = 0; ! 591: ! 592: } ! 593: ! 594: // If neither mono nor color hardware pointer is supported, there's no ! 595: // hardware pointer support and we're done. ! 596: ! 597: if ((!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER)) && ! 598: (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))) ! 599: { ! 600: return(TRUE); ! 601: } ! 602: ! 603: // It's a hardware pointer; set up pointer attributes. ! 604: ! 605: MaxHeight = ppdev->PointerCapabilities.MaxHeight; ! 606: ! 607: if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER) ! 608: { ! 609: // If color supported, allocate space for two 4-bpp DIBs (data/mask; ! 610: // mask is actually 1-bpp, but it has the same width in bytes as the ! 611: // data for convenience) ! 612: ! 613: // Width rounded up to nearest byte multiple ! 614: MaxWidthB = (ppdev->PointerCapabilities.MaxWidth + 1) / 2; ! 615: } ! 616: else ! 617: { ! 618: // If color not supported, must be mono, allocate space for two 1-bpp ! 619: // DIBs (data/mask). ! 620: ! 621: // Width rounded up to nearest byte multiple ! 622: MaxWidthB = (ppdev->PointerCapabilities.MaxWidth + 7) / 8; ! 623: } ! 624: ! 625: ppdev->cjPointerAttributes = ! 626: sizeof(VIDEO_POINTER_ATTRIBUTES) + ! 627: ((sizeof(UCHAR) * MaxWidthB * MaxHeight) * 2); ! 628: ! 629: ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) ! 630: LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, ppdev->cjPointerAttributes); ! 631: ! 632: if (ppdev->pPointerAttributes == NULL) { ! 633: DISPDBG((0, "VGA bInitPointer LocalAlloc failed\n")); ! 634: return(FALSE); ! 635: } ! 636: ! 637: ppdev->XorMaskStartOffset = MaxWidthB * MaxHeight; ! 638: ppdev->pPointerAttributes->WidthInBytes = MaxWidthB; ! 639: ppdev->pPointerAttributes->Width = ppdev->PointerCapabilities.MaxWidth; ! 640: ppdev->pPointerAttributes->Height = MaxHeight; ! 641: ppdev->pPointerAttributes->Column = 0; ! 642: ppdev->pPointerAttributes->Row = 0; ! 643: ppdev->pPointerAttributes->Enable = 0; ! 644: ! 645: ! 646: // Set the asynchronous support status (async means miniport is capable of ! 647: // drawing the cursor at any time, with no interference with any ongoing ! 648: // drawing operation) ! 649: ! 650: if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_ASYNC_POINTER) ! 651: { ! 652: ppdev->devinfo.flGraphicsCaps |= GCAPS_ASYNCMOVE; ! 653: } ! 654: else ! 655: { ! 656: ppdev->devinfo.flGraphicsCaps &= ~GCAPS_ASYNCMOVE; ! 657: } ! 658: ! 659: ppdev->flCursor |= CURSOR_HW; ! 660: ! 661: return(TRUE); ! 662: ! 663: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.