Properly skip known crasher in gdi32:metafile test.
[reactos.git] / rostests / winetests / gdi32 / dc.c
1 /*
2 * Unit tests for dc functions
3 *
4 * Copyright (c) 2005 Huw Davies
5 * Copyright (c) 2005 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 #define WINVER 0x0501 /* request latest DEVMODE */
23
24 #include <assert.h>
25 #include <stdio.h>
26
27 #include "wine/test.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "winerror.h"
32
33 static void dump_region(HRGN hrgn)
34 {
35 DWORD i, size;
36 RGNDATA *data = NULL;
37 RECT *rect;
38
39 if (!hrgn)
40 {
41 printf( "(null) region\n" );
42 return;
43 }
44 if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
45 if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
46 GetRegionData( hrgn, size, data );
47 printf( "%d rects:", data->rdh.nCount );
48 for (i = 0, rect = (RECT *)data->Buffer; i < data->rdh.nCount; i++, rect++)
49 printf( " (%d,%d)-(%d,%d)", rect->left, rect->top, rect->right, rect->bottom );
50 printf( "\n" );
51 HeapFree( GetProcessHeap(), 0, data );
52 }
53
54 static void test_savedc_2(void)
55 {
56 HWND hwnd;
57 HDC hdc;
58 HRGN hrgn;
59 RECT rc, rc_clip;
60 int ret;
61
62 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
63 0, 0, 0, NULL);
64 assert(hwnd != 0);
65 ShowWindow(hwnd, SW_SHOW);
66 UpdateWindow(hwnd);
67
68 hrgn = CreateRectRgn(0, 0, 0, 0);
69 assert(hrgn != 0);
70
71 hdc = GetDC(hwnd);
72 ok(hdc != NULL, "GetDC failed\n");
73
74 ret = GetClipBox(hdc, &rc_clip);
75 ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
76 ret = GetClipRgn(hdc, hrgn);
77 ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
78 ret = GetRgnBox(hrgn, &rc);
79 ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
80 ret, rc.left, rc.top, rc.right, rc.bottom);
81 /*dump_region(hrgn);*/
82 SetRect(&rc, 0, 0, 100, 100);
83 ok(EqualRect(&rc, &rc_clip),
84 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
85 rc.left, rc.top, rc.right, rc.bottom,
86 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
87
88 ret = SaveDC(hdc);
89 todo_wine
90 {
91 ok(ret == 1, "ret = %d\n", ret);
92 }
93
94 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
95 if (ret == COMPLEXREGION)
96 {
97 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
98 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
99 /* let's make sure that it's a simple region */
100 ret = GetClipRgn(hdc, hrgn);
101 ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
102 dump_region(hrgn);
103 }
104 else
105 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
106
107 ret = GetClipBox(hdc, &rc_clip);
108 ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
109 SetRect(&rc, 0, 0, 50, 50);
110 ok(EqualRect(&rc, &rc_clip), "rects are not equal\n");
111
112 ret = RestoreDC(hdc, 1);
113 ok(ret, "ret = %d\n", ret);
114
115 ret = GetClipBox(hdc, &rc_clip);
116 ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
117 SetRect(&rc, 0, 0, 100, 100);
118 ok(EqualRect(&rc, &rc_clip), "rects are not equal\n");
119
120 DeleteObject(hrgn);
121 ReleaseDC(hwnd, hdc);
122 DestroyWindow(hwnd);
123 }
124
125 static void test_savedc(void)
126 {
127 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
128 int ret;
129
130 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
131
132 ret = SaveDC(hdc);
133 ok(ret == 1, "ret = %d\n", ret);
134 ret = SaveDC(hdc);
135 ok(ret == 2, "ret = %d\n", ret);
136 ret = SaveDC(hdc);
137 ok(ret == 3, "ret = %d\n", ret);
138 ret = RestoreDC(hdc, -1);
139 ok(ret, "ret = %d\n", ret);
140 ret = SaveDC(hdc);
141 ok(ret == 3, "ret = %d\n", ret);
142 ret = RestoreDC(hdc, 1);
143 ok(ret, "ret = %d\n", ret);
144 ret = SaveDC(hdc);
145 ok(ret == 1, "ret = %d\n", ret);
146 ret = SaveDC(hdc);
147 ok(ret == 2, "ret = %d\n", ret);
148 ret = SaveDC(hdc);
149 ok(ret == 3, "ret = %d\n", ret);
150 ret = RestoreDC(hdc, -2);
151 ok(ret, "ret = %d\n", ret);
152 ret = SaveDC(hdc);
153 ok(ret == 2, "ret = %d\n", ret);
154 ret = RestoreDC(hdc, -2);
155 ok(ret, "ret = %d\n", ret);
156 ret = SaveDC(hdc);
157 ok(ret == 1, "ret = %d\n", ret);
158 ret = SaveDC(hdc);
159 ok(ret == 2, "ret = %d\n", ret);
160 ret = RestoreDC(hdc, -4);
161 ok(!ret, "ret = %d\n", ret);
162 ret = RestoreDC(hdc, 3);
163 ok(!ret, "ret = %d\n", ret);
164
165 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
166 ret = RestoreDC(hdc, -3);
167 ok(!ret ||
168 broken(ret), /* Win9x */
169 "ret = %d\n", ret);
170
171 /* Trying to clear an empty save stack fails. */
172 ret = RestoreDC(hdc, -3);
173 ok(!ret, "ret = %d\n", ret);
174
175 ret = SaveDC(hdc);
176 ok(ret == 3 ||
177 broken(ret == 1), /* Win9x */
178 "ret = %d\n", ret);
179
180 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
181 ret = RestoreDC(hdc, 0);
182 ok(!ret ||
183 broken(ret), /* Win9x */
184 "ret = %d\n", ret);
185
186 /* Trying to clear an empty save stack fails. */
187 ret = RestoreDC(hdc, 0);
188 ok(!ret, "ret = %d\n", ret);
189
190 ret = RestoreDC(hdc, 1);
191 ok(ret ||
192 broken(!ret), /* Win9x */
193 "ret = %d\n", ret);
194
195 DeleteDC(hdc);
196 }
197
198 static void test_GdiConvertToDevmodeW(void)
199 {
200 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
201 DEVMODEA dmA;
202 DEVMODEW *dmW;
203 BOOL ret;
204
205 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
206 if (!pGdiConvertToDevmodeW)
207 {
208 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
209 return;
210 }
211
212 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dmA);
213 ok(ret, "EnumDisplaySettingsExA error %u\n", GetLastError());
214 ok(dmA.dmSize >= FIELD_OFFSET(DEVMODEA, dmICMMethod), "dmSize is too small: %04x\n", dmA.dmSize);
215 ok(dmA.dmSize <= sizeof(DEVMODEA), "dmSize is too large: %04x\n", dmA.dmSize);
216
217 dmW = pGdiConvertToDevmodeW(&dmA);
218 ok(dmW->dmSize >= FIELD_OFFSET(DEVMODEW, dmICMMethod), "dmSize is too small: %04x\n", dmW->dmSize);
219 ok(dmW->dmSize <= sizeof(DEVMODEW), "dmSize is too large: %04x\n", dmW->dmSize);
220 HeapFree(GetProcessHeap(), 0, dmW);
221
222 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + sizeof(dmA.dmFields);
223 dmW = pGdiConvertToDevmodeW(&dmA);
224 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dmW->dmFields),
225 "wrong size %u\n", dmW->dmSize);
226 HeapFree(GetProcessHeap(), 0, dmW);
227
228 dmA.dmICMMethod = DMICMMETHOD_NONE;
229 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod) + sizeof(dmA.dmICMMethod);
230 dmW = pGdiConvertToDevmodeW(&dmA);
231 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod) + sizeof(dmW->dmICMMethod),
232 "wrong size %u\n", dmW->dmSize);
233 ok(dmW->dmICMMethod == DMICMMETHOD_NONE,
234 "expected DMICMMETHOD_NONE, got %u\n", dmW->dmICMMethod);
235 HeapFree(GetProcessHeap(), 0, dmW);
236
237 dmA.dmSize = 1024;
238 dmW = pGdiConvertToDevmodeW(&dmA);
239 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmPanningHeight) + sizeof(dmW->dmPanningHeight),
240 "wrong size %u\n", dmW->dmSize);
241 HeapFree(GetProcessHeap(), 0, dmW);
242
243 SetLastError(0xdeadbeef);
244 dmA.dmSize = 0;
245 dmW = pGdiConvertToDevmodeW(&dmA);
246 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
247 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
248
249 /* this is the minimal dmSize that XP accepts */
250 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
251 dmW = pGdiConvertToDevmodeW(&dmA);
252 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields),
253 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW, dmFields), dmW->dmSize);
254 HeapFree(GetProcessHeap(), 0, dmW);
255 }
256
257 static void test_CreateCompatibleDC(void)
258 {
259 BOOL bRet;
260 HDC hDC;
261 HDC hNewDC;
262
263 /* Create a DC compatible with the screen */
264 hDC = CreateCompatibleDC(NULL);
265 ok(hDC != NULL, "CreateCompatibleDC returned %p\n", hDC);
266
267 /* Delete this DC, this should succeed */
268 bRet = DeleteDC(hDC);
269 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
270
271 /* Try to create a DC compatible to the deleted DC. This has to fail */
272 hNewDC = CreateCompatibleDC(hDC);
273 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
274 }
275
276 static void test_DC_bitmap(void)
277 {
278 HDC hdc, hdcmem;
279 DWORD bits[64];
280 HBITMAP hbmp, oldhbmp;
281 COLORREF col;
282 int i, bitspixel;
283
284 /* fill bitmap data with b&w pattern */
285 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
286
287 hdc = GetDC(0);
288 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
289 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
290 /* create a memory dc */
291 hdcmem = CreateCompatibleDC( hdc);
292 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
293 /* tests */
294 /* test monochrome bitmap: should always work */
295 hbmp = CreateBitmap(32, 32, 1, 1, bits);
296 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
297 oldhbmp = SelectObject( hdcmem, hbmp);
298 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
299 col = GetPixel( hdcmem, 0, 0);
300 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
301 col = GetPixel( hdcmem, 1, 1);
302 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
303 col = GetPixel( hdcmem, 100, 1);
304 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
305 SelectObject( hdcmem, oldhbmp);
306 DeleteObject( hbmp);
307
308 /* test with 2 bits color depth, not likely to succeed */
309 hbmp = CreateBitmap(16, 16, 1, 2, bits);
310 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
311 oldhbmp = SelectObject( hdcmem, hbmp);
312 if( bitspixel != 2)
313 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
314 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
315 DeleteObject( hbmp);
316
317 /* test with 16 bits color depth, might succeed */
318 hbmp = CreateBitmap(6, 6, 1, 16, bits);
319 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
320 oldhbmp = SelectObject( hdcmem, hbmp);
321 if( bitspixel == 16) {
322 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
323 col = GetPixel( hdcmem, 0, 0);
324 ok( col == 0xffffff,
325 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
326 col = GetPixel( hdcmem, 1, 1);
327 ok( col == 0x000000,
328 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
329 }
330 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
331 DeleteObject( hbmp);
332
333 /* test with 32 bits color depth, probably succeed */
334 hbmp = CreateBitmap(4, 4, 1, 32, bits);
335 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
336 oldhbmp = SelectObject( hdcmem, hbmp);
337 if( bitspixel == 32) {
338 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
339 col = GetPixel( hdcmem, 0, 0);
340 ok( col == 0xffffff,
341 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
342 col = GetPixel( hdcmem, 1, 1);
343 ok( col == 0x000000,
344 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
345 }
346 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
347 DeleteObject( hbmp);
348 ReleaseDC( 0, hdc );
349 }
350
351 static void test_DeleteDC(void)
352 {
353 HWND hwnd;
354 HDC hdc, hdc_test;
355 WNDCLASSEX cls;
356 int ret;
357
358 /* window DC */
359 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
360 0, 0, 0, NULL);
361 ok(hwnd != 0, "CreateWindowExA failed\n");
362
363 hdc = GetDC(hwnd);
364 ok(hdc != 0, "GetDC failed\n");
365 ret = GetObjectType(hdc);
366 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
367 ret = DeleteDC(hdc);
368 ok(ret, "DeleteDC failed\n");
369 ret = GetObjectType(hdc);
370 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
371
372 hdc = GetWindowDC(hwnd);
373 ok(hdc != 0, "GetDC failed\n");
374 ret = GetObjectType(hdc);
375 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
376 ret = DeleteDC(hdc);
377 ok(ret, "DeleteDC failed\n");
378 ret = GetObjectType(hdc);
379 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
380
381 DestroyWindow(hwnd);
382
383 /* desktop window DC */
384 hwnd = GetDesktopWindow();
385 ok(hwnd != 0, "GetDesktopWindow failed\n");
386
387 hdc = GetDC(hwnd);
388 ok(hdc != 0, "GetDC failed\n");
389 ret = GetObjectType(hdc);
390 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
391 ret = DeleteDC(hdc);
392 ok(ret, "DeleteDC failed\n");
393 ret = GetObjectType(hdc);
394 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
395
396 hdc = GetWindowDC(hwnd);
397 ok(hdc != 0, "GetDC failed\n");
398 ret = GetObjectType(hdc);
399 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
400 ret = DeleteDC(hdc);
401 ok(ret, "DeleteDC failed\n");
402 ret = GetObjectType(hdc);
403 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
404
405 /* CS_CLASSDC */
406 memset(&cls, 0, sizeof(cls));
407 cls.cbSize = sizeof(cls);
408 cls.style = CS_CLASSDC;
409 cls.hInstance = GetModuleHandle(0);
410 cls.lpszClassName = "Wine class DC";
411 cls.lpfnWndProc = DefWindowProcA;
412 ret = RegisterClassExA(&cls);
413 ok(ret, "RegisterClassExA failed\n");
414
415 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
416 0, 0, 0, NULL);
417 ok(hwnd != 0, "CreateWindowExA failed\n");
418
419 hdc = GetDC(hwnd);
420 ok(hdc != 0, "GetDC failed\n");
421 ret = GetObjectType(hdc);
422 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
423 ret = DeleteDC(hdc);
424 ok(ret, "DeleteDC failed\n");
425 ret = GetObjectType(hdc);
426 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
427 ret = ReleaseDC(hwnd, hdc);
428 ok(ret, "ReleaseDC failed\n");
429 ret = GetObjectType(hdc);
430 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
431
432 hdc_test = hdc;
433
434 hdc = GetWindowDC(hwnd);
435 ok(hdc != 0, "GetDC failed\n");
436 ret = GetObjectType(hdc);
437 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
438 ret = DeleteDC(hdc);
439 ok(ret, "DeleteDC failed\n");
440 ret = GetObjectType(hdc);
441 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
442
443 DestroyWindow(hwnd);
444
445 ret = GetObjectType(hdc_test);
446 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
447
448 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
449 ok(ret, "UnregisterClassA failed\n");
450
451 ret = GetObjectType(hdc_test);
452 todo_wine
453 ok(!ret, "GetObjectType should fail for a deleted DC\n");
454
455 /* CS_OWNDC */
456 memset(&cls, 0, sizeof(cls));
457 cls.cbSize = sizeof(cls);
458 cls.style = CS_OWNDC;
459 cls.hInstance = GetModuleHandle(0);
460 cls.lpszClassName = "Wine own DC";
461 cls.lpfnWndProc = DefWindowProcA;
462 ret = RegisterClassExA(&cls);
463 ok(ret, "RegisterClassExA failed\n");
464
465 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
466 0, 0, 0, NULL);
467 ok(hwnd != 0, "CreateWindowExA failed\n");
468
469 hdc = GetDC(hwnd);
470 ok(hdc != 0, "GetDC failed\n");
471 ret = GetObjectType(hdc);
472 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
473 ret = DeleteDC(hdc);
474 ok(ret, "DeleteDC failed\n");
475 ret = GetObjectType(hdc);
476 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
477 ret = ReleaseDC(hwnd, hdc);
478 ok(ret, "ReleaseDC failed\n");
479 ret = GetObjectType(hdc);
480 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
481
482 hdc = GetWindowDC(hwnd);
483 ok(hdc != 0, "GetDC failed\n");
484 ret = GetObjectType(hdc);
485 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
486 ret = DeleteDC(hdc);
487 ok(ret, "DeleteDC failed\n");
488 ret = GetObjectType(hdc);
489 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
490
491 DestroyWindow(hwnd);
492
493 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
494 ok(ret, "UnregisterClassA failed\n");
495 }
496
497 static void test_boundsrect_invalid(void)
498 {
499 HDC hdc;
500 RECT rect, expect;
501 UINT ret;
502
503 hdc = GetDC(NULL);
504 ok(hdc != NULL, "GetDC failed\n");
505
506 ret = GetBoundsRect(hdc, NULL, 0);
507 ok(ret == 0 ||
508 broken(ret == DCB_RESET), /* Win9x */
509 "Expected GetBoundsRect to return 0, got %u\n", ret);
510
511 ret = GetBoundsRect(hdc, NULL, ~0U);
512 ok(ret == 0 ||
513 broken(ret == DCB_RESET), /* Win9x */
514 "Expected GetBoundsRect to return 0, got %u\n", ret);
515
516 if (GetBoundsRect(hdc, NULL, 0) == DCB_RESET)
517 win_skip("Win9x fails catastrophically with first GetBoundsRect call\n");
518 else
519 {
520 /* Test parameter handling order. */
521 SetRect(&rect, 0, 0, 50, 50);
522 ret = SetBoundsRect(hdc, &rect, DCB_SET);
523 ok(ret & DCB_RESET,
524 "Expected return flag DCB_RESET to be set, got %u\n", ret);
525
526 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
527 ok(ret == 0,
528 "Expected GetBoundsRect to return 0, got %u\n", ret);
529
530 ret = GetBoundsRect(hdc, &rect, 0);
531 ok(ret == DCB_RESET,
532 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
533 SetRect(&expect, 0, 0, 0, 0);
534 ok(EqualRect(&rect, &expect),
535 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
536 rect.left, rect.top, rect.right, rect.bottom);
537 }
538
539 if (GetBoundsRect(hdc, NULL, 0) == DCB_RESET)
540 win_skip("Win9x fails catastrophically with NULL device context parameter\n");
541 else
542 {
543 ret = GetBoundsRect(NULL, NULL, 0);
544 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
545
546 ret = GetBoundsRect(NULL, NULL, ~0U);
547 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
548
549 ret = SetBoundsRect(NULL, NULL, 0);
550 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
551
552 ret = SetBoundsRect(NULL, NULL, ~0U);
553 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
554 }
555
556 DeleteDC(hdc);
557 }
558
559 static void test_desktop_colorres(void)
560 {
561 HDC hdc = GetDC(NULL);
562 int bitspixel, colorres;
563
564 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
565 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
566
567 colorres = GetDeviceCaps(hdc, COLORRES);
568 ok(colorres != 0 ||
569 broken(colorres == 0), /* Win9x */
570 "Expected to get valid COLORRES capability value\n");
571
572 if (colorres)
573 {
574 switch (bitspixel)
575 {
576 case 8:
577 ok(colorres == 18,
578 "Expected COLORRES to be 18, got %d\n", colorres);
579 break;
580 case 16:
581 ok(colorres == 16,
582 "Expected COLORRES to be 16, got %d\n", colorres);
583 break;
584 case 24:
585 case 32:
586 ok(colorres == 24,
587 "Expected COLORRES to be 24, got %d\n", bitspixel);
588 break;
589 default:
590 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
591 break;
592 }
593 }
594
595 DeleteDC(hdc);
596 }
597
598 START_TEST(dc)
599 {
600 test_savedc();
601 test_savedc_2();
602 test_GdiConvertToDevmodeW();
603 test_CreateCompatibleDC();
604 test_DC_bitmap();
605 test_DeleteDC();
606 test_boundsrect_invalid();
607 test_desktop_colorres();
608 }