Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencliprgn.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: GNU GPL, See COPYING in the top level directory 00003 * PROJECT: ReactOS Win32k subsystem 00004 * PURPOSE: Clip region functions 00005 * FILE: subsystems/win32/win32k/objects/cliprgn.c 00006 * PROGRAMER: Unknown 00007 */ 00008 00009 #include <win32k.h> 00010 00011 #define NDEBUG 00012 #include <debug.h> 00013 00014 int FASTCALL 00015 CLIPPING_UpdateGCRegion(DC* Dc) 00016 { 00017 PROSRGNDATA CombinedRegion; 00018 //HRGN hRgnVis; 00019 PREGION prgnClip, prgnGCClip; 00020 00021 /* Would prefer this, but the rest of the code sucks... */ 00022 //ASSERT(Dc->rosdc.hGCClipRgn); 00023 //ASSERT(Dc->rosdc.hClipRgn); 00024 ASSERT(Dc->prgnVis); 00025 //hRgnVis = Dc->prgnVis->BaseObject.hHmgr; 00026 00027 if (Dc->rosdc.hGCClipRgn == NULL) 00028 Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); 00029 00030 prgnGCClip = REGION_LockRgn(Dc->rosdc.hGCClipRgn); 00031 ASSERT(prgnGCClip); 00032 00033 if (Dc->rosdc.hClipRgn == NULL) 00034 IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, NULL, RGN_COPY); 00035 else 00036 { 00037 prgnClip = REGION_LockRgn(Dc->rosdc.hClipRgn); // FIXME: Locking order, ugh! 00038 IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, prgnClip, RGN_AND); 00039 REGION_UnlockRgn(prgnClip); 00040 } 00041 REGION_UnlockRgn(prgnGCClip); 00042 00043 NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y); 00044 00045 if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL))) 00046 { 00047 CLIPOBJ *CombinedClip; 00048 00049 CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount, 00050 CombinedRegion->Buffer, 00051 &CombinedRegion->rdh.rcBound); 00052 00053 RGNOBJAPI_Unlock(CombinedRegion); 00054 00055 if ( !CombinedClip ) 00056 { 00057 DPRINT1("IntEngCreateClipRegion() failed\n"); 00058 return ERROR; 00059 } 00060 00061 if(Dc->rosdc.CombinedClip != NULL) 00062 IntEngDeleteClipRegion(Dc->rosdc.CombinedClip); 00063 00064 Dc->rosdc.CombinedClip = CombinedClip ; 00065 } 00066 00067 return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y); 00068 } 00069 00070 INT FASTCALL 00071 GdiSelectVisRgn(HDC hdc, HRGN hrgn) 00072 { 00073 int retval; 00074 DC *dc; 00075 PREGION prgn; 00076 00077 if (!hrgn) 00078 { 00079 EngSetLastError(ERROR_INVALID_PARAMETER); 00080 return ERROR; 00081 } 00082 if (!(dc = DC_LockDc(hdc))) 00083 { 00084 EngSetLastError(ERROR_INVALID_HANDLE); 00085 return ERROR; 00086 } 00087 00088 dc->fs &= ~DC_FLAG_DIRTY_RAO; 00089 00090 ASSERT (dc->prgnVis != NULL); 00091 00092 prgn = RGNOBJAPI_Lock(hrgn, NULL); 00093 retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR; 00094 RGNOBJAPI_Unlock(prgn); 00095 if ( retval != ERROR ) 00096 { 00097 IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y); 00098 CLIPPING_UpdateGCRegion(dc); 00099 } 00100 DC_UnlockDc(dc); 00101 00102 return retval; 00103 } 00104 00105 00106 int FASTCALL GdiExtSelectClipRgn(PDC dc, 00107 HRGN hrgn, 00108 int fnMode) 00109 { 00110 // dc->fs &= ~DC_FLAG_DIRTY_RAO; 00111 00112 if (!hrgn) 00113 { 00114 if (fnMode == RGN_COPY) 00115 { 00116 if (dc->rosdc.hClipRgn != NULL) 00117 { 00118 GreDeleteObject(dc->rosdc.hClipRgn); 00119 dc->rosdc.hClipRgn = NULL; 00120 } 00121 } 00122 else 00123 { 00124 EngSetLastError(ERROR_INVALID_PARAMETER); 00125 return ERROR; 00126 } 00127 } 00128 else 00129 { 00130 if (!dc->rosdc.hClipRgn) 00131 { 00132 RECTL rect; 00133 if(dc->prgnVis) 00134 { 00135 REGION_GetRgnBox(dc->prgnVis, &rect); 00136 dc->rosdc.hClipRgn = IntSysCreateRectRgnIndirect(&rect); 00137 } 00138 else 00139 { 00140 dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); 00141 } 00142 } 00143 if(fnMode == RGN_COPY) 00144 { 00145 NtGdiCombineRgn(dc->rosdc.hClipRgn, hrgn, 0, fnMode); 00146 } 00147 else 00148 NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode); 00149 } 00150 00151 return CLIPPING_UpdateGCRegion(dc); 00152 } 00153 00154 00155 int APIENTRY NtGdiExtSelectClipRgn(HDC hDC, 00156 HRGN hrgn, 00157 int fnMode) 00158 { 00159 int retval; 00160 DC *dc; 00161 00162 if (!(dc = DC_LockDc(hDC))) 00163 { 00164 EngSetLastError(ERROR_INVALID_HANDLE); 00165 return ERROR; 00166 } 00167 00168 retval = GdiExtSelectClipRgn ( dc, hrgn, fnMode ); 00169 00170 DC_UnlockDc(dc); 00171 return retval; 00172 } 00173 00174 INT FASTCALL 00175 GdiGetClipBox(HDC hDC, PRECTL rc) 00176 { 00177 INT retval; 00178 PDC dc; 00179 PROSRGNDATA pRgnNew, pRgn = NULL; 00180 BOOL Unlock = FALSE; // Small HACK 00181 00182 if (!(dc = DC_LockDc(hDC))) 00183 { 00184 return ERROR; 00185 } 00186 00187 /* FIXME: Rao and Vis only! */ 00188 if (dc->prgnAPI) // APIRGN 00189 { 00190 pRgn = dc->prgnAPI; 00191 } 00192 else if (dc->dclevel.prgnMeta) // METARGN 00193 { 00194 pRgn = dc->dclevel.prgnMeta; 00195 } 00196 else if (dc->rosdc.hClipRgn) 00197 { 00198 Unlock = TRUE ; 00199 pRgn = REGION_LockRgn(dc->rosdc.hClipRgn); // CLIPRGN 00200 } 00201 00202 if (pRgn) 00203 { 00204 pRgnNew = IntSysCreateRectpRgn( 0, 0, 0, 0 ); 00205 00206 if (!pRgnNew) 00207 { 00208 DC_UnlockDc(dc); 00209 if(Unlock) REGION_UnlockRgn(pRgn); 00210 return ERROR; 00211 } 00212 00213 IntGdiCombineRgn(pRgnNew, dc->prgnVis, pRgn, RGN_AND); 00214 00215 retval = REGION_GetRgnBox(pRgnNew, rc); 00216 00217 REGION_Delete(pRgnNew); 00218 00219 DC_UnlockDc(dc); 00220 if(Unlock) REGION_UnlockRgn(pRgn); 00221 return retval; 00222 } 00223 00224 retval = REGION_GetRgnBox(dc->prgnVis, rc); 00225 IntDPtoLP(dc, (LPPOINT)rc, 2); 00226 DC_UnlockDc(dc); 00227 00228 return retval; 00229 } 00230 00231 INT APIENTRY 00232 NtGdiGetAppClipBox(HDC hDC, PRECTL rc) 00233 { 00234 INT Ret; 00235 NTSTATUS Status = STATUS_SUCCESS; 00236 RECTL Saferect; 00237 00238 Ret = GdiGetClipBox(hDC, &Saferect); 00239 00240 _SEH2_TRY 00241 { 00242 ProbeForWrite(rc, 00243 sizeof(RECT), 00244 1); 00245 *rc = Saferect; 00246 } 00247 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00248 { 00249 Status = _SEH2_GetExceptionCode(); 00250 } 00251 _SEH2_END; 00252 00253 if(!NT_SUCCESS(Status)) 00254 { 00255 SetLastNtError(Status); 00256 return ERROR; 00257 } 00258 00259 return Ret; 00260 } 00261 00262 int APIENTRY NtGdiExcludeClipRect(HDC hDC, 00263 int LeftRect, 00264 int TopRect, 00265 int RightRect, 00266 int BottomRect) 00267 { 00268 INT Result; 00269 RECTL Rect; 00270 PREGION prgnNew, prgnClip; 00271 PDC dc = DC_LockDc(hDC); 00272 00273 if (!dc) 00274 { 00275 EngSetLastError(ERROR_INVALID_HANDLE); 00276 return ERROR; 00277 } 00278 00279 Rect.left = LeftRect; 00280 Rect.top = TopRect; 00281 Rect.right = RightRect; 00282 Rect.bottom = BottomRect; 00283 00284 IntLPtoDP(dc, (LPPOINT)&Rect, 2); 00285 00286 prgnNew = IntSysCreateRectpRgnIndirect(&Rect); 00287 if (!prgnNew) 00288 { 00289 Result = ERROR; 00290 } 00291 else 00292 { 00293 if (!dc->rosdc.hClipRgn) 00294 { 00295 dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); 00296 prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn); 00297 IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF); 00298 REGION_UnlockRgn(prgnClip); 00299 Result = SIMPLEREGION; 00300 } 00301 else 00302 { 00303 prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn); 00304 Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF); 00305 REGION_UnlockRgn(prgnClip); 00306 } 00307 REGION_Delete(prgnNew); 00308 } 00309 if (Result != ERROR) 00310 CLIPPING_UpdateGCRegion(dc); 00311 00312 DC_UnlockDc(dc); 00313 00314 return Result; 00315 } 00316 00317 int APIENTRY NtGdiIntersectClipRect(HDC hDC, 00318 int LeftRect, 00319 int TopRect, 00320 int RightRect, 00321 int BottomRect) 00322 { 00323 INT Result; 00324 RECTL Rect; 00325 HRGN NewRgn; 00326 PDC dc = DC_LockDc(hDC); 00327 00328 DPRINT("NtGdiIntersectClipRect(%x, %d,%d-%d,%d)\n", 00329 hDC, LeftRect, TopRect, RightRect, BottomRect); 00330 00331 if (!dc) 00332 { 00333 EngSetLastError(ERROR_INVALID_HANDLE); 00334 return ERROR; 00335 } 00336 00337 Rect.left = LeftRect; 00338 Rect.top = TopRect; 00339 Rect.right = RightRect; 00340 Rect.bottom = BottomRect; 00341 00342 IntLPtoDP(dc, (LPPOINT)&Rect, 2); 00343 00344 NewRgn = IntSysCreateRectRgnIndirect(&Rect); 00345 if (!NewRgn) 00346 { 00347 Result = ERROR; 00348 } 00349 else if (!dc->rosdc.hClipRgn) 00350 { 00351 dc->rosdc.hClipRgn = NewRgn; 00352 Result = SIMPLEREGION; 00353 } 00354 else 00355 { 00356 Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_AND); 00357 GreDeleteObject(NewRgn); 00358 } 00359 if (Result != ERROR) 00360 CLIPPING_UpdateGCRegion(dc); 00361 00362 DC_UnlockDc(dc); 00363 00364 return Result; 00365 } 00366 00367 int APIENTRY NtGdiOffsetClipRgn(HDC hDC, 00368 int XOffset, 00369 int YOffset) 00370 { 00371 INT Result; 00372 DC *dc; 00373 00374 if(!(dc = DC_LockDc(hDC))) 00375 { 00376 EngSetLastError(ERROR_INVALID_HANDLE); 00377 return ERROR; 00378 } 00379 00380 if(dc->rosdc.hClipRgn != NULL) 00381 { 00382 Result = NtGdiOffsetRgn(dc->rosdc.hClipRgn, 00383 XOffset, 00384 YOffset); 00385 CLIPPING_UpdateGCRegion(dc); 00386 } 00387 else 00388 { 00389 Result = NULLREGION; 00390 } 00391 00392 DC_UnlockDc(dc); 00393 return Result; 00394 } 00395 00396 BOOL APIENTRY NtGdiPtVisible(HDC hDC, 00397 int X, 00398 int Y) 00399 { 00400 HRGN rgn; 00401 DC *dc; 00402 00403 if(!(dc = DC_LockDc(hDC))) 00404 { 00405 EngSetLastError(ERROR_INVALID_HANDLE); 00406 return FALSE; 00407 } 00408 00409 rgn = dc->rosdc.hGCClipRgn; 00410 DC_UnlockDc(dc); 00411 00412 return (rgn ? NtGdiPtInRegion(rgn, X, Y) : FALSE); 00413 } 00414 00415 BOOL APIENTRY NtGdiRectVisible(HDC hDC, 00416 LPRECT UnsafeRect) 00417 { 00418 NTSTATUS Status = STATUS_SUCCESS; 00419 PROSRGNDATA Rgn; 00420 PDC dc = DC_LockDc(hDC); 00421 BOOL Result = FALSE; 00422 RECTL Rect; 00423 00424 if (!dc) 00425 { 00426 EngSetLastError(ERROR_INVALID_HANDLE); 00427 return FALSE; 00428 } 00429 00430 _SEH2_TRY 00431 { 00432 ProbeForRead(UnsafeRect, 00433 sizeof(RECT), 00434 1); 00435 Rect = *UnsafeRect; 00436 } 00437 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00438 { 00439 Status = _SEH2_GetExceptionCode(); 00440 } 00441 _SEH2_END; 00442 00443 if(!NT_SUCCESS(Status)) 00444 { 00445 DC_UnlockDc(dc); 00446 SetLastNtError(Status); 00447 return FALSE; 00448 } 00449 00450 if (dc->rosdc.hGCClipRgn) 00451 { 00452 if((Rgn = (PROSRGNDATA)RGNOBJAPI_Lock(dc->rosdc.hGCClipRgn, NULL))) 00453 { 00454 IntLPtoDP(dc, (LPPOINT)&Rect, 2); 00455 Result = REGION_RectInRegion(Rgn, &Rect); 00456 RGNOBJAPI_Unlock(Rgn); 00457 } 00458 } 00459 DC_UnlockDc(dc); 00460 00461 return Result; 00462 } 00463 00464 int 00465 FASTCALL 00466 IntGdiSetMetaRgn(PDC pDC) 00467 { 00468 INT Ret = ERROR; 00469 PROSRGNDATA TempRgn; 00470 00471 if ( pDC->dclevel.prgnMeta ) 00472 { 00473 if ( pDC->dclevel.prgnClip ) 00474 { 00475 TempRgn = IntSysCreateRectpRgn(0,0,0,0); 00476 if (TempRgn) 00477 { 00478 Ret = IntGdiCombineRgn( TempRgn, 00479 pDC->dclevel.prgnMeta, 00480 pDC->dclevel.prgnClip, 00481 RGN_AND); 00482 if ( Ret ) 00483 { 00484 GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnMeta->BaseObject); 00485 if (!((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.ulShareCount) 00486 REGION_Delete(pDC->dclevel.prgnMeta); 00487 00488 pDC->dclevel.prgnMeta = TempRgn; 00489 00490 GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnClip->BaseObject); 00491 if (!((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.ulShareCount) 00492 REGION_Delete(pDC->dclevel.prgnClip); 00493 00494 pDC->dclevel.prgnClip = NULL; 00495 00496 IntGdiReleaseRaoRgn(pDC); 00497 } 00498 else 00499 REGION_Delete(TempRgn); 00500 } 00501 } 00502 else 00503 Ret = REGION_Complexity(pDC->dclevel.prgnMeta); 00504 } 00505 else 00506 { 00507 if ( pDC->dclevel.prgnClip ) 00508 { 00509 Ret = REGION_Complexity(pDC->dclevel.prgnClip); 00510 pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip; 00511 pDC->dclevel.prgnClip = NULL; 00512 } 00513 else 00514 Ret = SIMPLEREGION; 00515 } 00516 return Ret; 00517 } 00518 00519 00520 int APIENTRY NtGdiSetMetaRgn(HDC hDC) 00521 { 00522 INT Ret; 00523 PDC pDC = DC_LockDc(hDC); 00524 00525 if (!pDC) 00526 { 00527 EngSetLastError(ERROR_INVALID_PARAMETER); 00528 return ERROR; 00529 } 00530 Ret = IntGdiSetMetaRgn(pDC); 00531 00532 DC_UnlockDc(pDC); 00533 return Ret; 00534 } 00535 00536 INT FASTCALL 00537 NEW_CLIPPING_UpdateGCRegion(PDC pDC) 00538 { 00539 CLIPOBJ * co; 00540 00541 /* Must have VisRgn set to a valid state! */ 00542 ASSERT (pDC->prgnVis); 00543 00544 if (pDC->prgnAPI) 00545 { 00546 REGION_Delete(pDC->prgnAPI); 00547 pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0); 00548 } 00549 00550 if (pDC->prgnRao) 00551 { 00552 REGION_Delete(pDC->prgnRao); 00553 pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0); 00554 } 00555 00556 if (pDC->dclevel.prgnMeta && pDC->dclevel.prgnClip) 00557 { 00558 IntGdiCombineRgn( pDC->prgnAPI, 00559 pDC->dclevel.prgnClip, 00560 pDC->dclevel.prgnMeta, 00561 RGN_AND); 00562 } 00563 else 00564 { 00565 if (pDC->dclevel.prgnClip) 00566 { 00567 IntGdiCombineRgn( pDC->prgnAPI, 00568 pDC->dclevel.prgnClip, 00569 NULL, 00570 RGN_COPY); 00571 } 00572 else if (pDC->dclevel.prgnMeta) 00573 { 00574 IntGdiCombineRgn( pDC->prgnAPI, 00575 pDC->dclevel.prgnMeta, 00576 NULL, 00577 RGN_COPY); 00578 } 00579 } 00580 00581 IntGdiCombineRgn( pDC->prgnRao, 00582 pDC->prgnVis, 00583 pDC->prgnAPI, 00584 RGN_AND); 00585 00586 RtlCopyMemory(&pDC->erclClip, 00587 &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound, 00588 sizeof(RECTL)); 00589 00590 pDC->fs &= ~DC_FLAG_DIRTY_RAO; 00591 00592 IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y); 00593 00594 // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build 00595 // the rects from region objects rects in pClipRgn->Buffer. 00596 // With pDC->co.pClipRgn->Buffer, 00597 // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis; 00598 00599 co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount, 00600 ((PROSRGNDATA)pDC->prgnRao)->Buffer, 00601 &pDC->erclClip); 00602 if (co) 00603 { 00604 if (pDC->rosdc.CombinedClip != NULL) 00605 IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); 00606 00607 pDC->rosdc.CombinedClip = co; 00608 } 00609 00610 return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y); 00611 } 00612 00613 /* EOF */ Generated on Sat May 26 2012 04:37:12 for ReactOS by
1.7.6.1
|