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"
34 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
36 static void dump_region(HRGN hrgn)
44 printf( "(null) region\n" );
47 if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
48 if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
49 GetRegionData( hrgn, size, data );
50 printf( "%d rects:", data->rdh.nCount );
51 for (i = 0, rect = (RECT *)data->Buffer; i < data->rdh.nCount; i++, rect++)
52 printf( " (%d,%d)-(%d,%d)", rect->left, rect->top, rect->right, rect->bottom );
54 HeapFree( GetProcessHeap(), 0, data );
57 static void test_savedc_2(void)
65 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
68 ShowWindow(hwnd, SW_SHOW);
71 hrgn = CreateRectRgn(0, 0, 0, 0);
75 ok(hdc != NULL, "GetDC failed\n");
77 ret = GetClipBox(hdc, &rc_clip);
78 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
79 ret = GetClipRgn(hdc, hrgn);
80 ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
81 ret = GetRgnBox(hrgn, &rc);
82 ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
83 ret, rc.left, rc.top, rc.right, rc.bottom);
84 /*dump_region(hrgn);*/
85 SetRect(&rc, 0, 0, 100, 100);
86 ok(EqualRect(&rc, &rc_clip),
87 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
88 rc.left, rc.top, rc.right, rc.bottom,
89 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
94 ok(ret == 1, "ret = %d\n", ret);
97 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
98 if (ret == COMPLEXREGION)
100 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
101 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
102 /* let's make sure that it's a simple region */
103 ret = GetClipRgn(hdc, hrgn);
104 ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
108 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
110 ret = GetClipBox(hdc, &rc_clip);
111 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
112 SetRect(&rc, 0, 0, 50, 50);
113 ok(EqualRect(&rc, &rc_clip),
114 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
115 rc.left, rc.top, rc.right, rc.bottom,
116 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
118 ret = RestoreDC(hdc, 1);
119 ok(ret, "ret = %d\n", ret);
121 ret = GetClipBox(hdc, &rc_clip);
122 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
123 SetRect(&rc, 0, 0, 100, 100);
124 ok(EqualRect(&rc, &rc_clip),
125 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
126 rc.left, rc.top, rc.right, rc.bottom,
127 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
130 ReleaseDC(hwnd, hdc);
134 static void test_savedc(void)
136 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
139 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
142 ok(ret == 1, "ret = %d\n", ret);
144 ok(ret == 2, "ret = %d\n", ret);
146 ok(ret == 3, "ret = %d\n", ret);
147 ret = RestoreDC(hdc, -1);
148 ok(ret, "ret = %d\n", ret);
150 ok(ret == 3, "ret = %d\n", ret);
151 ret = RestoreDC(hdc, 1);
152 ok(ret, "ret = %d\n", ret);
154 ok(ret == 1, "ret = %d\n", ret);
156 ok(ret == 2, "ret = %d\n", ret);
158 ok(ret == 3, "ret = %d\n", ret);
159 ret = RestoreDC(hdc, -2);
160 ok(ret, "ret = %d\n", ret);
162 ok(ret == 2, "ret = %d\n", ret);
163 ret = RestoreDC(hdc, -2);
164 ok(ret, "ret = %d\n", ret);
166 ok(ret == 1, "ret = %d\n", ret);
168 ok(ret == 2, "ret = %d\n", ret);
169 ret = RestoreDC(hdc, -4);
170 ok(!ret, "ret = %d\n", ret);
171 ret = RestoreDC(hdc, 3);
172 ok(!ret, "ret = %d\n", ret);
174 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
175 ret = RestoreDC(hdc, -3);
177 broken(ret), /* Win9x */
180 /* Trying to clear an empty save stack fails. */
181 ret = RestoreDC(hdc, -3);
182 ok(!ret, "ret = %d\n", ret);
186 broken(ret == 1), /* Win9x */
189 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
190 ret = RestoreDC(hdc, 0);
192 broken(ret), /* Win9x */
195 /* Trying to clear an empty save stack fails. */
196 ret = RestoreDC(hdc, 0);
197 ok(!ret, "ret = %d\n", ret);
199 ret = RestoreDC(hdc, 1);
201 broken(!ret), /* Win9x */
207 static void test_GdiConvertToDevmodeW(void)
209 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
214 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
215 if (!pGdiConvertToDevmodeW)
217 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
221 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dmA);
222 ok(ret, "EnumDisplaySettingsExA error %u\n", GetLastError());
223 ok(dmA.dmSize >= FIELD_OFFSET(DEVMODEA, dmICMMethod), "dmSize is too small: %04x\n", dmA.dmSize);
224 ok(dmA.dmSize <= sizeof(DEVMODEA), "dmSize is too large: %04x\n", dmA.dmSize);
226 dmW = pGdiConvertToDevmodeW(&dmA);
227 ok(dmW->dmSize >= FIELD_OFFSET(DEVMODEW, dmICMMethod), "dmSize is too small: %04x\n", dmW->dmSize);
228 ok(dmW->dmSize <= sizeof(DEVMODEW), "dmSize is too large: %04x\n", dmW->dmSize);
229 HeapFree(GetProcessHeap(), 0, dmW);
231 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + sizeof(dmA.dmFields);
232 dmW = pGdiConvertToDevmodeW(&dmA);
233 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dmW->dmFields),
234 "wrong size %u\n", dmW->dmSize);
235 HeapFree(GetProcessHeap(), 0, dmW);
237 dmA.dmICMMethod = DMICMMETHOD_NONE;
238 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod) + sizeof(dmA.dmICMMethod);
239 dmW = pGdiConvertToDevmodeW(&dmA);
240 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod) + sizeof(dmW->dmICMMethod),
241 "wrong size %u\n", dmW->dmSize);
242 ok(dmW->dmICMMethod == DMICMMETHOD_NONE,
243 "expected DMICMMETHOD_NONE, got %u\n", dmW->dmICMMethod);
244 HeapFree(GetProcessHeap(), 0, dmW);
247 dmW = pGdiConvertToDevmodeW(&dmA);
248 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmPanningHeight) + sizeof(dmW->dmPanningHeight),
249 "wrong size %u\n", dmW->dmSize);
250 HeapFree(GetProcessHeap(), 0, dmW);
252 SetLastError(0xdeadbeef);
254 dmW = pGdiConvertToDevmodeW(&dmA);
255 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
256 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
258 /* this is the minimal dmSize that XP accepts */
259 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
260 dmW = pGdiConvertToDevmodeW(&dmA);
261 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields),
262 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW, dmFields), dmW->dmSize);
263 HeapFree(GetProcessHeap(), 0, dmW);
266 static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr )
268 static const int caps[] =
313 if (GetObjectType( hdc ) == OBJ_METADC)
314 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
315 ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
316 "wrong caps on %s for %u: %u\n", descr, caps[i],
317 GetDeviceCaps( hdc, caps[i] ) );
319 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
320 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
321 "mismatched caps on %s for %u: %u/%u\n", descr, caps[i],
322 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
324 if (GetObjectType( hdc ) == OBJ_MEMDC)
326 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
327 BITMAPINFO *info = (BITMAPINFO *)buffer;
330 memset( buffer, 0, sizeof(buffer) );
331 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
332 info->bmiHeader.biWidth = 16;
333 info->bmiHeader.biHeight = 16;
334 info->bmiHeader.biPlanes = 1;
335 info->bmiHeader.biBitCount = 8;
336 info->bmiHeader.biCompression = BI_RGB;
337 dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
338 old = SelectObject( hdc, dib );
340 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
341 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
342 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
343 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
345 SelectObject( hdc, old );
350 static void test_CreateCompatibleDC(void)
353 HDC hdc, hNewDC, hdcMetafile, screen_dc;
357 screen_dc = GetDC( 0 );
358 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
360 /* Create a DC compatible with the screen */
361 hdc = CreateCompatibleDC(NULL);
362 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
363 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
364 caps = GetDeviceCaps( hdc, TECHNOLOGY );
365 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
367 test_device_caps( hdc, screen_dc, "display dc" );
369 /* Delete this DC, this should succeed */
370 bRet = DeleteDC(hdc);
371 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
373 /* Try to create a DC compatible to the deleted DC. This has to fail */
374 hNewDC = CreateCompatibleDC(hdc);
375 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
378 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
379 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
380 hNewDC = CreateCompatibleDC( hdcMetafile );
381 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
382 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
383 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
384 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
385 caps = GetDeviceCaps( hNewDC, TECHNOLOGY );
386 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
388 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
391 hdcMetafile = CreateMetaFileA(NULL);
392 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
393 hNewDC = CreateCompatibleDC( hdcMetafile );
394 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
395 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
396 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
397 test_device_caps( hdcMetafile, screen_dc, "metafile dc" );
398 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
400 DeleteObject( bitmap );
401 ReleaseDC( 0, screen_dc );
404 static void test_DC_bitmap(void)
408 HBITMAP hbmp, oldhbmp;
412 /* fill bitmap data with b&w pattern */
413 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
416 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
417 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
418 /* create a memory dc */
419 hdcmem = CreateCompatibleDC( hdc);
420 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
422 /* test monochrome bitmap: should always work */
423 hbmp = CreateBitmap(32, 32, 1, 1, bits);
424 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
425 oldhbmp = SelectObject( hdcmem, hbmp);
426 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
427 col = GetPixel( hdcmem, 0, 0);
428 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
429 col = GetPixel( hdcmem, 1, 1);
430 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
431 col = GetPixel( hdcmem, 100, 1);
432 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
433 SelectObject( hdcmem, oldhbmp);
436 /* test with 2 bits color depth, not likely to succeed */
437 hbmp = CreateBitmap(16, 16, 1, 2, bits);
438 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
439 oldhbmp = SelectObject( hdcmem, hbmp);
441 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
442 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
445 /* test with 16 bits color depth, might succeed */
446 hbmp = CreateBitmap(6, 6, 1, 16, bits);
447 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
448 oldhbmp = SelectObject( hdcmem, hbmp);
449 if( bitspixel == 16) {
450 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
451 col = GetPixel( hdcmem, 0, 0);
453 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
454 col = GetPixel( hdcmem, 1, 1);
456 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
458 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
461 /* test with 32 bits color depth, probably succeed */
462 hbmp = CreateBitmap(4, 4, 1, 32, bits);
463 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
464 oldhbmp = SelectObject( hdcmem, hbmp);
465 if( bitspixel == 32) {
466 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
467 col = GetPixel( hdcmem, 0, 0);
469 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
470 col = GetPixel( hdcmem, 1, 1);
472 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
474 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
479 static void test_DeleteDC(void)
487 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
489 ok(hwnd != 0, "CreateWindowExA failed\n");
492 ok(hdc != 0, "GetDC failed\n");
493 ret = GetObjectType(hdc);
494 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
496 ok(ret, "DeleteDC failed\n");
497 ret = GetObjectType(hdc);
498 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
500 hdc = GetWindowDC(hwnd);
501 ok(hdc != 0, "GetDC failed\n");
502 ret = GetObjectType(hdc);
503 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
505 ok(ret, "DeleteDC failed\n");
506 ret = GetObjectType(hdc);
507 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
511 /* desktop window DC */
512 hwnd = GetDesktopWindow();
513 ok(hwnd != 0, "GetDesktopWindow failed\n");
516 ok(hdc != 0, "GetDC failed\n");
517 ret = GetObjectType(hdc);
518 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
520 ok(ret, "DeleteDC failed\n");
521 ret = GetObjectType(hdc);
522 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
524 hdc = GetWindowDC(hwnd);
525 ok(hdc != 0, "GetDC failed\n");
526 ret = GetObjectType(hdc);
527 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
529 ok(ret, "DeleteDC failed\n");
530 ret = GetObjectType(hdc);
531 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
534 memset(&cls, 0, sizeof(cls));
535 cls.cbSize = sizeof(cls);
536 cls.style = CS_CLASSDC;
537 cls.hInstance = GetModuleHandle(0);
538 cls.lpszClassName = "Wine class DC";
539 cls.lpfnWndProc = DefWindowProcA;
540 ret = RegisterClassExA(&cls);
541 ok(ret, "RegisterClassExA failed\n");
543 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
545 ok(hwnd != 0, "CreateWindowExA failed\n");
548 ok(hdc != 0, "GetDC failed\n");
549 ret = GetObjectType(hdc);
550 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
552 ok(ret, "DeleteDC failed\n");
553 ret = GetObjectType(hdc);
554 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
555 ret = ReleaseDC(hwnd, hdc);
556 ok(ret, "ReleaseDC failed\n");
557 ret = GetObjectType(hdc);
558 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
562 hdc = GetWindowDC(hwnd);
563 ok(hdc != 0, "GetDC failed\n");
564 ret = GetObjectType(hdc);
565 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
567 ok(ret, "DeleteDC failed\n");
568 ret = GetObjectType(hdc);
569 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
573 ret = GetObjectType(hdc_test);
574 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
576 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
577 ok(ret, "UnregisterClassA failed\n");
579 ret = GetObjectType(hdc_test);
581 ok(!ret, "GetObjectType should fail for a deleted DC\n");
584 memset(&cls, 0, sizeof(cls));
585 cls.cbSize = sizeof(cls);
586 cls.style = CS_OWNDC;
587 cls.hInstance = GetModuleHandle(0);
588 cls.lpszClassName = "Wine own DC";
589 cls.lpfnWndProc = DefWindowProcA;
590 ret = RegisterClassExA(&cls);
591 ok(ret, "RegisterClassExA failed\n");
593 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
595 ok(hwnd != 0, "CreateWindowExA failed\n");
598 ok(hdc != 0, "GetDC failed\n");
599 ret = GetObjectType(hdc);
600 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
602 ok(ret, "DeleteDC failed\n");
603 ret = GetObjectType(hdc);
604 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
605 ret = ReleaseDC(hwnd, hdc);
606 ok(ret, "ReleaseDC failed\n");
607 ret = GetObjectType(hdc);
608 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
610 hdc = GetWindowDC(hwnd);
611 ok(hdc != 0, "GetDC failed\n");
612 ret = GetObjectType(hdc);
613 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
615 ok(ret, "DeleteDC failed\n");
616 ret = GetObjectType(hdc);
617 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
621 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
622 ok(ret, "UnregisterClassA failed\n");
625 static void test_boundsrect(void)
629 RECT rect, expect, set_rect;
632 hdc = CreateCompatibleDC(0);
633 ok(hdc != NULL, "CreateCompatibleDC failed\n");
634 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
635 SelectObject( hdc, bitmap );
637 ret = GetBoundsRect(hdc, NULL, 0);
638 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
640 ret = GetBoundsRect(hdc, NULL, ~0U);
641 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
643 /* Test parameter handling order. */
644 SetRect(&set_rect, 10, 20, 40, 50);
645 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
647 "Expected return flag DCB_RESET to be set, got %u\n", ret);
649 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
651 "Expected GetBoundsRect to return 0, got %u\n", ret);
653 ret = GetBoundsRect(hdc, &rect, 0);
655 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
656 SetRect(&expect, 0, 0, 0, 0);
657 ok(EqualRect(&rect, &expect) ||
658 broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
659 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
660 rect.left, rect.top, rect.right, rect.bottom);
662 ret = GetBoundsRect(NULL, NULL, 0);
663 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
665 ret = GetBoundsRect(NULL, NULL, ~0U);
666 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
668 ret = SetBoundsRect(NULL, NULL, 0);
669 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
671 ret = SetBoundsRect(NULL, NULL, ~0U);
672 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
674 SetRect(&set_rect, 10, 20, 40, 50);
675 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
676 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
678 ret = GetBoundsRect(hdc, &rect, 0);
679 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
680 SetRect(&expect, 10, 20, 40, 50);
681 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
682 rect.left, rect.top, rect.right, rect.bottom);
684 SetMapMode( hdc, MM_ANISOTROPIC );
685 SetViewportExtEx( hdc, 2, 2, NULL );
686 ret = GetBoundsRect(hdc, &rect, 0);
687 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
688 SetRect(&expect, 5, 10, 20, 25);
689 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
690 rect.left, rect.top, rect.right, rect.bottom);
692 SetViewportOrgEx( hdc, 20, 30, NULL );
693 ret = GetBoundsRect(hdc, &rect, 0);
694 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
695 SetRect(&expect, -5, -5, 10, 10);
696 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
697 rect.left, rect.top, rect.right, rect.bottom);
699 SetRect(&set_rect, 10, 20, 40, 50);
700 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
701 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
703 ret = GetBoundsRect(hdc, &rect, 0);
704 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
705 SetRect(&expect, 10, 20, 40, 50);
706 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
707 rect.left, rect.top, rect.right, rect.bottom);
709 SetMapMode( hdc, MM_TEXT );
710 SetViewportOrgEx( hdc, 0, 0, NULL );
711 ret = GetBoundsRect(hdc, &rect, 0);
712 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
713 SetRect(&expect, 40, 70, 100, 130);
714 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
715 rect.left, rect.top, rect.right, rect.bottom);
719 pSetLayout( hdc, LAYOUT_RTL );
720 ret = GetBoundsRect(hdc, &rect, 0);
721 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
722 SetRect(&expect, 159, 70, 99, 130);
723 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
724 rect.left, rect.top, rect.right, rect.bottom);
725 SetRect(&set_rect, 50, 25, 30, 35);
726 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
727 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
728 ret = GetBoundsRect(hdc, &rect, 0);
729 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
730 SetRect(&expect, 50, 25, 30, 35);
731 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
732 rect.left, rect.top, rect.right, rect.bottom);
734 pSetLayout( hdc, LAYOUT_LTR );
735 ret = GetBoundsRect(hdc, &rect, 0);
736 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
737 SetRect(&expect, 149, 25, 169, 35);
738 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
739 rect.left, rect.top, rect.right, rect.bottom);
742 /* empty rect resets, except on nt4 */
743 SetRect(&expect, 20, 20, 10, 10);
744 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
745 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
746 ret = GetBoundsRect(hdc, &rect, 0);
747 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
748 "GetBoundsRect returned %x\n", ret);
749 if (ret == DCB_RESET)
751 SetRect(&expect, 0, 0, 0, 0);
752 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
753 rect.left, rect.top, rect.right, rect.bottom);
755 SetRect(&expect, 20, 20, 20, 20);
756 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
757 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
758 ret = GetBoundsRect(hdc, &rect, 0);
759 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
760 SetRect(&expect, 0, 0, 0, 0);
761 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
762 rect.left, rect.top, rect.right, rect.bottom);
766 DeleteObject( bitmap );
769 static void test_desktop_colorres(void)
771 HDC hdc = GetDC(NULL);
772 int bitspixel, colorres;
774 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
775 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
777 colorres = GetDeviceCaps(hdc, COLORRES);
779 broken(colorres == 0), /* Win9x */
780 "Expected to get valid COLORRES capability value\n");
788 "Expected COLORRES to be 18, got %d\n", colorres);
792 "Expected COLORRES to be 16, got %d\n", colorres);
797 "Expected COLORRES to be 24, got %d\n", bitspixel);
800 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
805 ReleaseDC(NULL, hdc);
808 static void test_gamma(void)
811 HDC hdc = GetDC(NULL);
812 WORD oldramp[3][256], ramp[3][256];
815 ret = GetDeviceGammaRamp(hdc, &oldramp);
818 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
822 /* try to set back old ramp */
823 ret = SetDeviceGammaRamp(hdc, &oldramp);
826 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
830 memcpy(ramp, oldramp, sizeof(ramp));
832 /* set one color ramp to zeros */
833 memset(ramp[0], 0, sizeof(ramp[0]));
834 ret = SetDeviceGammaRamp(hdc, &ramp);
835 ok(!ret, "SetDeviceGammaRamp succeeded\n");
837 /* set one color ramp to a flat straight rising line */
838 for (i = 0; i < 256; i++) ramp[0][i] = i;
839 ret = SetDeviceGammaRamp(hdc, &ramp);
840 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
842 /* set one color ramp to a steep straight rising line */
843 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
844 ret = SetDeviceGammaRamp(hdc, &ramp);
845 ok(ret, "SetDeviceGammaRamp failed\n");
847 /* try a bright gamma ramp */
850 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
851 ret = SetDeviceGammaRamp(hdc, &ramp);
852 ok(!ret, "SetDeviceGammaRamp succeeded\n");
854 /* try ramps which are not uniform */
856 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
857 ret = SetDeviceGammaRamp(hdc, &ramp);
858 ok(ret, "SetDeviceGammaRamp failed\n");
860 for (i = 2; i < 256; i+=2)
862 ramp[0][i - 1] = ramp[0][i - 2];
863 ramp[0][i] = ramp[0][i - 2] + 512;
865 ret = SetDeviceGammaRamp(hdc, &ramp);
866 ok(ret, "SetDeviceGammaRamp failed\n");
868 /* cleanup: set old ramp again */
869 ret = SetDeviceGammaRamp(hdc, &oldramp);
870 ok(ret, "SetDeviceGammaRamp failed\n");
873 ReleaseDC(NULL, hdc);
876 static HDC create_printer_dc(void)
880 PRINTER_INFO_2A *pbuf = NULL;
881 DRIVER_INFO_3A *dbuf = NULL;
884 HMODULE winspool = LoadLibraryA( "winspool.drv" );
885 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
886 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
887 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
888 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
889 BOOL (WINAPI *pClosePrinter)(HANDLE);
891 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
892 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
893 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
894 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
895 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
897 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
900 len = sizeof(buffer);
901 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
902 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
904 pGetPrinterA( hprn, 2, NULL, 0, &len );
905 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
906 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
908 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
909 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
910 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
912 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
913 trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc,
914 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName );
916 HeapFree( GetProcessHeap(), 0, dbuf );
917 HeapFree( GetProcessHeap(), 0, pbuf );
918 if (hprn) pClosePrinter( hprn );
919 if (winspool) FreeLibrary( winspool );
920 if (!hdc) skip( "could not create a DC for the default printer\n" );
924 static void test_printer_dc(void)
926 HDC memdc, display_memdc;
929 HDC hdc = create_printer_dc();
933 memdc = CreateCompatibleDC( hdc );
934 display_memdc = CreateCompatibleDC( 0 );
936 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
937 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
939 ret = GetDeviceCaps( hdc, TECHNOLOGY );
940 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
942 ret = GetDeviceCaps( memdc, TECHNOLOGY );
943 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
945 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
946 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
948 test_device_caps( memdc, hdc, "printer dc" );
950 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
951 orig = SelectObject( memdc, bmp );
952 ok( orig != NULL, "SelectObject failed\n" );
953 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
955 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
956 SelectObject( memdc, orig );
959 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
960 orig = SelectObject( display_memdc, bmp );
961 ok( orig != NULL, "SelectObject failed\n" );
962 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
963 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
964 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
965 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
967 ret = GetPixel( hdc, 0, 0 );
968 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
971 DeleteDC( display_memdc );
978 pSetLayout = (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
981 test_GdiConvertToDevmodeW();
982 test_CreateCompatibleDC();
986 test_desktop_colorres();