winealsa: Fix AudioRenderClient Get/ReleaseBuffer protocol.
[wine] / dlls / gdi32 / tests / dc.c
1 /*
2  * Unit tests for dc functions
3  *
4  * Copyright (c) 2005 Huw Davies
5  * Copyright (c) 2005 Dmitry Timoshkov
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #define WINVER 0x0501 /* request latest DEVMODE */
23
24 #include <assert.h>
25 #include <stdio.h>
26
27 #include "wine/test.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "winspool.h"
32 #include "winerror.h"
33
34 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
35
36 static void dump_region(HRGN hrgn)
37 {
38     DWORD i, size;
39     RGNDATA *data = NULL;
40     RECT *rect;
41
42     if (!hrgn)
43     {
44         printf( "(null) region\n" );
45         return;
46     }
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 );
53     printf( "\n" );
54     HeapFree( GetProcessHeap(), 0, data );
55 }
56
57 static void test_savedc_2(void)
58 {
59     HWND hwnd;
60     HDC hdc;
61     HRGN hrgn;
62     RECT rc, rc_clip;
63     int ret;
64
65     hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
66                            0, 0, 0, NULL);
67     assert(hwnd != 0);
68     ShowWindow(hwnd, SW_SHOW);
69     UpdateWindow(hwnd);
70
71     hrgn = CreateRectRgn(0, 0, 0, 0);
72     assert(hrgn != 0);
73
74     hdc = GetDC(hwnd);
75     ok(hdc != NULL, "GetDC failed\n");
76
77     ret = GetClipBox(hdc, &rc_clip);
78     ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
79     ret = GetClipRgn(hdc, hrgn);
80     ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
81     ret = GetRgnBox(hrgn, &rc);
82     ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
83        ret, rc.left, rc.top, rc.right, rc.bottom);
84     /*dump_region(hrgn);*/
85     SetRect(&rc, 0, 0, 100, 100);
86     ok(EqualRect(&rc, &rc_clip),
87        "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
88        rc.left, rc.top, rc.right, rc.bottom,
89        rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
90
91     ret = SaveDC(hdc);
92 todo_wine
93 {
94     ok(ret == 1, "ret = %d\n", ret);
95 }
96
97     ret = IntersectClipRect(hdc, 0, 0, 50, 50);
98     if (ret == COMPLEXREGION)
99     {
100         /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
101         trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
102         /* let's make sure that it's a simple region */
103         ret = GetClipRgn(hdc, hrgn);
104         ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
105         dump_region(hrgn);
106     }
107     else
108         ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
109
110     ret = GetClipBox(hdc, &rc_clip);
111     ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
112     SetRect(&rc, 0, 0, 50, 50);
113     ok(EqualRect(&rc, &rc_clip),
114        "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
115        rc.left, rc.top, rc.right, rc.bottom,
116        rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
117
118     ret = RestoreDC(hdc, 1);
119     ok(ret, "ret = %d\n", ret);
120
121     ret = GetClipBox(hdc, &rc_clip);
122     ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
123     SetRect(&rc, 0, 0, 100, 100);
124     ok(EqualRect(&rc, &rc_clip),
125        "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
126        rc.left, rc.top, rc.right, rc.bottom,
127        rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
128
129     DeleteObject(hrgn);
130     ReleaseDC(hwnd, hdc);
131     DestroyWindow(hwnd);
132 }
133
134 static void test_savedc(void)
135 {
136     HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
137     int ret;
138
139     ok(hdc != NULL, "CreateDC rets %p\n", hdc);
140
141     ret = SaveDC(hdc);
142     ok(ret == 1, "ret = %d\n", ret);
143     ret = SaveDC(hdc);
144     ok(ret == 2, "ret = %d\n", ret);
145     ret = SaveDC(hdc);
146     ok(ret == 3, "ret = %d\n", ret);
147     ret = RestoreDC(hdc, -1);
148     ok(ret, "ret = %d\n", ret);
149     ret = SaveDC(hdc);
150     ok(ret == 3, "ret = %d\n", ret);
151     ret = RestoreDC(hdc, 1);
152     ok(ret, "ret = %d\n", ret);
153     ret = SaveDC(hdc);
154     ok(ret == 1, "ret = %d\n", ret);
155     ret = SaveDC(hdc);
156     ok(ret == 2, "ret = %d\n", ret);
157     ret = SaveDC(hdc);
158     ok(ret == 3, "ret = %d\n", ret);
159     ret = RestoreDC(hdc, -2);
160     ok(ret, "ret = %d\n", ret);
161     ret = SaveDC(hdc);
162     ok(ret == 2, "ret = %d\n", ret);
163     ret = RestoreDC(hdc, -2);
164     ok(ret, "ret = %d\n", ret);
165     ret = SaveDC(hdc);
166     ok(ret == 1, "ret = %d\n", ret);
167     ret = SaveDC(hdc);
168     ok(ret == 2, "ret = %d\n", ret); 
169     ret = RestoreDC(hdc, -4);
170     ok(!ret, "ret = %d\n", ret);
171     ret = RestoreDC(hdc, 3);
172     ok(!ret, "ret = %d\n", ret);
173
174     /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
175     ret = RestoreDC(hdc, -3);
176     ok(!ret ||
177        broken(ret), /* Win9x */
178        "ret = %d\n", ret);
179
180     /* Trying to clear an empty save stack fails. */
181     ret = RestoreDC(hdc, -3);
182     ok(!ret, "ret = %d\n", ret);
183
184     ret = SaveDC(hdc);
185     ok(ret == 3 ||
186        broken(ret == 1), /* Win9x */
187        "ret = %d\n", ret);
188
189     /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
190     ret = RestoreDC(hdc, 0);
191     ok(!ret ||
192        broken(ret), /* Win9x */
193        "ret = %d\n", ret);
194
195     /* Trying to clear an empty save stack fails. */
196     ret = RestoreDC(hdc, 0);
197     ok(!ret, "ret = %d\n", ret);
198
199     ret = RestoreDC(hdc, 1);
200     ok(ret ||
201        broken(!ret), /* Win9x */
202        "ret = %d\n", ret);
203
204     DeleteDC(hdc);
205 }
206
207 static void test_GdiConvertToDevmodeW(void)
208 {
209     DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
210     DEVMODEA dmA;
211     DEVMODEW *dmW;
212     BOOL ret;
213
214     pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
215     if (!pGdiConvertToDevmodeW)
216     {
217         win_skip("GdiConvertToDevmodeW is not available on this platform\n");
218         return;
219     }
220
221     ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dmA);
222     ok(ret, "EnumDisplaySettingsExA error %u\n", GetLastError());
223     ok(dmA.dmSize >= FIELD_OFFSET(DEVMODEA, dmICMMethod), "dmSize is too small: %04x\n", dmA.dmSize);
224     ok(dmA.dmSize <= sizeof(DEVMODEA), "dmSize is too large: %04x\n", dmA.dmSize);
225
226     dmW = pGdiConvertToDevmodeW(&dmA);
227     ok(dmW->dmSize >= FIELD_OFFSET(DEVMODEW, dmICMMethod), "dmSize is too small: %04x\n", dmW->dmSize);
228     ok(dmW->dmSize <= sizeof(DEVMODEW), "dmSize is too large: %04x\n", dmW->dmSize);
229     HeapFree(GetProcessHeap(), 0, dmW);
230
231     dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + sizeof(dmA.dmFields);
232     dmW = pGdiConvertToDevmodeW(&dmA);
233     ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dmW->dmFields),
234        "wrong size %u\n", dmW->dmSize);
235     HeapFree(GetProcessHeap(), 0, dmW);
236
237     dmA.dmICMMethod = DMICMMETHOD_NONE;
238     dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod) + sizeof(dmA.dmICMMethod);
239     dmW = pGdiConvertToDevmodeW(&dmA);
240     ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod) + sizeof(dmW->dmICMMethod),
241        "wrong size %u\n", dmW->dmSize);
242     ok(dmW->dmICMMethod == DMICMMETHOD_NONE,
243        "expected DMICMMETHOD_NONE, got %u\n", dmW->dmICMMethod);
244     HeapFree(GetProcessHeap(), 0, dmW);
245
246     dmA.dmSize = 1024;
247     dmW = pGdiConvertToDevmodeW(&dmA);
248     ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmPanningHeight) + sizeof(dmW->dmPanningHeight),
249        "wrong size %u\n", dmW->dmSize);
250     HeapFree(GetProcessHeap(), 0, dmW);
251
252     SetLastError(0xdeadbeef);
253     dmA.dmSize = 0;
254     dmW = pGdiConvertToDevmodeW(&dmA);
255     ok(!dmW, "GdiConvertToDevmodeW should fail\n");
256     ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
257
258     /* this is the minimal dmSize that XP accepts */
259     dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
260     dmW = pGdiConvertToDevmodeW(&dmA);
261     ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields),
262        "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW, dmFields), dmW->dmSize);
263     HeapFree(GetProcessHeap(), 0, dmW);
264 }
265
266 static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr )
267 {
268     static const int caps[] =
269     {
270         DRIVERVERSION,
271         TECHNOLOGY,
272         HORZSIZE,
273         VERTSIZE,
274         HORZRES,
275         VERTRES,
276         BITSPIXEL,
277         PLANES,
278         NUMBRUSHES,
279         NUMPENS,
280         NUMMARKERS,
281         NUMFONTS,
282         NUMCOLORS,
283         PDEVICESIZE,
284         CURVECAPS,
285         LINECAPS,
286         POLYGONALCAPS,
287         /* TEXTCAPS broken on printer DC on winxp */
288         CLIPCAPS,
289         RASTERCAPS,
290         ASPECTX,
291         ASPECTY,
292         ASPECTXY,
293         LOGPIXELSX,
294         LOGPIXELSY,
295         SIZEPALETTE,
296         NUMRESERVED,
297         COLORRES,
298         PHYSICALWIDTH,
299         PHYSICALHEIGHT,
300         PHYSICALOFFSETX,
301         PHYSICALOFFSETY,
302         SCALINGFACTORX,
303         SCALINGFACTORY,
304         VREFRESH,
305         DESKTOPVERTRES,
306         DESKTOPHORZRES,
307         BLTALIGNMENT,
308         SHADEBLENDCAPS
309     };
310     unsigned int i;
311     WORD ramp[3][256];
312     BOOL ret;
313
314     if (GetObjectType( hdc ) == OBJ_METADC)
315     {
316         for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
317             ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
318                 "wrong caps on %s for %u: %u\n", descr, caps[i],
319                 GetDeviceCaps( hdc, caps[i] ) );
320
321         SetLastError( 0xdeadbeef );
322         ret = GetDeviceGammaRamp( hdc, &ramp );
323         ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
324         ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
325             "wrong error %u on %s\n", GetLastError(), descr );
326     }
327     else
328     {
329         for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
330             ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
331                 "mismatched caps on %s for %u: %u/%u\n", descr, caps[i],
332                 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
333
334         SetLastError( 0xdeadbeef );
335         ret = GetDeviceGammaRamp( hdc, &ramp );
336         ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
337         ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
338             "wrong error %u on %s\n", GetLastError(), descr );
339     }
340
341     if (GetObjectType( hdc ) == OBJ_MEMDC)
342     {
343         char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
344         BITMAPINFO *info = (BITMAPINFO *)buffer;
345         HBITMAP dib, old;
346
347         memset( buffer, 0, sizeof(buffer) );
348         info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
349         info->bmiHeader.biWidth = 16;
350         info->bmiHeader.biHeight = 16;
351         info->bmiHeader.biPlanes = 1;
352         info->bmiHeader.biBitCount = 8;
353         info->bmiHeader.biCompression = BI_RGB;
354         dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
355         old = SelectObject( hdc, dib );
356
357         for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
358             ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
359                 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
360                 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
361
362         SetLastError( 0xdeadbeef );
363         ret = GetDeviceGammaRamp( hdc, &ramp );
364         ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
365         ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
366             "wrong error %u on %s\n", GetLastError(), descr );
367
368         SelectObject( hdc, old );
369         DeleteObject( dib );
370     }
371 }
372
373 static void test_CreateCompatibleDC(void)
374 {
375     BOOL bRet;
376     HDC hdc, hNewDC, hdcMetafile, screen_dc;
377     HBITMAP bitmap;
378     INT caps;
379
380     screen_dc = GetDC( 0 );
381     bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
382
383     /* Create a DC compatible with the screen */
384     hdc = CreateCompatibleDC(NULL);
385     ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
386     ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
387     caps = GetDeviceCaps( hdc, TECHNOLOGY );
388     ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
389
390     test_device_caps( hdc, screen_dc, "display dc" );
391
392     /* Delete this DC, this should succeed */
393     bRet = DeleteDC(hdc);
394     ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
395
396     /* Try to create a DC compatible to the deleted DC. This has to fail */
397     hNewDC = CreateCompatibleDC(hdc);
398     ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
399
400     hdc = GetDC( 0 );
401     hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
402     ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
403     hNewDC = CreateCompatibleDC( hdcMetafile );
404     ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
405     ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
406     caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
407     ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
408     caps = GetDeviceCaps( hNewDC, TECHNOLOGY );
409     ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
410     DeleteDC( hNewDC );
411     DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
412     ReleaseDC( 0, hdc );
413
414     hdcMetafile = CreateMetaFileA(NULL);
415     ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
416     hNewDC = CreateCompatibleDC( hdcMetafile );
417     ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
418     caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
419     ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
420     test_device_caps( hdcMetafile, screen_dc, "metafile dc" );
421     DeleteMetaFile( CloseMetaFile( hdcMetafile ));
422
423     DeleteObject( bitmap );
424     ReleaseDC( 0, screen_dc );
425 }
426
427 static void test_DC_bitmap(void)
428 {
429     HDC hdc, hdcmem;
430     DWORD bits[64];
431     HBITMAP hbmp, oldhbmp;
432     COLORREF col;
433     int i, bitspixel;
434
435     /* fill bitmap data with b&w pattern */
436     for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
437
438     hdc = GetDC(0);
439     ok( hdc != NULL, "CreateDC rets %p\n", hdc);
440     bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
441     /* create a memory dc */
442     hdcmem = CreateCompatibleDC( hdc);
443     ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
444     /* tests */
445     /* test monochrome bitmap: should always work */
446     hbmp = CreateBitmap(32, 32, 1, 1, bits);
447     ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
448     oldhbmp = SelectObject( hdcmem, hbmp);
449     ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
450     col = GetPixel( hdcmem, 0, 0);
451     ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
452     col = GetPixel( hdcmem, 1, 1);
453     ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
454     col = GetPixel( hdcmem, 100, 1);
455     ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
456     SelectObject( hdcmem, oldhbmp);
457     DeleteObject( hbmp);
458
459     /* test with 2 bits color depth, not likely to succeed */
460     hbmp = CreateBitmap(16, 16, 1, 2, bits);
461     ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
462     oldhbmp = SelectObject( hdcmem, hbmp);
463     if( bitspixel != 2)
464         ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return  NULL\n");
465     if( oldhbmp) SelectObject( hdcmem, oldhbmp);
466     DeleteObject( hbmp);
467
468     /* test with 16 bits color depth, might succeed */
469     hbmp = CreateBitmap(6, 6, 1, 16, bits);
470     ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
471     oldhbmp = SelectObject( hdcmem, hbmp);
472     if( bitspixel == 16) {
473         ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
474         col = GetPixel( hdcmem, 0, 0);
475         ok( col == 0xffffff,
476             "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
477         col = GetPixel( hdcmem, 1, 1);
478         ok( col == 0x000000,
479             "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
480     }
481     if( oldhbmp) SelectObject( hdcmem, oldhbmp);
482     DeleteObject( hbmp);
483
484     /* test with 32 bits color depth, probably succeed */
485     hbmp = CreateBitmap(4, 4, 1, 32, bits);
486     ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
487     oldhbmp = SelectObject( hdcmem, hbmp);
488     if( bitspixel == 32) {
489         ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
490         col = GetPixel( hdcmem, 0, 0);
491         ok( col == 0xffffff,
492             "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
493         col = GetPixel( hdcmem, 1, 1);
494         ok( col == 0x000000,
495             "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
496     }
497     if( oldhbmp) SelectObject( hdcmem, oldhbmp);
498     DeleteObject( hbmp);
499     ReleaseDC( 0, hdc );
500 }
501
502 static void test_DeleteDC(void)
503 {
504     HWND hwnd;
505     HDC hdc, hdc_test;
506     WNDCLASSEX cls;
507     int ret;
508
509     /* window DC */
510     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
511                            0, 0, 0, NULL);
512     ok(hwnd != 0, "CreateWindowExA failed\n");
513
514     hdc = GetDC(hwnd);
515     ok(hdc != 0, "GetDC failed\n");
516     ret = GetObjectType(hdc);
517     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
518     ret = DeleteDC(hdc);
519     ok(ret, "DeleteDC failed\n");
520     ret = GetObjectType(hdc);
521     ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
522
523     hdc = GetWindowDC(hwnd);
524     ok(hdc != 0, "GetDC failed\n");
525     ret = GetObjectType(hdc);
526     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
527     ret = DeleteDC(hdc);
528     ok(ret, "DeleteDC failed\n");
529     ret = GetObjectType(hdc);
530     ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
531
532     DestroyWindow(hwnd);
533
534     /* desktop window DC */
535     hwnd = GetDesktopWindow();
536     ok(hwnd != 0, "GetDesktopWindow failed\n");
537
538     hdc = GetDC(hwnd);
539     ok(hdc != 0, "GetDC failed\n");
540     ret = GetObjectType(hdc);
541     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
542     ret = DeleteDC(hdc);
543     ok(ret, "DeleteDC failed\n");
544     ret = GetObjectType(hdc);
545     ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
546
547     hdc = GetWindowDC(hwnd);
548     ok(hdc != 0, "GetDC failed\n");
549     ret = GetObjectType(hdc);
550     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
551     ret = DeleteDC(hdc);
552     ok(ret, "DeleteDC failed\n");
553     ret = GetObjectType(hdc);
554     ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
555
556     /* CS_CLASSDC */
557     memset(&cls, 0, sizeof(cls));
558     cls.cbSize = sizeof(cls);
559     cls.style = CS_CLASSDC;
560     cls.hInstance = GetModuleHandle(0);
561     cls.lpszClassName = "Wine class DC";
562     cls.lpfnWndProc = DefWindowProcA;
563     ret = RegisterClassExA(&cls);
564     ok(ret, "RegisterClassExA failed\n");
565
566     hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
567                            0, 0, 0, NULL);
568     ok(hwnd != 0, "CreateWindowExA failed\n");
569
570     hdc = GetDC(hwnd);
571     ok(hdc != 0, "GetDC failed\n");
572     ret = GetObjectType(hdc);
573     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
574     ret = DeleteDC(hdc);
575     ok(ret, "DeleteDC failed\n");
576     ret = GetObjectType(hdc);
577     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
578     ret = ReleaseDC(hwnd, hdc);
579     ok(ret, "ReleaseDC failed\n");
580     ret = GetObjectType(hdc);
581     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
582
583     hdc_test = hdc;
584
585     hdc = GetWindowDC(hwnd);
586     ok(hdc != 0, "GetDC failed\n");
587     ret = GetObjectType(hdc);
588     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
589     ret = DeleteDC(hdc);
590     ok(ret, "DeleteDC failed\n");
591     ret = GetObjectType(hdc);
592     ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
593
594     DestroyWindow(hwnd);
595
596     ret = GetObjectType(hdc_test);
597     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
598
599     ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
600     ok(ret, "UnregisterClassA failed\n");
601
602     ret = GetObjectType(hdc_test);
603 todo_wine
604     ok(!ret, "GetObjectType should fail for a deleted DC\n");
605
606     /* CS_OWNDC */
607     memset(&cls, 0, sizeof(cls));
608     cls.cbSize = sizeof(cls);
609     cls.style = CS_OWNDC;
610     cls.hInstance = GetModuleHandle(0);
611     cls.lpszClassName = "Wine own DC";
612     cls.lpfnWndProc = DefWindowProcA;
613     ret = RegisterClassExA(&cls);
614     ok(ret, "RegisterClassExA failed\n");
615
616     hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
617                            0, 0, 0, NULL);
618     ok(hwnd != 0, "CreateWindowExA failed\n");
619
620     hdc = GetDC(hwnd);
621     ok(hdc != 0, "GetDC failed\n");
622     ret = GetObjectType(hdc);
623     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
624     ret = DeleteDC(hdc);
625     ok(ret, "DeleteDC failed\n");
626     ret = GetObjectType(hdc);
627     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
628     ret = ReleaseDC(hwnd, hdc);
629     ok(ret, "ReleaseDC failed\n");
630     ret = GetObjectType(hdc);
631     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
632
633     hdc = GetWindowDC(hwnd);
634     ok(hdc != 0, "GetDC failed\n");
635     ret = GetObjectType(hdc);
636     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
637     ret = DeleteDC(hdc);
638     ok(ret, "DeleteDC failed\n");
639     ret = GetObjectType(hdc);
640     ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
641
642     DestroyWindow(hwnd);
643
644     ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
645     ok(ret, "UnregisterClassA failed\n");
646 }
647
648 static void test_boundsrect(void)
649 {
650     HDC hdc;
651     HBITMAP bitmap;
652     RECT rect, expect, set_rect;
653     UINT ret;
654
655     hdc = CreateCompatibleDC(0);
656     ok(hdc != NULL, "CreateCompatibleDC failed\n");
657     bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
658     SelectObject( hdc, bitmap );
659
660     ret = GetBoundsRect(hdc, NULL, 0);
661     ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
662
663     ret = GetBoundsRect(hdc, NULL, ~0U);
664     ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
665
666     /* Test parameter handling order. */
667     SetRect(&set_rect, 10, 20, 40, 50);
668     ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
669     ok(ret & DCB_RESET,
670        "Expected return flag DCB_RESET to be set, got %u\n", ret);
671
672     ret = GetBoundsRect(hdc, NULL, DCB_RESET);
673     ok(ret == 0,
674        "Expected GetBoundsRect to return 0, got %u\n", ret);
675
676     ret = GetBoundsRect(hdc, &rect, 0);
677     ok(ret == DCB_RESET,
678        "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
679     SetRect(&expect, 0, 0, 0, 0);
680     ok(EqualRect(&rect, &expect) ||
681        broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
682        "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
683        rect.left, rect.top, rect.right, rect.bottom);
684
685     ret = GetBoundsRect(NULL, NULL, 0);
686     ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
687
688     ret = GetBoundsRect(NULL, NULL, ~0U);
689     ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
690
691     ret = SetBoundsRect(NULL, NULL, 0);
692     ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
693
694     ret = SetBoundsRect(NULL, NULL, ~0U);
695     ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
696
697     SetRect(&set_rect, 10, 20, 40, 50);
698     ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
699     ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
700
701     ret = GetBoundsRect(hdc, &rect, 0);
702     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
703     SetRect(&expect, 10, 20, 40, 50);
704     ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
705        rect.left, rect.top, rect.right, rect.bottom);
706
707     SetMapMode( hdc, MM_ANISOTROPIC );
708     SetViewportExtEx( hdc, 2, 2, NULL );
709     ret = GetBoundsRect(hdc, &rect, 0);
710     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
711     SetRect(&expect, 5, 10, 20, 25);
712     ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
713        rect.left, rect.top, rect.right, rect.bottom);
714
715     SetViewportOrgEx( hdc, 20, 30, NULL );
716     ret = GetBoundsRect(hdc, &rect, 0);
717     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
718     SetRect(&expect, -5, -5, 10, 10);
719     ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
720        rect.left, rect.top, rect.right, rect.bottom);
721
722     SetRect(&set_rect, 10, 20, 40, 50);
723     ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
724     ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
725
726     ret = GetBoundsRect(hdc, &rect, 0);
727     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
728     SetRect(&expect, 10, 20, 40, 50);
729     ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
730        rect.left, rect.top, rect.right, rect.bottom);
731
732     SetMapMode( hdc, MM_TEXT );
733     SetViewportOrgEx( hdc, 0, 0, NULL );
734     ret = GetBoundsRect(hdc, &rect, 0);
735     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
736     SetRect(&expect, 40, 70, 100, 130);
737     ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
738        rect.left, rect.top, rect.right, rect.bottom);
739
740     if (pSetLayout)
741     {
742         pSetLayout( hdc, LAYOUT_RTL );
743         ret = GetBoundsRect(hdc, &rect, 0);
744         ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
745         SetRect(&expect, 159, 70, 99, 130);
746         ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
747            rect.left, rect.top, rect.right, rect.bottom);
748         SetRect(&set_rect, 50, 25, 30, 35);
749         ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
750         ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
751         ret = GetBoundsRect(hdc, &rect, 0);
752         ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
753         SetRect(&expect, 50, 25, 30, 35);
754         ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
755            rect.left, rect.top, rect.right, rect.bottom);
756
757         pSetLayout( hdc, LAYOUT_LTR );
758         ret = GetBoundsRect(hdc, &rect, 0);
759         ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
760         SetRect(&expect, 149, 25, 169, 35);
761         ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
762            rect.left, rect.top, rect.right, rect.bottom);
763     }
764
765     /* empty rect resets, except on nt4 */
766     SetRect(&expect, 20, 20, 10, 10);
767     ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
768     ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
769     ret = GetBoundsRect(hdc, &rect, 0);
770     ok(ret == DCB_RESET || broken(ret == DCB_SET)  /* nt4 */,
771        "GetBoundsRect returned %x\n", ret);
772     if (ret == DCB_RESET)
773     {
774         SetRect(&expect, 0, 0, 0, 0);
775         ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
776            rect.left, rect.top, rect.right, rect.bottom);
777
778         SetRect(&expect, 20, 20, 20, 20);
779         ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
780         ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
781         ret = GetBoundsRect(hdc, &rect, 0);
782         ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
783         SetRect(&expect, 0, 0, 0, 0);
784         ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
785            rect.left, rect.top, rect.right, rect.bottom);
786     }
787
788     DeleteDC( hdc );
789     DeleteObject( bitmap );
790 }
791
792 static void test_desktop_colorres(void)
793 {
794     HDC hdc = GetDC(NULL);
795     int bitspixel, colorres;
796
797     bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
798     ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
799
800     colorres = GetDeviceCaps(hdc, COLORRES);
801     ok(colorres != 0 ||
802        broken(colorres == 0), /* Win9x */
803        "Expected to get valid COLORRES capability value\n");
804
805     if (colorres)
806     {
807         switch (bitspixel)
808         {
809         case 8:
810             ok(colorres == 18,
811                "Expected COLORRES to be 18, got %d\n", colorres);
812             break;
813         case 16:
814             ok(colorres == 16,
815                "Expected COLORRES to be 16, got %d\n", colorres);
816             break;
817         case 24:
818         case 32:
819             ok(colorres == 24,
820                "Expected COLORRES to be 24, got %d\n", bitspixel);
821             break;
822         default:
823             ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
824             break;
825         }
826     }
827
828     ReleaseDC(NULL, hdc);
829 }
830
831 static void test_gamma(void)
832 {
833     BOOL ret;
834     HDC hdc = GetDC(NULL);
835     WORD oldramp[3][256], ramp[3][256];
836     INT i;
837
838     ret = GetDeviceGammaRamp(hdc, &oldramp);
839     if (!ret)
840     {
841         win_skip("GetDeviceGammaRamp failed, skipping tests\n");
842         goto done;
843     }
844
845     /* try to set back old ramp */
846     ret = SetDeviceGammaRamp(hdc, &oldramp);
847     if (!ret)
848     {
849         win_skip("SetDeviceGammaRamp failed, skipping tests\n");
850         goto done;
851     }
852
853     memcpy(ramp, oldramp, sizeof(ramp));
854
855     /* set one color ramp to zeros */
856     memset(ramp[0], 0, sizeof(ramp[0]));
857     ret = SetDeviceGammaRamp(hdc, &ramp);
858     ok(!ret, "SetDeviceGammaRamp succeeded\n");
859
860     /* set one color ramp to a flat straight rising line */
861     for (i = 0; i < 256; i++) ramp[0][i] = i;
862     ret = SetDeviceGammaRamp(hdc, &ramp);
863     todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
864
865     /* set one color ramp to a steep straight rising line */
866     for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
867     ret = SetDeviceGammaRamp(hdc, &ramp);
868     ok(ret, "SetDeviceGammaRamp failed\n");
869
870     /* try a bright gamma ramp */
871     ramp[0][0] = 0;
872     ramp[0][1] = 0x7FFF;
873     for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
874     ret = SetDeviceGammaRamp(hdc, &ramp);
875     ok(!ret, "SetDeviceGammaRamp succeeded\n");
876
877     /* try ramps which are not uniform */
878     ramp[0][0] = 0;
879     for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
880     ret = SetDeviceGammaRamp(hdc, &ramp);
881     ok(ret, "SetDeviceGammaRamp failed\n");
882     ramp[0][0] = 0;
883     for (i = 2; i < 256; i+=2)
884     {
885         ramp[0][i - 1] = ramp[0][i - 2];
886         ramp[0][i] = ramp[0][i - 2] + 512;
887     }
888     ret = SetDeviceGammaRamp(hdc, &ramp);
889     ok(ret, "SetDeviceGammaRamp failed\n");
890
891     /* cleanup: set old ramp again */
892     ret = SetDeviceGammaRamp(hdc, &oldramp);
893     ok(ret, "SetDeviceGammaRamp failed\n");
894
895 done:
896     ReleaseDC(NULL, hdc);
897 }
898
899 static HDC create_printer_dc(void)
900 {
901     char buffer[260];
902     DWORD len;
903     PRINTER_INFO_2A *pbuf = NULL;
904     DRIVER_INFO_3A *dbuf = NULL;
905     HANDLE hprn = 0;
906     HDC hdc = 0;
907     HMODULE winspool = LoadLibraryA( "winspool.drv" );
908     BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
909     BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
910     BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
911     BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
912     BOOL (WINAPI *pClosePrinter)(HANDLE);
913
914     pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
915     pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
916     pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
917     pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
918     pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
919
920     if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
921         goto done;
922
923     len = sizeof(buffer);
924     if (!pGetDefaultPrinterA( buffer, &len )) goto done;
925     if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
926
927     pGetPrinterA( hprn, 2, NULL, 0, &len );
928     pbuf = HeapAlloc( GetProcessHeap(), 0, len );
929     if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
930
931     pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
932     dbuf = HeapAlloc( GetProcessHeap(), 0, len );
933     if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
934
935     hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
936     trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc,
937            dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName );
938 done:
939     HeapFree( GetProcessHeap(), 0, dbuf );
940     HeapFree( GetProcessHeap(), 0, pbuf );
941     if (hprn) pClosePrinter( hprn );
942     if (winspool) FreeLibrary( winspool );
943     if (!hdc) skip( "could not create a DC for the default printer\n" );
944     return hdc;
945 }
946
947 static void test_printer_dc(void)
948 {
949     HDC memdc, display_memdc;
950     HBITMAP orig, bmp;
951     DWORD ret;
952     HDC hdc = create_printer_dc();
953
954     if (!hdc) return;
955
956     memdc = CreateCompatibleDC( hdc );
957     display_memdc = CreateCompatibleDC( 0 );
958
959     ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
960     ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
961
962     ret = GetDeviceCaps( hdc, TECHNOLOGY );
963     ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
964
965     ret = GetDeviceCaps( memdc, TECHNOLOGY );
966     ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
967
968     ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
969     ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
970
971     test_device_caps( memdc, hdc, "printer dc" );
972
973     bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
974     orig = SelectObject( memdc, bmp );
975     ok( orig != NULL, "SelectObject failed\n" );
976     ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
977
978     ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
979     SelectObject( memdc, orig );
980     DeleteObject( bmp );
981
982     bmp = CreateBitmap( 100, 100, 1, 1, NULL );
983     orig = SelectObject( display_memdc, bmp );
984     ok( orig != NULL, "SelectObject failed\n" );
985     ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
986     ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
987     ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
988     ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
989
990     ret = GetPixel( hdc, 0, 0 );
991     ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
992
993     DeleteDC( memdc );
994     DeleteDC( display_memdc );
995     DeleteDC( hdc );
996     DeleteObject( bmp );
997 }
998
999 START_TEST(dc)
1000 {
1001     pSetLayout = (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
1002     test_savedc();
1003     test_savedc_2();
1004     test_GdiConvertToDevmodeW();
1005     test_CreateCompatibleDC();
1006     test_DC_bitmap();
1007     test_DeleteDC();
1008     test_boundsrect();
1009     test_desktop_colorres();
1010     test_gamma();
1011     test_printer_dc();
1012 }