Annotation of ntddk/src/video/displays/vga256/bitblt.c, revision 1.1

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: bitblt.c
        !             3: *
        !             4: * Banked Frame Buffer bitblit
        !             5: *
        !             6: * Copyright (c) 1992 Microsoft Corporation
        !             7: *
        !             8: \**************************************************************************/
        !             9: 
        !            10: #include "driver.h"
        !            11: 
        !            12: /************************************************************************\
        !            13: * bIntersectRect
        !            14: *
        !            15: * Calculates the intersection between *prcSrc1 and *prcSrc2,
        !            16: * returning the resulting rect in *prcDst.  Returns TRUE if
        !            17: * *prcSrc1 intersects *prcSrc2, FALSE otherwise.  If there is no
        !            18: * intersection, an empty rect is returned in *prcDst.
        !            19: \************************************************************************/
        !            20: 
        !            21: static const RECTL rclEmpty = { 0, 0, 0, 0 };
        !            22: 
        !            23: BOOL bIntersectRect(
        !            24:     PRECTL prcDst,
        !            25:     PRECTL prcSrc1,
        !            26:     PRECTL prcSrc2)
        !            27: 
        !            28: {
        !            29:     prcDst->left  = max(prcSrc1->left, prcSrc2->left);
        !            30:     prcDst->right = min(prcSrc1->right, prcSrc2->right);
        !            31: 
        !            32:     // check for empty rect
        !            33: 
        !            34:     if (prcDst->left < prcDst->right)
        !            35:     {
        !            36:         prcDst->top    = max(prcSrc1->top, prcSrc2->top);
        !            37:         prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
        !            38: 
        !            39:         // check for empty rect
        !            40: 
        !            41:         if (prcDst->top < prcDst->bottom)
        !            42:             return(TRUE);        // not empty
        !            43:     }
        !            44: 
        !            45:     // empty rect
        !            46: 
        !            47:     *prcDst = rclEmpty;
        !            48: 
        !            49:     return(FALSE);
        !            50: }
        !            51: 
        !            52: /******************************Public*Routine******************************\
        !            53: * BOOL bPuntScreenToScreenCopyBits(ppdev, pco, pxlo, prclDest, pptlSrc)
        !            54: *
        !            55: * Performs a screen-to-screen CopyBits entirely using an intermediate
        !            56: * temporary buffer and GDI.
        !            57: *
        !            58: * We found that on most machines it was faster to have the engine copy
        !            59: * the source to a buffer, then blit the buffer to the destination, than
        !            60: * to have optimized ASM code that copies a word at a time.  The reason?
        !            61: * The engine does d-word moves, which are faster than word moves even
        !            62: * going over the bus to a 16 bit display device.
        !            63: *
        !            64: * We could also write optimized ASM code that does d-word moves, but the
        !            65: * win will be marginal, we're time constrained, we also need a routine
        !            66: * like this to handle complex clip objects and palette translates, and
        !            67: * most of the other times we can use planar copies for important things
        !            68: * like scrolls, anyways.
        !            69: *
        !            70: \**************************************************************************/
        !            71: 
        !            72: BOOL bPuntScreenToScreenCopyBits(
        !            73: PPDEV     ppdev,
        !            74: CLIPOBJ*  pco,
        !            75: XLATEOBJ* pxlo,
        !            76: RECTL*    prclDest,
        !            77: POINTL*   pptlSrc)
        !            78: {
        !            79:     RECTL    rclDest;
        !            80:     POINTL   ptlSrc;
        !            81:     BOOL     b = TRUE;
        !            82: 
        !            83:     SURFOBJ* pso    = ppdev->pSurfObj;
        !            84:     SURFOBJ* psoTmp = ppdev->psoTmp;
        !            85: 
        !            86:     if (prclDest->top < pptlSrc->y)
        !            87:     {
        !            88:         ////////////////////////////////////////////////////////////////
        !            89:         // Do a top-to-bottom copy:
        !            90:         ////////////////////////////////////////////////////////////////
        !            91: 
        !            92:         LONG ySrcBottom;
        !            93:         LONG yDestBottom;
        !            94: 
        !            95:         LONG yDestTop = prclDest->top;
        !            96:         LONG ySrcTop  = pptlSrc->y;
        !            97:         LONG ySrcLast = ySrcTop + (prclDest->bottom - prclDest->top);
        !            98: 
        !            99:         if (ySrcTop <  ppdev->rcl1WindowClip.top ||
        !           100:             ySrcTop >= ppdev->rcl1WindowClip.bottom)
        !           101:         {
        !           102:             ppdev->pfnBankControl(ppdev, ySrcTop, JustifyTop);
        !           103:         }
        !           104: 
        !           105:         pso->pvScan0 = ppdev->pvBitmapStart;
        !           106: 
        !           107:         while (TRUE)
        !           108:         {
        !           109:             // Copy an entire source bank into the temporary buffer:
        !           110: 
        !           111:             ySrcBottom     = min(ySrcLast, ppdev->rcl1WindowClip.bottom);
        !           112: 
        !           113:             ptlSrc.x       = pptlSrc->x;
        !           114:             ptlSrc.y       = ySrcTop;
        !           115: 
        !           116:             rclDest.left   = prclDest->left;
        !           117:             rclDest.top    = 0;
        !           118:             rclDest.right  = prclDest->right;
        !           119:             rclDest.bottom = ySrcBottom - ySrcTop;
        !           120: 
        !           121:             b &= EngCopyBits(psoTmp, pso, NULL, NULL, &rclDest, &ptlSrc);
        !           122: 
        !           123:             yDestBottom = yDestTop + rclDest.bottom;
        !           124: 
        !           125:             if (ppdev->rcl1WindowClip.top >= yDestBottom)
        !           126:             {
        !           127:                 ppdev->pfnBankControl(ppdev, yDestBottom - 1, JustifyBottom);
        !           128:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           129:             }
        !           130: 
        !           131:             while (TRUE)
        !           132:             {
        !           133:                 // Copy the temporary buffer into one or more destination
        !           134:                 // banks:
        !           135: 
        !           136:                 LONG yThisTop;
        !           137:                 LONG yThisBottom;
        !           138:                 LONG yOffset;
        !           139: 
        !           140:                 yThisBottom    = min(yDestBottom, ppdev->rcl1WindowClip.bottom);
        !           141:                 yThisTop       = max(yDestTop, ppdev->rcl1WindowClip.top);
        !           142:                 yOffset        = yThisTop - yDestTop;
        !           143: 
        !           144:                 ptlSrc.x       = prclDest->left;
        !           145:                 ptlSrc.y       = yOffset;
        !           146: 
        !           147:                 rclDest.left   = prclDest->left;
        !           148:                 rclDest.top    = yThisTop;
        !           149:                 rclDest.right  = prclDest->right;
        !           150:                 rclDest.bottom = yThisBottom;
        !           151: 
        !           152:                 b &= EngCopyBits(pso, psoTmp, pco, pxlo, &rclDest, &ptlSrc);
        !           153: 
        !           154:                 if (yOffset == 0)
        !           155:                     break;
        !           156: 
        !           157:                 ppdev->pfnBankControl(ppdev, yThisTop - 1, JustifyBottom);
        !           158:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           159:             }
        !           160: 
        !           161:             if (ySrcBottom >= ySrcLast)
        !           162:                 break;
        !           163: 
        !           164:             yDestTop = yDestBottom;
        !           165:             ySrcTop  = ySrcBottom;
        !           166: 
        !           167:             ppdev->pfnBankControl(ppdev, ySrcTop, JustifyTop);
        !           168:             pso->pvScan0 = ppdev->pvBitmapStart;
        !           169:         }
        !           170:     }
        !           171:     else
        !           172:     {
        !           173:         ////////////////////////////////////////////////////////////////
        !           174:         // Do a bottom-to-top copy:
        !           175:         ////////////////////////////////////////////////////////////////
        !           176: 
        !           177:         LONG ySrcTop;
        !           178:         LONG yDestTop;
        !           179: 
        !           180:         LONG yDestBottom = prclDest->bottom;
        !           181:         LONG ySrcFirst   = pptlSrc->y;
        !           182:         LONG ySrcBottom  = ySrcFirst + (prclDest->bottom - prclDest->top);
        !           183: 
        !           184:         if (ySrcBottom <= ppdev->rcl1WindowClip.top ||
        !           185:             ySrcBottom > ppdev->rcl1WindowClip.bottom)
        !           186:         {
        !           187:             ppdev->pfnBankControl(ppdev, ySrcBottom - 1, JustifyBottom);
        !           188:         }
        !           189: 
        !           190:         pso->pvScan0 = ppdev->pvBitmapStart;
        !           191: 
        !           192:         while (TRUE)
        !           193:         {
        !           194:             // Copy an entire source bank into the temporary buffer:
        !           195: 
        !           196:             ySrcTop        = max(ySrcFirst, ppdev->rcl1WindowClip.top);
        !           197: 
        !           198:             ptlSrc.x       = pptlSrc->x;
        !           199:             ptlSrc.y       = ySrcTop;
        !           200: 
        !           201:             rclDest.left   = prclDest->left;
        !           202:             rclDest.top    = 0;
        !           203:             rclDest.right  = prclDest->right;
        !           204:             rclDest.bottom = ySrcBottom - ySrcTop;
        !           205: 
        !           206:             b &= EngCopyBits(psoTmp, pso, NULL, NULL, &rclDest, &ptlSrc);
        !           207: 
        !           208:             yDestTop = yDestBottom - rclDest.bottom;
        !           209: 
        !           210:             if (ppdev->rcl1WindowClip.bottom <= yDestTop)
        !           211:             {
        !           212:                 ppdev->pfnBankControl(ppdev, yDestTop, JustifyTop);
        !           213:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           214:             }
        !           215: 
        !           216:             while (TRUE)
        !           217:             {
        !           218:                 // Copy the temporary buffer into one or more destination
        !           219:                 // banks:
        !           220: 
        !           221:                 LONG yThisTop;
        !           222:                 LONG yThisBottom;
        !           223:                 LONG yOffset;
        !           224: 
        !           225:                 yThisTop       = max(yDestTop, ppdev->rcl1WindowClip.top);
        !           226:                 yThisBottom    = min(yDestBottom, ppdev->rcl1WindowClip.bottom);
        !           227:                 yOffset        = yThisTop - yDestTop;
        !           228: 
        !           229:                 ptlSrc.x       = prclDest->left;
        !           230:                 ptlSrc.y       = yOffset;
        !           231: 
        !           232:                 rclDest.left   = prclDest->left;
        !           233:                 rclDest.top    = yThisTop;
        !           234:                 rclDest.right  = prclDest->right;
        !           235:                 rclDest.bottom = yThisBottom;
        !           236: 
        !           237:                 b &= EngCopyBits(pso, psoTmp, pco, pxlo, &rclDest, &ptlSrc);
        !           238: 
        !           239:                 if (yThisBottom == yDestBottom)
        !           240:                     break;
        !           241: 
        !           242:                 ppdev->pfnBankControl(ppdev, yThisBottom, JustifyTop);
        !           243:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           244:             }
        !           245: 
        !           246:             if (ySrcTop <= ySrcFirst)
        !           247:                 break;
        !           248: 
        !           249:             yDestBottom = yDestTop;
        !           250:             ySrcBottom  = ySrcTop;
        !           251: 
        !           252:             ppdev->pfnBankControl(ppdev, ySrcBottom - 1, JustifyBottom);
        !           253:             pso->pvScan0 = ppdev->pvBitmapStart;
        !           254:         }
        !           255:     }
        !           256: 
        !           257:     return(b);
        !           258: }
        !           259: 
        !           260: /******************************Public*Routine******************************\
        !           261: * BOOL bPuntScreenToScreenBitBlt(...)
        !           262: *
        !           263: * Performs a screen-to-screen BitBlt entirely using an intermediate temporary
        !           264: * buffer and GDI.
        !           265: *
        !           266: * This function is basically a clone of bPuntScreenToScreenCopyBits,
        !           267: * except that it can handle funky ROPs and stuff.
        !           268: \**************************************************************************/
        !           269: 
        !           270: BOOL bPuntScreenToScreenBitBlt(
        !           271: PPDEV     ppdev,
        !           272: SURFOBJ*  psoMask,
        !           273: CLIPOBJ*  pco,
        !           274: XLATEOBJ* pxlo,
        !           275: RECTL*    prclDest,
        !           276: POINTL*   pptlSrc,
        !           277: POINTL*   pptlMask,
        !           278: BRUSHOBJ* pbo,
        !           279: POINTL*   pptlBrush,
        !           280: ROP4      rop4)
        !           281: {
        !           282:     RECTL    rclDest;           // Temporary destination rectangle
        !           283:     POINTL   ptlSrc;            // Temporary source point
        !           284:     POINTL   ptlMask;           // Temporary mask offset
        !           285:     POINTL   ptlMaskAdjust;     // Adjustment for mask offset
        !           286:     BOOL     b = TRUE;
        !           287: 
        !           288:     SURFOBJ* pso    = ppdev->pSurfObj;
        !           289:     SURFOBJ* psoTmp = ppdev->psoTmp;
        !           290: 
        !           291:     if (psoMask != NULL)
        !           292:     {
        !           293:         ptlMaskAdjust.x = prclDest->left - pptlMask->x;
        !           294:         ptlMaskAdjust.y = prclDest->top  - pptlMask->y;
        !           295:     }
        !           296: 
        !           297:     if (prclDest->top < pptlSrc->y)
        !           298:     {
        !           299:         ////////////////////////////////////////////////////////////////
        !           300:         // Do a top-to-bottom copy:
        !           301:         ////////////////////////////////////////////////////////////////
        !           302: 
        !           303:         LONG ySrcBottom;
        !           304:         LONG yDestBottom;
        !           305: 
        !           306:         LONG yDestTop = prclDest->top;
        !           307:         LONG ySrcTop  = pptlSrc->y;
        !           308:         LONG ySrcLast = ySrcTop + (prclDest->bottom - prclDest->top);
        !           309: 
        !           310:         if (ySrcTop <  ppdev->rcl1WindowClip.top ||
        !           311:             ySrcTop >= ppdev->rcl1WindowClip.bottom)
        !           312:         {
        !           313:             ppdev->pfnBankControl(ppdev, ySrcTop, JustifyTop);
        !           314:         }
        !           315: 
        !           316:         pso->pvScan0 = ppdev->pvBitmapStart;
        !           317: 
        !           318:         while (TRUE)
        !           319:         {
        !           320:             // Copy an entire source bank into the temporary buffer:
        !           321: 
        !           322:             ySrcBottom     = min(ySrcLast, ppdev->rcl1WindowClip.bottom);
        !           323: 
        !           324:             ptlSrc.x       = pptlSrc->x;
        !           325:             ptlSrc.y       = ySrcTop;
        !           326: 
        !           327:             rclDest.left   = prclDest->left;
        !           328:             rclDest.top    = 0;
        !           329:             rclDest.right  = prclDest->right;
        !           330:             rclDest.bottom = ySrcBottom - ySrcTop;
        !           331: 
        !           332:             b &= EngCopyBits(psoTmp, pso, NULL, NULL, &rclDest, &ptlSrc);
        !           333: 
        !           334:             yDestBottom = yDestTop + rclDest.bottom;
        !           335: 
        !           336:             if (ppdev->rcl1WindowClip.top >= yDestBottom)
        !           337:             {
        !           338:                 ppdev->pfnBankControl(ppdev, yDestBottom - 1, JustifyBottom);
        !           339:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           340:             }
        !           341: 
        !           342:             while (TRUE)
        !           343:             {
        !           344:                 // Copy the temporary buffer into one or more destination
        !           345:                 // banks:
        !           346: 
        !           347:                 LONG yThisTop;
        !           348:                 LONG yThisBottom;
        !           349:                 LONG yOffset;
        !           350: 
        !           351:                 yThisBottom    = min(yDestBottom, ppdev->rcl1WindowClip.bottom);
        !           352:                 yThisTop       = max(yDestTop, ppdev->rcl1WindowClip.top);
        !           353:                 yOffset        = yThisTop - yDestTop;
        !           354: 
        !           355:                 ptlSrc.x       = prclDest->left;
        !           356:                 ptlSrc.y       = yOffset;
        !           357: 
        !           358:                 rclDest.left   = prclDest->left;
        !           359:                 rclDest.top    = yThisTop;
        !           360:                 rclDest.right  = prclDest->right;
        !           361:                 rclDest.bottom = yThisBottom;
        !           362: 
        !           363:                 ptlMask.x = rclDest.left - ptlMaskAdjust.x;
        !           364:                 ptlMask.y = rclDest.top  - ptlMaskAdjust.y;
        !           365: 
        !           366:                 b &= EngBitBlt(pso, psoTmp, psoMask, pco, pxlo, &rclDest,
        !           367:                                &ptlSrc, &ptlMask, pbo, pptlBrush, rop4);
        !           368: 
        !           369:                 if (yOffset == 0)
        !           370:                     break;
        !           371: 
        !           372:                 ppdev->pfnBankControl(ppdev, yThisTop - 1, JustifyBottom);
        !           373:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           374:             }
        !           375: 
        !           376:             if (ySrcBottom >= ySrcLast)
        !           377:                 break;
        !           378: 
        !           379:             yDestTop = yDestBottom;
        !           380:             ySrcTop  = ySrcBottom;
        !           381: 
        !           382:             ppdev->pfnBankControl(ppdev, ySrcTop, JustifyTop);
        !           383:             pso->pvScan0 = ppdev->pvBitmapStart;
        !           384:         }
        !           385:     }
        !           386:     else
        !           387:     {
        !           388:         ////////////////////////////////////////////////////////////////
        !           389:         // Do a bottom-to-top copy:
        !           390:         ////////////////////////////////////////////////////////////////
        !           391: 
        !           392:         LONG ySrcTop;
        !           393:         LONG yDestTop;
        !           394: 
        !           395:         LONG yDestBottom = prclDest->bottom;
        !           396:         LONG ySrcFirst   = pptlSrc->y;
        !           397:         LONG ySrcBottom  = ySrcFirst + (prclDest->bottom - prclDest->top);
        !           398: 
        !           399:         if (ySrcBottom <= ppdev->rcl1WindowClip.top ||
        !           400:             ySrcBottom > ppdev->rcl1WindowClip.bottom)
        !           401:         {
        !           402:             ppdev->pfnBankControl(ppdev, ySrcBottom - 1, JustifyBottom);
        !           403:         }
        !           404: 
        !           405:         pso->pvScan0 = ppdev->pvBitmapStart;
        !           406: 
        !           407:         while (TRUE)
        !           408:         {
        !           409:             // Copy an entire source bank into the temporary buffer:
        !           410: 
        !           411:             ySrcTop        = max(ySrcFirst, ppdev->rcl1WindowClip.top);
        !           412: 
        !           413:             ptlSrc.x       = pptlSrc->x;
        !           414:             ptlSrc.y       = ySrcTop;
        !           415: 
        !           416:             rclDest.left   = prclDest->left;
        !           417:             rclDest.top    = 0;
        !           418:             rclDest.right  = prclDest->right;
        !           419:             rclDest.bottom = ySrcBottom - ySrcTop;
        !           420: 
        !           421:             b &= EngCopyBits(psoTmp, pso, NULL, NULL, &rclDest, &ptlSrc);
        !           422: 
        !           423:             yDestTop = yDestBottom - rclDest.bottom;
        !           424: 
        !           425:             if (ppdev->rcl1WindowClip.bottom <= yDestTop)
        !           426:             {
        !           427:                 ppdev->pfnBankControl(ppdev, yDestTop, JustifyTop);
        !           428:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           429:             }
        !           430: 
        !           431:             while (TRUE)
        !           432:             {
        !           433:                 // Copy the temporary buffer into one or more destination
        !           434:                 // banks:
        !           435: 
        !           436:                 LONG yThisTop;
        !           437:                 LONG yThisBottom;
        !           438:                 LONG yOffset;
        !           439: 
        !           440:                 yThisTop       = max(yDestTop, ppdev->rcl1WindowClip.top);
        !           441:                 yThisBottom    = min(yDestBottom, ppdev->rcl1WindowClip.bottom);
        !           442:                 yOffset        = yThisTop - yDestTop;
        !           443: 
        !           444:                 ptlSrc.x       = prclDest->left;
        !           445:                 ptlSrc.y       = yOffset;
        !           446: 
        !           447:                 rclDest.left   = prclDest->left;
        !           448:                 rclDest.top    = yThisTop;
        !           449:                 rclDest.right  = prclDest->right;
        !           450:                 rclDest.bottom = yThisBottom;
        !           451: 
        !           452:                 ptlMask.x = rclDest.left - ptlMaskAdjust.x;
        !           453:                 ptlMask.y = rclDest.top  - ptlMaskAdjust.y;
        !           454: 
        !           455:                 b &= EngBitBlt(pso, psoTmp, psoMask, pco, pxlo, &rclDest,
        !           456:                                &ptlSrc, &ptlMask, pbo, pptlBrush, rop4);
        !           457: 
        !           458:                 if (yThisBottom == yDestBottom)
        !           459:                     break;
        !           460: 
        !           461:                 ppdev->pfnBankControl(ppdev, yThisBottom, JustifyTop);
        !           462:                 pso->pvScan0 = ppdev->pvBitmapStart;
        !           463:             }
        !           464: 
        !           465:             if (ySrcTop <= ySrcFirst)
        !           466:                 break;
        !           467: 
        !           468:             yDestBottom = yDestTop;
        !           469:             ySrcBottom  = ySrcTop;
        !           470: 
        !           471:             ppdev->pfnBankControl(ppdev, ySrcBottom - 1, JustifyBottom);
        !           472:             pso->pvScan0 = ppdev->pvBitmapStart;
        !           473:         }
        !           474:     }
        !           475: 
        !           476:     return(b);
        !           477: }
        !           478: 
        !           479: /******************************Public*Data*********************************\
        !           480: * ROP to mix translation table
        !           481: *
        !           482: * Table to translate ternary raster ops to mixes (binary raster ops). Ternary
        !           483: * raster ops that can't be translated to mixes are translated to 0 (0 is not
        !           484: * a valid mix).
        !           485: *
        !           486: \**************************************************************************/
        !           487: 
        !           488: UCHAR jRop3ToMix[256] = {
        !           489:     R2_BLACK, 0, 0, 0, 0, R2_NOTMERGEPEN, 0, 0,
        !           490:     0, 0, R2_MASKNOTPEN, 0, 0, 0, 0, R2_NOTCOPYPEN,
        !           491:     0, 0, 0, 0, 0, 0, 0, 0,
        !           492:     0, 0, 0, 0, 0, 0, 0, 0,
        !           493:     0, 0, 0, 0, 0, 0, 0, 0,
        !           494:     0, 0, 0, 0, 0, 0, 0, 0,
        !           495:     0, 0, 0, 0, 0, 0, 0, 0,
        !           496:     0, 0, 0, 0, 0, 0, 0, 0,
        !           497:     0, 0, 0, 0, 0, 0, 0, 0,
        !           498:     0, 0, 0, 0, 0, 0, 0, 0,
        !           499:     R2_MASKPENNOT, 0, 0, 0, 0, R2_NOT, 0, 0,
        !           500:     0, 0, R2_XORPEN, 0, 0, 0, 0, R2_NOTMASKPEN,
        !           501:     0, 0, 0, 0, 0, 0, 0, 0,
        !           502:     0, 0, 0, 0, 0, 0, 0, 0,
        !           503:     0, 0, 0, 0, 0, 0, 0, 0,
        !           504:     0, 0, 0, 0, 0, 0, 0, 0,
        !           505:     0, 0, 0, 0, 0, 0, 0, 0,
        !           506:     0, 0, 0, 0, 0, 0, 0, 0,
        !           507:     0, 0, 0, 0, 0, 0, 0, 0,
        !           508:     0, 0, 0, 0, 0, 0, 0, 0,
        !           509:     R2_MASKPEN, 0, 0, 0, 0, R2_NOTXORPEN, 0, 0,
        !           510:     0, 0, R2_NOP, 0, 0, 0, 0, R2_MERGENOTPEN,
        !           511:     0, 0, 0, 0, 0, 0, 0, 0,
        !           512:     0, 0, 0, 0, 0, 0, 0, 0,
        !           513:     0, 0, 0, 0, 0, 0, 0, 0,
        !           514:     0, 0, 0, 0, 0, 0, 0, 0,
        !           515:     0, 0, 0, 0, 0, 0, 0, 0,
        !           516:     0, 0, 0, 0, 0, 0, 0, 0,
        !           517:     0, 0, 0, 0, 0, 0, 0, 0,
        !           518:     0, 0, 0, 0, 0, 0, 0, 0,
        !           519:     R2_COPYPEN, 0, 0, 0, 0, R2_MERGEPENNOT, 0, 0,
        !           520:     0, 0, R2_MERGEPEN, 0, 0, 0, 0, R2_WHITE
        !           521: };
        !           522: 
        !           523: /******************************Public*Routine******************************\
        !           524: * BOOL DrvBitBlt(psoDest, psoSrc, psoMask, pco, pxlo, prclDest, pptlSrc,
        !           525: *                pptlMask, pbo, pptlBrush, rop4)
        !           526: *
        !           527: * This routine will handle any blit.  Perhaps glacially, but it will be
        !           528: * handled.
        !           529: \**************************************************************************/
        !           530: 
        !           531: BOOL DrvBitBlt(
        !           532: SURFOBJ*  psoDest,
        !           533: SURFOBJ*  psoSrc,
        !           534: SURFOBJ*  psoMask,
        !           535: CLIPOBJ*  pco,
        !           536: XLATEOBJ* pxlo,
        !           537: RECTL*    prclDest,
        !           538: POINTL*   pptlSrc,
        !           539: POINTL*   pptlMask,
        !           540: BRUSHOBJ* pbo,
        !           541: POINTL*   pptlBrush,
        !           542: ROP4      rop4)
        !           543: {
        !           544:     BOOL     b;
        !           545:     POINTL   ptlSrc;
        !           546:     RECTL    rclDest;
        !           547:     PPDEV    ppdev;
        !           548:     SURFOBJ* pso;
        !           549:     MIX      mix;           // Mix, when solid fill performed
        !           550:     BYTE     jClipping;
        !           551:     RECTL    rclTmp;
        !           552:     POINTL   ptlTmp;
        !           553:     BBENUM   bben;          // Clip enumerator
        !           554:     BOOL     bMore;         // Clip continuation flag
        !           555:     POINTL   ptlMask;       // Temporary mask for engine call-backs
        !           556:     POINTL   ptlMaskAdjust; // Adjustment for mask
        !           557:     INT      iCopyDir;
        !           558: 
        !           559:     RBRUSH_COLOR rbc;               // Pointer to RBRUSH or iSolidColor value
        !           560:     PFNFILL      pfnFill = vTrgBlt; // Pointer to appropriate fill routine
        !           561:                                     //  (solid color by default)
        !           562: 
        !           563:     // Set up the clipping type
        !           564:     if (pco == (CLIPOBJ *) NULL) {
        !           565:         // No CLIPOBJ provided, so we don't have to worry about clipping
        !           566:         jClipping = DC_TRIVIAL;
        !           567:     } else {
        !           568:         // Use the CLIPOBJ-provided clipping
        !           569:         jClipping = pco->iDComplexity;
        !           570:     }
        !           571: 
        !           572:     // Handle solid fills to the VGA surface with special-case code if planar
        !           573:     // mode is supported.
        !           574:     // LATER handle non-planar also
        !           575: 
        !           576:     if (psoDest->iType == STYPE_DEVICE) {
        !           577: 
        !           578:         // Destination is the VGA surface
        !           579: 
        !           580:         // Masked cases must be handled differently
        !           581: 
        !           582:         if ((((PPDEV) psoDest->dhsurf)->fl & DRIVER_PLANAR_CAPABLE) &&
        !           583:             ((rop4 & 0xFF) == ((rop4 >> 8) & 0xFF))) {
        !           584: 
        !           585:             // Special-case static code for no-mask cases
        !           586: 
        !           587:             // Calculate mix from ROP if possible (not possible if it's truly a
        !           588:             // ternary rop or a real rop4, but we can treat all pure binary
        !           589:             // rops as mixes rather than rop4s)
        !           590:             mix = jRop3ToMix[rop4 & 0xFF];
        !           591: 
        !           592:             switch (mix) {
        !           593:                 case R2_MASKNOTPEN:
        !           594:                 case R2_NOTCOPYPEN:
        !           595:                 case R2_XORPEN:
        !           596:                 case R2_MASKPEN:
        !           597:                 case R2_NOTXORPEN:
        !           598:                 case R2_MERGENOTPEN:
        !           599:                 case R2_COPYPEN:
        !           600:                 case R2_MERGEPEN:
        !           601:                 case R2_NOTMERGEPEN:
        !           602:                 case R2_MASKPENNOT:
        !           603:                 case R2_NOTMASKPEN:
        !           604:                 case R2_MERGEPENNOT:
        !           605: 
        !           606:                     // vTrgBlt can only handle solid color fills
        !           607: 
        !           608:                     if (pbo->iSolidColor != 0xffffffff)
        !           609:                     {
        !           610:                         rbc.iSolidColor = pbo->iSolidColor;
        !           611:                     }
        !           612:                     else
        !           613:                     {
        !           614:                         rbc.prb = (RBRUSH*) pbo->pvRbrush;
        !           615:                         if (rbc.prb == NULL)
        !           616:                         {
        !           617:                             rbc.prb = (RBRUSH*) BRUSHOBJ_pvGetRbrush(pbo);
        !           618:                             if (rbc.prb == NULL)
        !           619:                             {
        !           620:                             // If we haven't realized the brush, punt the call
        !           621:                             // to the engine:
        !           622: 
        !           623:                                 break;
        !           624:                             }
        !           625:                         }
        !           626:                         if (!(rbc.prb->fl & RBRUSH_BLACKWHITE) &&
        !           627:                             (mix != R2_COPYPEN))
        !           628:                         {
        !           629:                         // Only black/white brushes can handle ROPs other
        !           630:                         // than COPYPEN:
        !           631: 
        !           632:                             break;
        !           633:                         }
        !           634: 
        !           635:                         if (rbc.prb->fl & RBRUSH_NCOLOR)
        !           636:                             pfnFill = vColorPat;
        !           637:                         else
        !           638:                             pfnFill = vMonoPat;
        !           639:                     }
        !           640: 
        !           641:                 // Rops that are implicit solid colors
        !           642: 
        !           643:                 case R2_NOT:
        !           644:                 case R2_WHITE:
        !           645:                 case R2_BLACK:
        !           646:                     // We can do a special-case solid fill
        !           647: 
        !           648:                     switch(jClipping) {
        !           649:                         case DC_TRIVIAL:
        !           650: 
        !           651:                             // Just fill the rectangle:
        !           652: 
        !           653:                             (*pfnFill)((PPDEV) psoDest->dhsurf, 1,
        !           654:                                        prclDest, mix, rbc, pptlBrush);
        !           655: 
        !           656:                             break;
        !           657: 
        !           658:                         case DC_RECT:
        !           659: 
        !           660:                             // Clip the solid fill to the clip rectangle
        !           661:                             if (!bIntersectRect(&rclTmp, prclDest,
        !           662:                                     &pco->rclBounds))
        !           663:                                 return(TRUE);
        !           664: 
        !           665:                             // Fill the clipped rectangle
        !           666: 
        !           667:                             (*pfnFill)((PPDEV) psoDest->dhsurf, 1,
        !           668:                                        &rclTmp, mix, rbc, pptlBrush);
        !           669: 
        !           670:                             break;
        !           671: 
        !           672:                         case DC_COMPLEX:
        !           673: 
        !           674:                             ppdev = (PPDEV) psoDest->dhsurf;
        !           675: 
        !           676:                             CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
        !           677:                                                CD_ANY, BB_RECT_LIMIT);
        !           678: 
        !           679:                             do {
        !           680:                                 bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
        !           681:                                                       (PVOID) &bben);
        !           682: 
        !           683:                                 if (bben.c > 0)
        !           684:                                 {
        !           685:                                     RECTL* prclEnd = &bben.arcl[bben.c];
        !           686:                                     RECTL* prcl    = &bben.arcl[0];
        !           687: 
        !           688:                                     do {
        !           689:                                         bIntersectRect(prcl, prcl, prclDest);
        !           690:                                         prcl++;
        !           691: 
        !           692:                                     } while (prcl < prclEnd);
        !           693: 
        !           694:                                     (*pfnFill)(ppdev, bben.c, bben.arcl,
        !           695:                                                mix, rbc, pptlBrush);
        !           696:                                 }
        !           697: 
        !           698:                             } while(bMore);
        !           699:                     }
        !           700: 
        !           701:                 case R2_NOP:
        !           702:                     return(TRUE);
        !           703: 
        !           704:                 default:
        !           705:                     break;
        !           706:             }
        !           707:         }
        !           708:     }
        !           709: 
        !           710:     // Get the correct surface object for the target and the source
        !           711: 
        !           712:     if (psoDest->iType == STYPE_DEVICE) {
        !           713: 
        !           714:         if ((psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE)) {
        !           715: 
        !           716:             ////////////////////////////////////////////////////////////////
        !           717:             // BitBlt screen-to-screen:
        !           718:             ////////////////////////////////////////////////////////////////
        !           719: 
        !           720:             ppdev = (PPDEV) psoDest->dhsurf;
        !           721: 
        !           722:             // See if we can do a simple CopyBits:
        !           723: 
        !           724:             if (rop4 == 0x0000CCCC)
        !           725:             {
        !           726:                 ppdev = (PPDEV) psoDest->dhsurf;
        !           727: 
        !           728:                 // We can handle quadpixel-aligned screen-to-screen blts with
        !           729:                 // no translation:
        !           730: 
        !           731:                 if ((((pptlSrc->x ^ prclDest->left) & 3) == 0) &&
        !           732:                     (ppdev->fl & DRIVER_PLANAR_CAPABLE) &&
        !           733:                     ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)))
        !           734:                 {
        !           735:                     switch(jClipping)
        !           736:                     {
        !           737:                     case DC_TRIVIAL:
        !           738:                         vPlanarCopyBits(ppdev, prclDest, pptlSrc);
        !           739:                         return(TRUE);
        !           740: 
        !           741:                     case DC_RECT:
        !           742: 
        !           743:                         // Clip the target rectangle to the clip rectangle:
        !           744: 
        !           745:                         if (!bIntersectRect(&rclTmp, prclDest, &pco->rclBounds))
        !           746:                         {
        !           747:                             DISPDBG((0, "DrvBitBlt: Nothing to draw."));
        !           748:                             return(TRUE);
        !           749:                         }
        !           750: 
        !           751:                         ptlTmp.x = pptlSrc->x + rclTmp.left - prclDest->left;
        !           752:                         ptlTmp.y = pptlSrc->y + rclTmp.top  - prclDest->top;
        !           753: 
        !           754:                         vPlanarCopyBits(ppdev, &rclTmp, &ptlTmp);
        !           755:                         return(TRUE);
        !           756: 
        !           757:                     case DC_COMPLEX:
        !           758:                         if (pptlSrc->y >= prclDest->top)
        !           759:                         {
        !           760:                             if (pptlSrc->x >= prclDest->left)
        !           761:                                 iCopyDir = CD_RIGHTDOWN;
        !           762:                             else
        !           763:                                 iCopyDir = CD_LEFTDOWN;
        !           764:                         }
        !           765:                         else
        !           766:                         {
        !           767:                             if (pptlSrc->x >= prclDest->left)
        !           768:                                 iCopyDir = CD_RIGHTUP;
        !           769:                             else
        !           770:                                 iCopyDir = CD_LEFTUP;
        !           771:                         }
        !           772: 
        !           773:                         CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, iCopyDir, 0);
        !           774: 
        !           775:                         do {
        !           776:                             RECTL* prcl;
        !           777:                             RECTL* prclEnd;
        !           778: 
        !           779:                             bMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(bben),
        !           780:                                                   (PVOID) &bben);
        !           781: 
        !           782:                             prclEnd = &bben.arcl[bben.c];
        !           783:                             for (prcl = bben.arcl; prcl < prclEnd; prcl++)
        !           784:                             {
        !           785:                                 if (bIntersectRect(prcl, prclDest, prcl))
        !           786:                                 {
        !           787:                                     ptlTmp.x = pptlSrc->x + prcl->left - prclDest->left;
        !           788:                                     ptlTmp.y = pptlSrc->y + prcl->top  - prclDest->top;
        !           789: 
        !           790:                                     vPlanarCopyBits(ppdev, prcl, &ptlTmp);
        !           791:                                 }
        !           792:                             }
        !           793:                         } while (bMore);
        !           794: 
        !           795:                         return(TRUE);
        !           796:                     }
        !           797:                 }
        !           798: 
        !           799:                 // Can't handle in hardware, so punt:
        !           800: 
        !           801:                 return(bPuntScreenToScreenCopyBits(ppdev,
        !           802:                                                    pco,
        !           803:                                                    pxlo,
        !           804:                                                    prclDest,
        !           805:                                                    pptlSrc));
        !           806:             }
        !           807: 
        !           808:             // It's more complicated than a CopyBits, so punt it:
        !           809: 
        !           810:             return(bPuntScreenToScreenBitBlt(ppdev,
        !           811:                                              psoMask,
        !           812:                                              pco,
        !           813:                                              pxlo,
        !           814:                                              prclDest,
        !           815:                                              pptlSrc,
        !           816:                                              pptlMask,
        !           817:                                              pbo,
        !           818:                                              pptlBrush,
        !           819:                                              rop4));
        !           820:         }
        !           821: 
        !           822:         ////////////////////////////////////////////////////////////////
        !           823:         // BitBlt to screen:
        !           824:         ////////////////////////////////////////////////////////////////
        !           825: 
        !           826:         ppdev = (PPDEV) psoDest->dhsurf;
        !           827: 
        !           828:         if ((rop4 == 0x0000CCCC) &&
        !           829:             (psoSrc->iBitmapFormat == BMF_8BPP) &&
        !           830:             ((pxlo == NULL) || (pxlo->flXlate == XO_TRIVIAL)))
        !           831:         {
        !           832:         // We have special code for the common 8bpp from memory to screen
        !           833:         // with no ROPs:
        !           834: 
        !           835:             switch(jClipping)
        !           836:             {
        !           837:             case DC_TRIVIAL:
        !           838:                 vSrcCopy8bpp(ppdev, prclDest, pptlSrc,
        !           839:                              psoSrc->lDelta, psoSrc->pvScan0);
        !           840:                 return(TRUE);
        !           841: 
        !           842:             case DC_RECT:
        !           843: 
        !           844:                 // Clip the blt to the clip rectangle
        !           845: 
        !           846:                 bIntersectRect(&rclTmp, prclDest, &pco->rclBounds);
        !           847: 
        !           848:                 ptlTmp.x = pptlSrc->x + rclTmp.left - prclDest->left;
        !           849:                 ptlTmp.y = pptlSrc->y + rclTmp.top  - prclDest->top;
        !           850: 
        !           851:                 vSrcCopy8bpp(ppdev, &rclTmp, &ptlTmp,
        !           852:                              psoSrc->lDelta, psoSrc->pvScan0);
        !           853: 
        !           854:                 return(TRUE);
        !           855: 
        !           856:             case DC_COMPLEX:
        !           857: 
        !           858:                 CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
        !           859:                                    CD_ANY, BB_RECT_LIMIT);
        !           860: 
        !           861:                 do {
        !           862:                     bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
        !           863:                                           (PVOID) &bben);
        !           864: 
        !           865:                     if (bben.c > 0)
        !           866:                     {
        !           867:                         RECTL* prclEnd = &bben.arcl[bben.c];
        !           868:                         RECTL* prcl    = &bben.arcl[0];
        !           869: 
        !           870:                         do {
        !           871:                             bIntersectRect(prcl, prcl, prclDest);
        !           872: 
        !           873:                             ptlTmp.x = pptlSrc->x + prcl->left
        !           874:                                      - prclDest->left;
        !           875:                             ptlTmp.y = pptlSrc->y + prcl->top
        !           876:                                      - prclDest->top;
        !           877: 
        !           878:                             vSrcCopy8bpp(ppdev, prcl, &ptlTmp,
        !           879:                                          psoSrc->lDelta, psoSrc->pvScan0);
        !           880: 
        !           881:                             prcl++;
        !           882: 
        !           883:                         } while (prcl < prclEnd);
        !           884:                     }
        !           885: 
        !           886:                 } while(bMore);
        !           887: 
        !           888:                 return(TRUE);
        !           889:             }
        !           890:         }
        !           891: 
        !           892:         // Punt the memory-to-screen call back to the engine:
        !           893: 
        !           894:         if (psoMask != NULL)
        !           895:         {
        !           896:             ptlMaskAdjust.x = prclDest->left - pptlMask->x;
        !           897:             ptlMaskAdjust.y = prclDest->top  - pptlMask->y;
        !           898:         }
        !           899: 
        !           900:         pso = ppdev->pSurfObj;
        !           901: 
        !           902:         vBankStartBltDest(ppdev, pso, pptlSrc, prclDest, &ptlSrc, &rclDest);
        !           903: 
        !           904:         do {
        !           905:             ptlMask.x = rclDest.left - ptlMaskAdjust.x;
        !           906:             ptlMask.y = rclDest.top  - ptlMaskAdjust.y;
        !           907: 
        !           908:             b = EngBitBlt(pso,
        !           909:                           psoSrc,
        !           910:                           psoMask,
        !           911:                           pco,
        !           912:                           pxlo,
        !           913:                           &rclDest,
        !           914:                           &ptlSrc,
        !           915:                           &ptlMask,
        !           916:                           pbo,
        !           917:                           pptlBrush,
        !           918:                           rop4);
        !           919: 
        !           920:         } while (b && bBankEnumBltDest(ppdev, pso, pptlSrc, prclDest,
        !           921:                                        &ptlSrc, &rclDest));
        !           922: 
        !           923:         return(b);
        !           924:     }
        !           925:     else if ((psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE))
        !           926:     {
        !           927:         ////////////////////////////////////////////////////////////////
        !           928:         // BitBlt from screen:
        !           929:         ////////////////////////////////////////////////////////////////
        !           930: 
        !           931:         if (psoMask != NULL)
        !           932:         {
        !           933:             ptlMaskAdjust.x = prclDest->left - pptlMask->x;
        !           934:             ptlMaskAdjust.y = prclDest->top  - pptlMask->y;
        !           935:         }
        !           936: 
        !           937:         ppdev = (PPDEV) psoSrc->dhsurf;
        !           938:         pso   = ppdev->pSurfObj;
        !           939: 
        !           940:         vBankStartBltSrc(ppdev, pso, pptlSrc, prclDest, &ptlSrc, &rclDest);
        !           941: 
        !           942:         do {
        !           943:             ptlMask.x = rclDest.left - ptlMaskAdjust.x;
        !           944:             ptlMask.y = rclDest.top  - ptlMaskAdjust.y;
        !           945: 
        !           946:             b = EngBitBlt(psoDest,
        !           947:                           pso,
        !           948:                           psoMask,
        !           949:                           pco,
        !           950:                           pxlo,
        !           951:                           &rclDest,
        !           952:                           &ptlSrc,
        !           953:                           &ptlMask,
        !           954:                           pbo,
        !           955:                           pptlBrush,
        !           956:                           rop4);
        !           957: 
        !           958:         } while (b && bBankEnumBltSrc(ppdev, pso, pptlSrc, prclDest,
        !           959:                                       &ptlSrc, &rclDest));
        !           960: 
        !           961:         return(b);
        !           962:     }
        !           963: 
        !           964:     RIP("Got a funky format?");
        !           965:     return(FALSE);
        !           966: }
        !           967: 
        !           968: /***************************************************************************\
        !           969: * DrvCopyBits
        !           970: \***************************************************************************/
        !           971: 
        !           972: BOOL DrvCopyBits(
        !           973: SURFOBJ*  psoDest,
        !           974: SURFOBJ*  psoSrc,
        !           975: CLIPOBJ*  pco,
        !           976: XLATEOBJ* pxlo,
        !           977: RECTL*    prclDest,
        !           978: POINTL*   pptlSrc)
        !           979: {
        !           980:     BOOL     b;
        !           981:     POINTL   ptlSrc;
        !           982:     RECTL    rclDest;
        !           983:     PPDEV    ppdev;
        !           984:     SURFOBJ* pso;
        !           985:     BBENUM   bben;
        !           986:     BOOL     bMore;
        !           987:     BYTE     jClipping;
        !           988:     POINTL   ptlTmp;
        !           989:     RECTL    rclTmp;
        !           990:     INT      iCopyDir;
        !           991: 
        !           992:     // Get the correct surface object for the target and the source
        !           993: 
        !           994:     if (psoDest->iType == STYPE_DEVICE)
        !           995:     {
        !           996:         // We have to special case screen-to-screen operations:
        !           997: 
        !           998:         if ((psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE))
        !           999:         {
        !          1000: 
        !          1001:             ////////////////////////////////////////////////////////////////
        !          1002:             // CopyBits screen-to-screen:
        !          1003:             ////////////////////////////////////////////////////////////////
        !          1004: 
        !          1005:             ppdev = (PPDEV) psoDest->dhsurf;
        !          1006: 
        !          1007:             // We check to see if we can do a planar copy, because usually
        !          1008:             // it will be faster.  But the hardware has to be capable of
        !          1009:             // doing it, and the source and destination must be 4-pel
        !          1010:             // aligned.
        !          1011: 
        !          1012:             if ((((pptlSrc->x ^ prclDest->left) & 3) == 0) &&
        !          1013:                 (ppdev->fl & DRIVER_PLANAR_CAPABLE) &&
        !          1014:                 ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)))
        !          1015:             {
        !          1016:                 jClipping = (pco != NULL) ? pco->iDComplexity : DC_TRIVIAL;
        !          1017: 
        !          1018:                 switch(jClipping)
        !          1019:                 {
        !          1020:                 case DC_TRIVIAL:
        !          1021:                     vPlanarCopyBits(ppdev, prclDest, pptlSrc);
        !          1022:                     return(TRUE);
        !          1023: 
        !          1024:                 case DC_RECT:
        !          1025:                     // Clip the target rectangle to the clip rectangle:
        !          1026: 
        !          1027:                     if (!bIntersectRect(&rclTmp, prclDest, &pco->rclBounds))
        !          1028:                     {
        !          1029:                         DISPDBG((0, "DrvCopyBits: Nothing to draw."));
        !          1030:                         return(TRUE);
        !          1031:                     }
        !          1032: 
        !          1033:                     ptlTmp.x = pptlSrc->x + rclTmp.left - prclDest->left;
        !          1034:                     ptlTmp.y = pptlSrc->y + rclTmp.top  - prclDest->top;
        !          1035: 
        !          1036:                     vPlanarCopyBits(ppdev, &rclTmp, &ptlTmp);
        !          1037:                     return(TRUE);
        !          1038: 
        !          1039:                 case DC_COMPLEX:
        !          1040:                     if (pptlSrc->y >= prclDest->top)
        !          1041:                     {
        !          1042:                         if (pptlSrc->x >= prclDest->left)
        !          1043:                             iCopyDir = CD_RIGHTDOWN;
        !          1044:                         else
        !          1045:                             iCopyDir = CD_LEFTDOWN;
        !          1046:                     }
        !          1047:                     else
        !          1048:                     {
        !          1049:                         if (pptlSrc->x >= prclDest->left)
        !          1050:                             iCopyDir = CD_RIGHTUP;
        !          1051:                         else
        !          1052:                             iCopyDir = CD_LEFTUP;
        !          1053:                     }
        !          1054: 
        !          1055:                     CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, iCopyDir, 0);
        !          1056: 
        !          1057:                     do {
        !          1058:                         RECTL* prcl;
        !          1059:                         RECTL* prclEnd;
        !          1060: 
        !          1061:                         bMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(bben),
        !          1062:                                               (PVOID) &bben);
        !          1063: 
        !          1064:                         prclEnd = &bben.arcl[bben.c];
        !          1065:                         for (prcl = bben.arcl; prcl < prclEnd; prcl++)
        !          1066:                         {
        !          1067:                             if (bIntersectRect(prcl, prclDest, prcl))
        !          1068:                             {
        !          1069:                                 ptlTmp.x = pptlSrc->x + prcl->left - prclDest->left;
        !          1070:                                 ptlTmp.y = pptlSrc->y + prcl->top  - prclDest->top;
        !          1071: 
        !          1072:                                 vPlanarCopyBits(ppdev, prcl, &ptlTmp);
        !          1073:                             }
        !          1074:                         }
        !          1075:                     } while (bMore);
        !          1076: 
        !          1077:                     return(TRUE);
        !          1078:                 }
        !          1079:             }
        !          1080: 
        !          1081:             return(bPuntScreenToScreenCopyBits(ppdev,
        !          1082:                                                pco,
        !          1083:                                                pxlo,
        !          1084:                                                prclDest,
        !          1085:                                                pptlSrc));
        !          1086:         }
        !          1087: 
        !          1088:         ////////////////////////////////////////////////////////////////
        !          1089:         // CopyBits to screen:
        !          1090:         ////////////////////////////////////////////////////////////////
        !          1091: 
        !          1092:         ppdev = (PPDEV) psoDest->dhsurf;
        !          1093: 
        !          1094:         if ((psoSrc->iBitmapFormat == BMF_8BPP) &&
        !          1095:             ((pxlo == NULL) || (pxlo->flXlate == XO_TRIVIAL)))
        !          1096:         {
        !          1097:         // We have special code for the common 8bpp from memory to screen
        !          1098:         // with no ROPs:
        !          1099: 
        !          1100:             jClipping = (pco != NULL) ? pco->iDComplexity : DC_TRIVIAL;
        !          1101: 
        !          1102:             switch(jClipping)
        !          1103:             {
        !          1104:             case DC_TRIVIAL:
        !          1105:                 vSrcCopy8bpp(ppdev, prclDest, pptlSrc,
        !          1106:                              psoSrc->lDelta, psoSrc->pvScan0);
        !          1107:                 return(TRUE);
        !          1108: 
        !          1109:             case DC_RECT:
        !          1110: 
        !          1111:                 // Clip the blt to the clip rectangle
        !          1112: 
        !          1113:                 bIntersectRect(&rclTmp, prclDest, &pco->rclBounds);
        !          1114: 
        !          1115:                 ptlTmp.x = pptlSrc->x + rclTmp.left - prclDest->left;
        !          1116:                 ptlTmp.y = pptlSrc->y + rclTmp.top  - prclDest->top;
        !          1117: 
        !          1118:                 vSrcCopy8bpp(ppdev, &rclTmp, &ptlTmp,
        !          1119:                              psoSrc->lDelta, psoSrc->pvScan0);
        !          1120: 
        !          1121:                 return(TRUE);
        !          1122: 
        !          1123:             case DC_COMPLEX:
        !          1124: 
        !          1125:                 CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES,
        !          1126:                                    CD_ANY, BB_RECT_LIMIT);
        !          1127: 
        !          1128:                 do {
        !          1129:                     bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben),
        !          1130:                                           (PVOID) &bben);
        !          1131: 
        !          1132:                     if (bben.c > 0)
        !          1133:                     {
        !          1134:                         RECTL* prclEnd = &bben.arcl[bben.c];
        !          1135:                         RECTL* prcl    = &bben.arcl[0];
        !          1136: 
        !          1137:                         do {
        !          1138:                             bIntersectRect(prcl, prcl, prclDest);
        !          1139: 
        !          1140:                             ptlTmp.x = pptlSrc->x + prcl->left
        !          1141:                                      - prclDest->left;
        !          1142:                             ptlTmp.y = pptlSrc->y + prcl->top
        !          1143:                                      - prclDest->top;
        !          1144: 
        !          1145:                             vSrcCopy8bpp(ppdev, prcl, &ptlTmp,
        !          1146:                                          psoSrc->lDelta, psoSrc->pvScan0);
        !          1147: 
        !          1148:                             prcl++;
        !          1149: 
        !          1150:                         } while (prcl < prclEnd);
        !          1151:                     }
        !          1152: 
        !          1153:                 } while(bMore);
        !          1154: 
        !          1155:                 return(TRUE);
        !          1156:             }
        !          1157:         }
        !          1158: 
        !          1159:         // Fall back to the engine:
        !          1160: 
        !          1161:         pso = ppdev->pSurfObj;
        !          1162:         vBankStartBltDest(ppdev, pso, pptlSrc, prclDest, &ptlSrc, &rclDest);
        !          1163: 
        !          1164:         do {
        !          1165:             b = EngCopyBits(pso,
        !          1166:                             psoSrc,
        !          1167:                             pco,
        !          1168:                             pxlo,
        !          1169:                             &rclDest,
        !          1170:                             &ptlSrc);
        !          1171: 
        !          1172:         } while (b && bBankEnumBltDest(ppdev, pso, pptlSrc, prclDest,
        !          1173:                                        &ptlSrc, &rclDest));
        !          1174: 
        !          1175:         return(b);
        !          1176:     }
        !          1177:     else if ((psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE))
        !          1178:     {
        !          1179:         ////////////////////////////////////////////////////////////////
        !          1180:         // CopyBits from screen:
        !          1181:         ////////////////////////////////////////////////////////////////
        !          1182: 
        !          1183:         ppdev = (PPDEV) psoSrc->dhsurf;
        !          1184:         pso   = ppdev->pSurfObj;
        !          1185: 
        !          1186:         vBankStartBltSrc(ppdev, pso, pptlSrc, prclDest, &ptlSrc, &rclDest);
        !          1187: 
        !          1188:         do {
        !          1189:             b = EngCopyBits(psoDest,
        !          1190:                             pso,
        !          1191:                             pco,
        !          1192:                             pxlo,
        !          1193:                             &rclDest,
        !          1194:                             &ptlSrc);
        !          1195: 
        !          1196:         } while (b && bBankEnumBltSrc(ppdev, pso, pptlSrc, prclDest,
        !          1197:                                       &ptlSrc, &rclDest));
        !          1198: 
        !          1199:         return(b);
        !          1200:     }
        !          1201: }

unix.superglobalmegacorp.com

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