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