[GDI32_WINETEST] Add a PCH.
[reactos.git] / modules / rostests / winetests / gdi32 / dc.c
1 /*
2 * Unit tests for dc functions
3 *
4 * Copyright (c) 2005 Huw Davies
5 * Copyright (c) 2005,2016 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 #include "precomp.h"
23
24 #include <winspool.h>
25
26 #ifndef LAYOUT_LTR
27 #define LAYOUT_LTR 0
28 #endif
29
30 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
31
32 static void dump_region(HRGN hrgn)
33 {
34 DWORD i, size;
35 RGNDATA *data = NULL;
36 RECT *rect;
37
38 if (!hrgn)
39 {
40 printf( "(null) region\n" );
41 return;
42 }
43 if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
44 if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
45 GetRegionData( hrgn, size, data );
46 printf( "%d rects:", data->rdh.nCount );
47 for (i = 0, rect = (RECT *)data->Buffer; i < data->rdh.nCount; i++, rect++)
48 printf( " (%d,%d)-(%d,%d)", rect->left, rect->top, rect->right, rect->bottom );
49 printf( "\n" );
50 HeapFree( GetProcessHeap(), 0, data );
51 }
52
53 static void test_dc_values(void)
54 {
55 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
56 COLORREF color;
57 int extra;
58
59 ok( hdc != NULL, "CreateDC failed\n" );
60 color = SetBkColor( hdc, 0x12345678 );
61 ok( color == 0xffffff, "initial color %08x\n", color );
62 color = GetBkColor( hdc );
63 ok( color == 0x12345678, "wrong color %08x\n", color );
64 color = SetBkColor( hdc, 0xffffffff );
65 ok( color == 0x12345678, "wrong color %08x\n", color );
66 color = GetBkColor( hdc );
67 ok( color == 0xffffffff, "wrong color %08x\n", color );
68 color = SetBkColor( hdc, 0 );
69 ok( color == 0xffffffff, "wrong color %08x\n", color );
70 color = GetBkColor( hdc );
71 ok( color == 0, "wrong color %08x\n", color );
72
73 color = SetTextColor( hdc, 0xffeeddcc );
74 ok( color == 0, "initial color %08x\n", color );
75 color = GetTextColor( hdc );
76 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
77 color = SetTextColor( hdc, 0xffffffff );
78 ok( color == 0xffeeddcc, "wrong color %08x\n", color );
79 color = GetTextColor( hdc );
80 ok( color == 0xffffffff, "wrong color %08x\n", color );
81 color = SetTextColor( hdc, 0 );
82 ok( color == 0xffffffff, "wrong color %08x\n", color );
83 color = GetTextColor( hdc );
84 ok( color == 0, "wrong color %08x\n", color );
85
86 extra = GetTextCharacterExtra( hdc );
87 ok( extra == 0, "initial extra %d\n", extra );
88 SetTextCharacterExtra( hdc, 123 );
89 extra = GetTextCharacterExtra( hdc );
90 ok( extra == 123, "initial extra %d\n", extra );
91 SetMapMode( hdc, MM_LOMETRIC );
92 extra = GetTextCharacterExtra( hdc );
93 ok( extra == 123, "initial extra %d\n", extra );
94 SetMapMode( hdc, MM_TEXT );
95 extra = GetTextCharacterExtra( hdc );
96 ok( extra == 123, "initial extra %d\n", extra );
97
98 DeleteDC( hdc );
99 }
100
101 static void test_savedc_2(void)
102 {
103 HWND hwnd;
104 HDC hdc;
105 HRGN hrgn;
106 RECT rc, rc_clip;
107 int ret;
108
109 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
110 0, 0, 0, NULL);
111 assert(hwnd != 0);
112 ShowWindow(hwnd, SW_SHOW);
113 UpdateWindow(hwnd);
114
115 hrgn = CreateRectRgn(0, 0, 0, 0);
116 assert(hrgn != 0);
117
118 hdc = GetDC(hwnd);
119 ok(hdc != NULL, "GetDC failed\n");
120
121 ret = GetClipBox(hdc, &rc_clip);
122 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
123 ret = GetClipRgn(hdc, hrgn);
124 ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
125 ret = GetRgnBox(hrgn, &rc);
126 ok(ret == NULLREGION, "GetRgnBox returned %d %s instead of NULLREGION\n",
127 ret, wine_dbgstr_rect(&rc));
128 /*dump_region(hrgn);*/
129 SetRect(&rc, 0, 0, 100, 100);
130 ok(EqualRect(&rc, &rc_clip), "rects are not equal: %s - %s\n", wine_dbgstr_rect(&rc),
131 wine_dbgstr_rect(&rc_clip));
132
133 ret = SaveDC(hdc);
134 ok(ret == 1, "ret = %d\n", ret);
135
136 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
137 if (ret == COMPLEXREGION)
138 {
139 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
140 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
141 /* let's make sure that it's a simple region */
142 ret = GetClipRgn(hdc, hrgn);
143 ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
144 dump_region(hrgn);
145 }
146 else
147 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
148
149 ret = GetClipBox(hdc, &rc_clip);
150 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
151 SetRect(&rc, 0, 0, 50, 50);
152 ok(EqualRect(&rc, &rc_clip), "rects are not equal: %s - %s\n", wine_dbgstr_rect(&rc),
153 wine_dbgstr_rect(&rc_clip));
154
155 ret = RestoreDC(hdc, 1);
156 ok(ret, "ret = %d\n", ret);
157
158 ret = GetClipBox(hdc, &rc_clip);
159 ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
160 SetRect(&rc, 0, 0, 100, 100);
161 ok(EqualRect(&rc, &rc_clip), "rects are not equal: %s - %s\n", wine_dbgstr_rect(&rc),
162 wine_dbgstr_rect(&rc_clip));
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, int scale )
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 RECT rect;
349 UINT type;
350
351 if (GetObjectType( hdc ) == OBJ_METADC)
352 {
353 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
354 ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
355 "wrong caps on %s for %u: %u\n", descr, caps[i],
356 GetDeviceCaps( hdc, caps[i] ) );
357
358 SetLastError( 0xdeadbeef );
359 ret = GetDeviceGammaRamp( hdc, &ramp );
360 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
361 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
362 "wrong error %u on %s\n", GetLastError(), descr );
363 type = GetClipBox( hdc, &rect );
364 ok( type == ERROR, "GetClipBox returned %d on %s\n", type, descr );
365
366 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
367 SetMapMode( hdc, MM_TEXT );
368 Rectangle( hdc, 2, 2, 5, 5 );
369 type = GetBoundsRect( hdc, &rect, DCB_RESET );
370 ok( !type, "GetBoundsRect succeeded on %s\n", descr );
371 type = SetBoundsRect( hdc, &rect, DCB_RESET | DCB_ENABLE );
372 ok( !type, "SetBoundsRect succeeded on %s\n", descr );
373 }
374 else
375 {
376 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
377 {
378 INT precision = 0;
379 INT hdc_caps = GetDeviceCaps( hdc, caps[i] );
380
381 switch (caps[i])
382 {
383 case HORZSIZE:
384 case VERTSIZE:
385 hdc_caps /= scale;
386 precision = 1;
387 break;
388 case LOGPIXELSX:
389 case LOGPIXELSY:
390 hdc_caps *= scale;
391 break;
392 }
393
394 ok( abs(hdc_caps - GetDeviceCaps( ref_dc, caps[i] )) <= precision,
395 "mismatched caps on %s for %u: %u/%u (scale %d)\n", descr, caps[i],
396 hdc_caps, GetDeviceCaps( ref_dc, caps[i] ), scale );
397 }
398
399 SetLastError( 0xdeadbeef );
400 ret = GetDeviceGammaRamp( hdc, &ramp );
401 if (GetObjectType( hdc ) != OBJ_DC || GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER)
402 {
403 ok( !ret, "GetDeviceGammaRamp succeeded on %s (type %d)\n", descr, GetObjectType( hdc ) );
404 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
405 "wrong error %u on %s\n", GetLastError(), descr );
406 }
407 else
408 ok( ret || broken(!ret) /* NT4 */, "GetDeviceGammaRamp failed on %s (type %d), error %u\n", descr, GetObjectType( hdc ), GetLastError() );
409 type = GetClipBox( hdc, &rect );
410 todo_wine_if (GetObjectType( hdc ) == OBJ_ENHMETADC)
411 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
412
413 type = GetBoundsRect( hdc, &rect, 0 );
414 ok( type == DCB_RESET || broken(type == DCB_SET) /* XP */,
415 "GetBoundsRect returned type %x for %s\n", type, descr );
416 if (type == DCB_RESET)
417 ok( rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0,
418 "GetBoundsRect returned %s type %x for %s\n", wine_dbgstr_rect( &rect ),
419 type, descr );
420 type = SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
421 ok( type == (DCB_RESET | DCB_DISABLE) || broken(type == (DCB_SET | DCB_ENABLE)) /* XP */,
422 "SetBoundsRect returned %x for %s (hdc type %d)\n", type, descr, GetObjectType( hdc ) );
423
424 SetMapMode( hdc, MM_TEXT );
425 Rectangle( hdc, 2, 2, 4, 4 );
426 type = GetBoundsRect( hdc, &rect, DCB_RESET );
427 todo_wine_if (GetObjectType( hdc ) == OBJ_ENHMETADC || (GetObjectType( hdc ) == OBJ_DC && GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER))
428 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
429 "GetBoundsRect returned %s type %x for %s\n", wine_dbgstr_rect( &rect ),
430 type, descr );
431 }
432
433 type = GetClipBox( ref_dc, &rect );
434 if (type != COMPLEXREGION && type != ERROR) /* region can be complex on multi-monitor setups */
435 {
436 RECT ref_rect;
437
438 ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
439 if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY)
440 {
441 todo_wine_if (GetSystemMetrics( SM_CXSCREEN ) != GetSystemMetrics( SM_CXVIRTUALSCREEN ))
442 ok( GetDeviceCaps( ref_dc, DESKTOPHORZRES ) == GetSystemMetrics( SM_CXSCREEN ),
443 "Got DESKTOPHORZRES %d on %s, expected %d\n",
444 GetDeviceCaps( ref_dc, DESKTOPHORZRES ), descr, GetSystemMetrics( SM_CXSCREEN ) );
445
446 todo_wine_if (GetSystemMetrics( SM_CYSCREEN ) != GetSystemMetrics( SM_CYVIRTUALSCREEN ))
447 ok( GetDeviceCaps( ref_dc, DESKTOPVERTRES ) == GetSystemMetrics( SM_CYSCREEN ),
448 "Got DESKTOPVERTRES %d on %s, expected %d\n",
449 GetDeviceCaps( ref_dc, DESKTOPVERTRES ), descr, GetSystemMetrics( SM_CYSCREEN ) );
450
451 SetRect( &ref_rect, GetSystemMetrics( SM_XVIRTUALSCREEN ), GetSystemMetrics( SM_YVIRTUALSCREEN ),
452 GetSystemMetrics( SM_XVIRTUALSCREEN ) + GetSystemMetrics( SM_CXVIRTUALSCREEN ),
453 GetSystemMetrics( SM_YVIRTUALSCREEN ) + GetSystemMetrics( SM_CYVIRTUALSCREEN ) );
454 }
455 else
456 {
457 SetRect( &ref_rect, 0, 0, GetDeviceCaps( ref_dc, DESKTOPHORZRES ),
458 GetDeviceCaps( ref_dc, DESKTOPVERTRES ) );
459 }
460
461 todo_wine_if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY && GetObjectType( hdc ) != OBJ_ENHMETADC &&
462 (GetSystemMetrics( SM_XVIRTUALSCREEN ) || GetSystemMetrics( SM_YVIRTUALSCREEN )))
463 ok( EqualRect( &rect, &ref_rect ), "GetClipBox returned %s on %s\n",
464 wine_dbgstr_rect( &rect ), descr );
465 }
466
467 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_ACCUMULATE );
468 SetMapMode( ref_dc, MM_TEXT );
469 Rectangle( ref_dc, 3, 3, 5, 5 );
470 type = GetBoundsRect( ref_dc, &rect, DCB_RESET );
471 /* it may or may not work on non-memory DCs */
472 ok( (rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0 && type == DCB_RESET) ||
473 (rect.left == 3 && rect.top == 3 && rect.right == 5 && rect.bottom == 5 && type == DCB_SET),
474 "GetBoundsRect returned %s type %x on %s\n", wine_dbgstr_rect( &rect ), type, descr );
475
476 if (GetObjectType( hdc ) == OBJ_MEMDC)
477 {
478 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
479 BITMAPINFO *info = (BITMAPINFO *)buffer;
480 HBITMAP dib, old;
481
482 memset( buffer, 0, sizeof(buffer) );
483 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
484 info->bmiHeader.biWidth = 16;
485 info->bmiHeader.biHeight = 16;
486 info->bmiHeader.biPlanes = 1;
487 info->bmiHeader.biBitCount = 8;
488 info->bmiHeader.biCompression = BI_RGB;
489 dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
490 old = SelectObject( hdc, dib );
491
492 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
493 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
494 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
495 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
496
497 SetLastError( 0xdeadbeef );
498 ret = GetDeviceGammaRamp( hdc, &ramp );
499 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
500 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
501 "wrong error %u on %s\n", GetLastError(), descr );
502
503 type = GetClipBox( hdc, &rect );
504 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
505 ok( rect.left == 0 && rect.top == 0 && rect.right == 16 && rect.bottom == 16,
506 "GetClipBox returned %s on memdc for %s\n", wine_dbgstr_rect( &rect ), descr );
507
508 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
509 SetMapMode( hdc, MM_TEXT );
510 Rectangle( hdc, 5, 5, 12, 14 );
511 type = GetBoundsRect( hdc, &rect, DCB_RESET );
512 ok( rect.left == 5 && rect.top == 5 && rect.right == 12 && rect.bottom == 14 && type == DCB_SET,
513 "GetBoundsRect returned %s type %x on memdc for %s\n", wine_dbgstr_rect( &rect ),
514 type, descr );
515
516 SelectObject( hdc, old );
517 DeleteObject( dib );
518 }
519
520 /* restore hdc state */
521 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_DISABLE );
522 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_DISABLE );
523 }
524
525 static void test_CreateCompatibleDC(void)
526 {
527 BOOL bRet;
528 HDC hdc, hNewDC, hdcMetafile, screen_dc;
529 HBITMAP bitmap;
530 INT caps;
531 DEVMODEA dm;
532
533 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
534
535 bRet = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
536 ok(bRet, "EnumDisplaySettingsEx failed\n");
537 dm.u1.s1.dmScale = 200;
538 dm.dmFields |= DM_SCALE;
539 hdc = CreateDCA( "DISPLAY", NULL, NULL, &dm );
540
541 screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
542 test_device_caps( hdc, screen_dc, "display dc", 1 );
543 ResetDCA( hdc, &dm );
544 test_device_caps( hdc, screen_dc, "display dc", 1 );
545 DeleteDC( hdc );
546
547 /* Create a DC compatible with the screen */
548 hdc = CreateCompatibleDC(NULL);
549 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
550 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
551 caps = GetDeviceCaps( hdc, TECHNOLOGY );
552 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
553
554 test_device_caps( hdc, screen_dc, "display dc", 1 );
555
556 /* Delete this DC, this should succeed */
557 bRet = DeleteDC(hdc);
558 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
559
560 /* Try to create a DC compatible to the deleted DC. This has to fail */
561 hNewDC = CreateCompatibleDC(hdc);
562 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
563
564 hdc = GetDC( 0 );
565 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
566 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
567 hNewDC = CreateCompatibleDC( hdcMetafile );
568 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
569 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
570 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
571 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
572 test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
573 ResetDCA( hdcMetafile, &dm );
574 test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
575 DeleteDC( hNewDC );
576 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
577 ReleaseDC( 0, hdc );
578
579 hdcMetafile = CreateMetaFileA(NULL);
580 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
581 hNewDC = CreateCompatibleDC( hdcMetafile );
582 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
583 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
584 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
585 test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
586 ResetDCA( hdcMetafile, &dm );
587 test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
588 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
589
590 DeleteObject( bitmap );
591 DeleteDC( screen_dc );
592 }
593
594 static void test_DC_bitmap(void)
595 {
596 PIXELFORMATDESCRIPTOR descr;
597 HDC hdc, hdcmem;
598 DWORD bits[64];
599 HBITMAP hbmp, oldhbmp;
600 COLORREF col;
601 int i, bitspixel;
602 int ret, ret2;
603
604 /* fill bitmap data with b&w pattern */
605 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
606
607 hdc = GetDC(0);
608 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
609 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
610 /* create a memory dc */
611 hdcmem = CreateCompatibleDC( hdc);
612 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
613
614 /* test DescribePixelFormat with descr == NULL */
615 ret2 = DescribePixelFormat(hdcmem, 0, sizeof(descr), NULL);
616 ok(ret2 > 0, "expected ret2 > 0, got %d\n", ret2);
617 ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), NULL);
618 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
619 ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), NULL);
620 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
621
622 /* test DescribePixelFormat with descr != NULL */
623 memset(&descr, 0, sizeof(descr));
624 ret = DescribePixelFormat(hdcmem, 0, sizeof(descr), &descr);
625 ok(ret == 0, "expected ret == 0, got %d\n", ret);
626 ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
627
628 memset(&descr, 0, sizeof(descr));
629 ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), &descr);
630 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
631 ok(descr.nSize == sizeof(descr), "expected desc.nSize == sizeof(descr), got %d\n", descr.nSize);
632
633 memset(&descr, 0, sizeof(descr));
634 ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), &descr);
635 ok(ret == 0, "expected ret == 0, got %d\n", ret);
636 ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
637
638 /* test monochrome bitmap: should always work */
639 hbmp = CreateBitmap(32, 32, 1, 1, bits);
640 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
641 oldhbmp = SelectObject( hdcmem, hbmp);
642 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
643 col = GetPixel( hdcmem, 0, 0);
644 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
645 col = GetPixel( hdcmem, 1, 1);
646 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
647 col = GetPixel( hdcmem, 100, 1);
648 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
649 SelectObject( hdcmem, oldhbmp);
650 DeleteObject( hbmp);
651
652 /* test with 2 bits color depth, not likely to succeed */
653 hbmp = CreateBitmap(16, 16, 1, 2, bits);
654 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
655 oldhbmp = SelectObject( hdcmem, hbmp);
656 if( bitspixel != 2)
657 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
658 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
659 DeleteObject( hbmp);
660
661 /* test with 16 bits color depth, might succeed */
662 hbmp = CreateBitmap(6, 6, 1, 16, bits);
663 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
664 oldhbmp = SelectObject( hdcmem, hbmp);
665 if( bitspixel == 16) {
666 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
667 col = GetPixel( hdcmem, 0, 0);
668 ok( col == 0xffffff,
669 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
670 col = GetPixel( hdcmem, 1, 1);
671 ok( col == 0x000000,
672 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
673 }
674 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
675 DeleteObject( hbmp);
676
677 /* test with 32 bits color depth, probably succeed */
678 hbmp = CreateBitmap(4, 4, 1, 32, bits);
679 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
680 oldhbmp = SelectObject( hdcmem, hbmp);
681 if( bitspixel == 32) {
682 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
683 col = GetPixel( hdcmem, 0, 0);
684 ok( col == 0xffffff,
685 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
686 col = GetPixel( hdcmem, 1, 1);
687 ok( col == 0x000000,
688 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
689 }
690 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
691 DeleteObject( hbmp);
692 ReleaseDC( 0, hdc );
693 }
694
695 static void test_DeleteDC(void)
696 {
697 HWND hwnd;
698 HDC hdc, hdc_test;
699 WNDCLASSEXA cls;
700 int ret;
701
702 /* window DC */
703 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
704 0, 0, 0, NULL);
705 ok(hwnd != 0, "CreateWindowExA failed\n");
706
707 hdc = GetDC(hwnd);
708 ok(hdc != 0, "GetDC failed\n");
709 ret = GetObjectType(hdc);
710 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
711 ret = DeleteDC(hdc);
712 ok(ret, "DeleteDC failed\n");
713 ret = GetObjectType(hdc);
714 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
715
716 hdc = GetWindowDC(hwnd);
717 ok(hdc != 0, "GetDC failed\n");
718 ret = GetObjectType(hdc);
719 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
720 ret = DeleteDC(hdc);
721 ok(ret, "DeleteDC failed\n");
722 ret = GetObjectType(hdc);
723 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
724
725 DestroyWindow(hwnd);
726
727 /* desktop window DC */
728 hwnd = GetDesktopWindow();
729 ok(hwnd != 0, "GetDesktopWindow failed\n");
730
731 hdc = GetDC(hwnd);
732 ok(hdc != 0, "GetDC failed\n");
733 ret = GetObjectType(hdc);
734 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
735 ret = DeleteDC(hdc);
736 ok(ret, "DeleteDC failed\n");
737 ret = GetObjectType(hdc);
738 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
739
740 hdc = GetWindowDC(hwnd);
741 ok(hdc != 0, "GetDC failed\n");
742 ret = GetObjectType(hdc);
743 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
744 ret = DeleteDC(hdc);
745 ok(ret, "DeleteDC failed\n");
746 ret = GetObjectType(hdc);
747 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
748
749 /* CS_CLASSDC */
750 memset(&cls, 0, sizeof(cls));
751 cls.cbSize = sizeof(cls);
752 cls.style = CS_CLASSDC;
753 cls.hInstance = GetModuleHandleA(NULL);
754 cls.lpszClassName = "Wine class DC";
755 cls.lpfnWndProc = DefWindowProcA;
756 ret = RegisterClassExA(&cls);
757 ok(ret, "RegisterClassExA failed\n");
758
759 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
760 0, 0, 0, NULL);
761 ok(hwnd != 0, "CreateWindowExA failed\n");
762
763 hdc = GetDC(hwnd);
764 ok(hdc != 0, "GetDC failed\n");
765 ret = GetObjectType(hdc);
766 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
767 ret = DeleteDC(hdc);
768 ok(ret, "DeleteDC failed\n");
769 ret = GetObjectType(hdc);
770 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
771 ret = ReleaseDC(hwnd, hdc);
772 ok(ret, "ReleaseDC failed\n");
773 ret = GetObjectType(hdc);
774 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
775
776 hdc_test = hdc;
777
778 hdc = GetWindowDC(hwnd);
779 ok(hdc != 0, "GetDC failed\n");
780 ret = GetObjectType(hdc);
781 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
782 ret = DeleteDC(hdc);
783 ok(ret, "DeleteDC failed\n");
784 ret = GetObjectType(hdc);
785 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
786
787 DestroyWindow(hwnd);
788
789 ret = GetObjectType(hdc_test);
790 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
791
792 ret = UnregisterClassA("Wine class DC", GetModuleHandleA(NULL));
793 ok(ret, "UnregisterClassA failed\n");
794
795 ret = GetObjectType(hdc_test);
796 ok(!ret, "GetObjectType should fail for a deleted DC\n");
797
798 /* CS_OWNDC */
799 memset(&cls, 0, sizeof(cls));
800 cls.cbSize = sizeof(cls);
801 cls.style = CS_OWNDC;
802 cls.hInstance = GetModuleHandleA(NULL);
803 cls.lpszClassName = "Wine own DC";
804 cls.lpfnWndProc = DefWindowProcA;
805 ret = RegisterClassExA(&cls);
806 ok(ret, "RegisterClassExA failed\n");
807
808 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
809 0, 0, 0, NULL);
810 ok(hwnd != 0, "CreateWindowExA failed\n");
811
812 hdc = GetDC(hwnd);
813 ok(hdc != 0, "GetDC failed\n");
814 ret = GetObjectType(hdc);
815 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
816 ret = DeleteDC(hdc);
817 ok(ret, "DeleteDC failed\n");
818 ret = GetObjectType(hdc);
819 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
820 ret = ReleaseDC(hwnd, hdc);
821 ok(ret, "ReleaseDC failed\n");
822 ret = GetObjectType(hdc);
823 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
824
825 hdc = GetWindowDC(hwnd);
826 ok(hdc != 0, "GetDC failed\n");
827 ret = GetObjectType(hdc);
828 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
829 ret = DeleteDC(hdc);
830 ok(ret, "DeleteDC failed\n");
831 ret = GetObjectType(hdc);
832 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
833
834 DestroyWindow(hwnd);
835
836 ret = UnregisterClassA("Wine own DC", GetModuleHandleA(NULL));
837 ok(ret, "UnregisterClassA failed\n");
838 }
839
840 static void test_boundsrect(void)
841 {
842 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
843 BITMAPINFO *info = (BITMAPINFO *)buffer;
844 HDC hdc;
845 HBITMAP bitmap, dib, old;
846 RECT rect, expect, set_rect;
847 UINT ret;
848 int i, level;
849
850 hdc = CreateCompatibleDC(0);
851 ok(hdc != NULL, "CreateCompatibleDC failed\n");
852 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
853 old = SelectObject( hdc, bitmap );
854
855 ret = GetBoundsRect(hdc, NULL, 0);
856 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
857
858 ret = GetBoundsRect(hdc, NULL, ~0U);
859 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
860
861 /* Test parameter handling order. */
862 SetRect(&set_rect, 10, 20, 40, 50);
863 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
864 ok(ret & DCB_RESET,
865 "Expected return flag DCB_RESET to be set, got %u\n", ret);
866
867 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
868 ok(ret == 0,
869 "Expected GetBoundsRect to return 0, got %u\n", ret);
870
871 ret = GetBoundsRect(hdc, &rect, 0);
872 ok(ret == DCB_RESET,
873 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
874 SetRectEmpty(&expect);
875 ok(EqualRect(&rect, &expect), "Expected output rectangle (0,0)-(0,0), got %s\n",
876 wine_dbgstr_rect(&rect));
877
878 ret = GetBoundsRect(NULL, NULL, 0);
879 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
880
881 ret = GetBoundsRect(NULL, NULL, ~0U);
882 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
883
884 ret = SetBoundsRect(NULL, NULL, 0);
885 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
886
887 ret = SetBoundsRect(NULL, NULL, ~0U);
888 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
889
890 SetRect(&set_rect, 10, 20, 40, 50);
891 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
892 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
893
894 ret = GetBoundsRect(hdc, &rect, 0);
895 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
896 SetRect(&expect, 10, 20, 40, 50);
897 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
898
899 SetMapMode( hdc, MM_ANISOTROPIC );
900 SetViewportExtEx( hdc, 2, 2, NULL );
901 ret = GetBoundsRect(hdc, &rect, 0);
902 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
903 SetRect(&expect, 5, 10, 20, 25);
904 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
905
906 SetViewportOrgEx( hdc, 20, 30, NULL );
907 ret = GetBoundsRect(hdc, &rect, 0);
908 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
909 SetRect(&expect, -5, -5, 10, 10);
910 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
911
912 SetRect(&set_rect, 10, 20, 40, 50);
913 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
914 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
915
916 ret = GetBoundsRect(hdc, &rect, 0);
917 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
918 SetRect(&expect, 10, 20, 40, 50);
919 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
920
921 SetMapMode( hdc, MM_TEXT );
922 SetViewportOrgEx( hdc, 0, 0, NULL );
923 ret = GetBoundsRect(hdc, &rect, 0);
924 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
925 SetRect(&expect, 40, 70, 100, 130);
926 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
927
928 if (pSetLayout)
929 {
930 pSetLayout( hdc, LAYOUT_RTL );
931 ret = GetBoundsRect(hdc, &rect, 0);
932 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
933 SetRect(&expect, 159, 70, 99, 130);
934 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
935 SetRect(&set_rect, 50, 25, 30, 35);
936 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
937 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
938 ret = GetBoundsRect(hdc, &rect, 0);
939 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
940 SetRect(&expect, 50, 25, 30, 35);
941 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
942
943 pSetLayout( hdc, LAYOUT_LTR );
944 ret = GetBoundsRect(hdc, &rect, 0);
945 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
946 SetRect(&expect, 149, 25, 169, 35);
947 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
948 }
949
950 /* empty rect resets, except on nt4 */
951 SetRect(&expect, 20, 20, 10, 10);
952 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
953 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
954 ret = GetBoundsRect(hdc, &rect, 0);
955 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
956 "GetBoundsRect returned %x\n", ret);
957 if (ret == DCB_RESET)
958 {
959 SetRectEmpty(&expect);
960 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
961
962 SetRect(&expect, 20, 20, 20, 20);
963 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
964 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
965 ret = GetBoundsRect(hdc, &rect, 0);
966 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
967 SetRectEmpty(&expect);
968 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
969 }
970
971 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
972 MoveToEx( hdc, 10, 10, NULL );
973 LineTo( hdc, 20, 20 );
974 ret = GetBoundsRect( hdc, &rect, 0 );
975 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
976 SetRect( &expect, 10, 10, 21, 21 );
977 ok( EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
978 SetRect( &rect, 8, 8, 23, 23 );
979 expect = rect;
980 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
981 ret = GetBoundsRect( hdc, &rect, 0 );
982 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
983 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
984
985 level = SaveDC( hdc );
986 LineTo( hdc, 30, 25 );
987 ret = GetBoundsRect( hdc, &rect, 0 );
988 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
989 SetRect( &expect, 8, 8, 31, 26 );
990 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
991 SetBoundsRect( hdc, NULL, DCB_DISABLE );
992 LineTo( hdc, 40, 40 );
993 ret = GetBoundsRect( hdc, &rect, 0 );
994 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
995 SetRect( &expect, 8, 8, 31, 26 );
996 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
997 SetRect( &rect, 6, 6, 30, 30 );
998 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
999 ret = GetBoundsRect( hdc, &rect, 0 );
1000 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1001 SetRect( &expect, 6, 6, 31, 30 );
1002 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1003
1004 RestoreDC( hdc, level );
1005 ret = GetBoundsRect( hdc, &rect, 0 );
1006 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1007 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1008 LineTo( hdc, 40, 40 );
1009 ret = GetBoundsRect( hdc, &rect, 0 );
1010 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1011 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1012
1013 SelectObject( hdc, old );
1014 ret = GetBoundsRect( hdc, &rect, 0 );
1015 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1016 SetRect( &expect, 6, 6, 1, 1 );
1017 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1018 SetBoundsRect( hdc, NULL, DCB_ENABLE );
1019 LineTo( hdc, 50, 40 );
1020
1021 SelectObject( hdc, bitmap );
1022 ret = GetBoundsRect( hdc, &rect, 0 );
1023 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1024 SetRect( &expect, 6, 6, 51, 41 );
1025 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1026 SelectObject( hdc, GetStockObject( NULL_PEN ));
1027 LineTo( hdc, 50, 50 );
1028 ret = GetBoundsRect( hdc, &rect, 0 );
1029 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1030 SetRect( &expect, 6, 6, 51, 51 );
1031 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1032
1033 memset( buffer, 0, sizeof(buffer) );
1034 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1035 info->bmiHeader.biWidth = 256;
1036 info->bmiHeader.biHeight = 256;
1037 info->bmiHeader.biPlanes = 1;
1038 info->bmiHeader.biBitCount = 8;
1039 info->bmiHeader.biCompression = BI_RGB;
1040 dib = CreateDIBSection( 0, info, DIB_RGB_COLORS, NULL, NULL, 0 );
1041 ok( dib != 0, "failed to create DIB\n" );
1042 SelectObject( hdc, dib );
1043 ret = GetBoundsRect( hdc, &rect, 0 );
1044 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1045 SetRect( &expect, 6, 6, 51, 51 );
1046 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1047 LineTo( hdc, 55, 30 );
1048 ret = GetBoundsRect( hdc, &rect, 0 );
1049 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1050 SetRect( &expect, 6, 6, 56, 51 );
1051 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1052 LineTo( hdc, 300, 30 );
1053 ret = GetBoundsRect( hdc, &rect, 0 );
1054 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1055 SetRect( &expect, 6, 6, 256, 51 );
1056 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1057 LineTo( hdc, -300, -300 );
1058 ret = GetBoundsRect( hdc, &rect, 0 );
1059 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1060 SetRect( &expect, 0, 0, 256, 51 );
1061 ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
1062
1063 /* test the wide pen heuristics */
1064 SetBoundsRect( hdc, NULL, DCB_ENABLE | DCB_RESET );
1065 for (i = 0; i < 1000; i++)
1066 {
1067 static const UINT endcaps[3] = { PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT };
1068 static const UINT joins[3] = { PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER };
1069 LOGBRUSH brush = { BS_SOLID, RGB(0,0,0), 0 };
1070 UINT join = joins[i % 3];
1071 UINT endcap = endcaps[(i / 3) % 3];
1072 INT inflate, width = 1 + i / 9;
1073 HPEN pen = ExtCreatePen( PS_GEOMETRIC | join | endcap | PS_SOLID, width, &brush, 0, NULL );
1074 HPEN old = SelectObject( hdc, pen );
1075 MoveToEx( hdc, 100, 100, NULL );
1076 LineTo( hdc, 160, 100 );
1077 LineTo( hdc, 100, 160 );
1078 LineTo( hdc, 160, 160 );
1079 GetBoundsRect( hdc, &rect, DCB_RESET );
1080 SetRect( &expect, 100, 100, 161, 161 );
1081
1082 inflate = width + 2;
1083 if (join == PS_JOIN_MITER)
1084 {
1085 inflate *= 5;
1086 if (endcap == PS_ENDCAP_SQUARE)
1087 InflateRect( &expect, (inflate * 3 + 1) / 2, (inflate * 3 + 1) / 2 );
1088 else
1089 InflateRect( &expect, inflate, inflate );
1090 }
1091 else
1092 {
1093 if (endcap == PS_ENDCAP_SQUARE)
1094 InflateRect( &expect, inflate - inflate / 4, inflate - inflate / 4 );
1095 else
1096 InflateRect( &expect, (inflate + 1) / 2, (inflate + 1) / 2 );
1097 }
1098 expect.left = max( expect.left, 0 );
1099 expect.top = max( expect.top, 0 );
1100 expect.right = min( expect.right, 256 );
1101 expect.bottom = min( expect.bottom, 256 );
1102 ok(EqualRect(&rect, &expect), "Got %s expected %s %u/%x/%x\n", wine_dbgstr_rect(&rect),
1103 wine_dbgstr_rect(&expect), width, endcap, join);
1104 DeleteObject( SelectObject( hdc, old ));
1105 }
1106
1107 DeleteDC( hdc );
1108 DeleteObject( bitmap );
1109 DeleteObject( dib );
1110 }
1111
1112 static void test_desktop_colorres(void)
1113 {
1114 HDC hdc = GetDC(NULL);
1115 int bitspixel, colorres;
1116
1117 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
1118 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
1119
1120 colorres = GetDeviceCaps(hdc, COLORRES);
1121 ok(colorres != 0 ||
1122 broken(colorres == 0), /* Win9x */
1123 "Expected to get valid COLORRES capability value\n");
1124
1125 if (colorres)
1126 {
1127 switch (bitspixel)
1128 {
1129 case 8:
1130 ok(colorres == 18,
1131 "Expected COLORRES to be 18, got %d\n", colorres);
1132 break;
1133 case 16:
1134 ok(colorres == 16,
1135 "Expected COLORRES to be 16, got %d\n", colorres);
1136 break;
1137 case 24:
1138 case 32:
1139 ok(colorres == 24,
1140 "Expected COLORRES to be 24, got %d\n", bitspixel);
1141 break;
1142 default:
1143 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
1144 break;
1145 }
1146 }
1147
1148 ReleaseDC(NULL, hdc);
1149 }
1150
1151 static void test_gamma(void)
1152 {
1153 BOOL ret;
1154 HDC hdc = GetDC(NULL);
1155 WORD oldramp[3][256], ramp[3][256];
1156 INT i;
1157
1158 ret = GetDeviceGammaRamp(hdc, &oldramp);
1159 if (!ret)
1160 {
1161 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
1162 goto done;
1163 }
1164
1165 /* try to set back old ramp */
1166 ret = SetDeviceGammaRamp(hdc, &oldramp);
1167 if (!ret)
1168 {
1169 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
1170 goto done;
1171 }
1172
1173 memcpy(ramp, oldramp, sizeof(ramp));
1174
1175 /* set one color ramp to zeros */
1176 memset(ramp[0], 0, sizeof(ramp[0]));
1177 ret = SetDeviceGammaRamp(hdc, &ramp);
1178 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1179
1180 /* set one color ramp to a flat straight rising line */
1181 for (i = 0; i < 256; i++) ramp[0][i] = i;
1182 ret = SetDeviceGammaRamp(hdc, &ramp);
1183 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
1184
1185 /* set one color ramp to a steep straight rising line */
1186 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
1187 ret = SetDeviceGammaRamp(hdc, &ramp);
1188 ok(ret, "SetDeviceGammaRamp failed\n");
1189
1190 /* try a bright gamma ramp */
1191 ramp[0][0] = 0;
1192 ramp[0][1] = 0x7FFF;
1193 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
1194 ret = SetDeviceGammaRamp(hdc, &ramp);
1195 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1196
1197 /* try ramps which are not uniform */
1198 ramp[0][0] = 0;
1199 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
1200 ret = SetDeviceGammaRamp(hdc, &ramp);
1201 ok(ret, "SetDeviceGammaRamp failed\n");
1202 ramp[0][0] = 0;
1203 for (i = 2; i < 256; i+=2)
1204 {
1205 ramp[0][i - 1] = ramp[0][i - 2];
1206 ramp[0][i] = ramp[0][i - 2] + 512;
1207 }
1208 ret = SetDeviceGammaRamp(hdc, &ramp);
1209 ok(ret, "SetDeviceGammaRamp failed\n");
1210
1211 /* cleanup: set old ramp again */
1212 ret = SetDeviceGammaRamp(hdc, &oldramp);
1213 ok(ret, "SetDeviceGammaRamp failed\n");
1214
1215 done:
1216 ReleaseDC(NULL, hdc);
1217 }
1218
1219 static BOOL is_postscript_printer(HDC hdc)
1220 {
1221 char tech[256];
1222
1223 if (ExtEscape(hdc, GETTECHNOLOGY, 0, NULL, sizeof(tech), tech) > 0)
1224 return strcmp(tech, "PostScript") == 0;
1225
1226 return FALSE;
1227 }
1228
1229 static HDC create_printer_dc(int scale, BOOL reset)
1230 {
1231 char buffer[260];
1232 DWORD len;
1233 PRINTER_INFO_2A *pbuf = NULL;
1234 DRIVER_INFO_3A *dbuf = NULL;
1235 HANDLE hprn = 0;
1236 HDC hdc = 0;
1237 HMODULE winspool = LoadLibraryA( "winspool.drv" );
1238 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
1239 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
1240 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
1241 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
1242 BOOL (WINAPI *pClosePrinter)(HANDLE);
1243
1244 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
1245 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
1246 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
1247 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
1248 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
1249
1250 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
1251 goto done;
1252
1253 len = sizeof(buffer);
1254 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
1255 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
1256
1257 pGetPrinterA( hprn, 2, NULL, 0, &len );
1258 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
1259 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
1260
1261 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
1262 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
1263 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
1264
1265 pbuf->pDevMode->u1.s1.dmScale = scale;
1266 pbuf->pDevMode->dmFields |= DM_SCALE;
1267
1268 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
1269 trace( "hdc %p for driver '%s' printer '%s' port '%s' is %sPostScript\n", hdc,
1270 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName,
1271 is_postscript_printer(hdc) ? "" : "NOT " );
1272
1273 if (reset) ResetDCA( hdc, pbuf->pDevMode );
1274 done:
1275 HeapFree( GetProcessHeap(), 0, dbuf );
1276 HeapFree( GetProcessHeap(), 0, pbuf );
1277 if (hprn) pClosePrinter( hprn );
1278 if (winspool) FreeLibrary( winspool );
1279 if (!hdc) skip( "could not create a DC for the default printer\n" );
1280 return hdc;
1281 }
1282
1283 static void test_printer_dc(void)
1284 {
1285 HDC memdc, display_memdc, enhmf_dc;
1286 HBITMAP orig, bmp;
1287 DWORD ret;
1288 HDC hdc, hdc_200;
1289
1290 hdc = create_printer_dc(100, FALSE);
1291 hdc_200 = create_printer_dc(200, FALSE);
1292
1293 if (!hdc || !hdc_200) return;
1294
1295 test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 );
1296 DeleteDC( hdc_200 );
1297
1298 hdc_200 = create_printer_dc(200, TRUE);
1299 test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 );
1300 DeleteDC( hdc_200 );
1301
1302 memdc = CreateCompatibleDC( hdc );
1303 display_memdc = CreateCompatibleDC( 0 );
1304
1305 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
1306 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
1307
1308 ret = GetDeviceCaps( hdc, TECHNOLOGY );
1309 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1310
1311 ret = GetDeviceCaps( memdc, TECHNOLOGY );
1312 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1313
1314 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
1315 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
1316
1317 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
1318 orig = SelectObject( memdc, bmp );
1319 ok( orig != NULL, "SelectObject failed\n" );
1320 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1321
1322 test_device_caps( memdc, hdc, "printer dc", 1 );
1323
1324 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
1325 SelectObject( memdc, orig );
1326 DeleteObject( bmp );
1327
1328 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
1329 orig = SelectObject( display_memdc, bmp );
1330 ok( orig != NULL, "SelectObject failed\n" );
1331 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
1332 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1333 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1334 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1335
1336 ret = GetPixel( hdc, 0, 0 );
1337 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
1338
1339 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1340 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1341 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 );
1342 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1343
1344 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1345 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1346 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 );
1347 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1348
1349 DeleteDC( memdc );
1350 DeleteDC( display_memdc );
1351 DeleteDC( hdc );
1352 DeleteObject( bmp );
1353 }
1354
1355 static void print_something(HDC hdc)
1356 {
1357 static const char psadobe[10] = "%!PS-Adobe";
1358 char buf[1024], *p;
1359 char temp_path[MAX_PATH], file_name[MAX_PATH];
1360 DOCINFOA di;
1361 DWORD ret;
1362 HANDLE hfile;
1363
1364 GetTempPathA(sizeof(temp_path), temp_path);
1365 GetTempFileNameA(temp_path, "ps", 0, file_name);
1366
1367 di.cbSize = sizeof(di);
1368 di.lpszDocName = "Let's dance";
1369 di.lpszOutput = file_name;
1370 di.lpszDatatype = NULL;
1371 di.fwType = 0;
1372 ret = StartDocA(hdc, &di);
1373 ok(ret > 0, "StartDoc failed: %d\n", ret);
1374
1375 strcpy(buf + 2, "\n% ===> before DOWNLOADHEADER <===\n");
1376 *(WORD *)buf = strlen(buf + 2);
1377 ret = Escape(hdc, POSTSCRIPT_PASSTHROUGH, 0, buf, NULL);
1378 ok(ret == *(WORD *)buf, "POSTSCRIPT_PASSTHROUGH failed: %d\n", ret);
1379
1380 strcpy(buf, "deadbeef");
1381 ret = ExtEscape(hdc, DOWNLOADHEADER, 0, NULL, sizeof(buf), buf );
1382 ok(ret == 1, "DOWNLOADHEADER failed\n");
1383 ok(strcmp(buf, "deadbeef") != 0, "DOWNLOADHEADER failed\n");
1384
1385 strcpy(buf + 2, "\n% ===> after DOWNLOADHEADER <===\n");
1386 *(WORD *)buf = strlen(buf + 2);
1387 ret = Escape(hdc, POSTSCRIPT_PASSTHROUGH, 0, buf, NULL);
1388 ok(ret == *(WORD *)buf, "POSTSCRIPT_PASSTHROUGH failed: %d\n", ret);
1389
1390 ret = EndDoc(hdc);
1391 ok(ret == 1, "EndDoc failed\n");
1392
1393 hfile = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
1394 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1395 memset(buf, 0, sizeof(buf));
1396 ret = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
1397 ok(ret, "ReadFile failed\n");
1398 CloseHandle(hfile);
1399
1400 /* skip the HP PCL language selector */
1401 buf[sizeof(buf) - 1] = 0;
1402 p = buf;
1403 while (*p)
1404 {
1405 if (!(p[0] == 0x1b && p[1] == '%') && memcmp(p, "@PJL", 4) != 0)
1406 break;
1407
1408 p = strchr(p, '\n');
1409 if (!p) break;
1410
1411 while (*p == '\r' || *p == '\n') p++;
1412 }
1413 ok(p && !memcmp(p, psadobe, sizeof(psadobe)), "wrong signature: %.14s\n", p ? p : buf);
1414
1415 DeleteFileA(file_name);
1416 }
1417
1418 static void test_pscript_printer_dc(void)
1419 {
1420 HDC hdc;
1421 char buf[256];
1422 DWORD query, ret;
1423
1424 hdc = create_printer_dc(100, FALSE);
1425
1426 if (!hdc) return;
1427
1428 if (!is_postscript_printer(hdc))
1429 {
1430 skip("Default printer is not a PostScript device\n");
1431 DeleteDC( hdc );
1432 return;
1433 }
1434
1435 query = GETFACENAME;
1436 ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
1437 ok(!ret, "GETFACENAME is supported\n");
1438
1439 query = DOWNLOADFACE;
1440 ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
1441 ok(ret == 1, "DOWNLOADFACE is not supported\n");
1442
1443 query = OPENCHANNEL;
1444 ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
1445 ok(ret == 1, "OPENCHANNEL is not supported\n");
1446
1447 query = DOWNLOADHEADER;
1448 ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
1449 ok(ret == 1, "DOWNLOADHEADER is not supported\n");
1450
1451 query = CLOSECHANNEL;
1452 ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
1453 ok(ret == 1, "CLOSECHANNEL is not supported\n");
1454
1455 query = POSTSCRIPT_PASSTHROUGH;
1456 ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
1457 ok(ret == 1, "POSTSCRIPT_PASSTHROUGH is not supported\n");
1458
1459 ret = ExtEscape(hdc, GETFACENAME, 0, NULL, sizeof(buf), buf);
1460 ok(ret == 1, "GETFACENAME failed\n");
1461 trace("face name: %s\n", buf);
1462
1463 print_something(hdc);
1464
1465 DeleteDC(hdc);
1466 }
1467
1468 START_TEST(dc)
1469 {
1470 pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
1471 test_dc_values();
1472 test_savedc();
1473 test_savedc_2();
1474 test_GdiConvertToDevmodeW();
1475 test_CreateCompatibleDC();
1476 test_DC_bitmap();
1477 test_DeleteDC();
1478 test_boundsrect();
1479 test_desktop_colorres();
1480 test_gamma();
1481 test_printer_dc();
1482 test_pscript_printer_dc();
1483 }