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