1 /*
2  * Unit test suite for clipping
3  *
4  * Copyright 2005 Huw Davies
5  * Copyright 2008,2011,2013 Dmitry Timoshkov
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "wine/test.h"
23 #include "winbase.h"
24 #include "wingdi.h"
25 #include "winuser.h"
26 
test_GetRandomRgn(void)27 static void test_GetRandomRgn(void)
28 {
29     HWND hwnd = CreateWindowExA(0,"BUTTON","test",WS_VISIBLE|WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0);
30     HDC hdc;
31     HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
32     int ret;
33     RECT rc, rc2;
34     RECT ret_rc, window_rc;
35 
36     ok( hwnd != 0, "CreateWindow failed\n" );
37 
38     SetRect(&window_rc, 400, 300, 500, 400);
39     SetWindowPos(hwnd, HWND_TOPMOST, window_rc.left, window_rc.top,
40                  window_rc.right - window_rc.left, window_rc.bottom - window_rc.top, 0 );
41     hdc = GetDC(hwnd);
42 
43     ret = GetRandomRgn(hdc, hrgn, 1);
44     ok(ret == 0, "GetRandomRgn rets %d\n", ret);
45     ret = GetRandomRgn(hdc, hrgn, 2);
46     ok(ret == 0, "GetRandomRgn rets %d\n", ret);
47     ret = GetRandomRgn(hdc, hrgn, 3);
48     ok(ret == 0, "GetRandomRgn rets %d\n", ret);
49 
50     /* Set a clip region */
51     SetRect(&rc, 20, 20, 80, 80);
52     IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
53 
54     ret = GetRandomRgn(hdc, hrgn, 1);
55     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
56     GetRgnBox(hrgn, &ret_rc);
57     ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
58 
59     ret = GetRandomRgn(hdc, hrgn, 2);
60     ok(ret == 0, "GetRandomRgn rets %d\n", ret);
61 
62     ret = GetRandomRgn(hdc, hrgn, 3);
63     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
64     GetRgnBox(hrgn, &ret_rc);
65     ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
66 
67     /* Move the clip to the meta and clear the clip */
68     SetMetaRgn(hdc);
69 
70     ret = GetRandomRgn(hdc, hrgn, 1);
71     ok(ret == 0, "GetRandomRgn rets %d\n", ret);
72     ret = GetRandomRgn(hdc, hrgn, 2);
73     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
74     GetRgnBox(hrgn, &ret_rc);
75     ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
76 
77     ret = GetRandomRgn(hdc, hrgn, 3);
78     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
79     GetRgnBox(hrgn, &ret_rc);
80     ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
81 
82     /* Set a new clip (still got the meta) */
83     SetRect(&rc2, 10, 30, 70, 90);
84     IntersectClipRect(hdc, rc2.left, rc2.top, rc2.right, rc2.bottom);
85 
86     ret = GetRandomRgn(hdc, hrgn, 1);
87     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
88     GetRgnBox(hrgn, &ret_rc);
89     ok(EqualRect(&rc2, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
90 
91     ret = GetRandomRgn(hdc, hrgn, 2);
92     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
93     GetRgnBox(hrgn, &ret_rc);
94     ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
95 
96     IntersectRect(&rc2, &rc, &rc2);
97 
98     ret = GetRandomRgn(hdc, hrgn, 3);
99     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
100     GetRgnBox(hrgn, &ret_rc);
101     ok(EqualRect(&rc2, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
102 
103 
104     ret = GetRandomRgn(hdc, hrgn, SYSRGN);
105     ok(ret != 0, "GetRandomRgn rets %d\n", ret);
106     GetRgnBox(hrgn, &ret_rc);
107     if(GetVersion() & 0x80000000)
108         OffsetRect(&window_rc, -window_rc.left, -window_rc.top);
109     /* the window may be partially obscured so the region may be smaller */
110     IntersectRect( &window_rc, &ret_rc, &ret_rc );
111     ok(EqualRect(&window_rc, &ret_rc), "GetRandomRgn %s\n", wine_dbgstr_rect(&ret_rc));
112 
113     DeleteObject(hrgn);
114     ReleaseDC(hwnd, hdc);
115     DestroyWindow(hwnd);
116 }
117 
verify_region(HRGN hrgn,const RECT * rc)118 static void verify_region(HRGN hrgn, const RECT *rc)
119 {
120     union
121     {
122         RGNDATA data;
123         char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)];
124     } rgn;
125     const RECT *rect;
126     DWORD ret;
127 
128     ret = GetRegionData(hrgn, 0, NULL);
129     if (IsRectEmpty(rc))
130         ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", ret);
131     else
132         ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
133 
134     if (!ret) return;
135 
136     ret = GetRegionData(hrgn, sizeof(rgn), &rgn.data);
137     if (IsRectEmpty(rc))
138         ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", ret);
139     else
140         ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
141 
142     trace("size %u, type %u, count %u, rgn size %u, bound %s\n",
143           rgn.data.rdh.dwSize, rgn.data.rdh.iType, rgn.data.rdh.nCount, rgn.data.rdh.nRgnSize,
144           wine_dbgstr_rect(&rgn.data.rdh.rcBound));
145     if (rgn.data.rdh.nCount != 0)
146     {
147         rect = (const RECT *)rgn.data.Buffer;
148         trace("rect %s\n", wine_dbgstr_rect(rect));
149         ok(EqualRect(rect, rc), "rects don't match\n");
150     }
151 
152     ok(rgn.data.rdh.dwSize == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", rgn.data.rdh.dwSize);
153     ok(rgn.data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn.data.rdh.iType);
154     if (IsRectEmpty(rc))
155     {
156         ok(rgn.data.rdh.nCount == 0, "expected 0, got %u\n", rgn.data.rdh.nCount);
157         ok(rgn.data.rdh.nRgnSize == 0 ||
158            broken(rgn.data.rdh.nRgnSize == 168), /* NT4 */
159            "expected 0, got %u\n", rgn.data.rdh.nRgnSize);
160     }
161     else
162     {
163         ok(rgn.data.rdh.nCount == 1, "expected 1, got %u\n", rgn.data.rdh.nCount);
164         ok(rgn.data.rdh.nRgnSize == sizeof(RECT) ||
165            broken(rgn.data.rdh.nRgnSize == 168), /* NT4 */
166            "expected sizeof(RECT), got %u\n", rgn.data.rdh.nRgnSize);
167     }
168     ok(EqualRect(&rgn.data.rdh.rcBound, rc), "rects don't match\n");
169 }
170 
test_ExtCreateRegion(void)171 static void test_ExtCreateRegion(void)
172 {
173     static const RECT empty_rect;
174     static const RECT rc = { 111, 222, 333, 444 };
175     static const RECT arc[2] = { {0, 0, 10, 10}, {10, 10, 20, 20}};
176     static const RECT rc_xformed = { 76, 151, 187, 262 };
177     union
178     {
179         RGNDATA data;
180         char buf[sizeof(RGNDATAHEADER) + 2 * sizeof(RECT)];
181     } rgn;
182     HRGN hrgn;
183     XFORM xform;
184 
185     if (0) /* crashes under Win9x */
186     {
187         SetLastError(0xdeadbeef);
188         hrgn = ExtCreateRegion(NULL, 0, NULL);
189         ok(!hrgn, "ExtCreateRegion should fail\n");
190         ok(GetLastError() == ERROR_INVALID_PARAMETER, "ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
191     }
192 
193     rgn.data.rdh.dwSize = 0;
194     rgn.data.rdh.iType = 0;
195     rgn.data.rdh.nCount = 0;
196     rgn.data.rdh.nRgnSize = 0;
197     SetRectEmpty(&rgn.data.rdh.rcBound);
198     memcpy(rgn.data.Buffer, &rc, sizeof(rc));
199 
200     SetLastError(0xdeadbeef);
201     hrgn = ExtCreateRegion(NULL, sizeof(rgn), &rgn.data);
202     ok(!hrgn, "ExtCreateRegion should fail\n");
203     ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
204 
205     rgn.data.rdh.dwSize = sizeof(rgn.data.rdh) - 1;
206 
207     SetLastError(0xdeadbeef);
208     hrgn = ExtCreateRegion(NULL, sizeof(rgn), &rgn.data);
209     ok(!hrgn, "ExtCreateRegion should fail\n");
210     ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
211 
212     /* although XP doesn't care about the type Win9x does */
213     rgn.data.rdh.iType = RDH_RECTANGLES;
214     rgn.data.rdh.dwSize = sizeof(rgn.data.rdh);
215 
216     /* sizeof(RGNDATAHEADER) is large enough */
217     SetLastError(0xdeadbeef);
218     hrgn = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER), &rgn.data);
219     ok(hrgn != 0, "ExtCreateRegion error %u\n", GetLastError());
220     verify_region(hrgn, &empty_rect);
221     DeleteObject(hrgn);
222 
223     /* Cannot be smaller than sizeof(RGNDATAHEADER) */
224     SetLastError(0xdeadbeef);
225     hrgn = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) - 1, &rgn.data);
226     todo_wine
227     ok(!hrgn, "ExtCreateRegion should fail\n");
228     ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
229 
230     SetLastError(0xdeadbeef);
231     hrgn = ExtCreateRegion(NULL, sizeof(rgn), &rgn.data);
232     ok(hrgn != 0, "ExtCreateRegion error %u\n", GetLastError());
233     verify_region(hrgn, &empty_rect);
234     DeleteObject(hrgn);
235 
236     rgn.data.rdh.nCount = 1;
237     SetRectEmpty(&rgn.data.rdh.rcBound);
238     memcpy(rgn.data.Buffer, &rc, sizeof(rc));
239 
240     /* With a single rect this seems to work... */
241     SetLastError(0xdeadbeef);
242     hrgn = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + sizeof(RECT) - 1, &rgn.data);
243     ok(hrgn != 0, "ExtCreateRegion error %u\n", GetLastError());
244     verify_region(hrgn, &rc);
245     DeleteObject(hrgn);
246 
247     SetLastError(0xdeadbeef);
248     hrgn = ExtCreateRegion(NULL, sizeof(rgn), &rgn.data);
249     ok(hrgn != 0, "ExtCreateRegion error %u\n", GetLastError());
250     verify_region(hrgn, &rc);
251     DeleteObject(hrgn);
252 
253     rgn.data.rdh.dwSize = sizeof(rgn.data.rdh) + 1;
254 
255     SetLastError(0xdeadbeef);
256     hrgn = ExtCreateRegion(NULL, 1, &rgn.data);
257     ok(hrgn != 0 ||
258        broken(GetLastError() == 0xdeadbeef), /* NT4 */
259        "ExtCreateRegion error %u\n", GetLastError());
260     if(hrgn)
261     {
262         verify_region(hrgn, &rc);
263         DeleteObject(hrgn);
264     }
265 
266     xform.eM11 = 0.5; /* 50% width */
267     xform.eM12 = 0.0;
268     xform.eM21 = 0.0;
269     xform.eM22 = 0.5; /* 50% height */
270     xform.eDx = 20.0;
271     xform.eDy = 40.0;
272 
273     rgn.data.rdh.dwSize = sizeof(rgn.data.rdh);
274 
275     SetLastError(0xdeadbeef);
276     hrgn = ExtCreateRegion(&xform, sizeof(rgn), &rgn.data);
277     ok(hrgn != 0, "ExtCreateRegion error %u/%x\n", GetLastError(), GetLastError());
278     verify_region(hrgn, &rc_xformed);
279     DeleteObject(hrgn);
280 
281     rgn.data.rdh.nCount = 2;
282     SetRectEmpty(&rgn.data.rdh.rcBound);
283     memcpy(rgn.data.Buffer, arc, sizeof(arc));
284 
285     /* Buffer cannot be smaller than sizeof(RGNDATAHEADER) + 2 * sizeof(RECT) */
286     SetLastError(0xdeadbeef);
287     hrgn = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + 2 * sizeof(RECT) - 1, &rgn.data);
288     todo_wine
289     ok(!hrgn, "ExtCreateRegion should fail\n");
290     ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
291 
292 }
293 
test_GetClipRgn(void)294 static void test_GetClipRgn(void)
295 {
296     HDC hdc;
297     HRGN hrgn, hrgn2, hrgn3, hrgn4;
298     int ret;
299 
300     /* Test calling GetClipRgn with NULL device context and region handles. */
301     ret = GetClipRgn(NULL, NULL);
302     ok(ret == -1, "Expected GetClipRgn to return -1, got %d\n", ret);
303 
304     hdc = GetDC(NULL);
305     ok(hdc != NULL, "Expected GetDC to return a valid device context handle\n");
306 
307     /* Test calling GetClipRgn with a valid device context and NULL region. */
308     ret = GetClipRgn(hdc, NULL);
309     ok(ret == 0 ||
310        ret == -1 /* Win9x */,
311        "Expected GetClipRgn to return 0, got %d\n", ret);
312 
313     /* Initialize the test regions. */
314     hrgn = CreateRectRgn(100, 100, 100, 100);
315     ok(hrgn != NULL,
316        "Expected CreateRectRgn to return a handle to a new rectangular region\n");
317 
318     hrgn2 = CreateRectRgn(1, 2, 3, 4);
319     ok(hrgn2 != NULL,
320        "Expected CreateRectRgn to return a handle to a new rectangular region\n");
321 
322     hrgn3 = CreateRectRgn(1, 2, 3, 4);
323     ok(hrgn3 != NULL,
324        "Expected CreateRectRgn to return a handle to a new rectangular region\n");
325 
326     hrgn4 = CreateRectRgn(1, 2, 3, 4);
327     ok(hrgn4 != NULL,
328        "Expected CreateRectRgn to return a handle to a new rectangular region\n");
329 
330     /* Try getting a clipping region from the device context
331      * when the device context's clipping region isn't set. */
332     ret = GetClipRgn(hdc, hrgn2);
333     ok(ret == 0, "Expected GetClipRgn to return 0, got %d\n", ret);
334 
335     /* The region passed to GetClipRgn should be unchanged. */
336     ret = EqualRgn(hrgn2, hrgn3);
337     ok(ret == 1,
338        "Expected EqualRgn to compare the two regions as equal, got %d\n", ret);
339 
340     /* Try setting and getting back a clipping region. */
341     ret = SelectClipRgn(hdc, hrgn);
342     ok(ret == NULLREGION,
343        "Expected SelectClipRgn to return NULLREGION, got %d\n", ret);
344 
345     /* Passing a NULL region handle when the device context
346      * has a clipping region results in an error. */
347     ret = GetClipRgn(hdc, NULL);
348     ok(ret == -1, "Expected GetClipRgn to return -1, got %d\n", ret);
349 
350     ret = GetClipRgn(hdc, hrgn2);
351     ok(ret == 1, "Expected GetClipRgn to return 1, got %d\n", ret);
352 
353     ret = EqualRgn(hrgn, hrgn2);
354     ok(ret == 1,
355        "Expected EqualRgn to compare the two regions as equal, got %d\n", ret);
356 
357     /* Try unsetting and then query the clipping region. */
358     ret = SelectClipRgn(hdc, NULL);
359     ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
360        "Expected SelectClipRgn to return SIMPLEREGION, got %d\n", ret);
361 
362     ret = GetClipRgn(hdc, NULL);
363     ok(ret == 0 ||
364        ret == -1 /* Win9x */,
365        "Expected GetClipRgn to return 0, got %d\n", ret);
366 
367     ret = GetClipRgn(hdc, hrgn3);
368     ok(ret == 0, "Expected GetClipRgn to return 0, got %d\n", ret);
369 
370     ret = EqualRgn(hrgn3, hrgn4);
371     ok(ret == 1,
372        "Expected EqualRgn to compare the two regions as equal, got %d\n", ret);
373 
374     DeleteObject(hrgn4);
375     DeleteObject(hrgn3);
376     DeleteObject(hrgn2);
377     DeleteObject(hrgn);
378     ReleaseDC(NULL, hdc);
379 }
380 
test_memory_dc_clipping(void)381 static void test_memory_dc_clipping(void)
382 {
383     HDC hdc;
384     HRGN hrgn, hrgn_empty;
385     HBITMAP hbmp;
386     RECT rc;
387     int ret;
388 
389     hdc = CreateCompatibleDC(0);
390     hrgn_empty = CreateRectRgn(0, 0, 0, 0);
391     hrgn = CreateRectRgn(0, 0, 0, 0);
392     hbmp = CreateCompatibleBitmap(hdc, 100, 100);
393 
394     ret = GetClipRgn(hdc, hrgn);
395     ok(ret == 0, "expected 0, got %d\n", ret);
396 
397     ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
398     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
399 
400     ret = GetClipRgn(hdc, hrgn);
401     ok(ret == 1, "expected 1, got %d\n", ret);
402 
403     ret = GetRgnBox(hrgn, &rc);
404     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
405     ok(rc.left == 0 && rc.top == 0 && rc.right == 1 && rc.bottom == 1,
406        "expected 0,0-1,1, got %s\n", wine_dbgstr_rect(&rc));
407 
408     ret = ExtSelectClipRgn(hdc, 0, RGN_COPY);
409     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
410 
411     ret = GetClipRgn(hdc, hrgn);
412     ok(ret == 0, "expected 0, got %d\n", ret);
413 
414     ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
415     ok(ret == 0, "expected 0, got %d\n", ret);
416 
417     ret = GetClipRgn(hdc, hrgn);
418     ok(ret == 0, "expected 0, got %d\n", ret);
419 
420     SelectObject(hdc, hbmp);
421 
422     ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
423     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
424 
425     ret = GetClipRgn(hdc, hrgn);
426     ok(ret == 1, "expected 1, got %d\n", ret);
427 
428     ret = GetRgnBox(hrgn, &rc);
429     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
430     ok(rc.left == 0 && rc.top == 0 && rc.right == 100 && rc.bottom == 100,
431        "expected 0,0-100,100, got %s\n", wine_dbgstr_rect(&rc));
432 
433     SetRect( &rc, 10, 10, 20, 20 );
434     ret = RectVisible( hdc, &rc );
435     ok(ret, "RectVisible failed for %s\n", wine_dbgstr_rect(&rc));
436 
437     SetRect( &rc, 20, 20, 10, 10 );
438     ret = RectVisible( hdc, &rc );
439     ok(ret, "RectVisible failed for %s\n", wine_dbgstr_rect(&rc));
440 
441     ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
442     ok(ret == 0, "expected 0, got %d\n", ret);
443 
444     ret = GetClipRgn(hdc, hrgn);
445     ok(ret == 1, "expected 1, got %d\n", ret);
446 
447     ret = GetRgnBox(hrgn, &rc);
448     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
449     ok(rc.left == 0 && rc.top == 0 && rc.right == 100 && rc.bottom == 100,
450        "expected 0,0-100,100, got %s\n", wine_dbgstr_rect(&rc));
451 
452     DeleteDC(hdc);
453     DeleteObject(hrgn);
454     DeleteObject(hrgn_empty);
455     DeleteObject(hbmp);
456 }
457 
test_window_dc_clipping(void)458 static void test_window_dc_clipping(void)
459 {
460     HDC hdc;
461     HRGN hrgn, hrgn_empty;
462     HWND hwnd;
463     RECT rc, virtual_rect;
464     int ret, screen_width, screen_height;
465 
466     /* Windows versions earlier than Win2k do not support the virtual screen metrics,
467      * so we fall back to the primary screen metrics. */
468     screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
469     if(!screen_width) screen_width = GetSystemMetrics(SM_CXSCREEN);
470     screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
471     if(!screen_height) screen_height = GetSystemMetrics(SM_CYSCREEN);
472     SetRect(&virtual_rect, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
473             GetSystemMetrics(SM_XVIRTUALSCREEN) + screen_width, GetSystemMetrics(SM_YVIRTUALSCREEN) + screen_height);
474 
475     trace("screen resolution %d x %d\n", screen_width, screen_height);
476 
477     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
478                            -100, -100, screen_width * 2, screen_height * 2, 0, 0, 0, NULL);
479     hdc = GetWindowDC(0);
480     hrgn_empty = CreateRectRgn(0, 0, 0, 0);
481     hrgn = CreateRectRgn(0, 0, 0, 0);
482 
483     ret = GetClipRgn(hdc, hrgn);
484     ok(ret == 0, "expected 0, got %d\n", ret);
485 
486     ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
487     ok(ret == 0, "expected 0, got %d\n", ret);
488 
489     ret = GetClipRgn(hdc, hrgn);
490     ok(ret == 0, "expected 0, got %d\n", ret);
491 
492     ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
493     ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
494        "expected SIMPLEREGION, got %d\n", ret);
495 
496     ret = GetClipRgn(hdc, hrgn);
497     ok(ret == 1, "expected 1, got %d\n", ret);
498 
499     ret = GetRgnBox(hrgn, &rc);
500     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
501     ok(EqualRect(&rc, &virtual_rect), "expected %s, got %s\n", wine_dbgstr_rect(&virtual_rect),
502        wine_dbgstr_rect(&rc));
503 
504     SetRect( &rc, 10, 10, 20, 20 );
505     ret = RectVisible( hdc, &rc );
506     ok( ret, "RectVisible failed for %s\n", wine_dbgstr_rect(&rc));
507 
508     SetRect( &rc, 20, 20, 10, 10 );
509     ret = RectVisible( hdc, &rc );
510     ok( ret, "RectVisible failed for %s\n", wine_dbgstr_rect(&rc));
511 
512     ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
513     ok(ret == 0, "expected 0, got %d\n", ret);
514 
515     ret = GetClipRgn(hdc, hrgn);
516     ok(ret == 1, "expected 1, got %d\n", ret);
517 
518     ret = GetRgnBox(hrgn, &rc);
519     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
520     ok(EqualRect(&rc, &virtual_rect), "expected %s, got %s\n", wine_dbgstr_rect(&virtual_rect),
521        wine_dbgstr_rect(&rc));
522 
523     ret = ExtSelectClipRgn(hdc, 0, RGN_COPY);
524     ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
525        "expected SIMPLEREGION, got %d\n", ret);
526 
527     ret = GetClipRgn(hdc, hrgn);
528     ok(ret == 0, "expected 0, got %d\n", ret);
529 
530     DeleteDC(hdc);
531     DeleteObject(hrgn);
532     DeleteObject(hrgn_empty);
533     DestroyWindow(hwnd);
534 }
535 
536 
START_TEST(clipping)537 START_TEST(clipping)
538 {
539     test_GetRandomRgn();
540     test_ExtCreateRegion();
541     test_GetClipRgn();
542     test_memory_dc_clipping();
543     test_window_dc_clipping();
544 }
545