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