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
;
31 // would prefer this, but the rest of the code sucks
32 // ASSERT(Dc->rosdc.hGCClipRgn);
33 // ASSERT(Dc->rosdc.hClipRgn);
36 DPRINT1("Warning, prgnVis is NULL!\n");
40 hRgnVis
= Dc
->prgnVis
->BaseObject
.hHmgr
;
44 if (Dc
->rosdc
.hGCClipRgn
== NULL
)
45 Dc
->rosdc
.hGCClipRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
47 if (Dc
->rosdc
.hClipRgn
== NULL
)
48 NtGdiCombineRgn(Dc
->rosdc
.hGCClipRgn
, hRgnVis
, 0, RGN_COPY
);
49 else // FYI: Vis == NULL! source of "IntGdiCombineRgn requires hSrc2 != NULL for combine mode 1!"
50 NtGdiCombineRgn(Dc
->rosdc
.hGCClipRgn
, Dc
->rosdc
.hClipRgn
, hRgnVis
, RGN_AND
);
51 NtGdiOffsetRgn(Dc
->rosdc
.hGCClipRgn
, Dc
->ptlDCOrig
.x
, Dc
->ptlDCOrig
.y
);
53 if((CombinedRegion
= RGNOBJAPI_Lock(Dc
->rosdc
.hGCClipRgn
, NULL
)))
55 if (Dc
->rosdc
.CombinedClip
!= NULL
)
56 IntEngDeleteClipRegion(Dc
->rosdc
.CombinedClip
);
58 Dc
->rosdc
.CombinedClip
= IntEngCreateClipRegion(
59 CombinedRegion
->rdh
.nCount
,
60 CombinedRegion
->Buffer
,
61 &CombinedRegion
->rdh
.rcBound
);
63 RGNOBJAPI_Unlock(CombinedRegion
);
66 if ( NULL
== Dc
->rosdc
.CombinedClip
)
68 DPRINT1("IntEngCreateClipRegion() failed\n");
72 return NtGdiOffsetRgn(Dc
->rosdc
.hGCClipRgn
, -Dc
->ptlDCOrig
.x
, -Dc
->ptlDCOrig
.y
);
76 GdiSelectVisRgn(HDC hdc
, HRGN hrgn
)
83 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
86 if (!(dc
= DC_LockDc(hdc
)))
88 SetLastWin32Error(ERROR_INVALID_HANDLE
);
92 dc
->fs
&= ~DC_FLAG_DIRTY_RAO
;
94 if (dc
->prgnVis
== NULL
)
96 dc
->prgnVis
= IntSysCreateRectpRgn(0, 0, 0, 0);
97 GDIOBJ_CopyOwnership(hdc
, dc
->prgnVis
->BaseObject
.hHmgr
);
100 retval
= NtGdiCombineRgn(dc
->prgnVis
->BaseObject
.hHmgr
, hrgn
, 0, RGN_COPY
);
101 if ( retval
!= ERROR
)
103 IntGdiOffsetRgn(dc
->prgnVis
, -dc
->ptlDCOrig
.x
, -dc
->ptlDCOrig
.y
);
104 CLIPPING_UpdateGCRegion(dc
);
112 int FASTCALL
GdiExtSelectClipRgn(PDC dc
,
116 // dc->fs &= ~DC_FLAG_DIRTY_RAO;
120 if (fnMode
== RGN_COPY
)
122 if (dc
->rosdc
.hClipRgn
!= NULL
)
124 REGION_FreeRgnByHandle(dc
->rosdc
.hClipRgn
);
125 dc
->rosdc
.hClipRgn
= NULL
;
130 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
136 if (!dc
->rosdc
.hClipRgn
)
140 if((Rgn
= RGNOBJAPI_Lock(((PROSRGNDATA
)dc
->prgnVis
)->BaseObject
.hHmgr
, NULL
)))
142 REGION_GetRgnBox(Rgn
, &rect
);
143 RGNOBJAPI_Unlock(Rgn
);
144 dc
->rosdc
.hClipRgn
= IntSysCreateRectRgnIndirect(&rect
);
148 dc
->rosdc
.hClipRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
151 if(fnMode
== RGN_COPY
)
153 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, hrgn
, 0, fnMode
);
156 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, hrgn
, fnMode
);
159 return CLIPPING_UpdateGCRegion(dc
);
163 int APIENTRY
NtGdiExtSelectClipRgn(HDC hDC
,
170 if (!(dc
= DC_LockDc(hDC
)))
172 SetLastWin32Error(ERROR_INVALID_HANDLE
);
176 retval
= GdiExtSelectClipRgn ( dc
, hrgn
, fnMode
);
183 GdiGetClipBox(HDC hDC
, PRECTL rc
)
189 if (!(dc
= DC_LockDc(hDC
)))
194 if (!(Rgn
= RGNOBJAPI_Lock(dc
->rosdc
.hGCClipRgn
, NULL
)))
199 retval
= REGION_GetRgnBox(Rgn
, rc
);
200 RGNOBJAPI_Unlock(Rgn
);
201 IntDPtoLP(dc
, (LPPOINT
)rc
, 2);
208 NtGdiGetAppClipBox(HDC hDC
, PRECTL rc
)
211 NTSTATUS Status
= STATUS_SUCCESS
;
214 Ret
= GdiGetClipBox(hDC
, &Saferect
);
223 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
225 Status
= _SEH2_GetExceptionCode();
229 if(!NT_SUCCESS(Status
))
231 SetLastNtError(Status
);
238 int APIENTRY
NtGdiExcludeClipRect(HDC hDC
,
247 PDC dc
= DC_LockDc(hDC
);
251 SetLastWin32Error(ERROR_INVALID_HANDLE
);
255 Rect
.left
= LeftRect
;
257 Rect
.right
= RightRect
;
258 Rect
.bottom
= BottomRect
;
260 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
262 NewRgn
= IntSysCreateRectRgnIndirect(&Rect
);
269 if (!dc
->rosdc
.hClipRgn
)
271 dc
->rosdc
.hClipRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
272 NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, ((PROSRGNDATA
)dc
->prgnVis
)->BaseObject
.hHmgr
, NewRgn
, RGN_DIFF
);
273 Result
= SIMPLEREGION
;
277 Result
= NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, NewRgn
, RGN_DIFF
);
279 REGION_FreeRgnByHandle(NewRgn
);
282 CLIPPING_UpdateGCRegion(dc
);
289 int APIENTRY
NtGdiIntersectClipRect(HDC hDC
,
298 PDC dc
= DC_LockDc(hDC
);
300 DPRINT("NtGdiIntersectClipRect(%x, %d,%d-%d,%d)\n",
301 hDC
, LeftRect
, TopRect
, RightRect
, BottomRect
);
305 SetLastWin32Error(ERROR_INVALID_HANDLE
);
309 Rect
.left
= LeftRect
;
311 Rect
.right
= RightRect
;
312 Rect
.bottom
= BottomRect
;
314 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
316 NewRgn
= IntSysCreateRectRgnIndirect(&Rect
);
321 else if (!dc
->rosdc
.hClipRgn
)
323 dc
->rosdc
.hClipRgn
= NewRgn
;
324 Result
= SIMPLEREGION
;
328 Result
= NtGdiCombineRgn(dc
->rosdc
.hClipRgn
, dc
->rosdc
.hClipRgn
, NewRgn
, RGN_AND
);
329 REGION_FreeRgnByHandle(NewRgn
);
332 CLIPPING_UpdateGCRegion(dc
);
339 int APIENTRY
NtGdiOffsetClipRgn(HDC hDC
,
346 if(!(dc
= DC_LockDc(hDC
)))
348 SetLastWin32Error(ERROR_INVALID_HANDLE
);
352 if(dc
->rosdc
.hClipRgn
!= NULL
)
354 Result
= NtGdiOffsetRgn(dc
->rosdc
.hClipRgn
,
357 CLIPPING_UpdateGCRegion(dc
);
368 BOOL APIENTRY
NtGdiPtVisible(HDC hDC
,
375 if(!(dc
= DC_LockDc(hDC
)))
377 SetLastWin32Error(ERROR_INVALID_HANDLE
);
381 rgn
= dc
->rosdc
.hGCClipRgn
;
384 return (rgn
? NtGdiPtInRegion(rgn
, X
, Y
) : FALSE
);
387 BOOL APIENTRY
NtGdiRectVisible(HDC hDC
,
390 NTSTATUS Status
= STATUS_SUCCESS
;
392 PDC dc
= DC_LockDc(hDC
);
398 SetLastWin32Error(ERROR_INVALID_HANDLE
);
404 ProbeForRead(UnsafeRect
,
409 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
411 Status
= _SEH2_GetExceptionCode();
415 if(!NT_SUCCESS(Status
))
418 SetLastNtError(Status
);
422 if (dc
->rosdc
.hGCClipRgn
)
424 if((Rgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(dc
->rosdc
.hGCClipRgn
, NULL
)))
426 IntLPtoDP(dc
, (LPPOINT
)&Rect
, 2);
427 Result
= REGION_RectInRegion(Rgn
, &Rect
);
428 RGNOBJAPI_Unlock(Rgn
);
438 IntGdiSetMetaRgn(PDC pDC
)
443 if ( pDC
->dclevel
.prgnMeta
)
445 if ( pDC
->dclevel
.prgnClip
)
447 TempRgn
= IntSysCreateRectRgn(0,0,0,0);
450 Ret
= IntGdiCombineRgn( TempRgn
,
451 pDC
->dclevel
.prgnMeta
,
452 pDC
->dclevel
.prgnClip
,
456 GDIOBJ_ShareUnlockObjByPtr(pDC
->dclevel
.prgnMeta
);
457 if (!((PROSRGNDATA
)pDC
->dclevel
.prgnMeta
)->BaseObject
.ulShareCount
)
458 REGION_Delete(pDC
->dclevel
.prgnMeta
);
460 pDC
->dclevel
.prgnMeta
= TempRgn
;
462 GDIOBJ_ShareUnlockObjByPtr(pDC
->dclevel
.prgnClip
);
463 if (!((PROSRGNDATA
)pDC
->dclevel
.prgnClip
)->BaseObject
.ulShareCount
)
464 REGION_Delete(pDC
->dclevel
.prgnClip
);
466 pDC
->dclevel
.prgnClip
= NULL
;
468 IntGdiReleaseRaoRgn(pDC
);
471 REGION_Delete(TempRgn
);
475 Ret
= REGION_Complexity(pDC
->dclevel
.prgnMeta
);
479 if ( pDC
->dclevel
.prgnClip
)
481 Ret
= REGION_Complexity(pDC
->dclevel
.prgnClip
);
482 pDC
->dclevel
.prgnMeta
= pDC
->dclevel
.prgnClip
;
483 pDC
->dclevel
.prgnClip
= NULL
;
492 int APIENTRY
NtGdiSetMetaRgn(HDC hDC
)
495 PDC pDC
= DC_LockDc(hDC
);
499 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
502 Ret
= IntGdiSetMetaRgn(pDC
);
509 NEW_CLIPPING_UpdateGCRegion(PDC pDC
)
513 if (!pDC
->prgnVis
) return 0;
517 REGION_Delete(pDC
->prgnAPI
);
518 pDC
->prgnAPI
= IntSysCreateRectRgn(0,0,0,0);
523 REGION_Delete(pDC
->prgnRao
);
524 pDC
->prgnRao
= IntSysCreateRectRgn(0,0,0,0);
527 if (pDC
->dclevel
.prgnMeta
&& pDC
->dclevel
.prgnClip
)
529 IntGdiCombineRgn( pDC
->prgnAPI
,
530 pDC
->dclevel
.prgnClip
,
531 pDC
->dclevel
.prgnMeta
,
536 if (pDC
->dclevel
.prgnClip
)
537 IntGdiCombineRgn( pDC
->prgnAPI
,
538 pDC
->dclevel
.prgnClip
,
541 else if (pDC
->dclevel
.prgnMeta
)
542 IntGdiCombineRgn( pDC
->prgnAPI
,
543 pDC
->dclevel
.prgnMeta
,
548 IntGdiCombineRgn( pDC
->prgnRao
,
553 RtlCopyMemory(&pDC
->erclClip
, &((PROSRGNDATA
)pDC
->prgnRao
)->rdh
.rcBound
, sizeof(RECTL
));
554 pDC
->fs
&= ~DC_FLAG_DIRTY_RAO
;
556 // if (Dc->CombinedClip != NULL) IntEngDeleteClipRegion(Dc->CombinedClip);
558 co
= IntEngCreateClipRegion( ((PROSRGNDATA
)pDC
->prgnRao
)->rdh
.nCount
,
559 ((PROSRGNDATA
)pDC
->prgnRao
)->Buffer
,
562 return REGION_Complexity(pDC
->prgnRao
);