00077 {
00078     RECT  rcVis;
00079     RECT  rcSrc;
00080     RECT  rcClip;
00081     RECT  rcUnclippedSrc;
00082     RECT  rcDst;
00083     RECT  rcUpdate;
00084     RECT  rcValid;
00085     
BOOL  fSrcNotEmpty;
00086     
BOOL  fHaveVisRgn;
00087     POINT rgpt[2];
00088     
int   dxLog;
00089     
int   dyLog;
00090     
int   wClip;
00091     
int   wClipValid;
00092 
#if defined(USE_MIRRORING)
00093 
    BOOL  bMirroredDC=
FALSE;
00094 
#endif
00095 
00096     fHaveVisRgn = 
FALSE;
00097 
00098     
00099 
00100 
00101 
00102     GreLockDisplay(
gpDispInfo->
hDev);
00103 
00104     
if ((wClip = GreGetClipBox(hdc, &rcVis, TRUE)) == ERROR) {
00105 
00106 
ErrorExit:
00107 
00108         GreUnlockDisplay(
gpDispInfo->
hDev);
00109         
return ERROR;
00110     }
00111 
00112     
CopyRect(&rcSrc, (prcSrc) ? prcSrc : &rcVis);
00113     
if (prcClip) {
00114         
CopyRect(&rcClip, prcClip);
00115     }
00116 
00117     dxLog = dx;
00118     dyLog = dy;
00119 
00120     
if (fLogUnits) {
00121 
00122         
00123 
00124 
00125         GreLPtoDP(hdc, (LPPOINT)&rcVis, 2);
00126         GreLPtoDP(hdc, (LPPOINT)&rcSrc, 2);
00127 
00128 
#if defined(USE_MIRRORING)
00129 
        
00130         
00131         
00132         
00133         
00134         
00135         
if (GreGetLayout(hdc) & LAYOUT_RTL) {
00136             
int iTemp   = rcVis.left;
00137             rcVis.left  = rcVis.right;
00138             rcVis.right = iTemp;
00139 
00140             iTemp       = rcSrc.left;
00141             rcSrc.left  = rcSrc.right;
00142             rcSrc.right = iTemp;
00143 
00144             bMirroredDC = 
TRUE;
00145         }
00146 
#endif
00147 
00148         
if (prcClip) {
00149             GreLPtoDP(hdc, (LPPOINT)&rcClip, 2);
00150 
00151 
#if defined(USE_MIRRORING)
00152 
            
00153             
00154             
00155             
00156             
00157             
00158             
if (bMirroredDC) {
00159                 
int iTemp    = rcClip.left;
00160                 rcClip.left  = rcClip.right;
00161                 rcClip.right = iTemp;
00162             }
00163 
#endif
00164 
        }
00165 
00166         
00167 
00168 
00169 
00170 
00171         rgpt[0].x = rgpt[0].y = 0;
00172         rgpt[1].x = dx;
00173         rgpt[1].y = dy;
00174 
00175         GreLPtoDP(hdc, rgpt, 2);
00176 
00177         dx = rgpt[1].x - rgpt[0].x;
00178         dy = rgpt[1].y - rgpt[0].y;
00179     }
00180 
00181     
switch (wClip) {
00182     
case NULLREGION:
00183 
00184 NullExit:
00185 
00186         
if (hrgnUpdate && !
SetEmptyRgn(hrgnUpdate))
00187             
goto ErrorExit;
00188 
00189         
if (prcUpdate) {
00190             
SetRectEmpty(prcUpdate);
00191         }
00192 
00193         GreUnlockDisplay(
gpDispInfo->
hDev);
00194         
return NULLREGION;
00195 
00196     
case COMPLEXREGION:
00197         
GetTrueClipRgn(hdc, ghrgnScrlVis);
00198         fHaveVisRgn = 
TRUE;
00199         
break;
00200     }
00201 
00202     
00203 
00204 
00205 
00206 
00207     rcDst.left   = rcSrc.left   + dx;
00208     rcDst.right  = rcSrc.right  + dx;
00209     rcDst.top    = rcSrc.top    + dy;
00210     rcDst.bottom = rcSrc.bottom + dy;
00211 
00212     
00213 
00214 
00215     
if (prcClip) {
00216 
00217         
if ((wClip == SIMPLEREGION) &&
00218             ((hrgnInvalid == 
NULL) || (hrgnInvalid == 
HRGN_FULL))) {
00219 
00220             
00221 
00222 
00223             
if (!
IntersectRect(&rcVis, &rcVis, &rcClip))
00224                 
goto NullExit;
00225 
00226         } 
else {
00227 
00228             
if (!fHaveVisRgn) {
00229 
00230                 
if (
GetTrueClipRgn(hdc, ghrgnScrlVis) == ERROR)
00231                     
goto ErrorExit;
00232 
00233                 fHaveVisRgn = 
TRUE;
00234             }
00235 
00236             
SetRectRgnIndirect(ghrgnScrl1, &rcClip);
00237             wClip = 
IntersectRgn(ghrgnScrlVis, ghrgnScrl1, ghrgnScrlVis);
00238             
switch (wClip) {
00239             
case ERROR:
00240                 
goto ErrorExit;
00241 
00242             
case NULLREGION:
00243                 
goto NullExit;
00244 
00245             
case SIMPLEREGION:
00246 
00247                 
00248 
00249 
00250 
00251                 GreGetRgnBox(ghrgnScrlVis, &rcVis);
00252                 
break;
00253 
00254             
case COMPLEXREGION:
00255                 
break;
00256             }
00257         }
00258     }
00259 
00260     
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275     
if ((wClip == SIMPLEREGION) &&
00276             ((hrgnInvalid == 
NULL) || (hrgnInvalid == 
HRGN_FULL))) {
00277 
00278         
00279 
00280 
00281         
CopyRect(&rcUnclippedSrc, &rcSrc);
00282 
00283         
00284 
00285 
00286         
IntersectRect(&rcDst, &rcDst, &rcVis);
00287 
00288         
00289 
00290 
00291         fSrcNotEmpty = 
IntersectRect(&rcSrc, &rcSrc, &rcVis);
00292 
00293         
00294 
00295 
00296         
if (hrgnInvalid == 
HRGN_FULL) {
00297             
SetRectEmpty(&rcValid);
00298         } 
else {
00299 
00300             rcValid.left   = rcSrc.left   + dx;
00301             rcValid.right  = rcSrc.right  + dx;
00302             rcValid.top    = rcSrc.top    + dy;
00303             rcValid.bottom = rcSrc.bottom + dy;
00304 
00305             
IntersectRect(&rcValid, &rcValid, &rcDst);
00306         }
00307 
00308         
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324         
if (!fSrcNotEmpty) {
00325 
00326             
00327 
00328 
00329             
CopyRect(&rcUpdate, &rcDst);
00330             
goto RectUpdate;
00331 
00332         } 
else if (
IntersectRect(&rcUpdate, &rcSrc, &rcDst)) {
00333 
00334             
00335 
00336 
00337 
00338             
if (dx == 0 || dy == 0) {
00339 
00340                 
UnionRect(&rcUpdate, &rcSrc, &rcDst);
00341                 
SubtractRect(&rcUpdate, &rcUpdate, &rcValid);
00342                 
goto RectUpdate;
00343             }
00344 
00345         } 
else if (
EqualRect(&rcSrc, &rcUnclippedSrc)) {
00346 
00347             
00348 
00349 
00350 
00351             
CopyRect(&rcUpdate, &rcSrc);
00352 RectUpdate:
00353             
if (prcUpdate) {
00354                 
CopyRect(prcUpdate, &rcUpdate);
00355             }
00356 
00357             
if (hrgnUpdate && !
SetRectRgnIndirect(hrgnUpdate, &rcUpdate)) {
00358                 
goto ErrorExit;
00359             }
00360 
00361             wClip = SIMPLEREGION;
00362             
if (rcUpdate.left >= rcUpdate.right ||
00363                 rcUpdate.top >= rcUpdate.bottom)
00364 
00365                 wClip = NULLREGION;
00366 
00367             
goto DoRectBlt;
00368         }
00369 
00370         
00371 
00372 
00373 
00374 
00375 
00376 
00377         
if (hrgnUpdate == 
NULL && prcUpdate) {
00378             hrgnUpdate = 
ghrgnScrl2;
00379         }
00380 
00381         
if (hrgnUpdate != 
NULL) {
00382 
00383             
00384 
00385 
00386             
SetRectRgnIndirect(ghrgnScrl1, &rcSrc);
00387             
SetRectRgnIndirect(hrgnUpdate, &rcDst);
00388             
if (
UnionRgn(hrgnUpdate, hrgnUpdate, ghrgnScrl1) == ERROR)
00389                 
goto ErrorExit;
00390 
00391             
SetRectRgnIndirect(ghrgnScrl1, &rcValid);
00392             wClip = 
SubtractRgn(hrgnUpdate, hrgnUpdate, ghrgnScrl1);
00393             
if (wClip == ERROR)
00394                 
goto ErrorExit;
00395 
00396             
if (prcUpdate) {
00397                 GreGetRgnBox(hrgnUpdate, prcUpdate);
00398             }
00399         }
00400 
00401 DoRectBlt:
00402 
00403         
00404 
00405 
00406         
if (rcValid.left < rcValid.right && rcValid.top < rcValid.bottom) {
00407 
00408             
00409 
00410 
00411 
00412             
if (fLogUnits)
00413                 GreDPtoLP(hdc, (LPPOINT)&rcValid, 2);
00414 
00415             GreBitBlt(hdc,
00416                       rcValid.left,
00417                       rcValid.top,
00418                       rcValid.right - rcValid.left,
00419                       rcValid.bottom - rcValid.top,
00420                       hdc,
00421                       rcValid.left - dxLog,
00422                       rcValid.top - dyLog,
00423                       SRCCOPY,
00424                       0);
00425         }
00426 
00427     } 
else {
00428 
00429         
00430 
00431 
00432         
if (!fHaveVisRgn) {
00433 
00434             
if (
GetTrueClipRgn(hdc, ghrgnScrlVis) == ERROR)
00435                 
goto ErrorExit;
00436 
00437             fHaveVisRgn = 
TRUE;
00438         }
00439 
00440         
00441 
00442 
00443 
00444 
00445 
00446         
SetRectRgnIndirect(ghrgnScrlSrc, &rcSrc);
00447         
if (
IntersectRgn(ghrgnScrlSrc, ghrgnScrlSrc, ghrgnScrlVis) == ERROR)
00448             
goto ErrorExit;
00449 
00450         
00451 
00452 
00453         
SetRectRgnIndirect(ghrgnScrlDst, &rcDst);
00454         
if (
IntersectRgn(ghrgnScrlDst, ghrgnScrlDst, ghrgnScrlVis) == ERROR)
00455             
goto ErrorExit;
00456 
00457         
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465         wClipValid = NULLREGION;
00466         
if (hrgnInvalid != 
HRGN_FULL) {
00467 
00468             
00469 
00470 
00471             
if (
CopyRgn(ghrgnScrlValid, ghrgnScrlSrc) == ERROR)
00472                 
goto ErrorExit;
00473 
00474             GreOffsetRgn(ghrgnScrlValid, dx, dy);
00475             wClipValid = 
IntersectRgn(ghrgnScrlValid,
00476                                       ghrgnScrlValid,
00477                                       ghrgnScrlDst);
00478 
00479             
00480 
00481 
00482 
00483             
if (hrgnInvalid > 
HRGN_FULL) {
00484 
00485                 
if (wClipValid != ERROR && wClipValid != NULLREGION) {
00486                     POINT pt;
00487 
00488                     
GetDCOrgOnScreen(hdc, &pt);
00489             
00490                     
00491 
00492 
00493                     
CopyRgn(ghrgnScrl2, hrgnInvalid);
00494                     GreOffsetRgn(ghrgnScrl2, -pt.x, -pt.y);
00495 
00496                     wClipValid = 
SubtractRgn(ghrgnScrlValid,
00497                                              ghrgnScrlValid,
00498                                              ghrgnScrl2);
00499                 }
00500 
00501                 
if (wClipValid != ERROR && wClipValid != NULLREGION) {
00502                     GreOffsetRgn(ghrgnScrl2, dx, dy);
00503 
00504                     wClipValid = 
SubtractRgn(ghrgnScrlValid,
00505                                              ghrgnScrlValid,
00506                                              ghrgnScrl2);
00507                 }
00508             }
00509 
00510             
if (wClipValid == ERROR)
00511                 
goto ErrorExit;
00512         }
00513 
00514         
00515 
00516 
00517         
if (hrgnUpdate == 
NULL && prcUpdate) {
00518             hrgnUpdate = 
ghrgnScrl2;
00519         }
00520 
00521         
if (hrgnUpdate != 
NULL) {
00522 
00523             
00524 
00525 
00526             wClip = 
UnionRgn(hrgnUpdate, ghrgnScrlDst, ghrgnScrlSrc);
00527             
if (wClip == ERROR)
00528                 
goto ErrorExit;
00529 
00530             
if (wClipValid != NULLREGION) {
00531                 wClip = 
SubtractRgn(hrgnUpdate, hrgnUpdate, ghrgnScrlValid);
00532             }
00533 
00534             
if (prcUpdate) {
00535                 GreGetRgnBox(hrgnUpdate, prcUpdate);
00536             }
00537         }
00538 
00539         
if (wClipValid != NULLREGION) {
00540 
00541 
            #ifdef LATER
00542 
00543                 
00544 
00545 
00546                 HRGN hrgnSaveVis = 
CreateEmptyRgn();
00547                 
if (hrgnSaveVis != 
NULL) {
00548 
00549                     
BOOL fClipped;
00550 
00551                     fClipped = (GreGetRandomRgn(hdc, hrgnSaveVis, 1) == 1);
00552                     GreExtSelectClipRgn(hdc, ghrgnScrlValid, RGN_COPY);
00553 
00554                     
00555 
00556 
00557 
00558                     
if (fLogUnits)
00559                         GreDPtoLP(hdc, (LPPOINT)&rcDst, 2);
00560 
00561                     
00562 
00563 
00564 
00565                     GreBitBlt(hdc,
00566                               rcDst.left,
00567                               rcDst.top,
00568                               rcDst.right - rcDst.left,
00569                               rcDst.bottom - rcDst.top,
00570                               hdc,
00571                               rcDst.left - dxLog,
00572                               rcDst.top - dyLog,
00573                               SRCCOPY,
00574                               0);
00575 
00576                     GreExtSelectClipRgn(hdc,
00577                                         (fClipped ? hrgnSaveVis : NULL),
00578                                         RGN_COPY);
00579 
00580                     GreDeleteObject(hrgnSaveVis);
00581                 }
00582 
00583 
            #else
00584 
00585                 
00586 
00587 
00588 
00589                 POINT pt;
00590                 GreGetDCOrg(hdc, &pt);
00591 
00592                 GreOffsetRgn(ghrgnScrlValid, pt.x, pt.y);
00593 
00594                 
00595 
00596 
00597 
00598                 GreSelectVisRgn(hdc, ghrgnScrlValid, SVR_SWAP);
00599 
00600                 
00601 
00602 
00603 
00604                 
if (fLogUnits)
00605                     GreDPtoLP(hdc, (LPPOINT)&rcDst, 2);
00606 
00607                 
00608 
00609 
00610 
00611                 GreBitBlt(hdc,
00612                           rcDst.left,
00613                           rcDst.top,
00614                           rcDst.right - rcDst.left,
00615                           rcDst.bottom - rcDst.top,
00616                           hdc,
00617                           rcDst.left - dxLog,
00618                           rcDst.top - dyLog,
00619                           SRCCOPY,
00620                           0);
00621 
00622                 
00623 
00624 
00625 
00626                 GreSelectVisRgn(hdc, ghrgnScrlValid, SVR_SWAP);
00627 
00628 
            #endif
00629 
        }
00630     }
00631 
00632     
00633 
00634 
00635 
00636     
if (fLogUnits && prcUpdate) {
00637         GreDPtoLP(hdc, (LPPOINT)prcUpdate, 2);
00638     }
00639 
00640     GreUnlockDisplay(
gpDispInfo->
hDev);
00641 
00642     
return wClip;
00643 }