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