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