TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / gdi32 / tests / dc.c
blobcb42219836050869c899b97dde0ea0624d06c4b4
1 /*
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
23 #define WINVER 0x0501 /* request latest DEVMODE */
24 #define NONAMELESSSTRUCT
25 #define NONAMELESSUNION
27 #include <assert.h>
28 #include <stdio.h>
30 #include "wine/test.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winuser.h"
34 #include "winspool.h"
35 #include "winerror.h"
37 #ifndef LAYOUT_LTR
38 #define LAYOUT_LTR 0
39 #endif
41 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
43 static void dump_region(HRGN hrgn)
45 DWORD i, size;
46 RGNDATA *data = NULL;
47 RECT *rect;
49 if (!hrgn)
51 printf( "(null) region\n" );
52 return;
54 if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
55 if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
56 GetRegionData( hrgn, size, data );
57 printf( "%d rects:", data->rdh.nCount );
58 for (i = 0, rect = (RECT *)data->Buffer; i < data->rdh.nCount; i++, rect++)
59 printf( " (%d,%d)-(%d,%d)", rect->left, rect->top, rect->right, rect->bottom );
60 printf( "\n" );
61 HeapFree( GetProcessHeap(), 0, data );
64 static void test_dc_values(void)
66 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
67 COLORREF color;
68 int extra;
70 ok( hdc != NULL, "CreateDC failed\n" );
71 color = SetBkColor( hdc, 0x12345678 );
72 ok( color == 0xffffff, "initial color %08x\n", color );
73 color = GetBkColor( hdc );
74 ok( color == 0x12345678, "wrong color %08x\n", color );
75 color = SetBkColor( hdc, 0xffffffff );
76 ok( color == 0x12345678, "wrong color %08x\n", color );
77 color = GetBkColor( hdc );
78 ok( color == 0xffffffff, "wrong color %08x\n", color );
79 color = SetBkColor( hdc, 0 );
80 ok( color == 0xffffffff, "wrong color %08x\n", color );
81 color = GetBkColor( hdc );
82 ok( color == 0, "wrong color %08x\n", color );
84 color = SetTextColor( hdc, 0xffeeddcc );
85 ok( color == 0, "initial color %08x\n", color );
86 color = GetTextColor( hdc );
87 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
88 color = SetTextColor( hdc, 0xffffffff );
89 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
90 color = GetTextColor( hdc );
91 ok( color == 0xffffffff, "wrong color %08x\n", color );
92 color = SetTextColor( hdc, 0 );
93 ok( color == 0xffffffff, "wrong color %08x\n", color );
94 color = GetTextColor( hdc );
95 ok( color == 0, "wrong color %08x\n", color );
97 extra = GetTextCharacterExtra( hdc );
98 ok( extra == 0, "initial extra %d\n", extra );
99 SetTextCharacterExtra( hdc, 123 );
100 extra = GetTextCharacterExtra( hdc );
101 ok( extra == 123, "initial extra %d\n", extra );
102 SetMapMode( hdc, MM_LOMETRIC );
103 extra = GetTextCharacterExtra( hdc );
104 ok( extra == 123, "initial extra %d\n", extra );
105 SetMapMode( hdc, MM_TEXT );
106 extra = GetTextCharacterExtra( hdc );
107 ok( extra == 123, "initial extra %d\n", extra );
109 DeleteDC( hdc );
112 static void test_savedc_2(void)
114 HWND hwnd;
115 HDC hdc;
116 HRGN hrgn;
117 RECT rc, rc_clip;
118 int ret;
120 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
121 0, 0, 0, NULL);
122 assert(hwnd != 0);
123 ShowWindow(hwnd, SW_SHOW);
124 UpdateWindow(hwnd);
126 hrgn = CreateRectRgn(0, 0, 0, 0);
127 assert(hrgn != 0);
129 hdc = GetDC(hwnd);
130 ok(hdc != NULL, "GetDC failed\n");
132 ret = GetClipBox(hdc, &rc_clip);
133 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
134 ret = GetClipRgn(hdc, hrgn);
135 ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
136 ret = GetRgnBox(hrgn, &rc);
137 ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
138 ret, rc.left, rc.top, rc.right, rc.bottom);
139 /*dump_region(hrgn);*/
140 SetRect(&rc, 0, 0, 100, 100);
141 ok(EqualRect(&rc, &rc_clip),
142 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
143 rc.left, rc.top, rc.right, rc.bottom,
144 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
146 ret = SaveDC(hdc);
147 ok(ret == 1, "ret = %d\n", ret);
149 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
150 if (ret == COMPLEXREGION)
152 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
153 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
154 /* let's make sure that it's a simple region */
155 ret = GetClipRgn(hdc, hrgn);
156 ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
157 dump_region(hrgn);
159 else
160 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
162 ret = GetClipBox(hdc, &rc_clip);
163 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
164 SetRect(&rc, 0, 0, 50, 50);
165 ok(EqualRect(&rc, &rc_clip),
166 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
167 rc.left, rc.top, rc.right, rc.bottom,
168 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
170 ret = RestoreDC(hdc, 1);
171 ok(ret, "ret = %d\n", ret);
173 ret = GetClipBox(hdc, &rc_clip);
174 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
175 SetRect(&rc, 0, 0, 100, 100);
176 ok(EqualRect(&rc, &rc_clip),
177 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
178 rc.left, rc.top, rc.right, rc.bottom,
179 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
181 DeleteObject(hrgn);
182 ReleaseDC(hwnd, hdc);
183 DestroyWindow(hwnd);
186 static void test_savedc(void)
188 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
189 int ret;
191 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
193 ret = SaveDC(hdc);
194 ok(ret == 1, "ret = %d\n", ret);
195 ret = SaveDC(hdc);
196 ok(ret == 2, "ret = %d\n", ret);
197 ret = SaveDC(hdc);
198 ok(ret == 3, "ret = %d\n", ret);
199 ret = RestoreDC(hdc, -1);
200 ok(ret, "ret = %d\n", ret);
201 ret = SaveDC(hdc);
202 ok(ret == 3, "ret = %d\n", ret);
203 ret = RestoreDC(hdc, 1);
204 ok(ret, "ret = %d\n", ret);
205 ret = SaveDC(hdc);
206 ok(ret == 1, "ret = %d\n", ret);
207 ret = SaveDC(hdc);
208 ok(ret == 2, "ret = %d\n", ret);
209 ret = SaveDC(hdc);
210 ok(ret == 3, "ret = %d\n", ret);
211 ret = RestoreDC(hdc, -2);
212 ok(ret, "ret = %d\n", ret);
213 ret = SaveDC(hdc);
214 ok(ret == 2, "ret = %d\n", ret);
215 ret = RestoreDC(hdc, -2);
216 ok(ret, "ret = %d\n", ret);
217 ret = SaveDC(hdc);
218 ok(ret == 1, "ret = %d\n", ret);
219 ret = SaveDC(hdc);
220 ok(ret == 2, "ret = %d\n", ret);
221 ret = RestoreDC(hdc, -4);
222 ok(!ret, "ret = %d\n", ret);
223 ret = RestoreDC(hdc, 3);
224 ok(!ret, "ret = %d\n", ret);
226 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
227 ret = RestoreDC(hdc, -3);
228 ok(!ret ||
229 broken(ret), /* Win9x */
230 "ret = %d\n", ret);
232 /* Trying to clear an empty save stack fails. */
233 ret = RestoreDC(hdc, -3);
234 ok(!ret, "ret = %d\n", ret);
236 ret = SaveDC(hdc);
237 ok(ret == 3 ||
238 broken(ret == 1), /* Win9x */
239 "ret = %d\n", ret);
241 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
242 ret = RestoreDC(hdc, 0);
243 ok(!ret ||
244 broken(ret), /* Win9x */
245 "ret = %d\n", ret);
247 /* Trying to clear an empty save stack fails. */
248 ret = RestoreDC(hdc, 0);
249 ok(!ret, "ret = %d\n", ret);
251 ret = RestoreDC(hdc, 1);
252 ok(ret ||
253 broken(!ret), /* Win9x */
254 "ret = %d\n", ret);
256 DeleteDC(hdc);
259 static void test_GdiConvertToDevmodeW(void)
261 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
262 DEVMODEA dmA;
263 DEVMODEW *dmW;
264 BOOL ret;
266 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
267 if (!pGdiConvertToDevmodeW)
269 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
270 return;
273 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dmA);
274 ok(ret, "EnumDisplaySettingsExA error %u\n", GetLastError());
275 ok(dmA.dmSize >= FIELD_OFFSET(DEVMODEA, dmICMMethod), "dmSize is too small: %04x\n", dmA.dmSize);
276 ok(dmA.dmSize <= sizeof(DEVMODEA), "dmSize is too large: %04x\n", dmA.dmSize);
278 dmW = pGdiConvertToDevmodeW(&dmA);
279 ok(dmW->dmSize >= FIELD_OFFSET(DEVMODEW, dmICMMethod), "dmSize is too small: %04x\n", dmW->dmSize);
280 ok(dmW->dmSize <= sizeof(DEVMODEW), "dmSize is too large: %04x\n", dmW->dmSize);
281 HeapFree(GetProcessHeap(), 0, dmW);
283 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + sizeof(dmA.dmFields);
284 dmW = pGdiConvertToDevmodeW(&dmA);
285 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dmW->dmFields),
286 "wrong size %u\n", dmW->dmSize);
287 HeapFree(GetProcessHeap(), 0, dmW);
289 dmA.dmICMMethod = DMICMMETHOD_NONE;
290 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod) + sizeof(dmA.dmICMMethod);
291 dmW = pGdiConvertToDevmodeW(&dmA);
292 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod) + sizeof(dmW->dmICMMethod),
293 "wrong size %u\n", dmW->dmSize);
294 ok(dmW->dmICMMethod == DMICMMETHOD_NONE,
295 "expected DMICMMETHOD_NONE, got %u\n", dmW->dmICMMethod);
296 HeapFree(GetProcessHeap(), 0, dmW);
298 dmA.dmSize = 1024;
299 dmW = pGdiConvertToDevmodeW(&dmA);
300 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmPanningHeight) + sizeof(dmW->dmPanningHeight),
301 "wrong size %u\n", dmW->dmSize);
302 HeapFree(GetProcessHeap(), 0, dmW);
304 SetLastError(0xdeadbeef);
305 dmA.dmSize = 0;
306 dmW = pGdiConvertToDevmodeW(&dmA);
307 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
308 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
310 /* this is the minimal dmSize that XP accepts */
311 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
312 dmW = pGdiConvertToDevmodeW(&dmA);
313 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields),
314 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW, dmFields), dmW->dmSize);
315 HeapFree(GetProcessHeap(), 0, dmW);
318 static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale )
320 static const int caps[] =
322 DRIVERVERSION,
323 TECHNOLOGY,
324 HORZSIZE,
325 VERTSIZE,
326 HORZRES,
327 VERTRES,
328 BITSPIXEL,
329 PLANES,
330 NUMBRUSHES,
331 NUMPENS,
332 NUMMARKERS,
333 NUMFONTS,
334 NUMCOLORS,
335 PDEVICESIZE,
336 CURVECAPS,
337 LINECAPS,
338 POLYGONALCAPS,
339 /* TEXTCAPS broken on printer DC on winxp */
340 CLIPCAPS,
341 RASTERCAPS,
342 ASPECTX,
343 ASPECTY,
344 ASPECTXY,
345 LOGPIXELSX,
346 LOGPIXELSY,
347 SIZEPALETTE,
348 NUMRESERVED,
349 COLORRES,
350 PHYSICALWIDTH,
351 PHYSICALHEIGHT,
352 PHYSICALOFFSETX,
353 PHYSICALOFFSETY,
354 SCALINGFACTORX,
355 SCALINGFACTORY,
356 VREFRESH,
357 DESKTOPVERTRES,
358 DESKTOPHORZRES,
359 BLTALIGNMENT,
360 SHADEBLENDCAPS
362 unsigned int i;
363 WORD ramp[3][256];
364 BOOL ret;
365 RECT rect;
366 UINT type;
368 if (GetObjectType( hdc ) == OBJ_METADC)
370 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
371 ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
372 "wrong caps on %s for %u: %u\n", descr, caps[i],
373 GetDeviceCaps( hdc, caps[i] ) );
375 SetLastError( 0xdeadbeef );
376 ret = GetDeviceGammaRamp( hdc, &ramp );
377 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
378 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
379 "wrong error %u on %s\n", GetLastError(), descr );
380 type = GetClipBox( hdc, &rect );
381 ok( type == ERROR, "GetClipBox returned %d on %s\n", type, descr );
383 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
384 SetMapMode( hdc, MM_TEXT );
385 Rectangle( hdc, 2, 2, 5, 5 );
386 type = GetBoundsRect( hdc, &rect, DCB_RESET );
387 ok( !type, "GetBoundsRect succeeded on %s\n", descr );
388 type = SetBoundsRect( hdc, &rect, DCB_RESET | DCB_ENABLE );
389 ok( !type, "SetBoundsRect succeeded on %s\n", descr );
391 else
393 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
395 INT precision = 0;
396 INT hdc_caps = GetDeviceCaps( hdc, caps[i] );
398 switch (caps[i])
400 case HORZSIZE:
401 case VERTSIZE:
402 hdc_caps /= scale;
403 precision = 1;
404 break;
405 case LOGPIXELSX:
406 case LOGPIXELSY:
407 hdc_caps *= scale;
408 break;
411 ok( abs(hdc_caps - GetDeviceCaps( ref_dc, caps[i] )) <= precision,
412 "mismatched caps on %s for %u: %u/%u (scale %d)\n", descr, caps[i],
413 hdc_caps, GetDeviceCaps( ref_dc, caps[i] ), scale );
416 SetLastError( 0xdeadbeef );
417 ret = GetDeviceGammaRamp( hdc, &ramp );
418 if (GetObjectType( hdc ) != OBJ_DC || GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER)
420 ok( !ret, "GetDeviceGammaRamp succeeded on %s (type %d)\n", descr, GetObjectType( hdc ) );
421 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
422 "wrong error %u on %s\n", GetLastError(), descr );
424 else
425 ok( ret || broken(!ret) /* NT4 */, "GetDeviceGammaRamp failed on %s (type %d), error %u\n", descr, GetObjectType( hdc ), GetLastError() );
426 type = GetClipBox( hdc, &rect );
427 if (GetObjectType( hdc ) == OBJ_ENHMETADC)
428 todo_wine ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
429 else
430 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
432 type = GetBoundsRect( hdc, &rect, 0 );
433 ok( type == DCB_RESET || broken(type == DCB_SET) /* XP */,
434 "GetBoundsRect returned type %x for %s\n", type, descr );
435 if (type == DCB_RESET)
436 ok( rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0,
437 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
438 rect.left, rect.top, rect.right, rect.bottom, type, descr );
439 type = SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
440 ok( type == (DCB_RESET | DCB_DISABLE) || broken(type == (DCB_SET | DCB_ENABLE)) /* XP */,
441 "SetBoundsRect returned %x for %s (hdc type %d)\n", type, descr, GetObjectType( hdc ) );
443 SetMapMode( hdc, MM_TEXT );
444 Rectangle( hdc, 2, 2, 4, 4 );
445 type = GetBoundsRect( hdc, &rect, DCB_RESET );
446 if (GetObjectType( hdc ) == OBJ_ENHMETADC || (GetObjectType( hdc ) == OBJ_DC && GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER))
447 todo_wine
448 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
449 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
450 rect.left, rect.top, rect.right, rect.bottom, type, descr );
451 else
452 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
453 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
454 rect.left, rect.top, rect.right, rect.bottom, type, descr );
457 type = GetClipBox( ref_dc, &rect );
458 if (type != COMPLEXREGION && type != ERROR) /* region can be complex on multi-monitor setups */
460 RECT ref_rect;
462 ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
463 if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY)
465 if (GetSystemMetrics( SM_CXSCREEN ) != GetSystemMetrics( SM_CXVIRTUALSCREEN ))
466 todo_wine ok( GetDeviceCaps( ref_dc, DESKTOPHORZRES ) == GetSystemMetrics( SM_CXSCREEN ),
467 "Got DESKTOPHORZRES %d on %s, expected %d\n",
468 GetDeviceCaps( ref_dc, DESKTOPHORZRES ), descr, GetSystemMetrics( SM_CXSCREEN ) );
469 else
470 ok( GetDeviceCaps( ref_dc, DESKTOPHORZRES ) == GetSystemMetrics( SM_CXSCREEN ),
471 "Got DESKTOPHORZRES %d on %s, expected %d\n",
472 GetDeviceCaps( ref_dc, DESKTOPHORZRES ), descr, GetSystemMetrics( SM_CXSCREEN ) );
474 if (GetSystemMetrics( SM_CYSCREEN ) != GetSystemMetrics( SM_CYVIRTUALSCREEN ))
475 todo_wine ok( GetDeviceCaps( ref_dc, DESKTOPVERTRES ) == GetSystemMetrics( SM_CYSCREEN ),
476 "Got DESKTOPVERTRES %d on %s, expected %d\n",
477 GetDeviceCaps( ref_dc, DESKTOPVERTRES ), descr, GetSystemMetrics( SM_CYSCREEN ) );
478 else
479 ok( GetDeviceCaps( ref_dc, DESKTOPVERTRES ) == GetSystemMetrics( SM_CYSCREEN ),
480 "Got DESKTOPVERTRES %d on %s, expected %d\n",
481 GetDeviceCaps( ref_dc, DESKTOPVERTRES ), descr, GetSystemMetrics( SM_CYSCREEN ) );
483 SetRect( &ref_rect, GetSystemMetrics( SM_XVIRTUALSCREEN ), GetSystemMetrics( SM_YVIRTUALSCREEN ),
484 GetSystemMetrics( SM_XVIRTUALSCREEN ) + GetSystemMetrics( SM_CXVIRTUALSCREEN ),
485 GetSystemMetrics( SM_YVIRTUALSCREEN ) + GetSystemMetrics( SM_CYVIRTUALSCREEN ) );
487 else
489 SetRect( &ref_rect, 0, 0, GetDeviceCaps( ref_dc, DESKTOPHORZRES ),
490 GetDeviceCaps( ref_dc, DESKTOPVERTRES ) );
493 if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY && GetObjectType( hdc ) != OBJ_ENHMETADC &&
494 (GetSystemMetrics( SM_XVIRTUALSCREEN ) || GetSystemMetrics( SM_YVIRTUALSCREEN )))
495 todo_wine ok( EqualRect( &rect, &ref_rect ), "GetClipBox returned %d,%d,%d,%d on %s\n",
496 rect.left, rect.top, rect.right, rect.bottom, descr );
497 else
498 ok( EqualRect( &rect, &ref_rect ), "GetClipBox returned %d,%d,%d,%d on %s\n",
499 rect.left, rect.top, rect.right, rect.bottom, descr );
502 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_ACCUMULATE );
503 SetMapMode( ref_dc, MM_TEXT );
504 Rectangle( ref_dc, 3, 3, 5, 5 );
505 type = GetBoundsRect( ref_dc, &rect, DCB_RESET );
506 /* it may or may not work on non-memory DCs */
507 ok( (rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0 && type == DCB_RESET) ||
508 (rect.left == 3 && rect.top == 3 && rect.right == 5 && rect.bottom == 5 && type == DCB_SET),
509 "GetBoundsRect returned %d,%d,%d,%d type %x on %s\n",
510 rect.left, rect.top, rect.right, rect.bottom, type, descr );
512 if (GetObjectType( hdc ) == OBJ_MEMDC)
514 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
515 BITMAPINFO *info = (BITMAPINFO *)buffer;
516 HBITMAP dib, old;
518 memset( buffer, 0, sizeof(buffer) );
519 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
520 info->bmiHeader.biWidth = 16;
521 info->bmiHeader.biHeight = 16;
522 info->bmiHeader.biPlanes = 1;
523 info->bmiHeader.biBitCount = 8;
524 info->bmiHeader.biCompression = BI_RGB;
525 dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
526 old = SelectObject( hdc, dib );
528 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
529 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
530 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
531 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
533 SetLastError( 0xdeadbeef );
534 ret = GetDeviceGammaRamp( hdc, &ramp );
535 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
536 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
537 "wrong error %u on %s\n", GetLastError(), descr );
539 type = GetClipBox( hdc, &rect );
540 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
541 ok( rect.left == 0 && rect.top == 0 && rect.right == 16 && rect.bottom == 16,
542 "GetClipBox returned %d,%d,%d,%d on memdc for %s\n",
543 rect.left, rect.top, rect.right, rect.bottom, descr );
545 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
546 SetMapMode( hdc, MM_TEXT );
547 Rectangle( hdc, 5, 5, 12, 14 );
548 type = GetBoundsRect( hdc, &rect, DCB_RESET );
549 ok( rect.left == 5 && rect.top == 5 && rect.right == 12 && rect.bottom == 14 && type == DCB_SET,
550 "GetBoundsRect returned %d,%d,%d,%d type %x on memdc for %s\n",
551 rect.left, rect.top, rect.right, rect.bottom, type, descr );
553 SelectObject( hdc, old );
554 DeleteObject( dib );
557 /* restore hdc state */
558 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_DISABLE );
559 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_DISABLE );
562 static void test_CreateCompatibleDC(void)
564 BOOL bRet;
565 HDC hdc, hNewDC, hdcMetafile, screen_dc;
566 HBITMAP bitmap;
567 INT caps;
568 DEVMODEA dm;
570 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
572 bRet = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
573 ok(bRet, "EnumDisplaySettingsEx failed\n");
574 dm.u1.s1.dmScale = 200;
575 dm.dmFields |= DM_SCALE;
576 hdc = CreateDCA( "DISPLAY", NULL, NULL, &dm );
578 screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
579 test_device_caps( hdc, screen_dc, "display dc", 1 );
580 ResetDCA( hdc, &dm );
581 test_device_caps( hdc, screen_dc, "display dc", 1 );
582 DeleteDC( hdc );
584 /* Create a DC compatible with the screen */
585 hdc = CreateCompatibleDC(NULL);
586 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
587 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
588 caps = GetDeviceCaps( hdc, TECHNOLOGY );
589 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
591 test_device_caps( hdc, screen_dc, "display dc", 1 );
593 /* Delete this DC, this should succeed */
594 bRet = DeleteDC(hdc);
595 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
597 /* Try to create a DC compatible to the deleted DC. This has to fail */
598 hNewDC = CreateCompatibleDC(hdc);
599 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
601 hdc = GetDC( 0 );
602 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
603 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
604 hNewDC = CreateCompatibleDC( hdcMetafile );
605 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
606 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
607 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
608 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
609 test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
610 ResetDCA( hdcMetafile, &dm );
611 test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
612 DeleteDC( hNewDC );
613 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
614 ReleaseDC( 0, hdc );
616 hdcMetafile = CreateMetaFileA(NULL);
617 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
618 hNewDC = CreateCompatibleDC( hdcMetafile );
619 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
620 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
621 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
622 test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
623 ResetDCA( hdcMetafile, &dm );
624 test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
625 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
627 DeleteObject( bitmap );
628 DeleteDC( screen_dc );
631 static void test_DC_bitmap(void)
633 PIXELFORMATDESCRIPTOR descr;
634 HDC hdc, hdcmem;
635 DWORD bits[64];
636 HBITMAP hbmp, oldhbmp;
637 COLORREF col;
638 int i, bitspixel;
639 int ret, ret2;
641 /* fill bitmap data with b&w pattern */
642 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
644 hdc = GetDC(0);
645 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
646 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
647 /* create a memory dc */
648 hdcmem = CreateCompatibleDC( hdc);
649 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
651 /* test DescribePixelFormat with descr == NULL */
652 ret2 = DescribePixelFormat(hdcmem, 0, sizeof(descr), NULL);
653 ok(ret2 > 0, "expected ret2 > 0, got %d\n", ret2);
654 ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), NULL);
655 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
656 ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), NULL);
657 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
659 /* test DescribePixelFormat with descr != NULL */
660 memset(&descr, 0, sizeof(descr));
661 ret = DescribePixelFormat(hdcmem, 0, sizeof(descr), &descr);
662 ok(ret == 0, "expected ret == 0, got %d\n", ret);
663 ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
665 memset(&descr, 0, sizeof(descr));
666 ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), &descr);
667 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
668 ok(descr.nSize == sizeof(descr), "expected desc.nSize == sizeof(descr), got %d\n", descr.nSize);
670 memset(&descr, 0, sizeof(descr));
671 ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), &descr);
672 ok(ret == 0, "expected ret == 0, got %d\n", ret);
673 ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
675 /* test monochrome bitmap: should always work */
676 hbmp = CreateBitmap(32, 32, 1, 1, bits);
677 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
678 oldhbmp = SelectObject( hdcmem, hbmp);
679 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
680 col = GetPixel( hdcmem, 0, 0);
681 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
682 col = GetPixel( hdcmem, 1, 1);
683 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
684 col = GetPixel( hdcmem, 100, 1);
685 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
686 SelectObject( hdcmem, oldhbmp);
687 DeleteObject( hbmp);
689 /* test with 2 bits color depth, not likely to succeed */
690 hbmp = CreateBitmap(16, 16, 1, 2, bits);
691 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
692 oldhbmp = SelectObject( hdcmem, hbmp);
693 if( bitspixel != 2)
694 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
695 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
696 DeleteObject( hbmp);
698 /* test with 16 bits color depth, might succeed */
699 hbmp = CreateBitmap(6, 6, 1, 16, bits);
700 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
701 oldhbmp = SelectObject( hdcmem, hbmp);
702 if( bitspixel == 16) {
703 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
704 col = GetPixel( hdcmem, 0, 0);
705 ok( col == 0xffffff,
706 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
707 col = GetPixel( hdcmem, 1, 1);
708 ok( col == 0x000000,
709 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
711 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
712 DeleteObject( hbmp);
714 /* test with 32 bits color depth, probably succeed */
715 hbmp = CreateBitmap(4, 4, 1, 32, bits);
716 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
717 oldhbmp = SelectObject( hdcmem, hbmp);
718 if( bitspixel == 32) {
719 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
720 col = GetPixel( hdcmem, 0, 0);
721 ok( col == 0xffffff,
722 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
723 col = GetPixel( hdcmem, 1, 1);
724 ok( col == 0x000000,
725 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
727 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
728 DeleteObject( hbmp);
729 ReleaseDC( 0, hdc );
732 static void test_DeleteDC(void)
734 HWND hwnd;
735 HDC hdc, hdc_test;
736 WNDCLASSEXA cls;
737 int ret;
739 /* window DC */
740 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
741 0, 0, 0, NULL);
742 ok(hwnd != 0, "CreateWindowExA failed\n");
744 hdc = GetDC(hwnd);
745 ok(hdc != 0, "GetDC failed\n");
746 ret = GetObjectType(hdc);
747 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
748 ret = DeleteDC(hdc);
749 ok(ret, "DeleteDC failed\n");
750 ret = GetObjectType(hdc);
751 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
753 hdc = GetWindowDC(hwnd);
754 ok(hdc != 0, "GetDC failed\n");
755 ret = GetObjectType(hdc);
756 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
757 ret = DeleteDC(hdc);
758 ok(ret, "DeleteDC failed\n");
759 ret = GetObjectType(hdc);
760 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
762 DestroyWindow(hwnd);
764 /* desktop window DC */
765 hwnd = GetDesktopWindow();
766 ok(hwnd != 0, "GetDesktopWindow failed\n");
768 hdc = GetDC(hwnd);
769 ok(hdc != 0, "GetDC failed\n");
770 ret = GetObjectType(hdc);
771 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
772 ret = DeleteDC(hdc);
773 ok(ret, "DeleteDC failed\n");
774 ret = GetObjectType(hdc);
775 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
777 hdc = GetWindowDC(hwnd);
778 ok(hdc != 0, "GetDC failed\n");
779 ret = GetObjectType(hdc);
780 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
781 ret = DeleteDC(hdc);
782 ok(ret, "DeleteDC failed\n");
783 ret = GetObjectType(hdc);
784 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
786 /* CS_CLASSDC */
787 memset(&cls, 0, sizeof(cls));
788 cls.cbSize = sizeof(cls);
789 cls.style = CS_CLASSDC;
790 cls.hInstance = GetModuleHandleA(NULL);
791 cls.lpszClassName = "Wine class DC";
792 cls.lpfnWndProc = DefWindowProcA;
793 ret = RegisterClassExA(&cls);
794 ok(ret, "RegisterClassExA failed\n");
796 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
797 0, 0, 0, NULL);
798 ok(hwnd != 0, "CreateWindowExA failed\n");
800 hdc = GetDC(hwnd);
801 ok(hdc != 0, "GetDC failed\n");
802 ret = GetObjectType(hdc);
803 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
804 ret = DeleteDC(hdc);
805 ok(ret, "DeleteDC failed\n");
806 ret = GetObjectType(hdc);
807 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
808 ret = ReleaseDC(hwnd, hdc);
809 ok(ret, "ReleaseDC failed\n");
810 ret = GetObjectType(hdc);
811 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
813 hdc_test = hdc;
815 hdc = GetWindowDC(hwnd);
816 ok(hdc != 0, "GetDC failed\n");
817 ret = GetObjectType(hdc);
818 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
819 ret = DeleteDC(hdc);
820 ok(ret, "DeleteDC failed\n");
821 ret = GetObjectType(hdc);
822 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
824 DestroyWindow(hwnd);
826 ret = GetObjectType(hdc_test);
827 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
829 ret = UnregisterClassA("Wine class DC", GetModuleHandleA(NULL));
830 ok(ret, "UnregisterClassA failed\n");
832 ret = GetObjectType(hdc_test);
833 todo_wine
834 ok(!ret, "GetObjectType should fail for a deleted DC\n");
836 /* CS_OWNDC */
837 memset(&cls, 0, sizeof(cls));
838 cls.cbSize = sizeof(cls);
839 cls.style = CS_OWNDC;
840 cls.hInstance = GetModuleHandleA(NULL);
841 cls.lpszClassName = "Wine own DC";
842 cls.lpfnWndProc = DefWindowProcA;
843 ret = RegisterClassExA(&cls);
844 ok(ret, "RegisterClassExA failed\n");
846 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
847 0, 0, 0, NULL);
848 ok(hwnd != 0, "CreateWindowExA failed\n");
850 hdc = GetDC(hwnd);
851 ok(hdc != 0, "GetDC failed\n");
852 ret = GetObjectType(hdc);
853 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
854 ret = DeleteDC(hdc);
855 ok(ret, "DeleteDC failed\n");
856 ret = GetObjectType(hdc);
857 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
858 ret = ReleaseDC(hwnd, hdc);
859 ok(ret, "ReleaseDC failed\n");
860 ret = GetObjectType(hdc);
861 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
863 hdc = GetWindowDC(hwnd);
864 ok(hdc != 0, "GetDC failed\n");
865 ret = GetObjectType(hdc);
866 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
867 ret = DeleteDC(hdc);
868 ok(ret, "DeleteDC failed\n");
869 ret = GetObjectType(hdc);
870 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
872 DestroyWindow(hwnd);
874 ret = UnregisterClassA("Wine own DC", GetModuleHandleA(NULL));
875 ok(ret, "UnregisterClassA failed\n");
878 static void test_boundsrect(void)
880 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
881 BITMAPINFO *info = (BITMAPINFO *)buffer;
882 HDC hdc;
883 HBITMAP bitmap, dib, old;
884 RECT rect, expect, set_rect;
885 UINT ret;
886 int i, level;
888 hdc = CreateCompatibleDC(0);
889 ok(hdc != NULL, "CreateCompatibleDC failed\n");
890 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
891 old = SelectObject( hdc, bitmap );
893 ret = GetBoundsRect(hdc, NULL, 0);
894 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
896 ret = GetBoundsRect(hdc, NULL, ~0U);
897 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
899 /* Test parameter handling order. */
900 SetRect(&set_rect, 10, 20, 40, 50);
901 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
902 ok(ret & DCB_RESET,
903 "Expected return flag DCB_RESET to be set, got %u\n", ret);
905 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
906 ok(ret == 0,
907 "Expected GetBoundsRect to return 0, got %u\n", ret);
909 ret = GetBoundsRect(hdc, &rect, 0);
910 ok(ret == DCB_RESET,
911 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
912 SetRect(&expect, 0, 0, 0, 0);
913 ok(EqualRect(&rect, &expect) ||
914 broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
915 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
916 rect.left, rect.top, rect.right, rect.bottom);
918 ret = GetBoundsRect(NULL, NULL, 0);
919 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
921 ret = GetBoundsRect(NULL, NULL, ~0U);
922 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
924 ret = SetBoundsRect(NULL, NULL, 0);
925 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
927 ret = SetBoundsRect(NULL, NULL, ~0U);
928 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
930 SetRect(&set_rect, 10, 20, 40, 50);
931 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
932 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
934 ret = GetBoundsRect(hdc, &rect, 0);
935 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
936 SetRect(&expect, 10, 20, 40, 50);
937 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
938 rect.left, rect.top, rect.right, rect.bottom);
940 SetMapMode( hdc, MM_ANISOTROPIC );
941 SetViewportExtEx( hdc, 2, 2, NULL );
942 ret = GetBoundsRect(hdc, &rect, 0);
943 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
944 SetRect(&expect, 5, 10, 20, 25);
945 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
946 rect.left, rect.top, rect.right, rect.bottom);
948 SetViewportOrgEx( hdc, 20, 30, NULL );
949 ret = GetBoundsRect(hdc, &rect, 0);
950 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
951 SetRect(&expect, -5, -5, 10, 10);
952 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
953 rect.left, rect.top, rect.right, rect.bottom);
955 SetRect(&set_rect, 10, 20, 40, 50);
956 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
957 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
959 ret = GetBoundsRect(hdc, &rect, 0);
960 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
961 SetRect(&expect, 10, 20, 40, 50);
962 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
963 rect.left, rect.top, rect.right, rect.bottom);
965 SetMapMode( hdc, MM_TEXT );
966 SetViewportOrgEx( hdc, 0, 0, NULL );
967 ret = GetBoundsRect(hdc, &rect, 0);
968 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
969 SetRect(&expect, 40, 70, 100, 130);
970 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
971 rect.left, rect.top, rect.right, rect.bottom);
973 if (pSetLayout)
975 pSetLayout( hdc, LAYOUT_RTL );
976 ret = GetBoundsRect(hdc, &rect, 0);
977 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
978 SetRect(&expect, 159, 70, 99, 130);
979 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
980 rect.left, rect.top, rect.right, rect.bottom);
981 SetRect(&set_rect, 50, 25, 30, 35);
982 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
983 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
984 ret = GetBoundsRect(hdc, &rect, 0);
985 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
986 SetRect(&expect, 50, 25, 30, 35);
987 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
988 rect.left, rect.top, rect.right, rect.bottom);
990 pSetLayout( hdc, LAYOUT_LTR );
991 ret = GetBoundsRect(hdc, &rect, 0);
992 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
993 SetRect(&expect, 149, 25, 169, 35);
994 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
995 rect.left, rect.top, rect.right, rect.bottom);
998 /* empty rect resets, except on nt4 */
999 SetRect(&expect, 20, 20, 10, 10);
1000 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
1001 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
1002 ret = GetBoundsRect(hdc, &rect, 0);
1003 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
1004 "GetBoundsRect returned %x\n", ret);
1005 if (ret == DCB_RESET)
1007 SetRect(&expect, 0, 0, 0, 0);
1008 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
1009 rect.left, rect.top, rect.right, rect.bottom);
1011 SetRect(&expect, 20, 20, 20, 20);
1012 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
1013 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
1014 ret = GetBoundsRect(hdc, &rect, 0);
1015 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
1016 SetRect(&expect, 0, 0, 0, 0);
1017 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
1018 rect.left, rect.top, rect.right, rect.bottom);
1021 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
1022 MoveToEx( hdc, 10, 10, NULL );
1023 LineTo( hdc, 20, 20 );
1024 ret = GetBoundsRect( hdc, &rect, 0 );
1025 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1026 SetRect( &expect, 10, 10, 21, 21 );
1027 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1028 SetRect( &rect, 8, 8, 23, 23 );
1029 expect = rect;
1030 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
1031 ret = GetBoundsRect( hdc, &rect, 0 );
1032 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1033 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1035 level = SaveDC( hdc );
1036 LineTo( hdc, 30, 25 );
1037 ret = GetBoundsRect( hdc, &rect, 0 );
1038 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1039 SetRect( &expect, 8, 8, 31, 26 );
1040 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1041 SetBoundsRect( hdc, NULL, DCB_DISABLE );
1042 LineTo( hdc, 40, 40 );
1043 ret = GetBoundsRect( hdc, &rect, 0 );
1044 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1045 SetRect( &expect, 8, 8, 31, 26 );
1046 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1047 SetRect( &rect, 6, 6, 30, 30 );
1048 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
1049 ret = GetBoundsRect( hdc, &rect, 0 );
1050 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1051 SetRect( &expect, 6, 6, 31, 30 );
1052 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1054 RestoreDC( hdc, level );
1055 ret = GetBoundsRect( hdc, &rect, 0 );
1056 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1057 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1058 LineTo( hdc, 40, 40 );
1059 ret = GetBoundsRect( hdc, &rect, 0 );
1060 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1061 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1063 SelectObject( hdc, old );
1064 ret = GetBoundsRect( hdc, &rect, 0 );
1065 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1066 SetRect( &expect, 6, 6, 1, 1 );
1067 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1068 SetBoundsRect( hdc, NULL, DCB_ENABLE );
1069 LineTo( hdc, 50, 40 );
1071 SelectObject( hdc, bitmap );
1072 ret = GetBoundsRect( hdc, &rect, 0 );
1073 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1074 SetRect( &expect, 6, 6, 51, 41 );
1075 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1076 SelectObject( hdc, GetStockObject( NULL_PEN ));
1077 LineTo( hdc, 50, 50 );
1078 ret = GetBoundsRect( hdc, &rect, 0 );
1079 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1080 SetRect( &expect, 6, 6, 51, 51 );
1081 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1083 memset( buffer, 0, sizeof(buffer) );
1084 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1085 info->bmiHeader.biWidth = 256;
1086 info->bmiHeader.biHeight = 256;
1087 info->bmiHeader.biPlanes = 1;
1088 info->bmiHeader.biBitCount = 8;
1089 info->bmiHeader.biCompression = BI_RGB;
1090 dib = CreateDIBSection( 0, info, DIB_RGB_COLORS, NULL, NULL, 0 );
1091 ok( dib != 0, "failed to create DIB\n" );
1092 SelectObject( hdc, dib );
1093 ret = GetBoundsRect( hdc, &rect, 0 );
1094 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1095 SetRect( &expect, 6, 6, 51, 51 );
1096 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1097 LineTo( hdc, 55, 30 );
1098 ret = GetBoundsRect( hdc, &rect, 0 );
1099 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1100 SetRect( &expect, 6, 6, 56, 51 );
1101 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1102 LineTo( hdc, 300, 30 );
1103 ret = GetBoundsRect( hdc, &rect, 0 );
1104 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1105 SetRect( &expect, 6, 6, 256, 51 );
1106 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1107 LineTo( hdc, -300, -300 );
1108 ret = GetBoundsRect( hdc, &rect, 0 );
1109 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1110 SetRect( &expect, 0, 0, 256, 51 );
1111 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1113 /* test the wide pen heuristics */
1114 SetBoundsRect( hdc, NULL, DCB_ENABLE | DCB_RESET );
1115 for (i = 0; i < 1000; i++)
1117 static const UINT endcaps[3] = { PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT };
1118 static const UINT joins[3] = { PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER };
1119 LOGBRUSH brush = { BS_SOLID, RGB(0,0,0), 0 };
1120 UINT join = joins[i % 3];
1121 UINT endcap = endcaps[(i / 3) % 3];
1122 INT inflate, width = 1 + i / 9;
1123 HPEN pen = ExtCreatePen( PS_GEOMETRIC | join | endcap | PS_SOLID, width, &brush, 0, NULL );
1124 HPEN old = SelectObject( hdc, pen );
1125 MoveToEx( hdc, 100, 100, NULL );
1126 LineTo( hdc, 160, 100 );
1127 LineTo( hdc, 100, 160 );
1128 LineTo( hdc, 160, 160 );
1129 GetBoundsRect( hdc, &rect, DCB_RESET );
1130 SetRect( &expect, 100, 100, 161, 161 );
1132 inflate = width + 2;
1133 if (join == PS_JOIN_MITER)
1135 inflate *= 5;
1136 if (endcap == PS_ENDCAP_SQUARE)
1137 InflateRect( &expect, (inflate * 3 + 1) / 2, (inflate * 3 + 1) / 2 );
1138 else
1139 InflateRect( &expect, inflate, inflate );
1141 else
1143 if (endcap == PS_ENDCAP_SQUARE)
1144 InflateRect( &expect, inflate - inflate / 4, inflate - inflate / 4 );
1145 else
1146 InflateRect( &expect, (inflate + 1) / 2, (inflate + 1) / 2 );
1148 expect.left = max( expect.left, 0 );
1149 expect.top = max( expect.top, 0 );
1150 expect.right = min( expect.right, 256 );
1151 expect.bottom = min( expect.bottom, 256 );
1152 ok( EqualRect(&rect, &expect),
1153 "Got %d,%d,%d,%d expected %d,%d,%d,%d %u/%x/%x\n",
1154 rect.left, rect.top, rect.right, rect.bottom,
1155 expect.left, expect.top, expect.right, expect.bottom, width, endcap, join );
1156 DeleteObject( SelectObject( hdc, old ));
1159 DeleteDC( hdc );
1160 DeleteObject( bitmap );
1161 DeleteObject( dib );
1164 static void test_desktop_colorres(void)
1166 HDC hdc = GetDC(NULL);
1167 int bitspixel, colorres;
1169 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
1170 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
1172 colorres = GetDeviceCaps(hdc, COLORRES);
1173 ok(colorres != 0 ||
1174 broken(colorres == 0), /* Win9x */
1175 "Expected to get valid COLORRES capability value\n");
1177 if (colorres)
1179 switch (bitspixel)
1181 case 8:
1182 ok(colorres == 18,
1183 "Expected COLORRES to be 18, got %d\n", colorres);
1184 break;
1185 case 16:
1186 ok(colorres == 16,
1187 "Expected COLORRES to be 16, got %d\n", colorres);
1188 break;
1189 case 24:
1190 case 32:
1191 ok(colorres == 24,
1192 "Expected COLORRES to be 24, got %d\n", bitspixel);
1193 break;
1194 default:
1195 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
1196 break;
1200 ReleaseDC(NULL, hdc);
1203 static void test_gamma(void)
1205 BOOL ret;
1206 HDC hdc = GetDC(NULL);
1207 WORD oldramp[3][256], ramp[3][256];
1208 INT i;
1210 ret = GetDeviceGammaRamp(hdc, &oldramp);
1211 if (!ret)
1213 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
1214 goto done;
1217 /* try to set back old ramp */
1218 ret = SetDeviceGammaRamp(hdc, &oldramp);
1219 if (!ret)
1221 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
1222 goto done;
1225 memcpy(ramp, oldramp, sizeof(ramp));
1227 /* set one color ramp to zeros */
1228 memset(ramp[0], 0, sizeof(ramp[0]));
1229 ret = SetDeviceGammaRamp(hdc, &ramp);
1230 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1232 /* set one color ramp to a flat straight rising line */
1233 for (i = 0; i < 256; i++) ramp[0][i] = i;
1234 ret = SetDeviceGammaRamp(hdc, &ramp);
1235 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
1237 /* set one color ramp to a steep straight rising line */
1238 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
1239 ret = SetDeviceGammaRamp(hdc, &ramp);
1240 ok(ret, "SetDeviceGammaRamp failed\n");
1242 /* try a bright gamma ramp */
1243 ramp[0][0] = 0;
1244 ramp[0][1] = 0x7FFF;
1245 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
1246 ret = SetDeviceGammaRamp(hdc, &ramp);
1247 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1249 /* try ramps which are not uniform */
1250 ramp[0][0] = 0;
1251 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
1252 ret = SetDeviceGammaRamp(hdc, &ramp);
1253 ok(ret, "SetDeviceGammaRamp failed\n");
1254 ramp[0][0] = 0;
1255 for (i = 2; i < 256; i+=2)
1257 ramp[0][i - 1] = ramp[0][i - 2];
1258 ramp[0][i] = ramp[0][i - 2] + 512;
1260 ret = SetDeviceGammaRamp(hdc, &ramp);
1261 ok(ret, "SetDeviceGammaRamp failed\n");
1263 /* cleanup: set old ramp again */
1264 ret = SetDeviceGammaRamp(hdc, &oldramp);
1265 ok(ret, "SetDeviceGammaRamp failed\n");
1267 done:
1268 ReleaseDC(NULL, hdc);
1271 static BOOL is_postscript_printer(HDC hdc)
1273 char tech[256];
1275 if (ExtEscape(hdc, GETTECHNOLOGY, 0, NULL, sizeof(tech), tech) > 0)
1276 return strcmp(tech, "PostScript") == 0;
1278 return FALSE;
1281 static HDC create_printer_dc(int scale, BOOL reset)
1283 char buffer[260];
1284 DWORD len;
1285 PRINTER_INFO_2A *pbuf = NULL;
1286 DRIVER_INFO_3A *dbuf = NULL;
1287 HANDLE hprn = 0;
1288 HDC hdc = 0;
1289 HMODULE winspool = LoadLibraryA( "winspool.drv" );
1290 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
1291 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
1292 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
1293 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
1294 BOOL (WINAPI *pClosePrinter)(HANDLE);
1296 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
1297 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
1298 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
1299 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
1300 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
1302 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
1303 goto done;
1305 len = sizeof(buffer);
1306 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
1307 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
1309 pGetPrinterA( hprn, 2, NULL, 0, &len );
1310 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
1311 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
1313 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
1314 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
1315 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
1317 pbuf->pDevMode->u1.s1.dmScale = scale;
1318 pbuf->pDevMode->dmFields |= DM_SCALE;
1320 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
1321 trace( "hdc %p for driver '%s' printer '%s' port '%s' is %sPostScript\n", hdc,
1322 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName,
1323 is_postscript_printer(hdc) ? "" : "NOT " );
1325 if (reset) ResetDCA( hdc, pbuf->pDevMode );
1326 done:
1327 HeapFree( GetProcessHeap(), 0, dbuf );
1328 HeapFree( GetProcessHeap(), 0, pbuf );
1329 if (hprn) pClosePrinter( hprn );
1330 if (winspool) FreeLibrary( winspool );
1331 if (!hdc) skip( "could not create a DC for the default printer\n" );
1332 return hdc;
1335 static void test_printer_dc(void)
1337 HDC memdc, display_memdc, enhmf_dc;
1338 HBITMAP orig, bmp;
1339 DWORD ret;
1340 HDC hdc, hdc_200;
1342 hdc = create_printer_dc(100, FALSE);
1343 hdc_200 = create_printer_dc(200, FALSE);
1345 if (!hdc || !hdc_200) return;
1347 test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 );
1348 DeleteDC( hdc_200 );
1350 hdc_200 = create_printer_dc(200, TRUE);
1351 test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 );
1352 DeleteDC( hdc_200 );
1354 memdc = CreateCompatibleDC( hdc );
1355 display_memdc = CreateCompatibleDC( 0 );
1357 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
1358 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
1360 ret = GetDeviceCaps( hdc, TECHNOLOGY );
1361 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1363 ret = GetDeviceCaps( memdc, TECHNOLOGY );
1364 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1366 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
1367 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
1369 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
1370 orig = SelectObject( memdc, bmp );
1371 ok( orig != NULL, "SelectObject failed\n" );
1372 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1374 test_device_caps( memdc, hdc, "printer dc", 1 );
1376 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
1377 SelectObject( memdc, orig );
1378 DeleteObject( bmp );
1380 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
1381 orig = SelectObject( display_memdc, bmp );
1382 ok( orig != NULL, "SelectObject failed\n" );
1383 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
1384 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1385 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1386 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1388 ret = GetPixel( hdc, 0, 0 );
1389 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
1391 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1392 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1393 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 );
1394 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1396 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1397 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1398 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 );
1399 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1401 DeleteDC( memdc );
1402 DeleteDC( display_memdc );
1403 DeleteDC( hdc );
1404 DeleteObject( bmp );
1407 START_TEST(dc)
1409 pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
1410 test_dc_values();
1411 test_savedc();
1412 test_savedc_2();
1413 test_GdiConvertToDevmodeW();
1414 test_CreateCompatibleDC();
1415 test_DC_bitmap();
1416 test_DeleteDC();
1417 test_boundsrect();
1418 test_desktop_colorres();
1419 test_gamma();
1420 test_printer_dc();