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_dc_values(void)
59 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
62 ok( hdc != NULL, "CreateDC failed\n" );
63 color = SetBkColor( hdc, 0x12345678 );
64 ok( color == 0xffffff, "initial color %08x\n", color );
65 color = GetBkColor( hdc );
66 ok( color == 0x12345678, "wrong color %08x\n", color );
67 color = SetBkColor( hdc, 0xffffffff );
68 ok( color == 0x12345678, "wrong color %08x\n", color );
69 color = GetBkColor( hdc );
70 ok( color == 0xffffffff, "wrong color %08x\n", color );
71 color = SetBkColor( hdc, 0 );
72 ok( color == 0xffffffff, "wrong color %08x\n", color );
73 color = GetBkColor( hdc );
74 ok( color == 0, "wrong color %08x\n", color );
76 color = SetTextColor( hdc, 0xffeeddcc );
77 ok( color == 0, "initial color %08x\n", color );
78 color = GetTextColor( hdc );
79 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
80 color = SetTextColor( hdc, 0xffffffff );
81 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
82 color = GetTextColor( hdc );
83 ok( color == 0xffffffff, "wrong color %08x\n", color );
84 color = SetTextColor( hdc, 0 );
85 ok( color == 0xffffffff, "wrong color %08x\n", color );
86 color = GetTextColor( hdc );
87 ok( color == 0, "wrong color %08x\n", color );
92 static void test_savedc_2(void)
100 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
103 ShowWindow(hwnd, SW_SHOW);
106 hrgn = CreateRectRgn(0, 0, 0, 0);
110 ok(hdc != NULL, "GetDC failed\n");
112 ret = GetClipBox(hdc, &rc_clip);
113 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
114 ret = GetClipRgn(hdc, hrgn);
115 ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
116 ret = GetRgnBox(hrgn, &rc);
117 ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
118 ret, rc.left, rc.top, rc.right, rc.bottom);
119 /*dump_region(hrgn);*/
120 SetRect(&rc, 0, 0, 100, 100);
121 ok(EqualRect(&rc, &rc_clip),
122 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
123 rc.left, rc.top, rc.right, rc.bottom,
124 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
129 ok(ret == 1, "ret = %d\n", ret);
132 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
133 if (ret == COMPLEXREGION)
135 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
136 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
137 /* let's make sure that it's a simple region */
138 ret = GetClipRgn(hdc, hrgn);
139 ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
143 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
145 ret = GetClipBox(hdc, &rc_clip);
146 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
147 SetRect(&rc, 0, 0, 50, 50);
148 ok(EqualRect(&rc, &rc_clip),
149 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
150 rc.left, rc.top, rc.right, rc.bottom,
151 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
153 ret = RestoreDC(hdc, 1);
154 ok(ret, "ret = %d\n", ret);
156 ret = GetClipBox(hdc, &rc_clip);
157 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
158 SetRect(&rc, 0, 0, 100, 100);
159 ok(EqualRect(&rc, &rc_clip),
160 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
161 rc.left, rc.top, rc.right, rc.bottom,
162 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
165 ReleaseDC(hwnd, hdc);
169 static void test_savedc(void)
171 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
174 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
177 ok(ret == 1, "ret = %d\n", ret);
179 ok(ret == 2, "ret = %d\n", ret);
181 ok(ret == 3, "ret = %d\n", ret);
182 ret = RestoreDC(hdc, -1);
183 ok(ret, "ret = %d\n", ret);
185 ok(ret == 3, "ret = %d\n", ret);
186 ret = RestoreDC(hdc, 1);
187 ok(ret, "ret = %d\n", ret);
189 ok(ret == 1, "ret = %d\n", ret);
191 ok(ret == 2, "ret = %d\n", ret);
193 ok(ret == 3, "ret = %d\n", ret);
194 ret = RestoreDC(hdc, -2);
195 ok(ret, "ret = %d\n", ret);
197 ok(ret == 2, "ret = %d\n", ret);
198 ret = RestoreDC(hdc, -2);
199 ok(ret, "ret = %d\n", ret);
201 ok(ret == 1, "ret = %d\n", ret);
203 ok(ret == 2, "ret = %d\n", ret);
204 ret = RestoreDC(hdc, -4);
205 ok(!ret, "ret = %d\n", ret);
206 ret = RestoreDC(hdc, 3);
207 ok(!ret, "ret = %d\n", ret);
209 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
210 ret = RestoreDC(hdc, -3);
212 broken(ret), /* Win9x */
215 /* Trying to clear an empty save stack fails. */
216 ret = RestoreDC(hdc, -3);
217 ok(!ret, "ret = %d\n", ret);
221 broken(ret == 1), /* Win9x */
224 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
225 ret = RestoreDC(hdc, 0);
227 broken(ret), /* Win9x */
230 /* Trying to clear an empty save stack fails. */
231 ret = RestoreDC(hdc, 0);
232 ok(!ret, "ret = %d\n", ret);
234 ret = RestoreDC(hdc, 1);
236 broken(!ret), /* Win9x */
242 static void test_GdiConvertToDevmodeW(void)
244 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
249 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
250 if (!pGdiConvertToDevmodeW)
252 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
256 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dmA);
257 ok(ret, "EnumDisplaySettingsExA error %u\n", GetLastError());
258 ok(dmA.dmSize >= FIELD_OFFSET(DEVMODEA, dmICMMethod), "dmSize is too small: %04x\n", dmA.dmSize);
259 ok(dmA.dmSize <= sizeof(DEVMODEA), "dmSize is too large: %04x\n", dmA.dmSize);
261 dmW = pGdiConvertToDevmodeW(&dmA);
262 ok(dmW->dmSize >= FIELD_OFFSET(DEVMODEW, dmICMMethod), "dmSize is too small: %04x\n", dmW->dmSize);
263 ok(dmW->dmSize <= sizeof(DEVMODEW), "dmSize is too large: %04x\n", dmW->dmSize);
264 HeapFree(GetProcessHeap(), 0, dmW);
266 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + sizeof(dmA.dmFields);
267 dmW = pGdiConvertToDevmodeW(&dmA);
268 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dmW->dmFields),
269 "wrong size %u\n", dmW->dmSize);
270 HeapFree(GetProcessHeap(), 0, dmW);
272 dmA.dmICMMethod = DMICMMETHOD_NONE;
273 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod) + sizeof(dmA.dmICMMethod);
274 dmW = pGdiConvertToDevmodeW(&dmA);
275 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod) + sizeof(dmW->dmICMMethod),
276 "wrong size %u\n", dmW->dmSize);
277 ok(dmW->dmICMMethod == DMICMMETHOD_NONE,
278 "expected DMICMMETHOD_NONE, got %u\n", dmW->dmICMMethod);
279 HeapFree(GetProcessHeap(), 0, dmW);
282 dmW = pGdiConvertToDevmodeW(&dmA);
283 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmPanningHeight) + sizeof(dmW->dmPanningHeight),
284 "wrong size %u\n", dmW->dmSize);
285 HeapFree(GetProcessHeap(), 0, dmW);
287 SetLastError(0xdeadbeef);
289 dmW = pGdiConvertToDevmodeW(&dmA);
290 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
291 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
293 /* this is the minimal dmSize that XP accepts */
294 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
295 dmW = pGdiConvertToDevmodeW(&dmA);
296 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields),
297 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW, dmFields), dmW->dmSize);
298 HeapFree(GetProcessHeap(), 0, dmW);
301 static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr )
303 static const int caps[] =
322 /* TEXTCAPS broken on printer DC on winxp */
351 if (GetObjectType( hdc ) == OBJ_METADC)
353 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
354 ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
355 "wrong caps on %s for %u: %u\n", descr, caps[i],
356 GetDeviceCaps( hdc, caps[i] ) );
358 SetLastError( 0xdeadbeef );
359 ret = GetDeviceGammaRamp( hdc, &ramp );
360 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
361 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
362 "wrong error %u on %s\n", GetLastError(), descr );
363 type = GetClipBox( hdc, &rect );
364 ok( type == ERROR, "GetClipBox returned %d on %s\n", type, descr );
366 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
367 SetMapMode( hdc, MM_TEXT );
368 Rectangle( hdc, 2, 2, 5, 5 );
369 type = GetBoundsRect( hdc, &rect, DCB_RESET );
370 ok( !type, "GetBoundsRect succeeded on %s\n", descr );
371 type = SetBoundsRect( hdc, &rect, DCB_RESET | DCB_ENABLE );
372 ok( !type, "SetBoundsRect succeeded on %s\n", descr );
376 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
377 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
378 "mismatched caps on %s for %u: %u/%u\n", descr, caps[i],
379 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
381 SetLastError( 0xdeadbeef );
382 ret = GetDeviceGammaRamp( hdc, &ramp );
383 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
384 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
385 "wrong error %u on %s\n", GetLastError(), descr );
386 type = GetClipBox( hdc, &rect );
387 if (GetObjectType( hdc ) == OBJ_ENHMETADC)
388 todo_wine ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
390 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
392 type = SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
393 ok( type == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", type );
394 SetMapMode( hdc, MM_TEXT );
395 Rectangle( hdc, 2, 2, 4, 4 );
396 type = GetBoundsRect( hdc, &rect, DCB_RESET );
397 if (GetObjectType( hdc ) == OBJ_ENHMETADC)
399 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
400 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
401 rect.left, rect.top, rect.right, rect.bottom, type, descr );
403 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
404 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
405 rect.left, rect.top, rect.right, rect.bottom, type, descr );
408 type = GetClipBox( ref_dc, &rect );
409 if (type != COMPLEXREGION) /* region can be complex on multi-monitor setups */
411 ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
412 ok( rect.left == 0 && rect.top == 0 &&
413 rect.right == GetDeviceCaps( ref_dc, DESKTOPHORZRES ) &&
414 rect.bottom == GetDeviceCaps( ref_dc, DESKTOPVERTRES ),
415 "GetClipBox returned %d,%d,%d,%d on %s\n",
416 rect.left, rect.top, rect.right, rect.bottom, descr );
419 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_ACCUMULATE );
420 SetMapMode( ref_dc, MM_TEXT );
421 Rectangle( ref_dc, 3, 3, 5, 5 );
422 type = GetBoundsRect( ref_dc, &rect, DCB_RESET );
423 /* it may or may not work on non-memory DCs */
424 ok( (rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0 && type == DCB_RESET) ||
425 (rect.left == 3 && rect.top == 3 && rect.right == 5 && rect.bottom == 5 && type == DCB_SET),
426 "GetBoundsRect returned %d,%d,%d,%d type %x on %s\n",
427 rect.left, rect.top, rect.right, rect.bottom, type, descr );
429 if (GetObjectType( hdc ) == OBJ_MEMDC)
431 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
432 BITMAPINFO *info = (BITMAPINFO *)buffer;
435 memset( buffer, 0, sizeof(buffer) );
436 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
437 info->bmiHeader.biWidth = 16;
438 info->bmiHeader.biHeight = 16;
439 info->bmiHeader.biPlanes = 1;
440 info->bmiHeader.biBitCount = 8;
441 info->bmiHeader.biCompression = BI_RGB;
442 dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
443 old = SelectObject( hdc, dib );
445 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
446 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
447 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
448 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
450 SetLastError( 0xdeadbeef );
451 ret = GetDeviceGammaRamp( hdc, &ramp );
452 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
453 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
454 "wrong error %u on %s\n", GetLastError(), descr );
456 type = GetClipBox( hdc, &rect );
457 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
458 ok( rect.left == 0 && rect.top == 0 && rect.right == 16 && rect.bottom == 16,
459 "GetClipBox returned %d,%d,%d,%d on memdc for %s\n",
460 rect.left, rect.top, rect.right, rect.bottom, descr );
462 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
463 SetMapMode( hdc, MM_TEXT );
464 Rectangle( hdc, 5, 5, 12, 14 );
465 type = GetBoundsRect( hdc, &rect, DCB_RESET );
466 ok( rect.left == 5 && rect.top == 5 && rect.right == 12 && rect.bottom == 14 && type == DCB_SET,
467 "GetBoundsRect returned %d,%d,%d,%d type %x on memdc for %s\n",
468 rect.left, rect.top, rect.right, rect.bottom, type, descr );
470 SelectObject( hdc, old );
475 static void test_CreateCompatibleDC(void)
478 HDC hdc, hNewDC, hdcMetafile, screen_dc;
482 screen_dc = CreateDC( "DISPLAY", NULL, NULL, NULL );
483 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
485 /* Create a DC compatible with the screen */
486 hdc = CreateCompatibleDC(NULL);
487 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
488 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
489 caps = GetDeviceCaps( hdc, TECHNOLOGY );
490 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
492 test_device_caps( hdc, screen_dc, "display dc" );
494 /* Delete this DC, this should succeed */
495 bRet = DeleteDC(hdc);
496 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
498 /* Try to create a DC compatible to the deleted DC. This has to fail */
499 hNewDC = CreateCompatibleDC(hdc);
500 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
503 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
504 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
505 hNewDC = CreateCompatibleDC( hdcMetafile );
506 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
507 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
508 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
509 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
510 test_device_caps( hdcMetafile, hdc, "enhmetafile dc" );
512 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
515 hdcMetafile = CreateMetaFileA(NULL);
516 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
517 hNewDC = CreateCompatibleDC( hdcMetafile );
518 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
519 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
520 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
521 test_device_caps( hdcMetafile, screen_dc, "metafile dc" );
522 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
524 DeleteObject( bitmap );
525 DeleteDC( screen_dc );
528 static void test_DC_bitmap(void)
532 HBITMAP hbmp, oldhbmp;
536 /* fill bitmap data with b&w pattern */
537 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
540 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
541 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
542 /* create a memory dc */
543 hdcmem = CreateCompatibleDC( hdc);
544 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
546 /* test monochrome bitmap: should always work */
547 hbmp = CreateBitmap(32, 32, 1, 1, bits);
548 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
549 oldhbmp = SelectObject( hdcmem, hbmp);
550 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
551 col = GetPixel( hdcmem, 0, 0);
552 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
553 col = GetPixel( hdcmem, 1, 1);
554 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
555 col = GetPixel( hdcmem, 100, 1);
556 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
557 SelectObject( hdcmem, oldhbmp);
560 /* test with 2 bits color depth, not likely to succeed */
561 hbmp = CreateBitmap(16, 16, 1, 2, bits);
562 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
563 oldhbmp = SelectObject( hdcmem, hbmp);
565 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
566 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
569 /* test with 16 bits color depth, might succeed */
570 hbmp = CreateBitmap(6, 6, 1, 16, bits);
571 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
572 oldhbmp = SelectObject( hdcmem, hbmp);
573 if( bitspixel == 16) {
574 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
575 col = GetPixel( hdcmem, 0, 0);
577 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
578 col = GetPixel( hdcmem, 1, 1);
580 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
582 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
585 /* test with 32 bits color depth, probably succeed */
586 hbmp = CreateBitmap(4, 4, 1, 32, bits);
587 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
588 oldhbmp = SelectObject( hdcmem, hbmp);
589 if( bitspixel == 32) {
590 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
591 col = GetPixel( hdcmem, 0, 0);
593 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
594 col = GetPixel( hdcmem, 1, 1);
596 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
598 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
603 static void test_DeleteDC(void)
611 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
613 ok(hwnd != 0, "CreateWindowExA failed\n");
616 ok(hdc != 0, "GetDC failed\n");
617 ret = GetObjectType(hdc);
618 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
620 ok(ret, "DeleteDC failed\n");
621 ret = GetObjectType(hdc);
622 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
624 hdc = GetWindowDC(hwnd);
625 ok(hdc != 0, "GetDC failed\n");
626 ret = GetObjectType(hdc);
627 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
629 ok(ret, "DeleteDC failed\n");
630 ret = GetObjectType(hdc);
631 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
635 /* desktop window DC */
636 hwnd = GetDesktopWindow();
637 ok(hwnd != 0, "GetDesktopWindow failed\n");
640 ok(hdc != 0, "GetDC failed\n");
641 ret = GetObjectType(hdc);
642 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
644 ok(ret, "DeleteDC failed\n");
645 ret = GetObjectType(hdc);
646 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
648 hdc = GetWindowDC(hwnd);
649 ok(hdc != 0, "GetDC failed\n");
650 ret = GetObjectType(hdc);
651 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
653 ok(ret, "DeleteDC failed\n");
654 ret = GetObjectType(hdc);
655 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
658 memset(&cls, 0, sizeof(cls));
659 cls.cbSize = sizeof(cls);
660 cls.style = CS_CLASSDC;
661 cls.hInstance = GetModuleHandle(0);
662 cls.lpszClassName = "Wine class DC";
663 cls.lpfnWndProc = DefWindowProcA;
664 ret = RegisterClassExA(&cls);
665 ok(ret, "RegisterClassExA failed\n");
667 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
669 ok(hwnd != 0, "CreateWindowExA failed\n");
672 ok(hdc != 0, "GetDC failed\n");
673 ret = GetObjectType(hdc);
674 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
676 ok(ret, "DeleteDC failed\n");
677 ret = GetObjectType(hdc);
678 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
679 ret = ReleaseDC(hwnd, hdc);
680 ok(ret, "ReleaseDC failed\n");
681 ret = GetObjectType(hdc);
682 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
686 hdc = GetWindowDC(hwnd);
687 ok(hdc != 0, "GetDC failed\n");
688 ret = GetObjectType(hdc);
689 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
691 ok(ret, "DeleteDC failed\n");
692 ret = GetObjectType(hdc);
693 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
697 ret = GetObjectType(hdc_test);
698 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
700 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
701 ok(ret, "UnregisterClassA failed\n");
703 ret = GetObjectType(hdc_test);
705 ok(!ret, "GetObjectType should fail for a deleted DC\n");
708 memset(&cls, 0, sizeof(cls));
709 cls.cbSize = sizeof(cls);
710 cls.style = CS_OWNDC;
711 cls.hInstance = GetModuleHandle(0);
712 cls.lpszClassName = "Wine own DC";
713 cls.lpfnWndProc = DefWindowProcA;
714 ret = RegisterClassExA(&cls);
715 ok(ret, "RegisterClassExA failed\n");
717 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
719 ok(hwnd != 0, "CreateWindowExA failed\n");
722 ok(hdc != 0, "GetDC failed\n");
723 ret = GetObjectType(hdc);
724 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
726 ok(ret, "DeleteDC failed\n");
727 ret = GetObjectType(hdc);
728 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
729 ret = ReleaseDC(hwnd, hdc);
730 ok(ret, "ReleaseDC failed\n");
731 ret = GetObjectType(hdc);
732 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
734 hdc = GetWindowDC(hwnd);
735 ok(hdc != 0, "GetDC failed\n");
736 ret = GetObjectType(hdc);
737 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
739 ok(ret, "DeleteDC failed\n");
740 ret = GetObjectType(hdc);
741 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
745 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
746 ok(ret, "UnregisterClassA failed\n");
749 static void test_boundsrect(void)
751 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
752 BITMAPINFO *info = (BITMAPINFO *)buffer;
754 HBITMAP bitmap, dib, old;
755 RECT rect, expect, set_rect;
759 hdc = CreateCompatibleDC(0);
760 ok(hdc != NULL, "CreateCompatibleDC failed\n");
761 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
762 old = SelectObject( hdc, bitmap );
764 ret = GetBoundsRect(hdc, NULL, 0);
765 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
767 ret = GetBoundsRect(hdc, NULL, ~0U);
768 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
770 /* Test parameter handling order. */
771 SetRect(&set_rect, 10, 20, 40, 50);
772 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
774 "Expected return flag DCB_RESET to be set, got %u\n", ret);
776 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
778 "Expected GetBoundsRect to return 0, got %u\n", ret);
780 ret = GetBoundsRect(hdc, &rect, 0);
782 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
783 SetRect(&expect, 0, 0, 0, 0);
784 ok(EqualRect(&rect, &expect) ||
785 broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
786 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
787 rect.left, rect.top, rect.right, rect.bottom);
789 ret = GetBoundsRect(NULL, NULL, 0);
790 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
792 ret = GetBoundsRect(NULL, NULL, ~0U);
793 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
795 ret = SetBoundsRect(NULL, NULL, 0);
796 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
798 ret = SetBoundsRect(NULL, NULL, ~0U);
799 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
801 SetRect(&set_rect, 10, 20, 40, 50);
802 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
803 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
805 ret = GetBoundsRect(hdc, &rect, 0);
806 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
807 SetRect(&expect, 10, 20, 40, 50);
808 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
809 rect.left, rect.top, rect.right, rect.bottom);
811 SetMapMode( hdc, MM_ANISOTROPIC );
812 SetViewportExtEx( hdc, 2, 2, NULL );
813 ret = GetBoundsRect(hdc, &rect, 0);
814 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
815 SetRect(&expect, 5, 10, 20, 25);
816 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
817 rect.left, rect.top, rect.right, rect.bottom);
819 SetViewportOrgEx( hdc, 20, 30, NULL );
820 ret = GetBoundsRect(hdc, &rect, 0);
821 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
822 SetRect(&expect, -5, -5, 10, 10);
823 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
824 rect.left, rect.top, rect.right, rect.bottom);
826 SetRect(&set_rect, 10, 20, 40, 50);
827 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
828 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
830 ret = GetBoundsRect(hdc, &rect, 0);
831 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
832 SetRect(&expect, 10, 20, 40, 50);
833 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
834 rect.left, rect.top, rect.right, rect.bottom);
836 SetMapMode( hdc, MM_TEXT );
837 SetViewportOrgEx( hdc, 0, 0, NULL );
838 ret = GetBoundsRect(hdc, &rect, 0);
839 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
840 SetRect(&expect, 40, 70, 100, 130);
841 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
842 rect.left, rect.top, rect.right, rect.bottom);
846 pSetLayout( hdc, LAYOUT_RTL );
847 ret = GetBoundsRect(hdc, &rect, 0);
848 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
849 SetRect(&expect, 159, 70, 99, 130);
850 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
851 rect.left, rect.top, rect.right, rect.bottom);
852 SetRect(&set_rect, 50, 25, 30, 35);
853 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
854 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
855 ret = GetBoundsRect(hdc, &rect, 0);
856 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
857 SetRect(&expect, 50, 25, 30, 35);
858 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
859 rect.left, rect.top, rect.right, rect.bottom);
861 pSetLayout( hdc, LAYOUT_LTR );
862 ret = GetBoundsRect(hdc, &rect, 0);
863 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
864 SetRect(&expect, 149, 25, 169, 35);
865 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
866 rect.left, rect.top, rect.right, rect.bottom);
869 /* empty rect resets, except on nt4 */
870 SetRect(&expect, 20, 20, 10, 10);
871 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
872 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
873 ret = GetBoundsRect(hdc, &rect, 0);
874 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
875 "GetBoundsRect returned %x\n", ret);
876 if (ret == DCB_RESET)
878 SetRect(&expect, 0, 0, 0, 0);
879 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
880 rect.left, rect.top, rect.right, rect.bottom);
882 SetRect(&expect, 20, 20, 20, 20);
883 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
884 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
885 ret = GetBoundsRect(hdc, &rect, 0);
886 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
887 SetRect(&expect, 0, 0, 0, 0);
888 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
889 rect.left, rect.top, rect.right, rect.bottom);
892 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
893 MoveToEx( hdc, 10, 10, NULL );
894 LineTo( hdc, 20, 20 );
895 ret = GetBoundsRect( hdc, &rect, 0 );
896 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
897 SetRect( &expect, 10, 10, 21, 21 );
898 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
899 SetRect( &rect, 8, 8, 23, 23 );
901 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
902 ret = GetBoundsRect( hdc, &rect, 0 );
903 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
904 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
906 level = SaveDC( hdc );
907 LineTo( hdc, 30, 25 );
908 ret = GetBoundsRect( hdc, &rect, 0 );
909 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
910 SetRect( &expect, 8, 8, 31, 26 );
911 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
912 SetBoundsRect( hdc, NULL, DCB_DISABLE );
913 LineTo( hdc, 40, 40 );
914 ret = GetBoundsRect( hdc, &rect, 0 );
915 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
916 SetRect( &expect, 8, 8, 31, 26 );
917 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
918 SetRect( &rect, 6, 6, 30, 30 );
919 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
920 ret = GetBoundsRect( hdc, &rect, 0 );
921 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
922 SetRect( &expect, 6, 6, 31, 30 );
923 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
925 RestoreDC( hdc, level );
926 ret = GetBoundsRect( hdc, &rect, 0 );
927 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
928 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
929 LineTo( hdc, 40, 40 );
930 ret = GetBoundsRect( hdc, &rect, 0 );
931 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
932 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
934 SelectObject( hdc, old );
935 ret = GetBoundsRect( hdc, &rect, 0 );
936 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
937 SetRect( &expect, 6, 6, 1, 1 );
938 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
939 SetBoundsRect( hdc, NULL, DCB_ENABLE );
940 LineTo( hdc, 50, 40 );
942 SelectObject( hdc, bitmap );
943 ret = GetBoundsRect( hdc, &rect, 0 );
944 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
945 SetRect( &expect, 6, 6, 51, 41 );
946 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
947 SelectObject( hdc, GetStockObject( NULL_PEN ));
948 LineTo( hdc, 50, 50 );
949 ret = GetBoundsRect( hdc, &rect, 0 );
950 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
951 SetRect( &expect, 6, 6, 51, 51 );
952 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
954 memset( buffer, 0, sizeof(buffer) );
955 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
956 info->bmiHeader.biWidth = 256;
957 info->bmiHeader.biHeight = 256;
958 info->bmiHeader.biPlanes = 1;
959 info->bmiHeader.biBitCount = 8;
960 info->bmiHeader.biCompression = BI_RGB;
961 dib = CreateDIBSection( 0, info, DIB_RGB_COLORS, NULL, NULL, 0 );
962 ok( dib != 0, "failed to create DIB\n" );
963 SelectObject( hdc, dib );
964 ret = GetBoundsRect( hdc, &rect, 0 );
965 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
966 SetRect( &expect, 6, 6, 51, 51 );
967 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
968 LineTo( hdc, 55, 30 );
969 ret = GetBoundsRect( hdc, &rect, 0 );
970 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
971 SetRect( &expect, 6, 6, 56, 51 );
972 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
973 LineTo( hdc, 300, 30 );
974 ret = GetBoundsRect( hdc, &rect, 0 );
975 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
976 SetRect( &expect, 6, 6, 256, 51 );
977 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
978 LineTo( hdc, -300, -300 );
979 ret = GetBoundsRect( hdc, &rect, 0 );
980 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
981 SetRect( &expect, 0, 0, 256, 51 );
982 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
984 /* test the wide pen heuristics */
985 SetBoundsRect( hdc, NULL, DCB_ENABLE | DCB_RESET );
986 for (i = 0; i < 1000; i++)
988 static const UINT endcaps[3] = { PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT };
989 static const UINT joins[3] = { PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER };
990 LOGBRUSH brush = { BS_SOLID, RGB(0,0,0), 0 };
991 UINT join = joins[i % 3];
992 UINT endcap = endcaps[(i / 3) % 3];
993 INT inflate, width = 1 + i / 9;
994 HPEN pen = ExtCreatePen( PS_GEOMETRIC | join | endcap | PS_SOLID, width, &brush, 0, NULL );
995 HPEN old = SelectObject( hdc, pen );
996 MoveToEx( hdc, 100, 100, NULL );
997 LineTo( hdc, 160, 100 );
998 LineTo( hdc, 100, 160 );
999 LineTo( hdc, 160, 160 );
1000 GetBoundsRect( hdc, &rect, DCB_RESET );
1001 SetRect( &expect, 100, 100, 161, 161 );
1003 inflate = width + 2;
1004 if (join == PS_JOIN_MITER)
1007 if (endcap == PS_ENDCAP_SQUARE)
1008 InflateRect( &expect, (inflate * 3 + 1) / 2, (inflate * 3 + 1) / 2 );
1010 InflateRect( &expect, inflate, inflate );
1014 if (endcap == PS_ENDCAP_SQUARE)
1015 InflateRect( &expect, inflate - inflate / 4, inflate - inflate / 4 );
1017 InflateRect( &expect, (inflate + 1) / 2, (inflate + 1) / 2 );
1019 expect.left = max( expect.left, 0 );
1020 expect.top = max( expect.top, 0 );
1021 expect.right = min( expect.right, 256 );
1022 expect.bottom = min( expect.bottom, 256 );
1023 ok( EqualRect(&rect, &expect),
1024 "Got %d,%d,%d,%d expected %d,%d,%d,%d %u/%x/%x\n",
1025 rect.left, rect.top, rect.right, rect.bottom,
1026 expect.left, expect.top, expect.right, expect.bottom, width, endcap, join );
1027 DeleteObject( SelectObject( hdc, old ));
1031 DeleteObject( bitmap );
1032 DeleteObject( dib );
1035 static void test_desktop_colorres(void)
1037 HDC hdc = GetDC(NULL);
1038 int bitspixel, colorres;
1040 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
1041 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
1043 colorres = GetDeviceCaps(hdc, COLORRES);
1045 broken(colorres == 0), /* Win9x */
1046 "Expected to get valid COLORRES capability value\n");
1054 "Expected COLORRES to be 18, got %d\n", colorres);
1058 "Expected COLORRES to be 16, got %d\n", colorres);
1063 "Expected COLORRES to be 24, got %d\n", bitspixel);
1066 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
1071 ReleaseDC(NULL, hdc);
1074 static void test_gamma(void)
1077 HDC hdc = GetDC(NULL);
1078 WORD oldramp[3][256], ramp[3][256];
1081 ret = GetDeviceGammaRamp(hdc, &oldramp);
1084 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
1088 /* try to set back old ramp */
1089 ret = SetDeviceGammaRamp(hdc, &oldramp);
1092 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
1096 memcpy(ramp, oldramp, sizeof(ramp));
1098 /* set one color ramp to zeros */
1099 memset(ramp[0], 0, sizeof(ramp[0]));
1100 ret = SetDeviceGammaRamp(hdc, &ramp);
1101 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1103 /* set one color ramp to a flat straight rising line */
1104 for (i = 0; i < 256; i++) ramp[0][i] = i;
1105 ret = SetDeviceGammaRamp(hdc, &ramp);
1106 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
1108 /* set one color ramp to a steep straight rising line */
1109 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
1110 ret = SetDeviceGammaRamp(hdc, &ramp);
1111 ok(ret, "SetDeviceGammaRamp failed\n");
1113 /* try a bright gamma ramp */
1115 ramp[0][1] = 0x7FFF;
1116 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
1117 ret = SetDeviceGammaRamp(hdc, &ramp);
1118 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1120 /* try ramps which are not uniform */
1122 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
1123 ret = SetDeviceGammaRamp(hdc, &ramp);
1124 ok(ret, "SetDeviceGammaRamp failed\n");
1126 for (i = 2; i < 256; i+=2)
1128 ramp[0][i - 1] = ramp[0][i - 2];
1129 ramp[0][i] = ramp[0][i - 2] + 512;
1131 ret = SetDeviceGammaRamp(hdc, &ramp);
1132 ok(ret, "SetDeviceGammaRamp failed\n");
1134 /* cleanup: set old ramp again */
1135 ret = SetDeviceGammaRamp(hdc, &oldramp);
1136 ok(ret, "SetDeviceGammaRamp failed\n");
1139 ReleaseDC(NULL, hdc);
1142 static HDC create_printer_dc(void)
1146 PRINTER_INFO_2A *pbuf = NULL;
1147 DRIVER_INFO_3A *dbuf = NULL;
1150 HMODULE winspool = LoadLibraryA( "winspool.drv" );
1151 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
1152 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
1153 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
1154 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
1155 BOOL (WINAPI *pClosePrinter)(HANDLE);
1157 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
1158 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
1159 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
1160 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
1161 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
1163 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
1166 len = sizeof(buffer);
1167 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
1168 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
1170 pGetPrinterA( hprn, 2, NULL, 0, &len );
1171 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
1172 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
1174 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
1175 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
1176 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
1178 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
1179 trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc,
1180 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName );
1182 HeapFree( GetProcessHeap(), 0, dbuf );
1183 HeapFree( GetProcessHeap(), 0, pbuf );
1184 if (hprn) pClosePrinter( hprn );
1185 if (winspool) FreeLibrary( winspool );
1186 if (!hdc) skip( "could not create a DC for the default printer\n" );
1190 static void test_printer_dc(void)
1192 HDC memdc, display_memdc, enhmf_dc;
1195 HDC hdc = create_printer_dc();
1199 memdc = CreateCompatibleDC( hdc );
1200 display_memdc = CreateCompatibleDC( 0 );
1202 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
1203 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
1205 ret = GetDeviceCaps( hdc, TECHNOLOGY );
1206 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1208 ret = GetDeviceCaps( memdc, TECHNOLOGY );
1209 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1211 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
1212 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
1214 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
1215 orig = SelectObject( memdc, bmp );
1216 ok( orig != NULL, "SelectObject failed\n" );
1217 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1219 test_device_caps( memdc, hdc, "printer dc" );
1221 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
1222 SelectObject( memdc, orig );
1223 DeleteObject( bmp );
1225 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
1226 orig = SelectObject( display_memdc, bmp );
1227 ok( orig != NULL, "SelectObject failed\n" );
1228 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
1229 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1230 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1231 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1233 ret = GetPixel( hdc, 0, 0 );
1234 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
1236 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1237 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1238 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc" );
1239 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1242 DeleteDC( display_memdc );
1244 DeleteObject( bmp );
1249 pSetLayout = (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
1253 test_GdiConvertToDevmodeW();
1254 test_CreateCompatibleDC();
1258 test_desktop_colorres();