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