2 * Unit tests for dc functions
4 * Copyright (c) 2005 Huw Davies
5 * Copyright (c) 2005 Dmitry Timoshkov
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.
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.
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
22 #define WINVER 0x0501 /* request latest DEVMODE */
27 #include "wine/test.h"
33 static void dump_region(HRGN hrgn)
41 printf( "(null) region\n" );
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 );
51 HeapFree( GetProcessHeap(), 0, data );
54 static void test_savedc_2(void)
62 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
65 ShowWindow(hwnd, SW_SHOW);
68 hrgn = CreateRectRgn(0, 0, 0, 0);
72 ok(hdc != NULL, "GetDC failed\n");
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);
91 ok(ret == 1, "ret = %d\n", ret);
94 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
95 if (ret == COMPLEXREGION)
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);
105 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
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");
112 ret = RestoreDC(hdc, 1);
113 ok(ret, "ret = %d\n", ret);
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");
121 ReleaseDC(hwnd, hdc);
125 static void test_savedc(void)
127 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
130 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
133 ok(ret == 1, "ret = %d\n", ret);
135 ok(ret == 2, "ret = %d\n", ret);
137 ok(ret == 3, "ret = %d\n", ret);
138 ret = RestoreDC(hdc, -1);
139 ok(ret, "ret = %d\n", ret);
141 ok(ret == 3, "ret = %d\n", ret);
142 ret = RestoreDC(hdc, 1);
143 ok(ret, "ret = %d\n", ret);
145 ok(ret == 1, "ret = %d\n", ret);
147 ok(ret == 2, "ret = %d\n", ret);
149 ok(ret == 3, "ret = %d\n", ret);
150 ret = RestoreDC(hdc, -2);
151 ok(ret, "ret = %d\n", ret);
153 ok(ret == 2, "ret = %d\n", ret);
154 ret = RestoreDC(hdc, -2);
155 ok(ret, "ret = %d\n", ret);
157 ok(ret == 1, "ret = %d\n", ret);
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);
165 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
166 ret = RestoreDC(hdc, -3);
168 broken(ret), /* Win9x */
171 /* Trying to clear an empty save stack fails. */
172 ret = RestoreDC(hdc, -3);
173 ok(!ret, "ret = %d\n", ret);
177 broken(ret == 1), /* Win9x */
180 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
181 ret = RestoreDC(hdc, 0);
183 broken(ret), /* Win9x */
186 /* Trying to clear an empty save stack fails. */
187 ret = RestoreDC(hdc, 0);
188 ok(!ret, "ret = %d\n", ret);
190 ret = RestoreDC(hdc, 1);
192 broken(!ret), /* Win9x */
198 static void test_GdiConvertToDevmodeW(void)
200 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
205 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
206 if (!pGdiConvertToDevmodeW)
208 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
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);
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);
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);
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);
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);
243 SetLastError(0xdeadbeef);
245 dmW = pGdiConvertToDevmodeW(&dmA);
246 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
247 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
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);
257 static void test_CreateCompatibleDC(void)
263 /* Create a DC compatible with the screen */
264 hDC = CreateCompatibleDC(NULL);
265 ok(hDC != NULL, "CreateCompatibleDC returned %p\n", hDC);
267 /* Delete this DC, this should succeed */
268 bRet = DeleteDC(hDC);
269 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
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);
276 static void test_DC_bitmap(void)
280 HBITMAP hbmp, oldhbmp;
284 /* fill bitmap data with b&w pattern */
285 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
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);
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);
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);
313 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
314 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
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);
325 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
326 col = GetPixel( hdcmem, 1, 1);
328 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
330 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
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);
341 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
342 col = GetPixel( hdcmem, 1, 1);
344 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
346 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
351 static void test_DeleteDC(void)
359 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
361 ok(hwnd != 0, "CreateWindowExA failed\n");
364 ok(hdc != 0, "GetDC failed\n");
365 ret = GetObjectType(hdc);
366 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
368 ok(ret, "DeleteDC failed\n");
369 ret = GetObjectType(hdc);
370 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
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);
377 ok(ret, "DeleteDC failed\n");
378 ret = GetObjectType(hdc);
379 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
383 /* desktop window DC */
384 hwnd = GetDesktopWindow();
385 ok(hwnd != 0, "GetDesktopWindow failed\n");
388 ok(hdc != 0, "GetDC failed\n");
389 ret = GetObjectType(hdc);
390 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
392 ok(ret, "DeleteDC failed\n");
393 ret = GetObjectType(hdc);
394 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
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);
401 ok(ret, "DeleteDC failed\n");
402 ret = GetObjectType(hdc);
403 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
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");
415 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
417 ok(hwnd != 0, "CreateWindowExA failed\n");
420 ok(hdc != 0, "GetDC failed\n");
421 ret = GetObjectType(hdc);
422 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
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);
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);
439 ok(ret, "DeleteDC failed\n");
440 ret = GetObjectType(hdc);
441 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
445 ret = GetObjectType(hdc_test);
446 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
448 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
449 ok(ret, "UnregisterClassA failed\n");
451 ret = GetObjectType(hdc_test);
453 ok(!ret, "GetObjectType should fail for a deleted DC\n");
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");
465 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
467 ok(hwnd != 0, "CreateWindowExA failed\n");
470 ok(hdc != 0, "GetDC failed\n");
471 ret = GetObjectType(hdc);
472 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
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);
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);
487 ok(ret, "DeleteDC failed\n");
488 ret = GetObjectType(hdc);
489 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
493 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
494 ok(ret, "UnregisterClassA failed\n");
497 static void test_boundsrect_invalid(void)
504 ok(hdc != NULL, "GetDC failed\n");
506 ret = GetBoundsRect(hdc, NULL, 0);
508 broken(ret == DCB_RESET), /* Win9x */
509 "Expected GetBoundsRect to return 0, got %u\n", ret);
511 ret = GetBoundsRect(hdc, NULL, ~0U);
513 broken(ret == DCB_RESET), /* Win9x */
514 "Expected GetBoundsRect to return 0, got %u\n", ret);
516 if (GetBoundsRect(hdc, NULL, 0) == DCB_RESET)
517 win_skip("Win9x fails catastrophically with first GetBoundsRect call\n");
520 /* Test parameter handling order. */
521 SetRect(&rect, 0, 0, 50, 50);
522 ret = SetBoundsRect(hdc, &rect, DCB_SET);
524 "Expected return flag DCB_RESET to be set, got %u\n", ret);
526 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
528 "Expected GetBoundsRect to return 0, got %u\n", ret);
530 ret = GetBoundsRect(hdc, &rect, 0);
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);
539 if (GetBoundsRect(hdc, NULL, 0) == DCB_RESET)
540 win_skip("Win9x fails catastrophically with NULL device context parameter\n");
543 ret = GetBoundsRect(NULL, NULL, 0);
544 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
546 ret = GetBoundsRect(NULL, NULL, ~0U);
547 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
549 ret = SetBoundsRect(NULL, NULL, 0);
550 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
552 ret = SetBoundsRect(NULL, NULL, ~0U);
553 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
559 static void test_desktop_colorres(void)
561 HDC hdc = GetDC(NULL);
562 int bitspixel, colorres;
564 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
565 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
567 colorres = GetDeviceCaps(hdc, COLORRES);
569 broken(colorres == 0), /* Win9x */
570 "Expected to get valid COLORRES capability value\n");
578 "Expected COLORRES to be 18, got %d\n", colorres);
582 "Expected COLORRES to be 16, got %d\n", colorres);
587 "Expected COLORRES to be 24, got %d\n", bitspixel);
590 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
602 test_GdiConvertToDevmodeW();
603 test_CreateCompatibleDC();
606 test_boundsrect_invalid();
607 test_desktop_colorres();