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[] =
287 /* TEXTCAPS broken on printer DC on winxp */
314 if (GetObjectType( hdc ) == OBJ_METADC)
316 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
317 ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
318 "wrong caps on %s for %u: %u\n", descr, caps[i],
319 GetDeviceCaps( hdc, caps[i] ) );
321 SetLastError( 0xdeadbeef );
322 ret = GetDeviceGammaRamp( hdc, &ramp );
323 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
324 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
325 "wrong error %u on %s\n", GetLastError(), descr );
329 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
330 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
331 "mismatched caps on %s for %u: %u/%u\n", descr, caps[i],
332 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
334 SetLastError( 0xdeadbeef );
335 ret = GetDeviceGammaRamp( hdc, &ramp );
336 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
337 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
338 "wrong error %u on %s\n", GetLastError(), descr );
341 if (GetObjectType( hdc ) == OBJ_MEMDC)
343 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
344 BITMAPINFO *info = (BITMAPINFO *)buffer;
347 memset( buffer, 0, sizeof(buffer) );
348 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
349 info->bmiHeader.biWidth = 16;
350 info->bmiHeader.biHeight = 16;
351 info->bmiHeader.biPlanes = 1;
352 info->bmiHeader.biBitCount = 8;
353 info->bmiHeader.biCompression = BI_RGB;
354 dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
355 old = SelectObject( hdc, dib );
357 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
358 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
359 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
360 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
362 SetLastError( 0xdeadbeef );
363 ret = GetDeviceGammaRamp( hdc, &ramp );
364 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
365 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
366 "wrong error %u on %s\n", GetLastError(), descr );
368 SelectObject( hdc, old );
373 static void test_CreateCompatibleDC(void)
376 HDC hdc, hNewDC, hdcMetafile, screen_dc;
380 screen_dc = GetDC( 0 );
381 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
383 /* Create a DC compatible with the screen */
384 hdc = CreateCompatibleDC(NULL);
385 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
386 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
387 caps = GetDeviceCaps( hdc, TECHNOLOGY );
388 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
390 test_device_caps( hdc, screen_dc, "display dc" );
392 /* Delete this DC, this should succeed */
393 bRet = DeleteDC(hdc);
394 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
396 /* Try to create a DC compatible to the deleted DC. This has to fail */
397 hNewDC = CreateCompatibleDC(hdc);
398 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
401 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
402 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
403 hNewDC = CreateCompatibleDC( hdcMetafile );
404 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
405 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
406 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
407 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
408 caps = GetDeviceCaps( hNewDC, TECHNOLOGY );
409 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
411 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
414 hdcMetafile = CreateMetaFileA(NULL);
415 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
416 hNewDC = CreateCompatibleDC( hdcMetafile );
417 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
418 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
419 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
420 test_device_caps( hdcMetafile, screen_dc, "metafile dc" );
421 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
423 DeleteObject( bitmap );
424 ReleaseDC( 0, screen_dc );
427 static void test_DC_bitmap(void)
431 HBITMAP hbmp, oldhbmp;
435 /* fill bitmap data with b&w pattern */
436 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
439 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
440 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
441 /* create a memory dc */
442 hdcmem = CreateCompatibleDC( hdc);
443 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
445 /* test monochrome bitmap: should always work */
446 hbmp = CreateBitmap(32, 32, 1, 1, bits);
447 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
448 oldhbmp = SelectObject( hdcmem, hbmp);
449 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
450 col = GetPixel( hdcmem, 0, 0);
451 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
452 col = GetPixel( hdcmem, 1, 1);
453 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
454 col = GetPixel( hdcmem, 100, 1);
455 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
456 SelectObject( hdcmem, oldhbmp);
459 /* test with 2 bits color depth, not likely to succeed */
460 hbmp = CreateBitmap(16, 16, 1, 2, bits);
461 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
462 oldhbmp = SelectObject( hdcmem, hbmp);
464 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
465 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
468 /* test with 16 bits color depth, might succeed */
469 hbmp = CreateBitmap(6, 6, 1, 16, bits);
470 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
471 oldhbmp = SelectObject( hdcmem, hbmp);
472 if( bitspixel == 16) {
473 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
474 col = GetPixel( hdcmem, 0, 0);
476 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
477 col = GetPixel( hdcmem, 1, 1);
479 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
481 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
484 /* test with 32 bits color depth, probably succeed */
485 hbmp = CreateBitmap(4, 4, 1, 32, bits);
486 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
487 oldhbmp = SelectObject( hdcmem, hbmp);
488 if( bitspixel == 32) {
489 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
490 col = GetPixel( hdcmem, 0, 0);
492 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
493 col = GetPixel( hdcmem, 1, 1);
495 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
497 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
502 static void test_DeleteDC(void)
510 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
512 ok(hwnd != 0, "CreateWindowExA failed\n");
515 ok(hdc != 0, "GetDC failed\n");
516 ret = GetObjectType(hdc);
517 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
519 ok(ret, "DeleteDC failed\n");
520 ret = GetObjectType(hdc);
521 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
523 hdc = GetWindowDC(hwnd);
524 ok(hdc != 0, "GetDC failed\n");
525 ret = GetObjectType(hdc);
526 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
528 ok(ret, "DeleteDC failed\n");
529 ret = GetObjectType(hdc);
530 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
534 /* desktop window DC */
535 hwnd = GetDesktopWindow();
536 ok(hwnd != 0, "GetDesktopWindow failed\n");
539 ok(hdc != 0, "GetDC failed\n");
540 ret = GetObjectType(hdc);
541 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
543 ok(ret, "DeleteDC failed\n");
544 ret = GetObjectType(hdc);
545 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
547 hdc = GetWindowDC(hwnd);
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 || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
557 memset(&cls, 0, sizeof(cls));
558 cls.cbSize = sizeof(cls);
559 cls.style = CS_CLASSDC;
560 cls.hInstance = GetModuleHandle(0);
561 cls.lpszClassName = "Wine class DC";
562 cls.lpfnWndProc = DefWindowProcA;
563 ret = RegisterClassExA(&cls);
564 ok(ret, "RegisterClassExA failed\n");
566 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
568 ok(hwnd != 0, "CreateWindowExA failed\n");
571 ok(hdc != 0, "GetDC failed\n");
572 ret = GetObjectType(hdc);
573 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
575 ok(ret, "DeleteDC failed\n");
576 ret = GetObjectType(hdc);
577 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
578 ret = ReleaseDC(hwnd, hdc);
579 ok(ret, "ReleaseDC failed\n");
580 ret = GetObjectType(hdc);
581 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
585 hdc = GetWindowDC(hwnd);
586 ok(hdc != 0, "GetDC failed\n");
587 ret = GetObjectType(hdc);
588 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
590 ok(ret, "DeleteDC failed\n");
591 ret = GetObjectType(hdc);
592 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
596 ret = GetObjectType(hdc_test);
597 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
599 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
600 ok(ret, "UnregisterClassA failed\n");
602 ret = GetObjectType(hdc_test);
604 ok(!ret, "GetObjectType should fail for a deleted DC\n");
607 memset(&cls, 0, sizeof(cls));
608 cls.cbSize = sizeof(cls);
609 cls.style = CS_OWNDC;
610 cls.hInstance = GetModuleHandle(0);
611 cls.lpszClassName = "Wine own DC";
612 cls.lpfnWndProc = DefWindowProcA;
613 ret = RegisterClassExA(&cls);
614 ok(ret, "RegisterClassExA failed\n");
616 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
618 ok(hwnd != 0, "CreateWindowExA failed\n");
621 ok(hdc != 0, "GetDC failed\n");
622 ret = GetObjectType(hdc);
623 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
625 ok(ret, "DeleteDC failed\n");
626 ret = GetObjectType(hdc);
627 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
628 ret = ReleaseDC(hwnd, hdc);
629 ok(ret, "ReleaseDC failed\n");
630 ret = GetObjectType(hdc);
631 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
633 hdc = GetWindowDC(hwnd);
634 ok(hdc != 0, "GetDC failed\n");
635 ret = GetObjectType(hdc);
636 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
638 ok(ret, "DeleteDC failed\n");
639 ret = GetObjectType(hdc);
640 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
644 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
645 ok(ret, "UnregisterClassA failed\n");
648 static void test_boundsrect(void)
652 RECT rect, expect, set_rect;
655 hdc = CreateCompatibleDC(0);
656 ok(hdc != NULL, "CreateCompatibleDC failed\n");
657 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
658 SelectObject( hdc, bitmap );
660 ret = GetBoundsRect(hdc, NULL, 0);
661 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
663 ret = GetBoundsRect(hdc, NULL, ~0U);
664 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
666 /* Test parameter handling order. */
667 SetRect(&set_rect, 10, 20, 40, 50);
668 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
670 "Expected return flag DCB_RESET to be set, got %u\n", ret);
672 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
674 "Expected GetBoundsRect to return 0, got %u\n", ret);
676 ret = GetBoundsRect(hdc, &rect, 0);
678 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
679 SetRect(&expect, 0, 0, 0, 0);
680 ok(EqualRect(&rect, &expect) ||
681 broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
682 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
683 rect.left, rect.top, rect.right, rect.bottom);
685 ret = GetBoundsRect(NULL, NULL, 0);
686 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
688 ret = GetBoundsRect(NULL, NULL, ~0U);
689 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
691 ret = SetBoundsRect(NULL, NULL, 0);
692 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
694 ret = SetBoundsRect(NULL, NULL, ~0U);
695 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
697 SetRect(&set_rect, 10, 20, 40, 50);
698 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
699 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
701 ret = GetBoundsRect(hdc, &rect, 0);
702 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
703 SetRect(&expect, 10, 20, 40, 50);
704 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
705 rect.left, rect.top, rect.right, rect.bottom);
707 SetMapMode( hdc, MM_ANISOTROPIC );
708 SetViewportExtEx( hdc, 2, 2, NULL );
709 ret = GetBoundsRect(hdc, &rect, 0);
710 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
711 SetRect(&expect, 5, 10, 20, 25);
712 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
713 rect.left, rect.top, rect.right, rect.bottom);
715 SetViewportOrgEx( hdc, 20, 30, NULL );
716 ret = GetBoundsRect(hdc, &rect, 0);
717 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
718 SetRect(&expect, -5, -5, 10, 10);
719 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
720 rect.left, rect.top, rect.right, rect.bottom);
722 SetRect(&set_rect, 10, 20, 40, 50);
723 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
724 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
726 ret = GetBoundsRect(hdc, &rect, 0);
727 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
728 SetRect(&expect, 10, 20, 40, 50);
729 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
730 rect.left, rect.top, rect.right, rect.bottom);
732 SetMapMode( hdc, MM_TEXT );
733 SetViewportOrgEx( hdc, 0, 0, NULL );
734 ret = GetBoundsRect(hdc, &rect, 0);
735 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
736 SetRect(&expect, 40, 70, 100, 130);
737 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
738 rect.left, rect.top, rect.right, rect.bottom);
742 pSetLayout( hdc, LAYOUT_RTL );
743 ret = GetBoundsRect(hdc, &rect, 0);
744 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
745 SetRect(&expect, 159, 70, 99, 130);
746 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
747 rect.left, rect.top, rect.right, rect.bottom);
748 SetRect(&set_rect, 50, 25, 30, 35);
749 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
750 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
751 ret = GetBoundsRect(hdc, &rect, 0);
752 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
753 SetRect(&expect, 50, 25, 30, 35);
754 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
755 rect.left, rect.top, rect.right, rect.bottom);
757 pSetLayout( hdc, LAYOUT_LTR );
758 ret = GetBoundsRect(hdc, &rect, 0);
759 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
760 SetRect(&expect, 149, 25, 169, 35);
761 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
762 rect.left, rect.top, rect.right, rect.bottom);
765 /* empty rect resets, except on nt4 */
766 SetRect(&expect, 20, 20, 10, 10);
767 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
768 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
769 ret = GetBoundsRect(hdc, &rect, 0);
770 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
771 "GetBoundsRect returned %x\n", ret);
772 if (ret == DCB_RESET)
774 SetRect(&expect, 0, 0, 0, 0);
775 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
776 rect.left, rect.top, rect.right, rect.bottom);
778 SetRect(&expect, 20, 20, 20, 20);
779 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
780 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
781 ret = GetBoundsRect(hdc, &rect, 0);
782 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
783 SetRect(&expect, 0, 0, 0, 0);
784 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
785 rect.left, rect.top, rect.right, rect.bottom);
789 DeleteObject( bitmap );
792 static void test_desktop_colorres(void)
794 HDC hdc = GetDC(NULL);
795 int bitspixel, colorres;
797 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
798 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
800 colorres = GetDeviceCaps(hdc, COLORRES);
802 broken(colorres == 0), /* Win9x */
803 "Expected to get valid COLORRES capability value\n");
811 "Expected COLORRES to be 18, got %d\n", colorres);
815 "Expected COLORRES to be 16, got %d\n", colorres);
820 "Expected COLORRES to be 24, got %d\n", bitspixel);
823 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
828 ReleaseDC(NULL, hdc);
831 static void test_gamma(void)
834 HDC hdc = GetDC(NULL);
835 WORD oldramp[3][256], ramp[3][256];
838 ret = GetDeviceGammaRamp(hdc, &oldramp);
841 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
845 /* try to set back old ramp */
846 ret = SetDeviceGammaRamp(hdc, &oldramp);
849 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
853 memcpy(ramp, oldramp, sizeof(ramp));
855 /* set one color ramp to zeros */
856 memset(ramp[0], 0, sizeof(ramp[0]));
857 ret = SetDeviceGammaRamp(hdc, &ramp);
858 ok(!ret, "SetDeviceGammaRamp succeeded\n");
860 /* set one color ramp to a flat straight rising line */
861 for (i = 0; i < 256; i++) ramp[0][i] = i;
862 ret = SetDeviceGammaRamp(hdc, &ramp);
863 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
865 /* set one color ramp to a steep straight rising line */
866 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
867 ret = SetDeviceGammaRamp(hdc, &ramp);
868 ok(ret, "SetDeviceGammaRamp failed\n");
870 /* try a bright gamma ramp */
873 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
874 ret = SetDeviceGammaRamp(hdc, &ramp);
875 ok(!ret, "SetDeviceGammaRamp succeeded\n");
877 /* try ramps which are not uniform */
879 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
880 ret = SetDeviceGammaRamp(hdc, &ramp);
881 ok(ret, "SetDeviceGammaRamp failed\n");
883 for (i = 2; i < 256; i+=2)
885 ramp[0][i - 1] = ramp[0][i - 2];
886 ramp[0][i] = ramp[0][i - 2] + 512;
888 ret = SetDeviceGammaRamp(hdc, &ramp);
889 ok(ret, "SetDeviceGammaRamp failed\n");
891 /* cleanup: set old ramp again */
892 ret = SetDeviceGammaRamp(hdc, &oldramp);
893 ok(ret, "SetDeviceGammaRamp failed\n");
896 ReleaseDC(NULL, hdc);
899 static HDC create_printer_dc(void)
903 PRINTER_INFO_2A *pbuf = NULL;
904 DRIVER_INFO_3A *dbuf = NULL;
907 HMODULE winspool = LoadLibraryA( "winspool.drv" );
908 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
909 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
910 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
911 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
912 BOOL (WINAPI *pClosePrinter)(HANDLE);
914 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
915 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
916 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
917 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
918 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
920 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
923 len = sizeof(buffer);
924 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
925 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
927 pGetPrinterA( hprn, 2, NULL, 0, &len );
928 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
929 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
931 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
932 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
933 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
935 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
936 trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc,
937 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName );
939 HeapFree( GetProcessHeap(), 0, dbuf );
940 HeapFree( GetProcessHeap(), 0, pbuf );
941 if (hprn) pClosePrinter( hprn );
942 if (winspool) FreeLibrary( winspool );
943 if (!hdc) skip( "could not create a DC for the default printer\n" );
947 static void test_printer_dc(void)
949 HDC memdc, display_memdc;
952 HDC hdc = create_printer_dc();
956 memdc = CreateCompatibleDC( hdc );
957 display_memdc = CreateCompatibleDC( 0 );
959 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
960 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
962 ret = GetDeviceCaps( hdc, TECHNOLOGY );
963 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
965 ret = GetDeviceCaps( memdc, TECHNOLOGY );
966 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
968 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
969 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
971 test_device_caps( memdc, hdc, "printer dc" );
973 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
974 orig = SelectObject( memdc, bmp );
975 ok( orig != NULL, "SelectObject failed\n" );
976 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
978 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
979 SelectObject( memdc, orig );
982 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
983 orig = SelectObject( display_memdc, bmp );
984 ok( orig != NULL, "SelectObject failed\n" );
985 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
986 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
987 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
988 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
990 ret = GetPixel( hdc, 0, 0 );
991 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
994 DeleteDC( display_memdc );
1001 pSetLayout = (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
1004 test_GdiConvertToDevmodeW();
1005 test_CreateCompatibleDC();
1009 test_desktop_colorres();