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