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