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