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