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);
63 ok( hdc != NULL, "CreateDC failed\n" );
64 color = SetBkColor( hdc, 0x12345678 );
65 ok( color == 0xffffff, "initial color %08x\n", color );
66 color = GetBkColor( hdc );
67 ok( color == 0x12345678, "wrong color %08x\n", color );
68 color = SetBkColor( hdc, 0xffffffff );
69 ok( color == 0x12345678, "wrong color %08x\n", color );
70 color = GetBkColor( hdc );
71 ok( color == 0xffffffff, "wrong color %08x\n", color );
72 color = SetBkColor( hdc, 0 );
73 ok( color == 0xffffffff, "wrong color %08x\n", color );
74 color = GetBkColor( hdc );
75 ok( color == 0, "wrong color %08x\n", color );
77 color = SetTextColor( hdc, 0xffeeddcc );
78 ok( color == 0, "initial color %08x\n", color );
79 color = GetTextColor( hdc );
80 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
81 color = SetTextColor( hdc, 0xffffffff );
82 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
83 color = GetTextColor( hdc );
84 ok( color == 0xffffffff, "wrong color %08x\n", color );
85 color = SetTextColor( hdc, 0 );
86 ok( color == 0xffffffff, "wrong color %08x\n", color );
87 color = GetTextColor( hdc );
88 ok( color == 0, "wrong color %08x\n", color );
90 extra = GetTextCharacterExtra( hdc );
91 ok( extra == 0, "initial extra %d\n", extra );
92 SetTextCharacterExtra( hdc, 123 );
93 extra = GetTextCharacterExtra( hdc );
94 ok( extra == 123, "initial extra %d\n", extra );
95 SetMapMode( hdc, MM_LOMETRIC );
96 extra = GetTextCharacterExtra( hdc );
97 ok( extra == 123, "initial extra %d\n", extra );
98 SetMapMode( hdc, MM_TEXT );
99 extra = GetTextCharacterExtra( hdc );
100 ok( extra == 123, "initial extra %d\n", extra );
105 static void test_savedc_2(void)
113 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
116 ShowWindow(hwnd, SW_SHOW);
119 hrgn = CreateRectRgn(0, 0, 0, 0);
123 ok(hdc != NULL, "GetDC failed\n");
125 ret = GetClipBox(hdc, &rc_clip);
126 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
127 ret = GetClipRgn(hdc, hrgn);
128 ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
129 ret = GetRgnBox(hrgn, &rc);
130 ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
131 ret, rc.left, rc.top, rc.right, rc.bottom);
132 /*dump_region(hrgn);*/
133 SetRect(&rc, 0, 0, 100, 100);
134 ok(EqualRect(&rc, &rc_clip),
135 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
136 rc.left, rc.top, rc.right, rc.bottom,
137 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
140 ok(ret == 1, "ret = %d\n", ret);
142 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
143 if (ret == COMPLEXREGION)
145 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
146 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
147 /* let's make sure that it's a simple region */
148 ret = GetClipRgn(hdc, hrgn);
149 ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
153 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
155 ret = GetClipBox(hdc, &rc_clip);
156 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
157 SetRect(&rc, 0, 0, 50, 50);
158 ok(EqualRect(&rc, &rc_clip),
159 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
160 rc.left, rc.top, rc.right, rc.bottom,
161 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
163 ret = RestoreDC(hdc, 1);
164 ok(ret, "ret = %d\n", ret);
166 ret = GetClipBox(hdc, &rc_clip);
167 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
168 SetRect(&rc, 0, 0, 100, 100);
169 ok(EqualRect(&rc, &rc_clip),
170 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
171 rc.left, rc.top, rc.right, rc.bottom,
172 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
175 ReleaseDC(hwnd, hdc);
179 static void test_savedc(void)
181 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
184 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
187 ok(ret == 1, "ret = %d\n", ret);
189 ok(ret == 2, "ret = %d\n", ret);
191 ok(ret == 3, "ret = %d\n", ret);
192 ret = RestoreDC(hdc, -1);
193 ok(ret, "ret = %d\n", ret);
195 ok(ret == 3, "ret = %d\n", ret);
196 ret = RestoreDC(hdc, 1);
197 ok(ret, "ret = %d\n", ret);
199 ok(ret == 1, "ret = %d\n", ret);
201 ok(ret == 2, "ret = %d\n", ret);
203 ok(ret == 3, "ret = %d\n", ret);
204 ret = RestoreDC(hdc, -2);
205 ok(ret, "ret = %d\n", ret);
207 ok(ret == 2, "ret = %d\n", ret);
208 ret = RestoreDC(hdc, -2);
209 ok(ret, "ret = %d\n", ret);
211 ok(ret == 1, "ret = %d\n", ret);
213 ok(ret == 2, "ret = %d\n", ret);
214 ret = RestoreDC(hdc, -4);
215 ok(!ret, "ret = %d\n", ret);
216 ret = RestoreDC(hdc, 3);
217 ok(!ret, "ret = %d\n", ret);
219 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
220 ret = RestoreDC(hdc, -3);
222 broken(ret), /* Win9x */
225 /* Trying to clear an empty save stack fails. */
226 ret = RestoreDC(hdc, -3);
227 ok(!ret, "ret = %d\n", ret);
231 broken(ret == 1), /* Win9x */
234 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
235 ret = RestoreDC(hdc, 0);
237 broken(ret), /* Win9x */
240 /* Trying to clear an empty save stack fails. */
241 ret = RestoreDC(hdc, 0);
242 ok(!ret, "ret = %d\n", ret);
244 ret = RestoreDC(hdc, 1);
246 broken(!ret), /* Win9x */
252 static void test_GdiConvertToDevmodeW(void)
254 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
259 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
260 if (!pGdiConvertToDevmodeW)
262 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
266 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dmA);
267 ok(ret, "EnumDisplaySettingsExA error %u\n", GetLastError());
268 ok(dmA.dmSize >= FIELD_OFFSET(DEVMODEA, dmICMMethod), "dmSize is too small: %04x\n", dmA.dmSize);
269 ok(dmA.dmSize <= sizeof(DEVMODEA), "dmSize is too large: %04x\n", dmA.dmSize);
271 dmW = pGdiConvertToDevmodeW(&dmA);
272 ok(dmW->dmSize >= FIELD_OFFSET(DEVMODEW, dmICMMethod), "dmSize is too small: %04x\n", dmW->dmSize);
273 ok(dmW->dmSize <= sizeof(DEVMODEW), "dmSize is too large: %04x\n", dmW->dmSize);
274 HeapFree(GetProcessHeap(), 0, dmW);
276 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + sizeof(dmA.dmFields);
277 dmW = pGdiConvertToDevmodeW(&dmA);
278 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dmW->dmFields),
279 "wrong size %u\n", dmW->dmSize);
280 HeapFree(GetProcessHeap(), 0, dmW);
282 dmA.dmICMMethod = DMICMMETHOD_NONE;
283 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod) + sizeof(dmA.dmICMMethod);
284 dmW = pGdiConvertToDevmodeW(&dmA);
285 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod) + sizeof(dmW->dmICMMethod),
286 "wrong size %u\n", dmW->dmSize);
287 ok(dmW->dmICMMethod == DMICMMETHOD_NONE,
288 "expected DMICMMETHOD_NONE, got %u\n", dmW->dmICMMethod);
289 HeapFree(GetProcessHeap(), 0, dmW);
292 dmW = pGdiConvertToDevmodeW(&dmA);
293 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmPanningHeight) + sizeof(dmW->dmPanningHeight),
294 "wrong size %u\n", dmW->dmSize);
295 HeapFree(GetProcessHeap(), 0, dmW);
297 SetLastError(0xdeadbeef);
299 dmW = pGdiConvertToDevmodeW(&dmA);
300 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
301 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
303 /* this is the minimal dmSize that XP accepts */
304 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
305 dmW = pGdiConvertToDevmodeW(&dmA);
306 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields),
307 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW, dmFields), dmW->dmSize);
308 HeapFree(GetProcessHeap(), 0, dmW);
311 static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr )
313 static const int caps[] =
332 /* TEXTCAPS broken on printer DC on winxp */
361 if (GetObjectType( hdc ) == OBJ_METADC)
363 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
364 ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
365 "wrong caps on %s for %u: %u\n", descr, caps[i],
366 GetDeviceCaps( hdc, caps[i] ) );
368 SetLastError( 0xdeadbeef );
369 ret = GetDeviceGammaRamp( hdc, &ramp );
370 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
371 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
372 "wrong error %u on %s\n", GetLastError(), descr );
373 type = GetClipBox( hdc, &rect );
374 ok( type == ERROR, "GetClipBox returned %d on %s\n", type, descr );
376 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
377 SetMapMode( hdc, MM_TEXT );
378 Rectangle( hdc, 2, 2, 5, 5 );
379 type = GetBoundsRect( hdc, &rect, DCB_RESET );
380 ok( !type, "GetBoundsRect succeeded on %s\n", descr );
381 type = SetBoundsRect( hdc, &rect, DCB_RESET | DCB_ENABLE );
382 ok( !type, "SetBoundsRect succeeded on %s\n", descr );
386 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
387 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
388 "mismatched caps on %s for %u: %u/%u\n", descr, caps[i],
389 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
391 SetLastError( 0xdeadbeef );
392 ret = GetDeviceGammaRamp( hdc, &ramp );
393 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
394 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
395 "wrong error %u on %s\n", GetLastError(), descr );
396 type = GetClipBox( hdc, &rect );
397 if (GetObjectType( hdc ) == OBJ_ENHMETADC)
398 todo_wine ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
400 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
402 type = SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
403 ok( type == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", type );
404 SetMapMode( hdc, MM_TEXT );
405 Rectangle( hdc, 2, 2, 4, 4 );
406 type = GetBoundsRect( hdc, &rect, DCB_RESET );
407 if (GetObjectType( hdc ) == OBJ_ENHMETADC)
409 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
410 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
411 rect.left, rect.top, rect.right, rect.bottom, type, descr );
413 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
414 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
415 rect.left, rect.top, rect.right, rect.bottom, type, descr );
418 type = GetClipBox( ref_dc, &rect );
419 if (type != COMPLEXREGION) /* region can be complex on multi-monitor setups */
421 ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
422 ok( rect.left == 0 && rect.top == 0 &&
423 rect.right == GetDeviceCaps( ref_dc, DESKTOPHORZRES ) &&
424 rect.bottom == GetDeviceCaps( ref_dc, DESKTOPVERTRES ),
425 "GetClipBox returned %d,%d,%d,%d on %s\n",
426 rect.left, rect.top, rect.right, rect.bottom, descr );
429 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_ACCUMULATE );
430 SetMapMode( ref_dc, MM_TEXT );
431 Rectangle( ref_dc, 3, 3, 5, 5 );
432 type = GetBoundsRect( ref_dc, &rect, DCB_RESET );
433 /* it may or may not work on non-memory DCs */
434 ok( (rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0 && type == DCB_RESET) ||
435 (rect.left == 3 && rect.top == 3 && rect.right == 5 && rect.bottom == 5 && type == DCB_SET),
436 "GetBoundsRect returned %d,%d,%d,%d type %x on %s\n",
437 rect.left, rect.top, rect.right, rect.bottom, type, descr );
439 if (GetObjectType( hdc ) == OBJ_MEMDC)
441 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
442 BITMAPINFO *info = (BITMAPINFO *)buffer;
445 memset( buffer, 0, sizeof(buffer) );
446 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
447 info->bmiHeader.biWidth = 16;
448 info->bmiHeader.biHeight = 16;
449 info->bmiHeader.biPlanes = 1;
450 info->bmiHeader.biBitCount = 8;
451 info->bmiHeader.biCompression = BI_RGB;
452 dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
453 old = SelectObject( hdc, dib );
455 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
456 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
457 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
458 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
460 SetLastError( 0xdeadbeef );
461 ret = GetDeviceGammaRamp( hdc, &ramp );
462 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
463 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
464 "wrong error %u on %s\n", GetLastError(), descr );
466 type = GetClipBox( hdc, &rect );
467 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
468 ok( rect.left == 0 && rect.top == 0 && rect.right == 16 && rect.bottom == 16,
469 "GetClipBox returned %d,%d,%d,%d on memdc for %s\n",
470 rect.left, rect.top, rect.right, rect.bottom, descr );
472 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
473 SetMapMode( hdc, MM_TEXT );
474 Rectangle( hdc, 5, 5, 12, 14 );
475 type = GetBoundsRect( hdc, &rect, DCB_RESET );
476 ok( rect.left == 5 && rect.top == 5 && rect.right == 12 && rect.bottom == 14 && type == DCB_SET,
477 "GetBoundsRect returned %d,%d,%d,%d type %x on memdc for %s\n",
478 rect.left, rect.top, rect.right, rect.bottom, type, descr );
480 SelectObject( hdc, old );
485 static void test_CreateCompatibleDC(void)
488 HDC hdc, hNewDC, hdcMetafile, screen_dc;
492 screen_dc = CreateDC( "DISPLAY", NULL, NULL, NULL );
493 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
495 /* Create a DC compatible with the screen */
496 hdc = CreateCompatibleDC(NULL);
497 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
498 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
499 caps = GetDeviceCaps( hdc, TECHNOLOGY );
500 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
502 test_device_caps( hdc, screen_dc, "display dc" );
504 /* Delete this DC, this should succeed */
505 bRet = DeleteDC(hdc);
506 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
508 /* Try to create a DC compatible to the deleted DC. This has to fail */
509 hNewDC = CreateCompatibleDC(hdc);
510 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
513 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
514 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
515 hNewDC = CreateCompatibleDC( hdcMetafile );
516 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
517 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
518 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
519 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
520 test_device_caps( hdcMetafile, hdc, "enhmetafile dc" );
522 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
525 hdcMetafile = CreateMetaFileA(NULL);
526 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
527 hNewDC = CreateCompatibleDC( hdcMetafile );
528 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
529 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
530 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
531 test_device_caps( hdcMetafile, screen_dc, "metafile dc" );
532 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
534 DeleteObject( bitmap );
535 DeleteDC( screen_dc );
538 static void test_DC_bitmap(void)
542 HBITMAP hbmp, oldhbmp;
546 /* fill bitmap data with b&w pattern */
547 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
550 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
551 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
552 /* create a memory dc */
553 hdcmem = CreateCompatibleDC( hdc);
554 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
556 /* test monochrome bitmap: should always work */
557 hbmp = CreateBitmap(32, 32, 1, 1, bits);
558 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
559 oldhbmp = SelectObject( hdcmem, hbmp);
560 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
561 col = GetPixel( hdcmem, 0, 0);
562 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
563 col = GetPixel( hdcmem, 1, 1);
564 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
565 col = GetPixel( hdcmem, 100, 1);
566 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
567 SelectObject( hdcmem, oldhbmp);
570 /* test with 2 bits color depth, not likely to succeed */
571 hbmp = CreateBitmap(16, 16, 1, 2, bits);
572 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
573 oldhbmp = SelectObject( hdcmem, hbmp);
575 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
576 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
579 /* test with 16 bits color depth, might succeed */
580 hbmp = CreateBitmap(6, 6, 1, 16, bits);
581 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
582 oldhbmp = SelectObject( hdcmem, hbmp);
583 if( bitspixel == 16) {
584 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
585 col = GetPixel( hdcmem, 0, 0);
587 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
588 col = GetPixel( hdcmem, 1, 1);
590 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
592 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
595 /* test with 32 bits color depth, probably succeed */
596 hbmp = CreateBitmap(4, 4, 1, 32, bits);
597 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
598 oldhbmp = SelectObject( hdcmem, hbmp);
599 if( bitspixel == 32) {
600 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
601 col = GetPixel( hdcmem, 0, 0);
603 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
604 col = GetPixel( hdcmem, 1, 1);
606 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
608 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
613 static void test_DeleteDC(void)
621 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
623 ok(hwnd != 0, "CreateWindowExA failed\n");
626 ok(hdc != 0, "GetDC failed\n");
627 ret = GetObjectType(hdc);
628 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
630 ok(ret, "DeleteDC failed\n");
631 ret = GetObjectType(hdc);
632 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
634 hdc = GetWindowDC(hwnd);
635 ok(hdc != 0, "GetDC failed\n");
636 ret = GetObjectType(hdc);
637 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
639 ok(ret, "DeleteDC failed\n");
640 ret = GetObjectType(hdc);
641 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
645 /* desktop window DC */
646 hwnd = GetDesktopWindow();
647 ok(hwnd != 0, "GetDesktopWindow failed\n");
650 ok(hdc != 0, "GetDC failed\n");
651 ret = GetObjectType(hdc);
652 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
654 ok(ret, "DeleteDC failed\n");
655 ret = GetObjectType(hdc);
656 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
658 hdc = GetWindowDC(hwnd);
659 ok(hdc != 0, "GetDC failed\n");
660 ret = GetObjectType(hdc);
661 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
663 ok(ret, "DeleteDC failed\n");
664 ret = GetObjectType(hdc);
665 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
668 memset(&cls, 0, sizeof(cls));
669 cls.cbSize = sizeof(cls);
670 cls.style = CS_CLASSDC;
671 cls.hInstance = GetModuleHandle(0);
672 cls.lpszClassName = "Wine class DC";
673 cls.lpfnWndProc = DefWindowProcA;
674 ret = RegisterClassExA(&cls);
675 ok(ret, "RegisterClassExA failed\n");
677 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
679 ok(hwnd != 0, "CreateWindowExA failed\n");
682 ok(hdc != 0, "GetDC failed\n");
683 ret = GetObjectType(hdc);
684 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
686 ok(ret, "DeleteDC failed\n");
687 ret = GetObjectType(hdc);
688 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
689 ret = ReleaseDC(hwnd, hdc);
690 ok(ret, "ReleaseDC failed\n");
691 ret = GetObjectType(hdc);
692 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
696 hdc = GetWindowDC(hwnd);
697 ok(hdc != 0, "GetDC failed\n");
698 ret = GetObjectType(hdc);
699 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
701 ok(ret, "DeleteDC failed\n");
702 ret = GetObjectType(hdc);
703 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
707 ret = GetObjectType(hdc_test);
708 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
710 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
711 ok(ret, "UnregisterClassA failed\n");
713 ret = GetObjectType(hdc_test);
715 ok(!ret, "GetObjectType should fail for a deleted DC\n");
718 memset(&cls, 0, sizeof(cls));
719 cls.cbSize = sizeof(cls);
720 cls.style = CS_OWNDC;
721 cls.hInstance = GetModuleHandle(0);
722 cls.lpszClassName = "Wine own DC";
723 cls.lpfnWndProc = DefWindowProcA;
724 ret = RegisterClassExA(&cls);
725 ok(ret, "RegisterClassExA failed\n");
727 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
729 ok(hwnd != 0, "CreateWindowExA failed\n");
732 ok(hdc != 0, "GetDC failed\n");
733 ret = GetObjectType(hdc);
734 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
736 ok(ret, "DeleteDC failed\n");
737 ret = GetObjectType(hdc);
738 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
739 ret = ReleaseDC(hwnd, hdc);
740 ok(ret, "ReleaseDC failed\n");
741 ret = GetObjectType(hdc);
742 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
744 hdc = GetWindowDC(hwnd);
745 ok(hdc != 0, "GetDC failed\n");
746 ret = GetObjectType(hdc);
747 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
749 ok(ret, "DeleteDC failed\n");
750 ret = GetObjectType(hdc);
751 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
755 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
756 ok(ret, "UnregisterClassA failed\n");
759 static void test_boundsrect(void)
761 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
762 BITMAPINFO *info = (BITMAPINFO *)buffer;
764 HBITMAP bitmap, dib, old;
765 RECT rect, expect, set_rect;
769 hdc = CreateCompatibleDC(0);
770 ok(hdc != NULL, "CreateCompatibleDC failed\n");
771 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
772 old = SelectObject( hdc, bitmap );
774 ret = GetBoundsRect(hdc, NULL, 0);
775 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
777 ret = GetBoundsRect(hdc, NULL, ~0U);
778 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
780 /* Test parameter handling order. */
781 SetRect(&set_rect, 10, 20, 40, 50);
782 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
784 "Expected return flag DCB_RESET to be set, got %u\n", ret);
786 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
788 "Expected GetBoundsRect to return 0, got %u\n", ret);
790 ret = GetBoundsRect(hdc, &rect, 0);
792 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
793 SetRect(&expect, 0, 0, 0, 0);
794 ok(EqualRect(&rect, &expect) ||
795 broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
796 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
797 rect.left, rect.top, rect.right, rect.bottom);
799 ret = GetBoundsRect(NULL, NULL, 0);
800 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
802 ret = GetBoundsRect(NULL, NULL, ~0U);
803 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
805 ret = SetBoundsRect(NULL, NULL, 0);
806 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
808 ret = SetBoundsRect(NULL, NULL, ~0U);
809 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
811 SetRect(&set_rect, 10, 20, 40, 50);
812 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
813 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
815 ret = GetBoundsRect(hdc, &rect, 0);
816 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
817 SetRect(&expect, 10, 20, 40, 50);
818 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
819 rect.left, rect.top, rect.right, rect.bottom);
821 SetMapMode( hdc, MM_ANISOTROPIC );
822 SetViewportExtEx( hdc, 2, 2, NULL );
823 ret = GetBoundsRect(hdc, &rect, 0);
824 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
825 SetRect(&expect, 5, 10, 20, 25);
826 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
827 rect.left, rect.top, rect.right, rect.bottom);
829 SetViewportOrgEx( hdc, 20, 30, NULL );
830 ret = GetBoundsRect(hdc, &rect, 0);
831 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
832 SetRect(&expect, -5, -5, 10, 10);
833 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
834 rect.left, rect.top, rect.right, rect.bottom);
836 SetRect(&set_rect, 10, 20, 40, 50);
837 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
838 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
840 ret = GetBoundsRect(hdc, &rect, 0);
841 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
842 SetRect(&expect, 10, 20, 40, 50);
843 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
844 rect.left, rect.top, rect.right, rect.bottom);
846 SetMapMode( hdc, MM_TEXT );
847 SetViewportOrgEx( hdc, 0, 0, NULL );
848 ret = GetBoundsRect(hdc, &rect, 0);
849 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
850 SetRect(&expect, 40, 70, 100, 130);
851 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
852 rect.left, rect.top, rect.right, rect.bottom);
856 pSetLayout( hdc, LAYOUT_RTL );
857 ret = GetBoundsRect(hdc, &rect, 0);
858 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
859 SetRect(&expect, 159, 70, 99, 130);
860 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
861 rect.left, rect.top, rect.right, rect.bottom);
862 SetRect(&set_rect, 50, 25, 30, 35);
863 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
864 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
865 ret = GetBoundsRect(hdc, &rect, 0);
866 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
867 SetRect(&expect, 50, 25, 30, 35);
868 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
869 rect.left, rect.top, rect.right, rect.bottom);
871 pSetLayout( hdc, LAYOUT_LTR );
872 ret = GetBoundsRect(hdc, &rect, 0);
873 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
874 SetRect(&expect, 149, 25, 169, 35);
875 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
876 rect.left, rect.top, rect.right, rect.bottom);
879 /* empty rect resets, except on nt4 */
880 SetRect(&expect, 20, 20, 10, 10);
881 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
882 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
883 ret = GetBoundsRect(hdc, &rect, 0);
884 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
885 "GetBoundsRect returned %x\n", ret);
886 if (ret == DCB_RESET)
888 SetRect(&expect, 0, 0, 0, 0);
889 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
890 rect.left, rect.top, rect.right, rect.bottom);
892 SetRect(&expect, 20, 20, 20, 20);
893 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
894 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
895 ret = GetBoundsRect(hdc, &rect, 0);
896 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
897 SetRect(&expect, 0, 0, 0, 0);
898 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
899 rect.left, rect.top, rect.right, rect.bottom);
902 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
903 MoveToEx( hdc, 10, 10, NULL );
904 LineTo( hdc, 20, 20 );
905 ret = GetBoundsRect( hdc, &rect, 0 );
906 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
907 SetRect( &expect, 10, 10, 21, 21 );
908 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
909 SetRect( &rect, 8, 8, 23, 23 );
911 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
912 ret = GetBoundsRect( hdc, &rect, 0 );
913 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
914 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
916 level = SaveDC( hdc );
917 LineTo( hdc, 30, 25 );
918 ret = GetBoundsRect( hdc, &rect, 0 );
919 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
920 SetRect( &expect, 8, 8, 31, 26 );
921 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
922 SetBoundsRect( hdc, NULL, DCB_DISABLE );
923 LineTo( hdc, 40, 40 );
924 ret = GetBoundsRect( hdc, &rect, 0 );
925 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
926 SetRect( &expect, 8, 8, 31, 26 );
927 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
928 SetRect( &rect, 6, 6, 30, 30 );
929 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
930 ret = GetBoundsRect( hdc, &rect, 0 );
931 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
932 SetRect( &expect, 6, 6, 31, 30 );
933 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
935 RestoreDC( hdc, level );
936 ret = GetBoundsRect( hdc, &rect, 0 );
937 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
938 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
939 LineTo( hdc, 40, 40 );
940 ret = GetBoundsRect( hdc, &rect, 0 );
941 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
942 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
944 SelectObject( hdc, old );
945 ret = GetBoundsRect( hdc, &rect, 0 );
946 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
947 SetRect( &expect, 6, 6, 1, 1 );
948 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
949 SetBoundsRect( hdc, NULL, DCB_ENABLE );
950 LineTo( hdc, 50, 40 );
952 SelectObject( hdc, bitmap );
953 ret = GetBoundsRect( hdc, &rect, 0 );
954 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
955 SetRect( &expect, 6, 6, 51, 41 );
956 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
957 SelectObject( hdc, GetStockObject( NULL_PEN ));
958 LineTo( hdc, 50, 50 );
959 ret = GetBoundsRect( hdc, &rect, 0 );
960 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
961 SetRect( &expect, 6, 6, 51, 51 );
962 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
964 memset( buffer, 0, sizeof(buffer) );
965 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
966 info->bmiHeader.biWidth = 256;
967 info->bmiHeader.biHeight = 256;
968 info->bmiHeader.biPlanes = 1;
969 info->bmiHeader.biBitCount = 8;
970 info->bmiHeader.biCompression = BI_RGB;
971 dib = CreateDIBSection( 0, info, DIB_RGB_COLORS, NULL, NULL, 0 );
972 ok( dib != 0, "failed to create DIB\n" );
973 SelectObject( hdc, dib );
974 ret = GetBoundsRect( hdc, &rect, 0 );
975 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
976 SetRect( &expect, 6, 6, 51, 51 );
977 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
978 LineTo( hdc, 55, 30 );
979 ret = GetBoundsRect( hdc, &rect, 0 );
980 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
981 SetRect( &expect, 6, 6, 56, 51 );
982 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
983 LineTo( hdc, 300, 30 );
984 ret = GetBoundsRect( hdc, &rect, 0 );
985 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
986 SetRect( &expect, 6, 6, 256, 51 );
987 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
988 LineTo( hdc, -300, -300 );
989 ret = GetBoundsRect( hdc, &rect, 0 );
990 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
991 SetRect( &expect, 0, 0, 256, 51 );
992 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
994 /* test the wide pen heuristics */
995 SetBoundsRect( hdc, NULL, DCB_ENABLE | DCB_RESET );
996 for (i = 0; i < 1000; i++)
998 static const UINT endcaps[3] = { PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT };
999 static const UINT joins[3] = { PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER };
1000 LOGBRUSH brush = { BS_SOLID, RGB(0,0,0), 0 };
1001 UINT join = joins[i % 3];
1002 UINT endcap = endcaps[(i / 3) % 3];
1003 INT inflate, width = 1 + i / 9;
1004 HPEN pen = ExtCreatePen( PS_GEOMETRIC | join | endcap | PS_SOLID, width, &brush, 0, NULL );
1005 HPEN old = SelectObject( hdc, pen );
1006 MoveToEx( hdc, 100, 100, NULL );
1007 LineTo( hdc, 160, 100 );
1008 LineTo( hdc, 100, 160 );
1009 LineTo( hdc, 160, 160 );
1010 GetBoundsRect( hdc, &rect, DCB_RESET );
1011 SetRect( &expect, 100, 100, 161, 161 );
1013 inflate = width + 2;
1014 if (join == PS_JOIN_MITER)
1017 if (endcap == PS_ENDCAP_SQUARE)
1018 InflateRect( &expect, (inflate * 3 + 1) / 2, (inflate * 3 + 1) / 2 );
1020 InflateRect( &expect, inflate, inflate );
1024 if (endcap == PS_ENDCAP_SQUARE)
1025 InflateRect( &expect, inflate - inflate / 4, inflate - inflate / 4 );
1027 InflateRect( &expect, (inflate + 1) / 2, (inflate + 1) / 2 );
1029 expect.left = max( expect.left, 0 );
1030 expect.top = max( expect.top, 0 );
1031 expect.right = min( expect.right, 256 );
1032 expect.bottom = min( expect.bottom, 256 );
1033 ok( EqualRect(&rect, &expect),
1034 "Got %d,%d,%d,%d expected %d,%d,%d,%d %u/%x/%x\n",
1035 rect.left, rect.top, rect.right, rect.bottom,
1036 expect.left, expect.top, expect.right, expect.bottom, width, endcap, join );
1037 DeleteObject( SelectObject( hdc, old ));
1041 DeleteObject( bitmap );
1042 DeleteObject( dib );
1045 static void test_desktop_colorres(void)
1047 HDC hdc = GetDC(NULL);
1048 int bitspixel, colorres;
1050 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
1051 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
1053 colorres = GetDeviceCaps(hdc, COLORRES);
1055 broken(colorres == 0), /* Win9x */
1056 "Expected to get valid COLORRES capability value\n");
1064 "Expected COLORRES to be 18, got %d\n", colorres);
1068 "Expected COLORRES to be 16, got %d\n", colorres);
1073 "Expected COLORRES to be 24, got %d\n", bitspixel);
1076 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
1081 ReleaseDC(NULL, hdc);
1084 static void test_gamma(void)
1087 HDC hdc = GetDC(NULL);
1088 WORD oldramp[3][256], ramp[3][256];
1091 ret = GetDeviceGammaRamp(hdc, &oldramp);
1094 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
1098 /* try to set back old ramp */
1099 ret = SetDeviceGammaRamp(hdc, &oldramp);
1102 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
1106 memcpy(ramp, oldramp, sizeof(ramp));
1108 /* set one color ramp to zeros */
1109 memset(ramp[0], 0, sizeof(ramp[0]));
1110 ret = SetDeviceGammaRamp(hdc, &ramp);
1111 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1113 /* set one color ramp to a flat straight rising line */
1114 for (i = 0; i < 256; i++) ramp[0][i] = i;
1115 ret = SetDeviceGammaRamp(hdc, &ramp);
1116 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
1118 /* set one color ramp to a steep straight rising line */
1119 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
1120 ret = SetDeviceGammaRamp(hdc, &ramp);
1121 ok(ret, "SetDeviceGammaRamp failed\n");
1123 /* try a bright gamma ramp */
1125 ramp[0][1] = 0x7FFF;
1126 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
1127 ret = SetDeviceGammaRamp(hdc, &ramp);
1128 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1130 /* try ramps which are not uniform */
1132 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
1133 ret = SetDeviceGammaRamp(hdc, &ramp);
1134 ok(ret, "SetDeviceGammaRamp failed\n");
1136 for (i = 2; i < 256; i+=2)
1138 ramp[0][i - 1] = ramp[0][i - 2];
1139 ramp[0][i] = ramp[0][i - 2] + 512;
1141 ret = SetDeviceGammaRamp(hdc, &ramp);
1142 ok(ret, "SetDeviceGammaRamp failed\n");
1144 /* cleanup: set old ramp again */
1145 ret = SetDeviceGammaRamp(hdc, &oldramp);
1146 ok(ret, "SetDeviceGammaRamp failed\n");
1149 ReleaseDC(NULL, hdc);
1152 static HDC create_printer_dc(void)
1156 PRINTER_INFO_2A *pbuf = NULL;
1157 DRIVER_INFO_3A *dbuf = NULL;
1160 HMODULE winspool = LoadLibraryA( "winspool.drv" );
1161 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
1162 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
1163 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
1164 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
1165 BOOL (WINAPI *pClosePrinter)(HANDLE);
1167 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
1168 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
1169 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
1170 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
1171 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
1173 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
1176 len = sizeof(buffer);
1177 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
1178 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
1180 pGetPrinterA( hprn, 2, NULL, 0, &len );
1181 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
1182 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
1184 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
1185 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
1186 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
1188 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
1189 trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc,
1190 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName );
1192 HeapFree( GetProcessHeap(), 0, dbuf );
1193 HeapFree( GetProcessHeap(), 0, pbuf );
1194 if (hprn) pClosePrinter( hprn );
1195 if (winspool) FreeLibrary( winspool );
1196 if (!hdc) skip( "could not create a DC for the default printer\n" );
1200 static void test_printer_dc(void)
1202 HDC memdc, display_memdc, enhmf_dc;
1205 HDC hdc = create_printer_dc();
1209 memdc = CreateCompatibleDC( hdc );
1210 display_memdc = CreateCompatibleDC( 0 );
1212 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
1213 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
1215 ret = GetDeviceCaps( hdc, TECHNOLOGY );
1216 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1218 ret = GetDeviceCaps( memdc, TECHNOLOGY );
1219 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1221 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
1222 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
1224 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
1225 orig = SelectObject( memdc, bmp );
1226 ok( orig != NULL, "SelectObject failed\n" );
1227 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1229 test_device_caps( memdc, hdc, "printer dc" );
1231 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
1232 SelectObject( memdc, orig );
1233 DeleteObject( bmp );
1235 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
1236 orig = SelectObject( display_memdc, bmp );
1237 ok( orig != NULL, "SelectObject failed\n" );
1238 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
1239 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1240 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1241 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1243 ret = GetPixel( hdc, 0, 0 );
1244 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
1246 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1247 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1248 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc" );
1249 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1252 DeleteDC( display_memdc );
1254 DeleteObject( bmp );
1259 pSetLayout = (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
1263 test_GdiConvertToDevmodeW();
1264 test_CreateCompatibleDC();
1268 test_desktop_colorres();