1 #include <precomp.h> 2 3 #define NDEBUG 4 #include <debug.h> 5 6 HDC 7 FASTCALL 8 IntCreateDICW( 9 LPCWSTR lpwszDriver, 10 LPCWSTR lpwszDevice, 11 LPCWSTR lpwszOutput, 12 PDEVMODEW lpInitData, 13 ULONG iType) 14 { 15 UNICODE_STRING Device, Output; 16 HDC hdc = NULL; 17 BOOL Display = FALSE, Default = FALSE; 18 HANDLE UMdhpdev = 0; 19 20 HANDLE hspool = NULL; 21 22 if ( !ghSpooler && !LoadTheSpoolerDrv()) 23 { 24 DPRINT1("WinSpooler.Drv Did not load!\n"); 25 } 26 else 27 { 28 DPRINT("WinSpooler.Drv Loaded! hMod -> 0x%p\n", ghSpooler); 29 } 30 31 if ((!lpwszDevice) && (!lpwszDriver)) 32 { 33 Default = TRUE; // Ask Win32k to set Default device. 34 Display = TRUE; // Most likely to be DISPLAY. 35 } 36 else 37 { 38 if ((lpwszDevice) && (wcslen(lpwszDevice) != 0)) // First 39 { 40 if (!_wcsnicmp(lpwszDevice, L"\\\\.\\DISPLAY",11)) Display = TRUE; 41 RtlInitUnicodeString(&Device, lpwszDevice); 42 } 43 else 44 { 45 if (lpwszDriver) // Second 46 { 47 if ((!_wcsnicmp(lpwszDriver, L"DISPLAY",7)) || 48 (!_wcsnicmp(lpwszDriver, L"\\\\.\\DISPLAY",11))) Display = TRUE; 49 RtlInitUnicodeString(&Device, lpwszDriver); 50 } 51 } 52 } 53 54 if (lpwszOutput) RtlInitUnicodeString(&Output, lpwszOutput); 55 56 // Handle Print device or something else. 57 if (!Display) 58 { 59 // WIP - GDI Print Commit coming in soon. 60 DPRINT1("Not a DISPLAY device! %wZ\n", &Device); 61 return NULL; // Return NULL until then..... 62 } 63 64 hdc = NtGdiOpenDCW((Default ? NULL : &Device), 65 (PDEVMODEW) lpInitData, 66 (lpwszOutput ? &Output : NULL), 67 iType, // DCW 0 and ICW 1. 68 Display, 69 hspool, 70 &UMdhpdev ); 71 #if 0 72 // Handle something other than a normal dc object. 73 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) 74 { 75 PDC_ATTR Dc_Attr; 76 PLDC pLDC; 77 78 GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID*)&Dc_Attr); 79 80 pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC)); 81 82 Dc_Attr->pvLDC = pLDC; 83 pLDC->hDC = hdc; 84 pLDC->iType = LDC_LDC; // 1 (init) local DC, 2 EMF LDC 85 DbgPrint("DC_ATTR Allocated -> 0x%x\n",Dc_Attr); 86 } 87 #endif 88 return hdc; 89 } 90 91 92 /* 93 * @implemented 94 */ 95 HDC 96 WINAPI 97 CreateCompatibleDC( 98 _In_ HDC hdc) 99 { 100 HDC hdcNew; 101 // PDC_ATTR pdcattr; 102 103 hdcNew = NtGdiCreateCompatibleDC(hdc); 104 #if 0 105 if ( hdc && hdcNew) 106 { 107 if (GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID*)&pdcattr)) 108 { 109 if (pdcattr->pvLIcm) IcmCompatibleDC(hdcNew, hdc, pdcattr); 110 } 111 } 112 #endif 113 114 return hdcNew; 115 } 116 117 /* 118 * @implemented 119 */ 120 HDC 121 WINAPI 122 CreateDCA ( 123 LPCSTR lpszDriver, 124 LPCSTR lpszDevice, 125 LPCSTR lpszOutput, 126 CONST DEVMODEA * lpdvmInit) 127 { 128 ANSI_STRING DriverA, DeviceA, OutputA; 129 UNICODE_STRING DriverU, DeviceU, OutputU; 130 LPDEVMODEW dvmInitW = NULL; 131 HDC hdc; 132 133 /* 134 * If needed, convert to Unicode 135 * any string parameter. 136 */ 137 138 if (lpszDriver != NULL) 139 { 140 RtlInitAnsiString(&DriverA, (LPSTR)lpszDriver); 141 RtlAnsiStringToUnicodeString(&DriverU, &DriverA, TRUE); 142 } 143 else 144 { 145 DriverU.Buffer = NULL; 146 } 147 148 if (lpszDevice != NULL) 149 { 150 RtlInitAnsiString(&DeviceA, (LPSTR)lpszDevice); 151 RtlAnsiStringToUnicodeString(&DeviceU, &DeviceA, TRUE); 152 } 153 else 154 { 155 DeviceU.Buffer = NULL; 156 } 157 158 if (lpszOutput != NULL) 159 { 160 RtlInitAnsiString(&OutputA, (LPSTR)lpszOutput); 161 RtlAnsiStringToUnicodeString(&OutputU, &OutputA, TRUE); 162 } 163 else 164 { 165 OutputU.Buffer = NULL; 166 } 167 168 if (lpdvmInit != NULL) 169 dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit); 170 171 hdc = IntCreateDICW(DriverU.Buffer, 172 DeviceU.Buffer, 173 OutputU.Buffer, 174 lpdvmInit ? dvmInitW : NULL, 175 0); 176 HEAP_free(dvmInitW); 177 178 /* Free Unicode parameters. */ 179 RtlFreeUnicodeString(&DriverU); 180 RtlFreeUnicodeString(&DeviceU); 181 RtlFreeUnicodeString(&OutputU); 182 183 /* Return the DC handle. */ 184 return hdc; 185 } 186 187 188 /* 189 * @implemented 190 */ 191 HDC 192 WINAPI 193 CreateDCW ( 194 LPCWSTR lpwszDriver, 195 LPCWSTR lpwszDevice, 196 LPCWSTR lpwszOutput, 197 CONST DEVMODEW *lpInitData) 198 { 199 return IntCreateDICW(lpwszDriver, 200 lpwszDevice, 201 lpwszOutput, 202 (PDEVMODEW)lpInitData, 203 0); 204 } 205 206 207 /* 208 * @implemented 209 */ 210 HDC 211 WINAPI 212 CreateICW( 213 LPCWSTR lpszDriver, 214 LPCWSTR lpszDevice, 215 LPCWSTR lpszOutput, 216 CONST DEVMODEW *lpdvmInit) 217 { 218 return IntCreateDICW(lpszDriver, 219 lpszDevice, 220 lpszOutput, 221 (PDEVMODEW)lpdvmInit, 222 1); 223 } 224 225 226 /* 227 * @implemented 228 */ 229 HDC 230 WINAPI 231 CreateICA( 232 LPCSTR lpszDriver, 233 LPCSTR lpszDevice, 234 LPCSTR lpszOutput, 235 CONST DEVMODEA *lpdvmInit) 236 { 237 NTSTATUS Status; 238 LPWSTR lpszDriverW, lpszDeviceW, lpszOutputW; 239 LPDEVMODEW dvmInitW = NULL; 240 HDC hdc = 0; 241 242 Status = HEAP_strdupA2W(&lpszDriverW, lpszDriver); 243 if (!NT_SUCCESS(Status)) 244 SetLastError(RtlNtStatusToDosError(Status)); 245 else 246 { 247 Status = HEAP_strdupA2W(&lpszDeviceW, lpszDevice); 248 if (!NT_SUCCESS(Status)) 249 SetLastError(RtlNtStatusToDosError(Status)); 250 else 251 { 252 Status = HEAP_strdupA2W(&lpszOutputW, lpszOutput); 253 if (!NT_SUCCESS(Status)) 254 SetLastError(RtlNtStatusToDosError(Status)); 255 else 256 { 257 if (lpdvmInit) 258 dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit); 259 260 hdc = IntCreateDICW(lpszDriverW, 261 lpszDeviceW, 262 lpszOutputW, 263 lpdvmInit ? dvmInitW : NULL, 264 1 ); 265 HEAP_free(dvmInitW); 266 HEAP_free(lpszOutputW); 267 } 268 HEAP_free(lpszDeviceW); 269 } 270 HEAP_free(lpszDriverW); 271 } 272 273 return hdc; 274 } 275 276 277 /* 278 * @implemented 279 */ 280 BOOL 281 WINAPI 282 DeleteDC(HDC hdc) 283 { 284 ULONG hType = GDI_HANDLE_GET_TYPE(hdc); 285 286 if (hType != GDILoObjType_LO_DC_TYPE) 287 { 288 return METADC_RosGlueDeleteDC(hdc); 289 } 290 291 //if ( ghICM || pdcattr->pvLIcm ) 292 // IcmDeleteLocalDC( hdc, pdcattr, NULL ); 293 294 return NtGdiDeleteObjectApp(hdc); 295 } 296 297 298 /* 299 * @implemented 300 */ 301 INT 302 WINAPI 303 SaveDC(IN HDC hdc) 304 { 305 HANDLE_METADC1P(INT, SaveDC, 0, hdc); 306 return NtGdiSaveDC(hdc); 307 } 308 309 310 /* 311 * @implemented 312 */ 313 BOOL 314 WINAPI 315 RestoreDC(IN HDC hdc, 316 IN INT iLevel) 317 { 318 HANDLE_METADC(BOOL, RestoreDC, FALSE, hdc, iLevel); 319 return NtGdiRestoreDC(hdc, iLevel); 320 } 321 322 323 /* 324 * @implemented 325 */ 326 BOOL 327 WINAPI 328 CancelDC(HDC hDC) 329 { 330 PDC_ATTR pDc_Attr; 331 332 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC && 333 GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_METADC ) 334 { 335 PLDC pLDC = GdiGetLDC(hDC); 336 if ( !pLDC ) 337 { 338 SetLastError(ERROR_INVALID_HANDLE); 339 return FALSE; 340 } 341 /* If a document has started set it to die. */ 342 if (pLDC->Flags & LDC_INIT_DOCUMENT) pLDC->Flags |= LDC_KILL_DOCUMENT; 343 344 return NtGdiCancelDC(hDC); 345 } 346 347 if (GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr)) 348 { 349 pDc_Attr->ulDirty_ &= ~DC_PLAYMETAFILE; 350 return TRUE; 351 } 352 353 return FALSE; 354 } 355 356 INT 357 WINAPI 358 GetArcDirection( 359 _In_ HDC hdc) 360 { 361 return GetDCDWord( hdc, GdiGetArcDirection, 0); 362 } 363 364 365 INT 366 WINAPI 367 SetArcDirection( 368 _In_ HDC hdc, 369 _In_ INT nDirection) 370 { 371 return GetAndSetDCDWord(hdc, GdiGetSetArcDirection, nDirection, EMR_SETARCDIRECTION, 0, 0); 372 } 373 374 /* 375 * @unimplemented 376 */ 377 BOOL 378 WINAPI 379 GdiReleaseDC(HDC hdc) 380 { 381 return 0; 382 } 383 384 385 /* 386 * @implemented 387 */ 388 BOOL 389 WINAPI 390 GdiCleanCacheDC(HDC hdc) 391 { 392 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_DC_TYPE) 393 return TRUE; 394 SetLastError(ERROR_INVALID_HANDLE); 395 return FALSE; 396 } 397 398 /* 399 * @implemented 400 */ 401 HDC 402 WINAPI 403 GdiConvertAndCheckDC(HDC hdc) 404 { 405 PLDC pldc; 406 ULONG hType = GDI_HANDLE_GET_TYPE(hdc); 407 if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE) 408 return hdc; 409 pldc = GdiGetLDC(hdc); 410 if (pldc) 411 { 412 if (pldc->Flags & LDC_SAPCALLBACK) GdiSAPCallback(pldc); 413 if (pldc->Flags & LDC_KILL_DOCUMENT) return NULL; 414 if (pldc->Flags & LDC_STARTPAGE) StartPage(hdc); 415 return hdc; 416 } 417 SetLastError(ERROR_INVALID_HANDLE); 418 return NULL; 419 } 420 421 422 /* 423 * @implemented 424 * 425 */ 426 HGDIOBJ 427 WINAPI 428 GetCurrentObject( 429 _In_ HDC hdc, 430 _In_ UINT uObjectType) 431 { 432 PDC_ATTR pdcattr = NULL; 433 434 /* Check if this is a user mode object */ 435 if ((uObjectType == OBJ_PEN) || 436 (uObjectType == OBJ_EXTPEN) || 437 (uObjectType == OBJ_BRUSH) || 438 (uObjectType == OBJ_COLORSPACE)) 439 { 440 /* Get the DC attribute */ 441 pdcattr = GdiGetDcAttr(hdc); 442 if (pdcattr == NULL) 443 { 444 return NULL; 445 } 446 } 447 448 /* Check what object was requested */ 449 switch (uObjectType) 450 { 451 case OBJ_EXTPEN: 452 case OBJ_PEN: 453 return pdcattr->hpen; 454 455 case OBJ_BRUSH: 456 return pdcattr->hbrush; 457 458 case OBJ_COLORSPACE: 459 return pdcattr->hColorSpace; 460 461 case OBJ_PAL: 462 uObjectType = GDI_OBJECT_TYPE_PALETTE; 463 break; 464 465 case OBJ_FONT: 466 uObjectType = GDI_OBJECT_TYPE_FONT; 467 break; 468 469 case OBJ_BITMAP: 470 uObjectType = GDI_OBJECT_TYPE_BITMAP; 471 break; 472 473 /* All others are invalid */ 474 default: 475 SetLastError(ERROR_INVALID_PARAMETER); 476 return NULL; 477 } 478 479 /* Pass the request to win32k */ 480 return NtGdiGetDCObject(hdc, uObjectType); 481 } 482 483 484 /* 485 * @implemented 486 */ 487 int 488 WINAPI 489 EnumObjects(HDC hdc, 490 int nObjectType, 491 GOBJENUMPROC lpObjectFunc, 492 LPARAM lParam) 493 { 494 ULONG ObjectsCount; 495 ULONG Size; 496 PVOID Buffer = NULL; 497 DWORD_PTR EndOfBuffer; 498 int Result = 0; 499 500 switch (nObjectType) 501 { 502 case OBJ_BRUSH: 503 Size = sizeof(LOGBRUSH); 504 break; 505 506 case OBJ_PEN: 507 Size = sizeof(LOGPEN); 508 break; 509 510 default: 511 SetLastError(ERROR_INVALID_PARAMETER); 512 return 0; 513 } 514 515 ObjectsCount = NtGdiEnumObjects(hdc, nObjectType, 0, NULL); 516 if (!ObjectsCount) return 0; 517 518 Buffer = HeapAlloc(GetProcessHeap(), 0, ObjectsCount * Size); 519 if (!Buffer) 520 { 521 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 522 return 0; 523 } 524 525 if (!NtGdiEnumObjects(hdc, nObjectType, ObjectsCount * Size, Buffer)) 526 { 527 HeapFree(GetProcessHeap(), 0, Buffer); 528 return 0; 529 } 530 531 EndOfBuffer = (DWORD_PTR)Buffer + (ObjectsCount * Size); 532 while ((DWORD_PTR)Buffer < EndOfBuffer) 533 { 534 Result = lpObjectFunc(Buffer, lParam); 535 if (!Result) break; 536 Buffer = (PVOID)((DWORD_PTR)Buffer + Size); 537 } 538 539 HeapFree(GetProcessHeap(), 0, Buffer); 540 return Result; 541 } 542 543 544 /* 545 * @implemented 546 * 547 */ 548 int 549 WINAPI 550 GetDeviceCaps( 551 _In_ HDC hdc, 552 _In_ int nIndex) 553 { 554 PDC_ATTR pdcattr; 555 PLDC pldc; 556 ULONG hType = GDI_HANDLE_GET_TYPE(hdc); 557 PDEVCAPS pDevCaps = GdiDevCaps; // Primary display device capabilities. 558 DPRINT("Device CAPS1\n"); 559 560 HANDLE_METADC16(INT, GetDeviceCaps, 0, hdc, nIndex); 561 562 if ( hType != GDILoObjType_LO_DC_TYPE && hType != GDILoObjType_LO_METADC16_TYPE ) 563 { 564 pldc = GdiGetLDC(hdc); 565 if ( !pldc ) 566 { 567 SetLastError(ERROR_INVALID_HANDLE); 568 return 0; 569 } 570 if (!(pldc->Flags & LDC_DEVCAPS) ) 571 { 572 if (!NtGdiGetDeviceCapsAll(hdc, &pldc->DevCaps) ) 573 SetLastError(ERROR_INVALID_PARAMETER); 574 575 pldc->Flags |= LDC_DEVCAPS; 576 } 577 pDevCaps = &pldc->DevCaps; 578 } 579 else 580 { 581 /* Get the DC attribute */ 582 pdcattr = GdiGetDcAttr(hdc); 583 if ( pdcattr == NULL ) 584 { 585 SetLastError(ERROR_INVALID_PARAMETER); 586 return 0; 587 } 588 589 if (!(pdcattr->ulDirty_ & DC_PRIMARY_DISPLAY)) 590 return NtGdiGetDeviceCaps(hdc, nIndex); 591 } 592 593 switch (nIndex) 594 { 595 case DRIVERVERSION: 596 return pDevCaps->ulVersion; 597 598 case TECHNOLOGY: 599 return pDevCaps->ulTechnology; 600 601 case HORZSIZE: 602 return pDevCaps->ulHorzSize; 603 604 case VERTSIZE: 605 return pDevCaps->ulVertSize; 606 607 case HORZRES: 608 return pDevCaps->ulHorzRes; 609 610 case VERTRES: 611 return pDevCaps->ulVertRes; 612 613 case LOGPIXELSX: 614 return pDevCaps->ulLogPixelsX; 615 616 case LOGPIXELSY: 617 return pDevCaps->ulLogPixelsY; 618 619 case BITSPIXEL: 620 return pDevCaps->ulBitsPixel; 621 622 case PLANES: 623 return pDevCaps->ulPlanes; 624 625 case NUMBRUSHES: 626 return -1; 627 628 case NUMPENS: 629 return pDevCaps->ulNumPens; 630 631 case NUMFONTS: 632 return pDevCaps->ulNumFonts; 633 634 case NUMCOLORS: 635 return pDevCaps->ulNumColors; 636 637 case ASPECTX: 638 return pDevCaps->ulAspectX; 639 640 case ASPECTY: 641 return pDevCaps->ulAspectY; 642 643 case ASPECTXY: 644 return pDevCaps->ulAspectXY; 645 646 case CLIPCAPS: 647 return CP_RECTANGLE; 648 649 case SIZEPALETTE: 650 return pDevCaps->ulSizePalette; 651 652 case NUMRESERVED: 653 return 20; 654 655 case COLORRES: 656 return pDevCaps->ulColorRes; 657 658 case DESKTOPVERTRES: 659 return pDevCaps->ulVertRes; 660 661 case DESKTOPHORZRES: 662 return pDevCaps->ulHorzRes; 663 664 case BLTALIGNMENT: 665 return pDevCaps->ulBltAlignment; 666 667 case SHADEBLENDCAPS: 668 return pDevCaps->ulShadeBlend; 669 670 case COLORMGMTCAPS: 671 return pDevCaps->ulColorMgmtCaps; 672 673 case PHYSICALWIDTH: 674 return pDevCaps->ulPhysicalWidth; 675 676 case PHYSICALHEIGHT: 677 return pDevCaps->ulPhysicalHeight; 678 679 case PHYSICALOFFSETX: 680 return pDevCaps->ulPhysicalOffsetX; 681 682 case PHYSICALOFFSETY: 683 return pDevCaps->ulPhysicalOffsetY; 684 685 case VREFRESH: 686 return pDevCaps->ulVRefresh; 687 688 case RASTERCAPS: 689 return pDevCaps->ulRasterCaps; 690 691 case CURVECAPS: 692 return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE | 693 CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT); 694 695 case LINECAPS: 696 return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE | 697 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS); 698 699 case POLYGONALCAPS: 700 return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE | 701 PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS); 702 703 case TEXTCAPS: 704 return pDevCaps->ulTextCaps; 705 706 case PDEVICESIZE: 707 case SCALINGFACTORX: 708 case SCALINGFACTORY: 709 default: 710 return 0; 711 } 712 return 0; 713 } 714 715 /* 716 * @implemented 717 */ 718 DWORD 719 WINAPI 720 GetRelAbs( 721 _In_ HDC hdc, 722 _In_ DWORD dwIgnore) 723 { 724 return GetDCDWord(hdc, GdiGetRelAbs, 0); 725 } 726 727 728 /* 729 * @implemented 730 */ 731 INT 732 WINAPI 733 SetRelAbs( 734 HDC hdc, 735 INT Mode) 736 { 737 return GetAndSetDCDWord(hdc, GdiGetSetRelAbs, Mode, 0, META_SETRELABS, 0); 738 } 739 740 741 /* 742 * @implemented 743 */ 744 DWORD 745 WINAPI 746 GetAndSetDCDWord( 747 _In_ HDC hdc, 748 _In_ UINT u, 749 _In_ DWORD dwIn, 750 _In_ ULONG ulMFId, 751 _In_ USHORT usMF16Id, 752 _In_ DWORD dwError) 753 { 754 DWORD dwResult; 755 PLDC pldc; 756 757 if ( GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE && 758 ulMFId != EMR_MAX + 1 ) 759 { 760 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 761 { 762 return METADC_SetD( hdc, dwIn, usMF16Id ); 763 } 764 pldc = GdiGetLDC(hdc); 765 if ( pldc->iType == LDC_EMFLDC) 766 { 767 if (!EMFDC_SetD( pldc, dwIn, ulMFId )) 768 return 0; 769 } 770 } 771 772 /* Call win32k to do the real work */ 773 if (!NtGdiGetAndSetDCDword(hdc, u, dwIn, &dwResult)) 774 { 775 return dwError; 776 } 777 778 return dwResult; 779 } 780 781 782 /* 783 * @implemented 784 */ 785 DWORD 786 WINAPI 787 GetDCDWord( 788 _In_ HDC hdc, 789 _In_ UINT u, 790 _In_ DWORD dwError) 791 { 792 DWORD dwResult; 793 794 if (!NtGdiGetDCDword(hdc, u, &dwResult)) 795 { 796 return dwError; 797 } 798 799 return dwResult; 800 } 801 802 803 /* 804 * @implemented 805 */ 806 BOOL 807 WINAPI 808 GetAspectRatioFilterEx( 809 HDC hdc, 810 LPSIZE lpAspectRatio) 811 { 812 return NtGdiGetDCPoint(hdc, GdiGetAspectRatioFilter, (PPOINTL)lpAspectRatio ); 813 } 814 815 816 /* 817 * @implemented 818 */ 819 UINT 820 WINAPI 821 GetBoundsRect( 822 HDC hdc, 823 LPRECT lprcBounds, 824 UINT flags 825 ) 826 { 827 return NtGdiGetBoundsRect(hdc,lprcBounds,flags & ~DCB_WINDOWMGR); 828 } 829 830 831 /* 832 * @implemented 833 */ 834 UINT 835 WINAPI 836 SetBoundsRect(HDC hdc, 837 CONST RECT *prc, 838 UINT flags) 839 { 840 /* FIXME add check for validate the flags */ 841 return NtGdiSetBoundsRect(hdc, (LPRECT)prc, flags & ~DCB_WINDOWMGR); 842 } 843 844 845 /* 846 * @implemented 847 * 848 */ 849 int 850 WINAPI 851 GetClipBox(HDC hdc, 852 LPRECT lprc) 853 { 854 return NtGdiGetAppClipBox(hdc, lprc); 855 } 856 857 858 /* 859 * @implemented 860 */ 861 COLORREF 862 WINAPI 863 GetDCBrushColor( 864 _In_ HDC hdc) 865 { 866 PDC_ATTR pdcattr; 867 868 /* Get the DC attribute */ 869 pdcattr = GdiGetDcAttr(hdc); 870 if (pdcattr == NULL) 871 { 872 SetLastError(ERROR_INVALID_PARAMETER); 873 return CLR_INVALID; 874 } 875 876 return pdcattr->ulBrushClr; 877 } 878 879 /* 880 * @implemented 881 */ 882 COLORREF 883 WINAPI 884 GetDCPenColor( 885 _In_ HDC hdc) 886 { 887 PDC_ATTR pdcattr; 888 889 /* Get the DC attribute */ 890 pdcattr = GdiGetDcAttr(hdc); 891 if (pdcattr == NULL) 892 { 893 SetLastError(ERROR_INVALID_PARAMETER); 894 return CLR_INVALID; 895 } 896 897 return pdcattr->ulPenClr; 898 } 899 900 /* 901 * @implemented 902 */ 903 COLORREF 904 WINAPI 905 SetDCBrushColor( 906 _In_ HDC hdc, 907 _In_ COLORREF crColor) 908 { 909 PDC_ATTR pdcattr; 910 COLORREF crOldColor; 911 912 /* Get the DC attribute */ 913 pdcattr = GdiGetDcAttr(hdc); 914 if (pdcattr == NULL) 915 { 916 SetLastError(ERROR_INVALID_PARAMETER); 917 return CLR_INVALID; 918 } 919 920 /* We handle only enhanced meta DCs here */ 921 HANDLE_EMETAFDC(COLORREF, SetDCBrushColor, CLR_INVALID, hdc, crColor); 922 923 /* Get old color and store the new */ 924 crOldColor = pdcattr->ulBrushClr; 925 pdcattr->ulBrushClr = crColor; 926 927 if (pdcattr->crBrushClr != crColor) 928 { 929 pdcattr->ulDirty_ |= DIRTY_FILL; 930 pdcattr->crBrushClr = crColor; 931 } 932 933 return crOldColor; 934 } 935 936 /* 937 * @implemented 938 */ 939 COLORREF 940 WINAPI 941 SetDCPenColor( 942 _In_ HDC hdc, 943 _In_ COLORREF crColor) 944 { 945 PDC_ATTR pdcattr; 946 COLORREF crOldColor; 947 948 /* Get the DC attribute */ 949 pdcattr = GdiGetDcAttr(hdc); 950 if (pdcattr == NULL) 951 { 952 SetLastError(ERROR_INVALID_PARAMETER); 953 return CLR_INVALID; 954 } 955 956 /* We handle only enhanced meta DCs here */ 957 HANDLE_EMETAFDC(COLORREF, SetDCPenColor, CLR_INVALID, hdc, crColor); 958 959 /* Get old color and store the new */ 960 crOldColor = pdcattr->ulPenClr; 961 pdcattr->ulPenClr = (ULONG)crColor; 962 963 if (pdcattr->crPenClr != crColor) 964 { 965 pdcattr->ulDirty_ |= DIRTY_LINE; 966 pdcattr->crPenClr = crColor; 967 } 968 969 return crOldColor; 970 } 971 972 /* 973 * @implemented 974 * 975 */ 976 COLORREF 977 WINAPI 978 GetBkColor( 979 _In_ HDC hdc) 980 { 981 PDC_ATTR pdcattr; 982 983 /* Get the DC attribute */ 984 pdcattr = GdiGetDcAttr(hdc); 985 if (pdcattr == NULL) 986 { 987 /* Don't set LastError here! */ 988 return CLR_INVALID; 989 } 990 991 return pdcattr->ulBackgroundClr; 992 } 993 994 /* 995 * @implemented 996 */ 997 COLORREF 998 WINAPI 999 SetBkColor( 1000 _In_ HDC hdc, 1001 _In_ COLORREF crColor) 1002 { 1003 PDC_ATTR pdcattr; 1004 COLORREF crOldColor; 1005 1006 HANDLE_METADC(COLORREF, SetBkColor, CLR_INVALID, hdc, crColor); 1007 1008 /* Get the DC attribute */ 1009 pdcattr = GdiGetDcAttr(hdc); 1010 if (pdcattr == NULL) 1011 { 1012 SetLastError(ERROR_INVALID_PARAMETER); 1013 return CLR_INVALID; 1014 } 1015 1016 /* Get old color and store the new */ 1017 crOldColor = pdcattr->ulBackgroundClr; 1018 pdcattr->ulBackgroundClr = crColor; 1019 1020 if (pdcattr->crBackgroundClr != crColor) 1021 { 1022 pdcattr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); 1023 pdcattr->crBackgroundClr = crColor; 1024 } 1025 1026 return crOldColor; 1027 } 1028 1029 /* 1030 * @implemented 1031 * 1032 */ 1033 int 1034 WINAPI 1035 GetBkMode(HDC hdc) 1036 { 1037 PDC_ATTR pdcattr; 1038 1039 /* Get the DC attribute */ 1040 pdcattr = GdiGetDcAttr(hdc); 1041 if (pdcattr == NULL) 1042 { 1043 /* Don't set LastError here! */ 1044 return 0; 1045 } 1046 1047 return pdcattr->lBkMode; 1048 } 1049 1050 /* 1051 * @implemented 1052 * 1053 */ 1054 int 1055 WINAPI 1056 SetBkMode( 1057 _In_ HDC hdc, 1058 _In_ int iBkMode) 1059 { 1060 PDC_ATTR pdcattr; 1061 INT iOldMode; 1062 1063 /* Avoid bad mode setting */ 1064 if ((iBkMode != TRANSPARENT) && (iBkMode != OPAQUE)) 1065 { 1066 DPRINT1("SetBkMode: Incorrect value\n"); 1067 return 0; 1068 } 1069 1070 HANDLE_METADC(INT, SetBkMode, 0, hdc, iBkMode); 1071 1072 /* Get the DC attribute */ 1073 pdcattr = GdiGetDcAttr(hdc); 1074 if (pdcattr == NULL) 1075 { 1076 SetLastError(ERROR_INVALID_PARAMETER); 1077 return 0; 1078 } 1079 1080 iOldMode = pdcattr->lBkMode; 1081 pdcattr->jBkMode = iBkMode; // Processed 1082 pdcattr->lBkMode = iBkMode; // Raw 1083 1084 return iOldMode; 1085 } 1086 1087 /* 1088 * @implemented 1089 * 1090 */ 1091 int 1092 WINAPI 1093 GetROP2( 1094 _In_ HDC hdc) 1095 { 1096 PDC_ATTR pdcattr; 1097 1098 /* Get the DC attribute */ 1099 pdcattr = GdiGetDcAttr(hdc); 1100 if (pdcattr == NULL) 1101 { 1102 /* Do not set LastError here! */ 1103 return 0; 1104 } 1105 1106 return pdcattr->jROP2; 1107 } 1108 1109 /* 1110 * @implemented 1111 */ 1112 int 1113 WINAPI 1114 SetROP2( 1115 _In_ HDC hdc, 1116 _In_ int rop2) 1117 { 1118 PDC_ATTR pdcattr; 1119 INT rop2Old; 1120 1121 HANDLE_METADC(INT, SetROP2, 0, hdc, rop2); 1122 1123 /* Get the DC attribute */ 1124 pdcattr = GdiGetDcAttr(hdc); 1125 if (pdcattr == NULL) 1126 { 1127 SetLastError(ERROR_INVALID_PARAMETER); 1128 return 0; 1129 } 1130 1131 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 1132 { 1133 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 1134 { 1135 NtGdiFlush(); 1136 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 1137 } 1138 } 1139 1140 rop2Old = pdcattr->jROP2; 1141 pdcattr->jROP2 = (BYTE)rop2; 1142 1143 return rop2Old; 1144 } 1145 1146 1147 /* 1148 * @implemented 1149 * 1150 */ 1151 int 1152 WINAPI 1153 GetPolyFillMode(HDC hdc) 1154 { 1155 PDC_ATTR pdcattr; 1156 1157 /* Get DC attribute */ 1158 pdcattr = GdiGetDcAttr(hdc); 1159 if (pdcattr == NULL) 1160 { 1161 /* Don't set LastError here! */ 1162 return 0; 1163 } 1164 1165 /* Return current fill mode */ 1166 return pdcattr->lFillMode; 1167 } 1168 1169 /* 1170 * @unimplemented 1171 */ 1172 int 1173 WINAPI 1174 SetPolyFillMode( 1175 _In_ HDC hdc, 1176 _In_ int iPolyFillMode) 1177 { 1178 INT iOldPolyFillMode; 1179 PDC_ATTR pdcattr; 1180 1181 HANDLE_METADC(INT, SetPolyFillMode, 0, hdc, iPolyFillMode); 1182 1183 /* Get the DC attribute */ 1184 pdcattr = GdiGetDcAttr(hdc); 1185 if (pdcattr == NULL) 1186 { 1187 SetLastError(ERROR_INVALID_PARAMETER); 1188 return 0; 1189 } 1190 1191 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 1192 { 1193 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 1194 { 1195 NtGdiFlush(); // Sync up pdcattr from Kernel space. 1196 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 1197 } 1198 } 1199 1200 iOldPolyFillMode = pdcattr->lFillMode; 1201 pdcattr->lFillMode = iPolyFillMode; 1202 1203 return iOldPolyFillMode; 1204 } 1205 1206 /* 1207 * @implemented 1208 * 1209 */ 1210 int 1211 WINAPI 1212 GetGraphicsMode(HDC hdc) 1213 { 1214 PDC_ATTR pdcattr; 1215 1216 /* Get the DC attribute */ 1217 pdcattr = GdiGetDcAttr(hdc); 1218 if (pdcattr == NULL) 1219 { 1220 /* Don't set LastError here! */ 1221 return 0; 1222 } 1223 1224 /* Return current graphics mode */ 1225 return pdcattr->iGraphicsMode; 1226 } 1227 1228 /* 1229 * @unimplemented 1230 */ 1231 int 1232 WINAPI 1233 SetGraphicsMode( 1234 _In_ HDC hdc, 1235 _In_ int iMode) 1236 { 1237 INT iOldMode; 1238 PDC_ATTR pdcattr; 1239 1240 /* Check parameters */ 1241 if ((iMode < GM_COMPATIBLE) || (iMode > GM_ADVANCED)) 1242 { 1243 SetLastError(ERROR_INVALID_PARAMETER); 1244 return 0; 1245 } 1246 1247 /* Get the DC attribute */ 1248 pdcattr = GdiGetDcAttr(hdc); 1249 if (pdcattr == NULL) 1250 { 1251 SetLastError(ERROR_INVALID_PARAMETER); 1252 return 0; 1253 } 1254 1255 /* Check for trivial case */ 1256 if (iMode == pdcattr->iGraphicsMode) 1257 return iMode; 1258 1259 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 1260 { 1261 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 1262 { 1263 NtGdiFlush(); // Sync up pdcattr from Kernel space. 1264 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 1265 } 1266 } 1267 1268 /* One would think that setting the graphics mode to GM_COMPATIBLE 1269 * would also reset the world transformation matrix to the unity 1270 * matrix. However, in Windows, this is not the case. This doesn't 1271 * make a lot of sense to me, but that's the way it is. 1272 */ 1273 iOldMode = pdcattr->iGraphicsMode; 1274 pdcattr->iGraphicsMode = iMode; 1275 1276 return iOldMode; 1277 } 1278 1279 /* 1280 * @implemented 1281 */ 1282 HDC 1283 WINAPI 1284 ResetDCW( 1285 _In_ HDC hdc, 1286 _In_ CONST DEVMODEW *lpInitData) 1287 { 1288 NtGdiResetDC ( hdc, (PDEVMODEW)lpInitData, NULL, NULL, NULL); 1289 return hdc; 1290 } 1291 1292 1293 /* 1294 * @implemented 1295 */ 1296 HDC 1297 WINAPI 1298 ResetDCA( 1299 _In_ HDC hdc, 1300 _In_ CONST DEVMODEA *lpInitData) 1301 { 1302 LPDEVMODEW InitDataW; 1303 1304 InitDataW = GdiConvertToDevmodeW((LPDEVMODEA)lpInitData); 1305 1306 NtGdiResetDC ( hdc, InitDataW, NULL, NULL, NULL); 1307 HEAP_free(InitDataW); 1308 return hdc; 1309 } 1310 1311 1312 /* FIXME: include correct header */ 1313 HPALETTE WINAPI NtUserSelectPalette(HDC hDC, 1314 HPALETTE hpal, 1315 BOOL ForceBackground); 1316 1317 HPALETTE 1318 WINAPI 1319 SelectPalette( 1320 HDC hdc, 1321 HPALETTE hpal, 1322 BOOL bForceBackground) 1323 { 1324 if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) 1325 { 1326 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 1327 { 1328 return (HPALETTE)((ULONG_PTR)METADC_SelectPalette(hdc, hpal)); 1329 } 1330 else 1331 { 1332 PLDC pLDC = GdiGetLDC(hdc); 1333 if ( !pLDC ) 1334 { 1335 SetLastError(ERROR_INVALID_HANDLE); 1336 return NULL; 1337 } 1338 if ( pLDC->iType == LDC_EMFLDC && !(EMFDC_SelectPalette(pLDC, hpal)) ) 1339 { 1340 return NULL; 1341 } 1342 } 1343 } 1344 return NtUserSelectPalette(hdc, hpal, bForceBackground); 1345 } 1346 1347 /* 1348 * @implemented 1349 * 1350 */ 1351 int 1352 WINAPI 1353 GetStretchBltMode(HDC hdc) 1354 { 1355 PDC_ATTR pdcattr; 1356 1357 /* Get the DC attribute */ 1358 pdcattr = GdiGetDcAttr(hdc); 1359 if (pdcattr == NULL) 1360 { 1361 /* Don't set LastError here! */ 1362 return 0; 1363 } 1364 1365 return pdcattr->lStretchBltMode; 1366 } 1367 1368 /* 1369 * @implemented 1370 */ 1371 int 1372 WINAPI 1373 SetStretchBltMode( 1374 _In_ HDC hdc, 1375 _In_ int iStretchMode) 1376 { 1377 INT iOldMode; 1378 PDC_ATTR pdcattr; 1379 1380 HANDLE_METADC(INT, SetStretchBltMode, 0, hdc, iStretchMode); 1381 1382 /* Get the DC attribute */ 1383 pdcattr = GdiGetDcAttr(hdc); 1384 if (pdcattr == NULL) 1385 { 1386 SetLastError(ERROR_INVALID_PARAMETER); 1387 return 0; 1388 } 1389 1390 iOldMode = pdcattr->lStretchBltMode; 1391 pdcattr->lStretchBltMode = iStretchMode; 1392 1393 // Wine returns an error here. We set the default. 1394 if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK; 1395 1396 pdcattr->jStretchBltMode = iStretchMode; 1397 1398 return iOldMode; 1399 } 1400 1401 /* 1402 * @implemented 1403 */ 1404 HFONT 1405 WINAPI 1406 GetHFONT(HDC hdc) 1407 { 1408 PDC_ATTR pdcattr; 1409 1410 /* Get the DC attribute */ 1411 pdcattr = GdiGetDcAttr(hdc); 1412 if (pdcattr == NULL) 1413 { 1414 /* Don't set LastError here! */ 1415 return NULL; 1416 } 1417 1418 /* Return the current font */ 1419 return pdcattr->hlfntNew; 1420 } 1421 1422 1423 1424 HBITMAP 1425 WINAPI 1426 GdiSelectBitmap( 1427 _In_ HDC hdc, 1428 _In_ HBITMAP hbmp) 1429 { 1430 return NtGdiSelectBitmap(hdc, hbmp); 1431 } 1432 1433 HBRUSH 1434 WINAPI 1435 GdiSelectBrush( 1436 _In_ HDC hdc, 1437 _In_ HBRUSH hbr) 1438 { 1439 PDC_ATTR pdcattr; 1440 HBRUSH hbrOld; 1441 1442 HANDLE_METADC(HBRUSH, SelectObject, NULL, hdc, hbr); 1443 1444 /* Get the DC attribute */ 1445 pdcattr = GdiGetDcAttr(hdc); 1446 if (pdcattr == NULL) 1447 { 1448 SetLastError(ERROR_INVALID_PARAMETER); 1449 return NULL; 1450 } 1451 1452 /* Get the current brush. If it matches the new brush, we're done */ 1453 hbrOld = pdcattr->hbrush; 1454 if (hbrOld == hbr) 1455 return hbrOld; 1456 1457 /* Set the new brush and update dirty flags */ 1458 pdcattr->hbrush = hbr; 1459 pdcattr->ulDirty_ |= DC_BRUSH_DIRTY; 1460 return hbrOld; 1461 } 1462 1463 HPEN 1464 WINAPI 1465 GdiSelectPen( 1466 _In_ HDC hdc, 1467 _In_ HPEN hpen) 1468 { 1469 PDC_ATTR pdcattr; 1470 HPEN hpenOld; 1471 1472 HANDLE_METADC(HPEN, SelectObject, NULL, hdc, hpen); 1473 1474 /* Get the DC attribute */ 1475 pdcattr = GdiGetDcAttr(hdc); 1476 if (pdcattr == NULL) 1477 { 1478 SetLastError(ERROR_INVALID_HANDLE); 1479 return NULL; 1480 } 1481 1482 /* Get the current pen. If it matches the new pen, we're done */ 1483 hpenOld = pdcattr->hpen; 1484 if (hpenOld == hpen) 1485 return hpenOld; 1486 1487 /* Set the new pen and update dirty flags */ 1488 pdcattr->ulDirty_ |= DC_PEN_DIRTY; 1489 pdcattr->hpen = hpen; 1490 return hpenOld; 1491 } 1492 1493 HFONT 1494 WINAPI 1495 GdiSelectFont( 1496 _In_ HDC hdc, 1497 _In_ HFONT hfont) 1498 { 1499 PDC_ATTR pdcattr; 1500 HFONT hfontOld; 1501 1502 HANDLE_METADC(HFONT, SelectObject, NULL, hdc, hfont); 1503 1504 /* Get the DC attribute */ 1505 pdcattr = GdiGetDcAttr(hdc); 1506 if (pdcattr == NULL) 1507 { 1508 SetLastError(ERROR_INVALID_PARAMETER); 1509 return NULL; 1510 } 1511 1512 /* Get the current font. If it matches the new font, we're done */ 1513 hfontOld = pdcattr->hlfntNew; 1514 if (hfontOld == hfont) 1515 return hfontOld; 1516 1517 /* Set the new font and update dirty flags */ 1518 pdcattr->hlfntNew = hfont; 1519 pdcattr->ulDirty_ &= ~SLOW_WIDTHS; 1520 pdcattr->ulDirty_ |= DIRTY_CHARSET; 1521 1522 /* If the DC does not have a DIB section selected, try a batch command */ 1523 if (!(pdcattr->ulDirty_ & DC_DIBSECTION)) 1524 { 1525 PGDIBSOBJECT pgO; 1526 1527 pgO = GdiAllocBatchCommand(hdc, GdiBCSelObj); 1528 if (pgO) 1529 { 1530 pgO->hgdiobj = hfont; 1531 return hfontOld; 1532 } 1533 } 1534 1535 /* We could not use the batch command, call win32k */ 1536 return NtGdiSelectFont(hdc, hfont); 1537 } 1538 1539 1540 /* 1541 * @implemented 1542 * 1543 */ 1544 HGDIOBJ 1545 WINAPI 1546 SelectObject( 1547 _In_ HDC hdc, 1548 _In_ HGDIOBJ hobj) 1549 { 1550 /* Fix up 16 bit handles */ 1551 hobj = GdiFixUpHandle(hobj); 1552 if (!GdiValidateHandle(hobj)) 1553 { 1554 return NULL; 1555 } 1556 1557 /* Call the appropriate select function */ 1558 switch (GDI_HANDLE_GET_TYPE(hobj)) 1559 { 1560 case GDILoObjType_LO_REGION_TYPE: 1561 return (HGDIOBJ)UlongToHandle(ExtSelectClipRgn(hdc, hobj, RGN_COPY)); 1562 1563 case GDILoObjType_LO_BITMAP_TYPE: 1564 case GDILoObjType_LO_DIBSECTION_TYPE: 1565 return GdiSelectBitmap(hdc, hobj); 1566 1567 case GDILoObjType_LO_BRUSH_TYPE: 1568 return GdiSelectBrush(hdc, hobj); 1569 1570 case GDILoObjType_LO_PEN_TYPE: 1571 case GDILoObjType_LO_EXTPEN_TYPE: 1572 return GdiSelectPen(hdc, hobj); 1573 1574 case GDILoObjType_LO_FONT_TYPE: 1575 return GdiSelectFont(hdc, hobj); 1576 1577 case GDILoObjType_LO_ICMLCS_TYPE: 1578 return SetColorSpace(hdc, hobj); 1579 1580 case GDILoObjType_LO_PALETTE_TYPE: 1581 SetLastError(ERROR_INVALID_FUNCTION); 1582 1583 default: 1584 return NULL; 1585 } 1586 1587 return NULL; 1588 } 1589