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 } 1499