usp10: Merge neutral scripts.
[wine.git] / dlls / gdi32 / tests / dc.c
blob26b7c61963b17aadbbcec3a461307b19d7227d5c
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
22 #define WINVER 0x0501 /* request latest DEVMODE */
24 #include <assert.h>
25 #include <stdio.h>
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"
34 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
36 static void dump_region(HRGN hrgn)
38 DWORD i, size;
39 RGNDATA *data = NULL;
40 RECT *rect;
42 if (!hrgn)
44 printf( "(null) region\n" );
45 return;
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 );
57 static void test_savedc_2(void)
59 HWND hwnd;
60 HDC hdc;
61 HRGN hrgn;
62 RECT rc, rc_clip;
63 int ret;
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);
71 hrgn = CreateRectRgn(0, 0, 0, 0);
72 assert(hrgn != 0);
74 hdc = GetDC(hwnd);
75 ok(hdc != NULL, "GetDC failed\n");
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);
91 ret = SaveDC(hdc);
92 todo_wine
94 ok(ret == 1, "ret = %d\n", ret);
97 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
98 if (ret == COMPLEXREGION)
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);
107 else
108 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
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);
118 ret = RestoreDC(hdc, 1);
119 ok(ret, "ret = %d\n", ret);
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);
129 DeleteObject(hrgn);
130 ReleaseDC(hwnd, hdc);
131 DestroyWindow(hwnd);
134 static void test_savedc(void)
136 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
137 int ret;
139 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
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);
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);
180 /* Trying to clear an empty save stack fails. */
181 ret = RestoreDC(hdc, -3);
182 ok(!ret, "ret = %d\n", ret);
184 ret = SaveDC(hdc);
185 ok(ret == 3 ||
186 broken(ret == 1), /* Win9x */
187 "ret = %d\n", ret);
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);
195 /* Trying to clear an empty save stack fails. */
196 ret = RestoreDC(hdc, 0);
197 ok(!ret, "ret = %d\n", ret);
199 ret = RestoreDC(hdc, 1);
200 ok(ret ||
201 broken(!ret), /* Win9x */
202 "ret = %d\n", ret);
204 DeleteDC(hdc);
207 static void test_GdiConvertToDevmodeW(void)
209 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
210 DEVMODEA dmA;
211 DEVMODEW *dmW;
212 BOOL ret;
214 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
215 if (!pGdiConvertToDevmodeW)
217 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
218 return;
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);
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);
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);
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);
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);
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());
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);
266 static void test_CreateCompatibleDC(void)
268 BOOL bRet;
269 HDC hdc, hNewDC, hdcMetafile;
270 HBITMAP bitmap;
271 INT caps;
273 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
275 /* Create a DC compatible with the screen */
276 hdc = CreateCompatibleDC(NULL);
277 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
278 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
279 caps = GetDeviceCaps( hdc, TECHNOLOGY );
280 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
282 /* Delete this DC, this should succeed */
283 bRet = DeleteDC(hdc);
284 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
286 /* Try to create a DC compatible to the deleted DC. This has to fail */
287 hNewDC = CreateCompatibleDC(hdc);
288 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
290 hdc = GetDC( 0 );
291 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
292 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
293 hNewDC = CreateCompatibleDC( hdcMetafile );
294 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
295 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
296 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
297 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
298 caps = GetDeviceCaps( hNewDC, TECHNOLOGY );
299 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
300 DeleteDC( hNewDC );
301 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
302 ReleaseDC( 0, hdc );
304 hdcMetafile = CreateMetaFileA(NULL);
305 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
306 hNewDC = CreateCompatibleDC( hdcMetafile );
307 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
308 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
309 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
310 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
312 DeleteObject( bitmap );
315 static void test_DC_bitmap(void)
317 HDC hdc, hdcmem;
318 DWORD bits[64];
319 HBITMAP hbmp, oldhbmp;
320 COLORREF col;
321 int i, bitspixel;
323 /* fill bitmap data with b&w pattern */
324 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
326 hdc = GetDC(0);
327 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
328 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
329 /* create a memory dc */
330 hdcmem = CreateCompatibleDC( hdc);
331 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
332 /* tests */
333 /* test monochrome bitmap: should always work */
334 hbmp = CreateBitmap(32, 32, 1, 1, bits);
335 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
336 oldhbmp = SelectObject( hdcmem, hbmp);
337 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
338 col = GetPixel( hdcmem, 0, 0);
339 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
340 col = GetPixel( hdcmem, 1, 1);
341 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
342 col = GetPixel( hdcmem, 100, 1);
343 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
344 SelectObject( hdcmem, oldhbmp);
345 DeleteObject( hbmp);
347 /* test with 2 bits color depth, not likely to succeed */
348 hbmp = CreateBitmap(16, 16, 1, 2, bits);
349 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
350 oldhbmp = SelectObject( hdcmem, hbmp);
351 if( bitspixel != 2)
352 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
353 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
354 DeleteObject( hbmp);
356 /* test with 16 bits color depth, might succeed */
357 hbmp = CreateBitmap(6, 6, 1, 16, bits);
358 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
359 oldhbmp = SelectObject( hdcmem, hbmp);
360 if( bitspixel == 16) {
361 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
362 col = GetPixel( hdcmem, 0, 0);
363 ok( col == 0xffffff,
364 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
365 col = GetPixel( hdcmem, 1, 1);
366 ok( col == 0x000000,
367 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
369 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
370 DeleteObject( hbmp);
372 /* test with 32 bits color depth, probably succeed */
373 hbmp = CreateBitmap(4, 4, 1, 32, bits);
374 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
375 oldhbmp = SelectObject( hdcmem, hbmp);
376 if( bitspixel == 32) {
377 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
378 col = GetPixel( hdcmem, 0, 0);
379 ok( col == 0xffffff,
380 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
381 col = GetPixel( hdcmem, 1, 1);
382 ok( col == 0x000000,
383 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
385 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
386 DeleteObject( hbmp);
387 ReleaseDC( 0, hdc );
390 static void test_DeleteDC(void)
392 HWND hwnd;
393 HDC hdc, hdc_test;
394 WNDCLASSEX cls;
395 int ret;
397 /* window DC */
398 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
399 0, 0, 0, NULL);
400 ok(hwnd != 0, "CreateWindowExA failed\n");
402 hdc = GetDC(hwnd);
403 ok(hdc != 0, "GetDC failed\n");
404 ret = GetObjectType(hdc);
405 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
406 ret = DeleteDC(hdc);
407 ok(ret, "DeleteDC failed\n");
408 ret = GetObjectType(hdc);
409 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
411 hdc = GetWindowDC(hwnd);
412 ok(hdc != 0, "GetDC failed\n");
413 ret = GetObjectType(hdc);
414 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
415 ret = DeleteDC(hdc);
416 ok(ret, "DeleteDC failed\n");
417 ret = GetObjectType(hdc);
418 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
420 DestroyWindow(hwnd);
422 /* desktop window DC */
423 hwnd = GetDesktopWindow();
424 ok(hwnd != 0, "GetDesktopWindow failed\n");
426 hdc = GetDC(hwnd);
427 ok(hdc != 0, "GetDC failed\n");
428 ret = GetObjectType(hdc);
429 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
430 ret = DeleteDC(hdc);
431 ok(ret, "DeleteDC failed\n");
432 ret = GetObjectType(hdc);
433 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
435 hdc = GetWindowDC(hwnd);
436 ok(hdc != 0, "GetDC failed\n");
437 ret = GetObjectType(hdc);
438 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
439 ret = DeleteDC(hdc);
440 ok(ret, "DeleteDC failed\n");
441 ret = GetObjectType(hdc);
442 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
444 /* CS_CLASSDC */
445 memset(&cls, 0, sizeof(cls));
446 cls.cbSize = sizeof(cls);
447 cls.style = CS_CLASSDC;
448 cls.hInstance = GetModuleHandle(0);
449 cls.lpszClassName = "Wine class DC";
450 cls.lpfnWndProc = DefWindowProcA;
451 ret = RegisterClassExA(&cls);
452 ok(ret, "RegisterClassExA failed\n");
454 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
455 0, 0, 0, NULL);
456 ok(hwnd != 0, "CreateWindowExA failed\n");
458 hdc = GetDC(hwnd);
459 ok(hdc != 0, "GetDC failed\n");
460 ret = GetObjectType(hdc);
461 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
462 ret = DeleteDC(hdc);
463 ok(ret, "DeleteDC failed\n");
464 ret = GetObjectType(hdc);
465 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
466 ret = ReleaseDC(hwnd, hdc);
467 ok(ret, "ReleaseDC failed\n");
468 ret = GetObjectType(hdc);
469 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
471 hdc_test = hdc;
473 hdc = GetWindowDC(hwnd);
474 ok(hdc != 0, "GetDC failed\n");
475 ret = GetObjectType(hdc);
476 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
477 ret = DeleteDC(hdc);
478 ok(ret, "DeleteDC failed\n");
479 ret = GetObjectType(hdc);
480 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
482 DestroyWindow(hwnd);
484 ret = GetObjectType(hdc_test);
485 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
487 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
488 ok(ret, "UnregisterClassA failed\n");
490 ret = GetObjectType(hdc_test);
491 todo_wine
492 ok(!ret, "GetObjectType should fail for a deleted DC\n");
494 /* CS_OWNDC */
495 memset(&cls, 0, sizeof(cls));
496 cls.cbSize = sizeof(cls);
497 cls.style = CS_OWNDC;
498 cls.hInstance = GetModuleHandle(0);
499 cls.lpszClassName = "Wine own DC";
500 cls.lpfnWndProc = DefWindowProcA;
501 ret = RegisterClassExA(&cls);
502 ok(ret, "RegisterClassExA failed\n");
504 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
505 0, 0, 0, NULL);
506 ok(hwnd != 0, "CreateWindowExA failed\n");
508 hdc = GetDC(hwnd);
509 ok(hdc != 0, "GetDC failed\n");
510 ret = GetObjectType(hdc);
511 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
512 ret = DeleteDC(hdc);
513 ok(ret, "DeleteDC failed\n");
514 ret = GetObjectType(hdc);
515 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
516 ret = ReleaseDC(hwnd, hdc);
517 ok(ret, "ReleaseDC failed\n");
518 ret = GetObjectType(hdc);
519 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
521 hdc = GetWindowDC(hwnd);
522 ok(hdc != 0, "GetDC failed\n");
523 ret = GetObjectType(hdc);
524 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
525 ret = DeleteDC(hdc);
526 ok(ret, "DeleteDC failed\n");
527 ret = GetObjectType(hdc);
528 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
530 DestroyWindow(hwnd);
532 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
533 ok(ret, "UnregisterClassA failed\n");
536 static void test_boundsrect(void)
538 HDC hdc;
539 HBITMAP bitmap;
540 RECT rect, expect, set_rect;
541 UINT ret;
543 hdc = CreateCompatibleDC(0);
544 ok(hdc != NULL, "CreateCompatibleDC failed\n");
545 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
546 SelectObject( hdc, bitmap );
548 ret = GetBoundsRect(hdc, NULL, 0);
549 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
551 ret = GetBoundsRect(hdc, NULL, ~0U);
552 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
554 /* Test parameter handling order. */
555 SetRect(&set_rect, 10, 20, 40, 50);
556 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
557 ok(ret & DCB_RESET,
558 "Expected return flag DCB_RESET to be set, got %u\n", ret);
560 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
561 ok(ret == 0,
562 "Expected GetBoundsRect to return 0, got %u\n", ret);
564 ret = GetBoundsRect(hdc, &rect, 0);
565 ok(ret == DCB_RESET,
566 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
567 SetRect(&expect, 0, 0, 0, 0);
568 ok(EqualRect(&rect, &expect) ||
569 broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
570 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
571 rect.left, rect.top, rect.right, rect.bottom);
573 ret = GetBoundsRect(NULL, NULL, 0);
574 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
576 ret = GetBoundsRect(NULL, NULL, ~0U);
577 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
579 ret = SetBoundsRect(NULL, NULL, 0);
580 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
582 ret = SetBoundsRect(NULL, NULL, ~0U);
583 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
585 SetRect(&set_rect, 10, 20, 40, 50);
586 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
587 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
589 ret = GetBoundsRect(hdc, &rect, 0);
590 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
591 SetRect(&expect, 10, 20, 40, 50);
592 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
593 rect.left, rect.top, rect.right, rect.bottom);
595 SetMapMode( hdc, MM_ANISOTROPIC );
596 SetViewportExtEx( hdc, 2, 2, NULL );
597 ret = GetBoundsRect(hdc, &rect, 0);
598 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
599 SetRect(&expect, 5, 10, 20, 25);
600 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
601 rect.left, rect.top, rect.right, rect.bottom);
603 SetViewportOrgEx( hdc, 20, 30, NULL );
604 ret = GetBoundsRect(hdc, &rect, 0);
605 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
606 SetRect(&expect, -5, -5, 10, 10);
607 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
608 rect.left, rect.top, rect.right, rect.bottom);
610 SetRect(&set_rect, 10, 20, 40, 50);
611 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
612 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
614 ret = GetBoundsRect(hdc, &rect, 0);
615 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
616 SetRect(&expect, 10, 20, 40, 50);
617 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
618 rect.left, rect.top, rect.right, rect.bottom);
620 SetMapMode( hdc, MM_TEXT );
621 SetViewportOrgEx( hdc, 0, 0, NULL );
622 ret = GetBoundsRect(hdc, &rect, 0);
623 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
624 SetRect(&expect, 40, 70, 100, 130);
625 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
626 rect.left, rect.top, rect.right, rect.bottom);
628 if (pSetLayout)
630 pSetLayout( hdc, LAYOUT_RTL );
631 ret = GetBoundsRect(hdc, &rect, 0);
632 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
633 SetRect(&expect, 159, 70, 99, 130);
634 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
635 rect.left, rect.top, rect.right, rect.bottom);
636 SetRect(&set_rect, 50, 25, 30, 35);
637 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
638 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
639 ret = GetBoundsRect(hdc, &rect, 0);
640 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
641 SetRect(&expect, 50, 25, 30, 35);
642 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
643 rect.left, rect.top, rect.right, rect.bottom);
645 pSetLayout( hdc, LAYOUT_LTR );
646 ret = GetBoundsRect(hdc, &rect, 0);
647 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
648 SetRect(&expect, 149, 25, 169, 35);
649 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
650 rect.left, rect.top, rect.right, rect.bottom);
653 /* empty rect resets, except on nt4 */
654 SetRect(&expect, 20, 20, 10, 10);
655 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
656 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
657 ret = GetBoundsRect(hdc, &rect, 0);
658 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
659 "GetBoundsRect returned %x\n", ret);
660 if (ret == DCB_RESET)
662 SetRect(&expect, 0, 0, 0, 0);
663 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
664 rect.left, rect.top, rect.right, rect.bottom);
666 SetRect(&expect, 20, 20, 20, 20);
667 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
668 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
669 ret = GetBoundsRect(hdc, &rect, 0);
670 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
671 SetRect(&expect, 0, 0, 0, 0);
672 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
673 rect.left, rect.top, rect.right, rect.bottom);
676 DeleteDC( hdc );
677 DeleteObject( bitmap );
680 static void test_desktop_colorres(void)
682 HDC hdc = GetDC(NULL);
683 int bitspixel, colorres;
685 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
686 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
688 colorres = GetDeviceCaps(hdc, COLORRES);
689 ok(colorres != 0 ||
690 broken(colorres == 0), /* Win9x */
691 "Expected to get valid COLORRES capability value\n");
693 if (colorres)
695 switch (bitspixel)
697 case 8:
698 ok(colorres == 18,
699 "Expected COLORRES to be 18, got %d\n", colorres);
700 break;
701 case 16:
702 ok(colorres == 16,
703 "Expected COLORRES to be 16, got %d\n", colorres);
704 break;
705 case 24:
706 case 32:
707 ok(colorres == 24,
708 "Expected COLORRES to be 24, got %d\n", bitspixel);
709 break;
710 default:
711 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
712 break;
716 ReleaseDC(NULL, hdc);
719 static void test_gamma(void)
721 BOOL ret;
722 HDC hdc = GetDC(NULL);
723 WORD oldramp[3][256], ramp[3][256];
724 INT i;
726 ret = GetDeviceGammaRamp(hdc, &oldramp);
727 if (!ret)
729 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
730 goto done;
733 /* try to set back old ramp */
734 ret = SetDeviceGammaRamp(hdc, &oldramp);
735 if (!ret)
737 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
738 goto done;
741 memcpy(ramp, oldramp, sizeof(ramp));
743 /* set one color ramp to zeros */
744 memset(ramp[0], 0, sizeof(ramp[0]));
745 ret = SetDeviceGammaRamp(hdc, &ramp);
746 ok(!ret, "SetDeviceGammaRamp succeeded\n");
748 /* set one color ramp to a flat straight rising line */
749 for (i = 0; i < 256; i++) ramp[0][i] = i;
750 ret = SetDeviceGammaRamp(hdc, &ramp);
751 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
753 /* set one color ramp to a steep straight rising line */
754 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
755 ret = SetDeviceGammaRamp(hdc, &ramp);
756 ok(ret, "SetDeviceGammaRamp failed\n");
758 /* try a bright gamma ramp */
759 ramp[0][0] = 0;
760 ramp[0][1] = 0x7FFF;
761 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
762 ret = SetDeviceGammaRamp(hdc, &ramp);
763 ok(!ret, "SetDeviceGammaRamp succeeded\n");
765 /* try ramps which are not uniform */
766 ramp[0][0] = 0;
767 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
768 ret = SetDeviceGammaRamp(hdc, &ramp);
769 ok(ret, "SetDeviceGammaRamp failed\n");
770 ramp[0][0] = 0;
771 for (i = 2; i < 256; i+=2)
773 ramp[0][i - 1] = ramp[0][i - 2];
774 ramp[0][i] = ramp[0][i - 2] + 512;
776 ret = SetDeviceGammaRamp(hdc, &ramp);
777 ok(ret, "SetDeviceGammaRamp failed\n");
779 /* cleanup: set old ramp again */
780 ret = SetDeviceGammaRamp(hdc, &oldramp);
781 ok(ret, "SetDeviceGammaRamp failed\n");
783 done:
784 ReleaseDC(NULL, hdc);
787 static HDC create_printer_dc(void)
789 char buffer[260];
790 DWORD len;
791 PRINTER_INFO_2A *pbuf = NULL;
792 DRIVER_INFO_3A *dbuf = NULL;
793 HANDLE hprn = 0;
794 HDC hdc = 0;
795 HMODULE winspool = LoadLibraryA( "winspool.drv" );
796 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
797 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
798 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
799 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
800 BOOL (WINAPI *pClosePrinter)(HANDLE);
802 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
803 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
804 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
805 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
806 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
808 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
809 goto done;
811 len = sizeof(buffer);
812 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
813 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
815 pGetPrinterA( hprn, 2, NULL, 0, &len );
816 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
817 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
819 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
820 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
821 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
823 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
824 trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc,
825 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName );
826 done:
827 HeapFree( GetProcessHeap(), 0, dbuf );
828 HeapFree( GetProcessHeap(), 0, pbuf );
829 if (hprn) pClosePrinter( hprn );
830 if (winspool) FreeLibrary( winspool );
831 if (!hdc) skip( "could not create a DC for the default printer\n" );
832 return hdc;
835 static void test_printer_dc(void)
837 HDC memdc, display_memdc;
838 HBITMAP orig, bmp;
839 DWORD ret;
840 HDC hdc = create_printer_dc();
842 if (!hdc) return;
844 memdc = CreateCompatibleDC( hdc );
845 display_memdc = CreateCompatibleDC( 0 );
847 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
848 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
850 ret = GetDeviceCaps( hdc, TECHNOLOGY );
851 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
853 ret = GetDeviceCaps( memdc, TECHNOLOGY );
854 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
856 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
857 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
859 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
860 orig = SelectObject( memdc, bmp );
861 ok( orig != NULL, "SelectObject failed\n" );
862 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
864 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
865 SelectObject( memdc, orig );
866 DeleteObject( bmp );
868 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
869 orig = SelectObject( display_memdc, bmp );
870 ok( orig != NULL, "SelectObject failed\n" );
871 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
872 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
873 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
874 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
876 ret = GetPixel( hdc, 0, 0 );
877 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
879 DeleteDC( memdc );
880 DeleteDC( display_memdc );
881 DeleteDC( hdc );
882 DeleteObject( bmp );
885 START_TEST(dc)
887 pSetLayout = (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
888 test_savedc();
889 test_savedc_2();
890 test_GdiConvertToDevmodeW();
891 test_CreateCompatibleDC();
892 test_DC_bitmap();
893 test_DeleteDC();
894 test_boundsrect();
895 test_desktop_colorres();
896 test_gamma();
897 test_printer_dc();