Annotation of ntddk/src/video/displays/vga/cursor.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.