2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 CLIPPING_UpdateGCRegion(DC
* Dc
)
28 PROSRGNDATA CombinedRegion
;
30 if (Dc
->rosdc
.hGCClipRgn
== NULL
)
31 Dc
->rosdc
.hGCClipRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
33 if (Dc
->rosdc
.hClipRgn
== NULL
)
34 NtGdiCombineRgn(Dc
->rosdc
.hGCClipRgn
, Dc
->rosdc
.hVisRgn
, 0, RGN_COPY
);
35 else // FYI: Vis == NULL! source of "IntGdiCombineRgn requires hSrc2 != NULL for combine mode 1!"
36 NtGdiCombineRgn(Dc
->rosdc
.hGCClipRgn
, Dc
->rosdc
.hClipRgn
, Dc
->rosdc
.hVisRgn
, RGN_AND
);
37 NtGdiOffsetRgn(Dc
->rosdc
.hGCClipRgn
, Dc
->ptlDCOrig
.x
, Dc
->ptlDCOrig
.y
);
39 if((CombinedRegion
= RGNOBJAPI_Lock(Dc
->rosdc
.hGCClipRgn
, NULL
)))
41 if (Dc
->rosdc
.CombinedClip
!= NULL
)
42 IntEngDeleteClipRegion(Dc
->rosdc
.CombinedClip
);
44 Dc
->rosdc
.CombinedClip
= IntEngCreateClipRegion(
45 CombinedRegion
->rdh
.nCount
,
46 CombinedRegion
->Buffer
,
47 &CombinedRegion
->rdh
.rcBound
);
49 RGNOBJAPI_Unlock(CombinedRegion
);
52 if ( NULL
== Dc
->rosdc
.CombinedClip
)
54 DPRINT1("IntEngCreateClipRegion() failed\n");
58 return NtGdiOffsetRgn(Dc
->rosdc
.hGCClipRgn
, -Dc
->ptlDCOrig
.x
, -Dc
->ptlDCOrig
.y
);
62 GdiSelectVisRgn(HDC hdc
, HRGN hrgn
)
69 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
72 if (!(dc
= DC_LockDc(hdc
)))
74 SetLastWin32Error(ERROR_INVALID_HANDLE
);
78 dc
->fs
&= ~DC_FLAG_DIRTY_RAO
;
80 if (dc
->rosdc
.hVisRgn
== NULL
)
82 dc
->rosdc
.hVisRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
83 GDIOBJ_CopyOwnership(hdc
, dc
->rosdc
.hVisRgn
);
86 retval
= NtGdiCombineRgn(dc
->rosdc
.hVisRgn
, hrgn
, 0, RGN_COPY
);
87 if ( retval
!= ERROR
)
89 NtGdiOffsetRgn(dc
->rosdc
.hVisRgn
, -dc
->ptlDCOrig
.x
, -dc
->ptlDCOrig
.y
);
90 CLIPPING_UpdateGCRegion(dc
);
98 int FASTCALL
GdiExtSelectClipRgn(PDC dc
,
102 // dc->fs &= ~DC_FLAG_DIRTY_RAO;
106 if (fnMode
== RGN_COPY
)
108 if (dc
->rosdc
.hClipRgn
!= NULL
)
110 GreDeleteObject(dc
->rosdc
.hClipRgn
);
111 dc
->rosdc
.hClipRgn
= NULL
;
116 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
122 if (!dc
->rosdc
.hClipRgn
)
126 if((Rgn
= RGNOBJAPI_Lock(dc
->rosdc
.hVisRgn
, NULL
)))
128 REGION_GetRgnBox(Rgn
, &rect
);
129 RGNOBJAPI_Unlock(Rgn
);
130 dc
->rosdc
.hClipRgn
= UnsafeIntCreateRectRgnIndirect(&rect
);
134 dc
->rosdc
.hClipRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
137 if(fnMode
== RGN_COPY
)
139 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, hrgn
, 0, fnMode
);
142 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, hrgn
, fnMode
);
145 return CLIPPING_UpdateGCRegion(dc
);
149 int APIENTRY
NtGdiExtSelectClipRgn(HDC hDC
,
156 if (!(dc
= DC_LockDc(hDC
)))
158 SetLastWin32Error(ERROR_INVALID_HANDLE
);
162 retval
= GdiExtSelectClipRgn ( dc
, hrgn
, fnMode
);
169 GdiGetClipBox(HDC hDC
, PRECTL rc
)
175 if (!(dc
= DC_LockDc(hDC
)))
180 if (!(Rgn
= RGNOBJAPI_Lock(dc
->rosdc
.hGCClipRgn
, NULL
)))
185 retval
= REGION_GetRgnBox(Rgn
, rc
);
186 RGNOBJAPI_Unlock(Rgn
);
187 IntDPtoLP(dc
, (LPPOINT
)rc
, 2);
194 NtGdiGetAppClipBox(HDC hDC
, PRECTL rc
)
197 NTSTATUS Status
= STATUS_SUCCESS
;
200 Ret
= GdiGetClipBox(hDC
, &Saferect
);
209 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
211 Status
= _SEH2_GetExceptionCode();
215 if(!NT_SUCCESS(Status
))
217 SetLastNtError(Status
);
224 int APIENTRY
NtGdiExcludeClipRect(HDC hDC
,
233 PDC dc
= DC_LockDc(hDC
);
237 SetLastWin32Error(ERROR_INVALID_HANDLE
);
241 Rect
.left
= LeftRect
;
243 Rect
.right
= RightRect
;
244 Rect
.bottom
= BottomRect
;
246 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
248 NewRgn
= UnsafeIntCreateRectRgnIndirect(&Rect
);
255 if (!dc
->rosdc
.hClipRgn
)
257 dc
->rosdc
.hClipRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
258 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hVisRgn
, NewRgn
, RGN_DIFF
);
259 Result
= SIMPLEREGION
;
263 Result
= NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, NewRgn
, RGN_DIFF
);
265 GreDeleteObject(NewRgn
);
268 CLIPPING_UpdateGCRegion(dc
);
275 int APIENTRY
NtGdiIntersectClipRect(HDC hDC
,
284 PDC dc
= DC_LockDc(hDC
);
286 DPRINT("NtGdiIntersectClipRect(%x, %d,%d-%d,%d)\n",
287 hDC
, LeftRect
, TopRect
, RightRect
, BottomRect
);
291 SetLastWin32Error(ERROR_INVALID_HANDLE
);
295 Rect
.left
= LeftRect
;
297 Rect
.right
= RightRect
;
298 Rect
.bottom
= BottomRect
;
300 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
302 NewRgn
= UnsafeIntCreateRectRgnIndirect(&Rect
);
307 else if (!dc
->rosdc
.hClipRgn
)
309 dc
->rosdc
.hClipRgn
= NewRgn
;
310 Result
= SIMPLEREGION
;
314 Result
= NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, NewRgn
, RGN_AND
);
315 GreDeleteObject(NewRgn
);
318 CLIPPING_UpdateGCRegion(dc
);
325 int APIENTRY
NtGdiOffsetClipRgn(HDC hDC
,
332 if(!(dc
= DC_LockDc(hDC
)))
334 SetLastWin32Error(ERROR_INVALID_HANDLE
);
338 if(dc
->rosdc
.hClipRgn
!= NULL
)
340 Result
= NtGdiOffsetRgn(dc
->rosdc
.hClipRgn
,
343 CLIPPING_UpdateGCRegion(dc
);
354 BOOL APIENTRY
NtGdiPtVisible(HDC hDC
,
361 if(!(dc
= DC_LockDc(hDC
)))
363 SetLastWin32Error(ERROR_INVALID_HANDLE
);
367 rgn
= dc
->rosdc
.hGCClipRgn
;
370 return (rgn
? NtGdiPtInRegion(rgn
, X
, Y
) : FALSE
);
373 BOOL APIENTRY
NtGdiRectVisible(HDC hDC
,
376 NTSTATUS Status
= STATUS_SUCCESS
;
378 PDC dc
= DC_LockDc(hDC
);
384 SetLastWin32Error(ERROR_INVALID_HANDLE
);
390 ProbeForRead(UnsafeRect
,
395 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
397 Status
= _SEH2_GetExceptionCode();
401 if(!NT_SUCCESS(Status
))
404 SetLastNtError(Status
);
408 if (dc
->rosdc
.hGCClipRgn
)
410 if((Rgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(dc
->rosdc
.hGCClipRgn
, NULL
)))
412 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
413 Result
= REGION_RectInRegion(Rgn
, &Rect
);
414 RGNOBJAPI_Unlock(Rgn
);
424 IntGdiSetMetaRgn(PDC pDC
)
429 if ( pDC
->dclevel
.prgnMeta
)
431 if ( pDC
->dclevel
.prgnClip
)
433 TempRgn
= IntGdiCreateRectRgn(0,0,0,0);
436 Ret
= IntGdiCombineRgn( TempRgn
,
437 pDC
->dclevel
.prgnMeta
,
438 pDC
->dclevel
.prgnClip
,
442 GDIOBJ_ShareUnlockObjByPtr(pDC
->dclevel
.prgnMeta
);
443 if (!((PROSRGNDATA
)pDC
->dclevel
.prgnMeta
)->BaseObject
.ulShareCount
)
444 REGION_Delete(pDC
->dclevel
.prgnMeta
);
446 pDC
->dclevel
.prgnMeta
= TempRgn
;
448 GDIOBJ_ShareUnlockObjByPtr(pDC
->dclevel
.prgnClip
);
449 if (!((PROSRGNDATA
)pDC
->dclevel
.prgnClip
)->BaseObject
.ulShareCount
)
450 REGION_Delete(pDC
->dclevel
.prgnClip
);
452 pDC
->dclevel
.prgnClip
= NULL
;
454 IntGdiReleaseRaoRgn(pDC
);
457 REGION_Delete(TempRgn
);
461 Ret
= REGION_Complexity(pDC
->dclevel
.prgnMeta
);
465 if ( pDC
->dclevel
.prgnClip
)
467 Ret
= REGION_Complexity(pDC
->dclevel
.prgnClip
);
468 pDC
->dclevel
.prgnMeta
= pDC
->dclevel
.prgnClip
;
469 pDC
->dclevel
.prgnClip
= NULL
;
478 int APIENTRY
NtGdiSetMetaRgn(HDC hDC
)
481 PDC pDC
= DC_LockDc(hDC
);
485 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
488 Ret
= IntGdiSetMetaRgn(pDC
);
495 NEW_CLIPPING_UpdateGCRegion(PDC pDC
)
499 if (!pDC
->prgnVis
) return 0;
503 REGION_Delete(pDC
->prgnAPI
);
504 pDC
->prgnAPI
= IntGdiCreateRectRgn(0,0,0,0);
509 REGION_Delete(pDC
->prgnRao
);
510 pDC
->prgnRao
= IntGdiCreateRectRgn(0,0,0,0);
513 if (pDC
->dclevel
.prgnMeta
&& pDC
->dclevel
.prgnClip
)
515 IntGdiCombineRgn( pDC
->prgnAPI
,
516 pDC
->dclevel
.prgnClip
,
517 pDC
->dclevel
.prgnMeta
,
522 if (pDC
->dclevel
.prgnClip
)
523 IntGdiCombineRgn( pDC
->prgnAPI
,
524 pDC
->dclevel
.prgnClip
,
527 else if (pDC
->dclevel
.prgnMeta
)
528 IntGdiCombineRgn( pDC
->prgnAPI
,
529 pDC
->dclevel
.prgnMeta
,
534 IntGdiCombineRgn( pDC
->prgnRao
,
539 RtlCopyMemory(&pDC
->erclClip
, &((PROSRGNDATA
)pDC
->prgnRao
)->rdh
.rcBound
, sizeof(RECTL
));
540 pDC
->fs
&= ~DC_FLAG_DIRTY_RAO
;
542 // if (Dc->CombinedClip != NULL) IntEngDeleteClipRegion(Dc->CombinedClip);
544 co
= IntEngCreateClipRegion( ((PROSRGNDATA
)pDC
->prgnRao
)->rdh
.nCount
,
545 ((PROSRGNDATA
)pDC
->prgnRao
)->Buffer
,
548 return REGION_Complexity(pDC
->prgnRao
);