removed an ASSERT that occured when system ran out of GDI handles, and added more...
[reactos.git] / reactos / subsys / win32k / objects / cliprgn.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
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.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: cliprgn.c,v 1.43 2004/12/07 19:53:44 royce Exp $ */
20 #include <w32k.h>
21
22 int FASTCALL
23 CLIPPING_UpdateGCRegion(DC* Dc)
24 {
25 PROSRGNDATA CombinedRegion;
26
27 if (Dc->w.hGCClipRgn == NULL)
28 Dc->w.hGCClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
29
30 if (Dc->w.hClipRgn == NULL)
31 NtGdiCombineRgn(Dc->w.hGCClipRgn, Dc->w.hVisRgn, 0, RGN_COPY);
32 else
33 NtGdiCombineRgn(Dc->w.hGCClipRgn, Dc->w.hClipRgn, Dc->w.hVisRgn, RGN_AND);
34 NtGdiOffsetRgn(Dc->w.hGCClipRgn, Dc->w.DCOrgX, Dc->w.DCOrgY);
35
36 CombinedRegion = RGNDATA_LockRgn(Dc->w.hGCClipRgn);
37 ASSERT(CombinedRegion != NULL);
38
39 if (Dc->CombinedClip != NULL)
40 IntEngDeleteClipRegion(Dc->CombinedClip);
41
42 Dc->CombinedClip = IntEngCreateClipRegion(
43 CombinedRegion->rdh.nCount,
44 (PRECTL)CombinedRegion->Buffer,
45 (PRECTL)&CombinedRegion->rdh.rcBound);
46
47 RGNDATA_UnlockRgn(Dc->w.hGCClipRgn);
48 if ( NULL == Dc->CombinedClip )
49 {
50 DPRINT1("IntEngCreateClipRegion() failed\n");
51 return ERROR;
52 }
53 return NtGdiOffsetRgn(Dc->w.hGCClipRgn, -Dc->w.DCOrgX, -Dc->w.DCOrgY);
54 }
55
56 HRGN WINAPI SaveVisRgn(HDC hdc)
57 {
58 HRGN copy;
59 PROSRGNDATA obj, copyObj;
60 PDC dc = DC_LockDc(hdc);
61
62 if (!dc) return 0;
63
64 obj = RGNDATA_LockRgn(dc->w.hVisRgn);
65
66 if(!(copy = NtGdiCreateRectRgn(0, 0, 0, 0)))
67 {
68 RGNDATA_UnlockRgn(dc->w.hVisRgn);
69 DC_UnlockDc(hdc);
70 return 0;
71 }
72 NtGdiCombineRgn(copy, dc->w.hVisRgn, 0, RGN_COPY);
73 copyObj = RGNDATA_LockRgn(copy);
74 /* copyObj->header.hNext = obj->header.hNext;
75 header.hNext = copy; */
76
77 return copy;
78 }
79
80 INT STDCALL
81 NtGdiSelectVisRgn(HDC hdc, HRGN hrgn)
82 {
83 int retval;
84 DC *dc;
85
86 if (!hrgn)
87 {
88 SetLastWin32Error(ERROR_INVALID_PARAMETER);
89 return ERROR;
90 }
91 if (!(dc = DC_LockDc(hdc)))
92 {
93 SetLastWin32Error(ERROR_INVALID_HANDLE);
94 return ERROR;
95 }
96
97 dc->w.flags &= ~DC_DIRTY;
98
99 if (dc->w.hVisRgn == NULL)
100 {
101 dc->w.hVisRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
102 GDIOBJ_CopyOwnership(hdc, dc->w.hVisRgn);
103 }
104
105 retval = NtGdiCombineRgn(dc->w.hVisRgn, hrgn, 0, RGN_COPY);
106 if ( retval != ERROR )
107 retval = CLIPPING_UpdateGCRegion(dc);
108 DC_UnlockDc( hdc );
109
110 return retval;
111 }
112
113 int STDCALL NtGdiExtSelectClipRgn(HDC hDC,
114 HRGN hrgn,
115 int fnMode)
116 {
117 int retval;
118 DC *dc;
119
120 if (!(dc = DC_LockDc(hDC)))
121 {
122 SetLastWin32Error(ERROR_INVALID_HANDLE);
123 return ERROR;
124 }
125
126 // dc->w.flags &= ~DC_DIRTY;
127
128 if (!hrgn)
129 {
130 if (fnMode == RGN_COPY)
131 {
132 if (dc->w.hClipRgn != NULL)
133 {
134 NtGdiDeleteObject(dc->w.hClipRgn);
135 dc->w.hClipRgn = NULL;
136 retval = NULLREGION;
137 }
138 }
139 else
140 {
141 DC_UnlockDc( hDC );
142 SetLastWin32Error(ERROR_INVALID_PARAMETER);
143 return ERROR;
144 }
145 }
146 else
147 {
148 if (!dc->w.hClipRgn)
149 {
150 PROSRGNDATA Rgn;
151 RECT rect;
152 if((Rgn = RGNDATA_LockRgn(dc->w.hVisRgn)))
153 {
154 UnsafeIntGetRgnBox(Rgn, &rect);
155 RGNDATA_UnlockRgn(dc->w.hVisRgn);
156 dc->w.hClipRgn = UnsafeIntCreateRectRgnIndirect(&rect);
157 }
158 else
159 {
160 dc->w.hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
161 }
162 }
163 if(fnMode == RGN_COPY)
164 {
165 NtGdiCombineRgn(dc->w.hClipRgn, hrgn, 0, fnMode);
166 }
167 else
168 NtGdiCombineRgn(dc->w.hClipRgn, dc->w.hClipRgn, hrgn, fnMode);
169 }
170
171 retval = CLIPPING_UpdateGCRegion(dc);
172 DC_UnlockDc( hDC );
173
174 return retval;
175 }
176
177 INT FASTCALL
178 IntGdiGetClipBox(HDC hDC, LPRECT rc)
179 {
180 PROSRGNDATA Rgn;
181 INT retval;
182 PDC dc;
183
184 if (!(dc = DC_LockDc(hDC)))
185 {
186 SetLastWin32Error(ERROR_INVALID_HANDLE);
187 return ERROR;
188 }
189
190 if (!(Rgn = RGNDATA_LockRgn(dc->w.hGCClipRgn)))
191 {
192 DC_UnlockDc( hDC );
193 SetLastWin32Error(ERROR_INVALID_HANDLE);
194 return ERROR;
195 }
196 retval = UnsafeIntGetRgnBox(Rgn, rc);
197 RGNDATA_UnlockRgn(dc->w.hGCClipRgn);
198 IntDPtoLP(dc, (LPPOINT)rc, 2);
199 DC_UnlockDc(hDC);
200
201 return retval;
202 }
203
204 int STDCALL NtGdiGetClipBox(HDC hDC,
205 LPRECT rc)
206 {
207 int Ret;
208 NTSTATUS Status;
209 RECT Saferect;
210
211 Ret = IntGdiGetClipBox(hDC, &Saferect);
212
213 Status = MmCopyToCaller(rc, &Saferect, sizeof(RECT));
214 if(!NT_SUCCESS(Status))
215 {
216
217 SetLastNtError(Status);
218 return ERROR;
219 }
220
221 return Ret;
222 }
223
224 int STDCALL NtGdiGetMetaRgn(HDC hDC,
225 HRGN hrgn)
226 {
227 UNIMPLEMENTED;
228 return 0;
229 }
230
231 int STDCALL NtGdiExcludeClipRect(HDC hDC,
232 int LeftRect,
233 int TopRect,
234 int RightRect,
235 int BottomRect)
236 {
237 INT Result;
238 RECT Rect;
239 HRGN NewRgn;
240 PDC dc = DC_LockDc(hDC);
241
242 if (!dc)
243 {
244 SetLastWin32Error(ERROR_INVALID_HANDLE);
245 return ERROR;
246 }
247
248 Rect.left = LeftRect;
249 Rect.top = TopRect;
250 Rect.right = RightRect;
251 Rect.bottom = BottomRect;
252
253 IntLPtoDP(dc, (LPPOINT)&Rect, 2);
254
255 NewRgn = UnsafeIntCreateRectRgnIndirect(&Rect);
256 if (!NewRgn)
257 {
258 Result = ERROR;
259 }
260 else
261 {
262 if (!dc->w.hClipRgn)
263 {
264 dc->w.hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
265 NtGdiCombineRgn(dc->w.hClipRgn, dc->w.hVisRgn, NewRgn, RGN_DIFF);
266 Result = SIMPLEREGION;
267 }
268 else
269 {
270 Result = NtGdiCombineRgn(dc->w.hClipRgn, dc->w.hClipRgn, NewRgn, RGN_DIFF);
271 }
272 NtGdiDeleteObject(NewRgn);
273 }
274 if (Result != ERROR)
275 CLIPPING_UpdateGCRegion(dc);
276
277 DC_UnlockDc(hDC);
278
279 return Result;
280 }
281
282 int STDCALL NtGdiIntersectClipRect(HDC hDC,
283 int LeftRect,
284 int TopRect,
285 int RightRect,
286 int BottomRect)
287 {
288 INT Result;
289 RECT Rect;
290 HRGN NewRgn;
291 PDC dc = DC_LockDc(hDC);
292
293 DPRINT("NtGdiIntersectClipRect(%x, %d,%d-%d,%d)\n",
294 hDC, LeftRect, TopRect, RightRect, BottomRect);
295
296 if (!dc)
297 {
298 SetLastWin32Error(ERROR_INVALID_HANDLE);
299 return ERROR;
300 }
301
302 Rect.left = LeftRect;
303 Rect.top = TopRect;
304 Rect.right = RightRect;
305 Rect.bottom = BottomRect;
306
307 IntLPtoDP(dc, (LPPOINT)&Rect, 2);
308
309 NewRgn = UnsafeIntCreateRectRgnIndirect(&Rect);
310 if (!NewRgn)
311 {
312 Result = ERROR;
313 }
314 else if (!dc->w.hClipRgn)
315 {
316 dc->w.hClipRgn = NewRgn;
317 Result = SIMPLEREGION;
318 }
319 else
320 {
321 Result = NtGdiCombineRgn(dc->w.hClipRgn, dc->w.hClipRgn, NewRgn, RGN_AND);
322 NtGdiDeleteObject(NewRgn);
323 }
324 if (Result != ERROR)
325 CLIPPING_UpdateGCRegion(dc);
326
327 DC_UnlockDc(hDC);
328
329 return Result;
330 }
331
332 int STDCALL NtGdiOffsetClipRgn(HDC hDC,
333 int XOffset,
334 int YOffset)
335 {
336 UNIMPLEMENTED;
337 return 0;
338 }
339
340 BOOL STDCALL NtGdiPtVisible(HDC hDC,
341 int X,
342 int Y)
343 {
344 HRGN rgn;
345 DC *dc;
346
347 if(!(dc = DC_LockDc(hDC)))
348 {
349 SetLastWin32Error(ERROR_INVALID_HANDLE);
350 return FALSE;
351 }
352
353 rgn = dc->w.hGCClipRgn;
354 DC_UnlockDc(hDC);
355
356 return (rgn ? NtGdiPtInRegion(rgn, X, Y) : FALSE);
357 }
358
359 BOOL STDCALL NtGdiRectVisible(HDC hDC,
360 CONST PRECT UnsafeRect)
361 {
362 NTSTATUS Status;
363 PROSRGNDATA Rgn;
364 PDC dc = DC_LockDc(hDC);
365 BOOL Result = FALSE;
366 RECT Rect;
367
368 if (!dc)
369 {
370 SetLastWin32Error(ERROR_INVALID_HANDLE);
371 return FALSE;
372 }
373
374 Status = MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT));
375 if(!NT_SUCCESS(Status))
376 {
377 DC_UnlockDc(hDC);
378 return FALSE;
379 }
380
381 if (dc->w.hGCClipRgn)
382 {
383 if((Rgn = (PROSRGNDATA)RGNDATA_LockRgn(dc->w.hGCClipRgn)))
384 {
385 IntLPtoDP(dc, (LPPOINT)&Rect, 2);
386 Result = UnsafeIntRectInRegion(Rgn, &Rect);
387 RGNDATA_UnlockRgn(dc->w.hGCClipRgn);
388 }
389 }
390 DC_UnlockDc(hDC);
391
392 return Result;
393 }
394
395 BOOL STDCALL NtGdiSelectClipPath(HDC hDC,
396 int Mode)
397 {
398 UNIMPLEMENTED;
399 return FALSE;
400 }
401
402 INT STDCALL
403 NtGdiSelectClipRgn(HDC hDC, HRGN hRgn)
404 {
405 return NtGdiExtSelectClipRgn(hDC, hRgn, RGN_COPY);
406 }
407
408 int STDCALL NtGdiSetMetaRgn(HDC hDC)
409 {
410 UNIMPLEMENTED;
411 return 0;
412 }
413
414 /* EOF */