|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: pointer.c * ! 3: * * ! 4: * This module contains the hardware Pointer support for the framebuffer * ! 5: * * ! 6: * Copyright (c) 1992 Microsoft Corporation * ! 7: \**************************************************************************/ ! 8: ! 9: #include "driver.h" ! 10: ! 11: BOOL bCopyColorPointer( ! 12: PPDEV ppdev, ! 13: SURFOBJ *psoMask, ! 14: SURFOBJ *psoColor, ! 15: XLATEOBJ *pxlo); ! 16: ! 17: BOOL bCopyMonoPointer( ! 18: PPDEV ppdev, ! 19: SURFOBJ *psoMask); ! 20: ! 21: BOOL bSetHardwarePointerShape( ! 22: SURFOBJ *pso, ! 23: SURFOBJ *psoMask, ! 24: SURFOBJ *psoColor, ! 25: XLATEOBJ *pxlo, ! 26: LONG x, ! 27: LONG y, ! 28: FLONG fl); ! 29: ! 30: /******************************Public*Routine******************************\ ! 31: * DrvMovePointer ! 32: * ! 33: * Moves the hardware pointer to a new position. ! 34: * ! 35: \**************************************************************************/ ! 36: ! 37: VOID DrvMovePointer ! 38: ( ! 39: SURFOBJ *pso, ! 40: LONG x, ! 41: LONG y, ! 42: RECTL *prcl ! 43: ) ! 44: { ! 45: PPDEV ppdev = (PPDEV) pso->dhpdev; ! 46: DWORD returnedDataLength; ! 47: VIDEO_POINTER_POSITION NewPointerPosition; ! 48: ! 49: // We don't use the exclusion rectangle because we only support ! 50: // hardware Pointers. If we were doing our own Pointer simulations ! 51: // we would want to update prcl so that the engine would call us ! 52: // to exclude out pointer before drawing to the pixels in prcl. ! 53: ! 54: UNREFERENCED_PARAMETER(prcl); ! 55: ! 56: if (x == -1) ! 57: { ! 58: // A new position of (-1,-1) means hide the pointer. ! 59: if (!DeviceIoControl(ppdev->hDriver, ! 60: IOCTL_VIDEO_DISABLE_POINTER, ! 61: NULL, ! 62: 0, ! 63: NULL, ! 64: 0, ! 65: &returnedDataLength, ! 66: NULL)) ! 67: { ! 68: // Not the end of the world, print warning in checked build. ! 69: ! 70: DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_DISABLE_POINTER\n")); ! 71: } ! 72: } ! 73: else ! 74: { ! 75: NewPointerPosition.Column = (SHORT) x - (SHORT) (ppdev->ptlHotSpot.x); ! 76: NewPointerPosition.Row = (SHORT) y - (SHORT) (ppdev->ptlHotSpot.y); ! 77: // Call NT screen driver to move Pointer. ! 78: ! 79: if (!DeviceIoControl(ppdev->hDriver, ! 80: IOCTL_VIDEO_SET_POINTER_POSITION, ! 81: &NewPointerPosition, ! 82: sizeof(VIDEO_POINTER_POSITION), ! 83: NULL, ! 84: 0, ! 85: &returnedDataLength, ! 86: NULL)) ! 87: { ! 88: // Not the end of the world, print warning in checked build. ! 89: ! 90: DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_SET_POINTER_POSITION\n")); ! 91: } ! 92: } ! 93: } ! 94: ! 95: /******************************Public*Routine******************************\ ! 96: * DrvSetPointerShape ! 97: * ! 98: * Sets the new pointer shape. ! 99: * ! 100: \**************************************************************************/ ! 101: ! 102: ULONG DrvSetPointerShape ! 103: ( ! 104: SURFOBJ *pso, ! 105: SURFOBJ *psoMask, ! 106: SURFOBJ *psoColor, ! 107: XLATEOBJ *pxlo, ! 108: LONG xHot, ! 109: LONG yHot, ! 110: LONG x, ! 111: LONG y, ! 112: RECTL *prcl, ! 113: FLONG fl ! 114: ) ! 115: { ! 116: PPDEV ppdev = (PPDEV) pso->dhpdev; ! 117: DWORD returnedDataLength; ! 118: ! 119: // We don't use the exclusion rectangle because we only support ! 120: // hardware Pointers. If we were doing our own Pointer simulations ! 121: // we would want to update prcl so that the engine would call us ! 122: // to exclude out pointer before drawing to the pixels in prcl. ! 123: UNREFERENCED_PARAMETER(prcl); ! 124: ! 125: if (ppdev->pPointerAttributes == (PVIDEO_POINTER_ATTRIBUTES) NULL) ! 126: { ! 127: // Mini-port has no hardware Pointer support. ! 128: return(SPS_ERROR); ! 129: } ! 130: ! 131: // See if we are being asked to hide the pointer ! 132: ! 133: if (psoMask == (SURFOBJ *) NULL) ! 134: { ! 135: if (!DeviceIoControl(ppdev->hDriver, ! 136: IOCTL_VIDEO_DISABLE_POINTER, ! 137: NULL, ! 138: 0, ! 139: NULL, ! 140: 0, ! 141: &returnedDataLength, ! 142: NULL)) ! 143: { ! 144: // It should never be possible to fail. ! 145: // Message supplied for debugging. ! 146: ! 147: DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n")); ! 148: } ! 149: ! 150: return(TRUE); ! 151: } ! 152: ! 153: ppdev->ptlHotSpot.x = xHot; ! 154: ppdev->ptlHotSpot.y = yHot; ! 155: ! 156: if (!bSetHardwarePointerShape(pso,psoMask,psoColor,pxlo,x,y,fl)) ! 157: { ! 158: if (ppdev->fHwCursorActive) { ! 159: ppdev->fHwCursorActive = FALSE; ! 160: ! 161: if (!DeviceIoControl(ppdev->hDriver, ! 162: IOCTL_VIDEO_DISABLE_POINTER, ! 163: NULL, ! 164: 0, ! 165: NULL, ! 166: 0, ! 167: &returnedDataLength, ! 168: NULL)) { ! 169: ! 170: DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n")); ! 171: } ! 172: } ! 173: // ! 174: // Mini-port declines to realize this Pointer ! 175: // ! 176: return(SPS_DECLINE); ! 177: } else ! 178: ppdev->fHwCursorActive = TRUE; ! 179: ! 180: return(SPS_ACCEPT_NOEXCLUDE); ! 181: } ! 182: ! 183: /******************************Public*Routine******************************\ ! 184: * bSetHardwarePointerShape ! 185: * ! 186: * Changes the shape of the Hardware Pointer. ! 187: * ! 188: * Returns: True if successful, False if Pointer shape can't be hardware. ! 189: * ! 190: \**************************************************************************/ ! 191: ! 192: BOOL bSetHardwarePointerShape( ! 193: SURFOBJ *pso, ! 194: SURFOBJ *psoMask, ! 195: SURFOBJ *psoColor, ! 196: XLATEOBJ *pxlo, ! 197: LONG x, ! 198: LONG y, ! 199: FLONG fl) ! 200: { ! 201: PPDEV ppdev = (PPDEV) pso->dhpdev; ! 202: PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; ! 203: DWORD returnedDataLength; ! 204: ! 205: if (psoColor != (SURFOBJ *) NULL) ! 206: { ! 207: if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER) && ! 208: bCopyColorPointer(ppdev, psoMask, psoColor, pxlo)) ! 209: { ! 210: pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER; ! 211: } else { ! 212: return(FALSE); ! 213: } ! 214: ! 215: } else { ! 216: ! 217: if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER) && ! 218: bCopyMonoPointer(ppdev, psoMask)) ! 219: { ! 220: pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER; ! 221: } else { ! 222: return(FALSE); ! 223: } ! 224: } ! 225: ! 226: // Initialize Pointer attributes and position ! 227: ! 228: pPointerAttributes->Column = (SHORT)(x - ppdev->ptlHotSpot.x); ! 229: pPointerAttributes->Row = (SHORT)(y - ppdev->ptlHotSpot.y); ! 230: pPointerAttributes->Enable = 1; ! 231: ! 232: if (fl & SPS_ANIMATESTART) { ! 233: pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START; ! 234: } else if (fl & SPS_ANIMATEUPDATE) { ! 235: pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE; ! 236: } ! 237: ! 238: // Set the new Pointer shape. ! 239: ! 240: if (!DeviceIoControl(ppdev->hDriver, ! 241: IOCTL_VIDEO_SET_POINTER_ATTR, ! 242: pPointerAttributes, ! 243: ppdev->cjPointerAttributes, ! 244: NULL, ! 245: 0, ! 246: &returnedDataLength, ! 247: NULL)) { ! 248: ! 249: DISPDBG((1, "DISP:Failed IOCTL_VIDEO_SET_POINTER_ATTR call\n")); ! 250: return(FALSE); ! 251: } ! 252: ! 253: return(TRUE); ! 254: } ! 255: ! 256: /******************************Public*Routine******************************\ ! 257: * bCopyMonoPointer ! 258: * ! 259: * Copies two monochrome masks into a buffer of the maximum size handled by the ! 260: * miniport, with any extra bits set to 0. The masks are converted to topdown ! 261: * form if they aren't already. Returns TRUE if we can handle this pointer in ! 262: * hardware, FALSE if not. ! 263: * ! 264: \**************************************************************************/ ! 265: ! 266: BOOL bCopyMonoPointer( ! 267: PPDEV ppdev, ! 268: SURFOBJ *pso) ! 269: { ! 270: ULONG cx; ! 271: ULONG cy; ! 272: PBYTE pjSrcAnd, pjSrcXor; ! 273: LONG lDeltaSrc, lDeltaDst; ! 274: LONG lSrcWidthInBytes; ! 275: ULONG cxSrc = pso->sizlBitmap.cx; ! 276: ULONG cySrc = pso->sizlBitmap.cy; ! 277: ULONG cxSrcBytes; ! 278: PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; ! 279: PBYTE pjDstAnd = pPointerAttributes->Pixels; ! 280: PBYTE pjDstXor = pPointerAttributes->Pixels; ! 281: ! 282: // Make sure the new pointer isn't too big to handle ! 283: // (*2 because both masks are in there) ! 284: if ((cxSrc > ppdev->PointerCapabilities.MaxWidth) || ! 285: (cySrc > (ppdev->PointerCapabilities.MaxHeight * 2))) ! 286: { ! 287: return(FALSE); ! 288: } ! 289: ! 290: pjDstXor += ((ppdev->PointerCapabilities.MaxWidth + 7) / 8) * ! 291: ppdev->pPointerAttributes->Height; ! 292: ! 293: // set the desk and mask to 0xff ! 294: RtlFillMemory(pjDstAnd, ppdev->pPointerAttributes->WidthInBytes * ! 295: ppdev->pPointerAttributes->Height, 0xFF); ! 296: ! 297: // Zero the dest XOR mask ! 298: RtlZeroMemory(pjDstXor, ppdev->pPointerAttributes->WidthInBytes * ! 299: ppdev->pPointerAttributes->Height); ! 300: ! 301: cxSrcBytes = (cxSrc + 7) / 8; ! 302: ! 303: if ((lDeltaSrc = pso->lDelta) < 0) ! 304: { ! 305: lSrcWidthInBytes = -lDeltaSrc; ! 306: } else { ! 307: lSrcWidthInBytes = lDeltaSrc; ! 308: } ! 309: ! 310: pjSrcAnd = (PBYTE) pso->pvBits; ! 311: ! 312: // If the incoming pointer bitmap is bottomup, we'll flip it to topdown to ! 313: // save the miniport some work ! 314: if (!(pso->fjBitmap & BMF_TOPDOWN)) ! 315: { ! 316: // Copy from the bottom ! 317: pjSrcAnd += lSrcWidthInBytes * (cySrc - 1); ! 318: } ! 319: ! 320: // Height of just AND mask ! 321: cySrc = cySrc / 2; ! 322: ! 323: // Point to XOR mask ! 324: pjSrcXor = pjSrcAnd + (cySrc * lDeltaSrc); ! 325: ! 326: // Offset from end of one dest scan to start of next ! 327: lDeltaDst = ppdev->pPointerAttributes->WidthInBytes; ! 328: ! 329: for (cy = 0; cy < cySrc; ++cy) ! 330: { ! 331: RtlCopyMemory(pjDstAnd, pjSrcAnd, cxSrcBytes); ! 332: RtlCopyMemory(pjDstXor, pjSrcXor, cxSrcBytes); ! 333: ! 334: // Point to next source and dest scans ! 335: pjSrcAnd += lDeltaSrc; ! 336: pjSrcXor += lDeltaSrc; ! 337: pjDstAnd += lDeltaDst; ! 338: pjDstXor += lDeltaDst; ! 339: } ! 340: ! 341: return(TRUE); ! 342: } ! 343: ! 344: /******************************Public*Routine******************************\ ! 345: * bCopyColorPointer ! 346: * ! 347: * Copies the mono and color masks into the buffer of maximum size ! 348: * handled by the miniport with any extra bits set to 0. Color translation ! 349: * is handled at this time. The masks are converted to topdown form if they ! 350: * aren't already. Returns TRUE if we can handle this pointer in hardware, ! 351: * FALSE if not. ! 352: * ! 353: \**************************************************************************/ ! 354: BOOL bCopyColorPointer( ! 355: PPDEV ppdev, ! 356: SURFOBJ *psoMask, ! 357: SURFOBJ *psoColor, ! 358: XLATEOBJ *pxlo) ! 359: { ! 360: return(FALSE); ! 361: } ! 362: ! 363: ! 364: /******************************Public*Routine******************************\ ! 365: * bInitPointer ! 366: * ! 367: * Initialize the Pointer attributes. ! 368: * ! 369: \**************************************************************************/ ! 370: ! 371: BOOL bInitPointer(PPDEV ppdev, DEVINFO *pdevinfo) ! 372: { ! 373: DWORD returnedDataLength; ! 374: ! 375: ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL; ! 376: ppdev->cjPointerAttributes = 0; // initialized in screen.c ! 377: ! 378: // Ask the miniport whether it provides pointer support. ! 379: ! 380: if (!DeviceIoControl(ppdev->hDriver, ! 381: IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES, &ppdev->ulMode, ! 382: sizeof(PVIDEO_MODE), &ppdev->PointerCapabilities, ! 383: sizeof(ppdev->PointerCapabilities), &returnedDataLength, NULL)) ! 384: { ! 385: return(FALSE); ! 386: } ! 387: ! 388: // If neither mono nor color hardware pointer is supported, there's no ! 389: // hardware pointer support and we're done. ! 390: if ((!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER)) && ! 391: (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))) ! 392: { ! 393: return(TRUE); ! 394: } ! 395: ! 396: // Note: The buffer itself is allocated after we set the ! 397: // mode. At that time we know the pixel depth and we can ! 398: // allocate the correct size for the color pointer if supported. ! 399: ! 400: ! 401: // Set the asynchronous support status (async means miniport is capable of ! 402: // drawing the Pointer at any time, with no interference with any ongoing ! 403: // drawing operation) ! 404: ! 405: if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_ASYNC_POINTER) ! 406: { ! 407: pdevinfo->flGraphicsCaps |= GCAPS_ASYNCMOVE; ! 408: } ! 409: else ! 410: { ! 411: pdevinfo->flGraphicsCaps &= ~GCAPS_ASYNCMOVE; ! 412: } ! 413: ! 414: return(TRUE); ! 415: } ! 416:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.