Annotation of ntddk/src/video/displays/vga/cursor.c, revision 1.1.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.