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