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