1 #include <win32k.h> 2 3 #define NDEBUG 4 #include <debug.h> 5 6 BOOL FASTCALL 7 GreDPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount) 8 { 9 PDC dc; 10 if (!(dc = DC_LockDc(hdc))) 11 { 12 EngSetLastError(ERROR_INVALID_HANDLE); 13 return FALSE; 14 } 15 IntDPtoLP(dc, lpPoints, nCount); 16 DC_UnlockDc(dc); 17 return TRUE; 18 } 19 20 BOOL FASTCALL 21 GreLPtoDP(HDC hdc, LPPOINT lpPoints, INT nCount) 22 { 23 PDC dc; 24 if (!(dc = DC_LockDc(hdc))) 25 { 26 EngSetLastError(ERROR_INVALID_HANDLE); 27 return FALSE; 28 } 29 IntLPtoDP(dc, lpPoints, nCount); 30 DC_UnlockDc(dc); 31 return TRUE; 32 } 33 34 int FASTCALL 35 GreGetBkMode(HDC hdc) 36 { 37 PDC dc; 38 LONG lBkMode; 39 if (!(dc = DC_LockDc(hdc))) 40 { 41 EngSetLastError(ERROR_INVALID_HANDLE); 42 return CLR_INVALID; 43 } 44 lBkMode = dc->pdcattr->lBkMode; 45 DC_UnlockDc(dc); 46 return lBkMode; 47 } 48 49 COLORREF FASTCALL 50 GreGetBkColor(HDC hdc) 51 { 52 PDC dc; 53 COLORREF crBk; 54 if (!(dc = DC_LockDc(hdc))) 55 { 56 EngSetLastError(ERROR_INVALID_HANDLE); 57 return CLR_INVALID; 58 } 59 crBk = dc->pdcattr->ulBackgroundClr; 60 DC_UnlockDc(dc); 61 return crBk; 62 } 63 64 int FASTCALL 65 GreGetMapMode(HDC hdc) 66 { 67 PDC dc; 68 INT iMapMode; 69 if (!(dc = DC_LockDc(hdc))) 70 { 71 EngSetLastError(ERROR_INVALID_HANDLE); 72 return CLR_INVALID; 73 } 74 iMapMode = dc->pdcattr->iMapMode; 75 DC_UnlockDc(dc); 76 return iMapMode; 77 } 78 79 COLORREF FASTCALL 80 GreGetTextColor(HDC hdc) 81 { 82 PDC dc; 83 ULONG ulForegroundClr; 84 if (!(dc = DC_LockDc(hdc))) 85 { 86 EngSetLastError(ERROR_INVALID_HANDLE); 87 return CLR_INVALID; 88 } 89 ulForegroundClr = dc->pdcattr->ulForegroundClr; 90 DC_UnlockDc(dc); 91 return ulForegroundClr; 92 } 93 94 COLORREF FASTCALL 95 IntGdiSetBkColor(HDC hDC, COLORREF color) 96 { 97 COLORREF oldColor; 98 PDC dc; 99 PDC_ATTR pdcattr; 100 HBRUSH hBrush; 101 102 if (!(dc = DC_LockDc(hDC))) 103 { 104 EngSetLastError(ERROR_INVALID_HANDLE); 105 return CLR_INVALID; 106 } 107 pdcattr = dc->pdcattr; 108 109 oldColor = pdcattr->ulBackgroundClr; 110 pdcattr->ulBackgroundClr = color; 111 112 if (pdcattr->crBackgroundClr != color) 113 { 114 pdcattr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set. 115 pdcattr->crBackgroundClr = color; 116 } 117 hBrush = pdcattr->hbrush; 118 DC_UnlockDc(dc); 119 NtGdiSelectBrush(hDC, hBrush); 120 return oldColor; 121 } 122 123 INT FASTCALL 124 IntGdiSetBkMode(HDC hDC, INT Mode) 125 { 126 COLORREF oldMode; 127 PDC dc; 128 PDC_ATTR pdcattr; 129 130 if (!(dc = DC_LockDc(hDC))) 131 { 132 EngSetLastError(ERROR_INVALID_HANDLE); 133 return CLR_INVALID; 134 } 135 pdcattr = dc->pdcattr; 136 oldMode = pdcattr->lBkMode; 137 pdcattr->jBkMode = Mode; 138 pdcattr->lBkMode = Mode; 139 DC_UnlockDc(dc); 140 return oldMode; 141 } 142 143 UINT 144 FASTCALL 145 IntGdiSetTextAlign(HDC hDC, 146 UINT Mode) 147 { 148 UINT prevAlign; 149 DC *dc; 150 PDC_ATTR pdcattr; 151 152 dc = DC_LockDc(hDC); 153 if (!dc) 154 { 155 EngSetLastError(ERROR_INVALID_HANDLE); 156 return GDI_ERROR; 157 } 158 pdcattr = dc->pdcattr; 159 prevAlign = pdcattr->lTextAlign; 160 pdcattr->lTextAlign = Mode; 161 DC_UnlockDc(dc); 162 return prevAlign; 163 } 164 165 COLORREF 166 FASTCALL 167 IntGdiSetTextColor(HDC hDC, 168 COLORREF color) 169 { 170 COLORREF crOldColor; 171 PDC pdc; 172 PDC_ATTR pdcattr; 173 174 pdc = DC_LockDc(hDC); 175 if (!pdc) 176 { 177 EngSetLastError(ERROR_INVALID_HANDLE); 178 return CLR_INVALID; 179 } 180 pdcattr = pdc->pdcattr; 181 182 crOldColor = (COLORREF) pdcattr->ulForegroundClr; 183 pdcattr->ulForegroundClr = (ULONG)color; 184 185 if (pdcattr->crForegroundClr != color) 186 { 187 pdcattr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL); 188 pdcattr->crForegroundClr = color; 189 } 190 191 DC_vUpdateTextBrush(pdc); 192 DC_vUpdateLineBrush(pdc); 193 DC_vUpdateFillBrush(pdc); 194 195 DC_UnlockDc(pdc); 196 197 return crOldColor; 198 } 199 200 COLORREF FASTCALL 201 IntSetDCBrushColor(HDC hdc, COLORREF crColor) 202 { 203 COLORREF OldColor = CLR_INVALID; 204 PDC dc; 205 if (!(dc = DC_LockDc(hdc))) 206 { 207 EngSetLastError(ERROR_INVALID_HANDLE); 208 return CLR_INVALID; 209 } 210 else 211 { 212 OldColor = (COLORREF) dc->pdcattr->ulBrushClr; 213 dc->pdcattr->ulBrushClr = (ULONG) crColor; 214 215 if ( dc->pdcattr->crBrushClr != crColor ) 216 { 217 dc->pdcattr->ulDirty_ |= DIRTY_FILL; 218 dc->pdcattr->crBrushClr = crColor; 219 } 220 } 221 DC_UnlockDc(dc); 222 return OldColor; 223 } 224 225 BOOL FASTCALL 226 GreSetBrushOrg( 227 HDC hdc, 228 INT x, 229 INT y, 230 LPPOINT pptOut) 231 { 232 PDC pdc = DC_LockDc(hdc); 233 if (pdc == NULL) 234 { 235 EngSetLastError(ERROR_INVALID_HANDLE); 236 return FALSE; 237 } 238 239 if (pptOut != NULL) 240 { 241 *pptOut = pdc->pdcattr->ptlBrushOrigin; 242 } 243 244 pdc->pdcattr->ptlBrushOrigin.x = x; 245 pdc->pdcattr->ptlBrushOrigin.y = y; 246 247 DC_vSetBrushOrigin(pdc, x, y); 248 249 DC_UnlockDc(pdc); 250 return TRUE; 251 } 252 253 COLORREF FASTCALL 254 IntSetDCPenColor(HDC hdc, COLORREF crColor) 255 { 256 COLORREF OldColor; 257 PDC dc; 258 if (!(dc = DC_LockDc(hdc))) 259 { 260 EngSetLastError(ERROR_INVALID_PARAMETER); 261 return CLR_INVALID; 262 } 263 264 OldColor = (COLORREF)dc->pdcattr->ulPenClr; 265 dc->pdcattr->ulPenClr = (ULONG)crColor; 266 267 if (dc->pdcattr->crPenClr != crColor) 268 { 269 dc->pdcattr->ulDirty_ |= DIRTY_LINE; 270 dc->pdcattr->crPenClr = crColor; 271 } 272 DC_UnlockDc(dc); 273 return OldColor; 274 } 275 276 int 277 FASTCALL 278 GreSetStretchBltMode(HDC hDC, int iStretchMode) 279 { 280 PDC pdc; 281 PDC_ATTR pdcattr; 282 INT oSMode = 0; 283 284 pdc = DC_LockDc(hDC); 285 if (pdc) 286 { 287 pdcattr = pdc->pdcattr; 288 oSMode = pdcattr->lStretchBltMode; 289 pdcattr->lStretchBltMode = iStretchMode; 290 291 // Wine returns an error here. We set the default. 292 if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK; 293 294 pdcattr->jStretchBltMode = iStretchMode; 295 DC_UnlockDc(pdc); 296 } 297 return oSMode; 298 } 299 300 int FASTCALL 301 GreGetGraphicsMode(HDC hdc) 302 { 303 PDC dc; 304 int GraphicsMode; 305 if (!(dc = DC_LockDc(hdc))) 306 { 307 EngSetLastError(ERROR_INVALID_HANDLE); 308 return CLR_INVALID; 309 } 310 GraphicsMode = dc->pdcattr->iGraphicsMode; 311 DC_UnlockDc(dc); 312 return GraphicsMode; 313 } 314 315 VOID 316 FASTCALL 317 DCU_SetDcUndeletable(HDC hDC) 318 { 319 PDC dc = DC_LockDc(hDC); 320 if (!dc) 321 { 322 EngSetLastError(ERROR_INVALID_HANDLE); 323 return; 324 } 325 326 dc->fs |= DC_FLAG_PERMANENT; 327 DC_UnlockDc(dc); 328 return; 329 } 330 331 #if 0 332 BOOL FASTCALL 333 IntIsPrimarySurface(SURFOBJ *SurfObj) 334 { 335 if (PrimarySurface.pSurface == NULL) 336 { 337 return FALSE; 338 } 339 return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF? 340 } 341 #endif 342 343 BOOL 344 FASTCALL 345 IntSetDefaultRegion(PDC pdc) 346 { 347 PSURFACE pSurface; 348 PREGION prgn; 349 RECTL rclWnd, rclClip; 350 351 IntGdiReleaseRaoRgn(pdc); 352 353 rclWnd.left = 0; 354 rclWnd.top = 0; 355 rclWnd.right = pdc->dclevel.sizl.cx; 356 rclWnd.bottom = pdc->dclevel.sizl.cy; 357 rclClip = rclWnd; 358 359 //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock); 360 if (pdc->ppdev->flFlags & PDEV_META_DEVICE) 361 { 362 pSurface = pdc->dclevel.pSurface; 363 if (pSurface && pSurface->flags & PDEV_SURFACE) 364 { 365 rclClip.left += pdc->ppdev->ptlOrigion.x; 366 rclClip.top += pdc->ppdev->ptlOrigion.y; 367 rclClip.right += pdc->ppdev->ptlOrigion.x; 368 rclClip.bottom += pdc->ppdev->ptlOrigion.y; 369 } 370 } 371 //EngReleaseSemaphore(pdc->ppdev->hsemDevLock); 372 373 prgn = pdc->prgnVis; 374 375 if (prgn && prgn != prgnDefault) 376 { 377 REGION_SetRectRgn( prgn, 378 rclClip.left, 379 rclClip.top, 380 rclClip.right , 381 rclClip.bottom ); 382 } 383 else 384 { 385 prgn = IntSysCreateRectpRgn( rclClip.left, 386 rclClip.top, 387 rclClip.right , 388 rclClip.bottom ); 389 pdc->prgnVis = prgn; 390 } 391 392 if (prgn) 393 { 394 pdc->ptlDCOrig.x = 0; 395 pdc->ptlDCOrig.y = 0; 396 pdc->erclWindow = rclWnd; 397 pdc->erclClip = rclClip; 398 /* Might be an InitDC or DCE... */ 399 pdc->ptlFillOrigin.x = pdc->dcattr.ptlBrushOrigin.x; 400 pdc->ptlFillOrigin.y = pdc->dcattr.ptlBrushOrigin.y; 401 return TRUE; 402 } 403 404 pdc->prgnVis = prgnDefault; 405 return FALSE; 406 } 407 408 409 BOOL APIENTRY 410 NtGdiCancelDC(HDC hDC) 411 { 412 UNIMPLEMENTED; 413 return FALSE; 414 } 415 416 417 WORD APIENTRY 418 IntGdiSetHookFlags(HDC hDC, WORD Flags) 419 { 420 WORD wRet; 421 DC *dc = DC_LockDc(hDC); 422 423 if (NULL == dc) 424 { 425 EngSetLastError(ERROR_INVALID_HANDLE); 426 return 0; 427 } 428 429 wRet = dc->fs & DC_FLAG_DIRTY_RAO; // FIXME: Wrong flag! 430 431 /* Info in "Undocumented Windows" is slightly confusing. */ 432 DPRINT("DC %p, Flags %04x\n", hDC, Flags); 433 434 if (Flags & DCHF_INVALIDATEVISRGN) 435 { 436 /* hVisRgn has to be updated */ 437 dc->fs |= DC_FLAG_DIRTY_RAO; 438 } 439 else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags) 440 { 441 //dc->fs &= ~DC_FLAG_DIRTY_RAO; 442 } 443 444 DC_UnlockDc(dc); 445 446 return wRet; 447 } 448 449 450 BOOL 451 APIENTRY 452 NtGdiGetDCDword( 453 HDC hDC, 454 UINT u, 455 DWORD *Result) 456 { 457 BOOL Ret = TRUE; 458 PDC pdc; 459 PDC_ATTR pdcattr; 460 461 DWORD SafeResult = 0; 462 NTSTATUS Status = STATUS_SUCCESS; 463 464 if (!Result) 465 { 466 EngSetLastError(ERROR_INVALID_PARAMETER); 467 return FALSE; 468 } 469 470 pdc = DC_LockDc(hDC); 471 if (!pdc) 472 { 473 EngSetLastError(ERROR_INVALID_HANDLE); 474 return FALSE; 475 } 476 pdcattr = pdc->pdcattr; 477 478 switch (u) 479 { 480 case GdiGetJournal: 481 break; 482 483 case GdiGetRelAbs: 484 SafeResult = pdcattr->lRelAbs; 485 break; 486 487 case GdiGetBreakExtra: 488 SafeResult = pdcattr->lBreakExtra; 489 break; 490 491 case GdiGerCharBreak: 492 SafeResult = pdcattr->cBreak; 493 break; 494 495 case GdiGetArcDirection: 496 if (pdcattr->dwLayout & LAYOUT_RTL) 497 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0); 498 else 499 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE; 500 break; 501 502 case GdiGetEMFRestorDc: 503 SafeResult = pdc->dclevel.lSaveDepth; 504 break; 505 506 case GdiGetFontLanguageInfo: 507 SafeResult = IntGetFontLanguageInfo(pdc); 508 break; 509 510 case GdiGetIsMemDc: 511 SafeResult = pdc->dctype; 512 break; 513 514 case GdiGetMapMode: 515 SafeResult = pdcattr->iMapMode; 516 break; 517 518 case GdiGetTextCharExtra: 519 SafeResult = pdcattr->lTextExtra; 520 break; 521 522 default: 523 EngSetLastError(ERROR_INVALID_PARAMETER); 524 Ret = FALSE; 525 break; 526 } 527 528 if (Ret) 529 { 530 _SEH2_TRY 531 { 532 ProbeForWrite(Result, sizeof(DWORD), 1); 533 *Result = SafeResult; 534 } 535 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 536 { 537 Status = _SEH2_GetExceptionCode(); 538 } 539 _SEH2_END; 540 541 if (!NT_SUCCESS(Status)) 542 { 543 SetLastNtError(Status); 544 Ret = FALSE; 545 } 546 } 547 548 DC_UnlockDc(pdc); 549 return Ret; 550 } 551 552 _Success_(return != FALSE) 553 BOOL 554 APIENTRY 555 NtGdiGetAndSetDCDword( 556 _In_ HDC hdc, 557 _In_ UINT u, 558 _In_ DWORD dwIn, 559 _Out_ DWORD *pdwResult) 560 { 561 BOOL Ret = TRUE; 562 PDC pdc; 563 PDC_ATTR pdcattr; 564 565 DWORD SafeResult = 0; 566 NTSTATUS Status = STATUS_SUCCESS; 567 568 if (!pdwResult) 569 { 570 EngSetLastError(ERROR_INVALID_PARAMETER); 571 return FALSE; 572 } 573 574 pdc = DC_LockDc(hdc); 575 if (!pdc) 576 { 577 EngSetLastError(ERROR_INVALID_HANDLE); 578 return FALSE; 579 } 580 pdcattr = pdc->pdcattr; 581 582 switch (u) 583 { 584 case GdiGetSetCopyCount: 585 SafeResult = pdc->ulCopyCount; 586 pdc->ulCopyCount = dwIn; 587 break; 588 589 case GdiGetSetTextAlign: 590 SafeResult = pdcattr->lTextAlign; 591 pdcattr->lTextAlign = dwIn; 592 // pdcattr->flTextAlign = dwIn; // Flags! 593 break; 594 595 case GdiGetSetRelAbs: 596 SafeResult = pdcattr->lRelAbs; 597 pdcattr->lRelAbs = dwIn; 598 break; 599 600 case GdiGetSetTextCharExtra: 601 SafeResult = pdcattr->lTextExtra; 602 pdcattr->lTextExtra = dwIn; 603 break; 604 605 case GdiGetSetSelectFont: 606 break; 607 608 case GdiGetSetMapperFlagsInternal: 609 if (dwIn & ~1) 610 { 611 EngSetLastError(ERROR_INVALID_PARAMETER); 612 Ret = FALSE; 613 break; 614 } 615 SafeResult = pdcattr->flFontMapper; 616 pdcattr->flFontMapper = dwIn; 617 break; 618 619 case GdiGetSetMapMode: 620 SafeResult = IntGdiSetMapMode(pdc, dwIn); 621 break; 622 623 case GdiGetSetArcDirection: 624 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE) 625 { 626 EngSetLastError(ERROR_INVALID_PARAMETER); 627 Ret = FALSE; 628 break; 629 } 630 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left 631 { 632 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0); 633 if (dwIn == AD_CLOCKWISE) 634 { 635 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; 636 break; 637 } 638 pdc->dclevel.flPath |= DCPATH_CLOCKWISE; 639 } 640 else // Left to Right 641 { 642 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + 643 AD_COUNTERCLOCKWISE; 644 if (dwIn == AD_COUNTERCLOCKWISE) 645 { 646 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; 647 break; 648 } 649 pdc->dclevel.flPath |= DCPATH_CLOCKWISE; 650 } 651 break; 652 653 default: 654 EngSetLastError(ERROR_INVALID_PARAMETER); 655 Ret = FALSE; 656 break; 657 } 658 659 if (Ret) 660 { 661 _SEH2_TRY 662 { 663 ProbeForWrite(pdwResult, sizeof(DWORD), 1); 664 *pdwResult = SafeResult; 665 } 666 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 667 { 668 Status = _SEH2_GetExceptionCode(); 669 } 670 _SEH2_END; 671 672 if (!NT_SUCCESS(Status)) 673 { 674 SetLastNtError(Status); 675 Ret = FALSE; 676 } 677 } 678 679 DC_UnlockDc(pdc); 680 return Ret; 681 } 682 683 VOID 684 FASTCALL 685 IntUpdateBoundsRect(PDC pdc, PRECTL pRect) 686 { 687 if (pdc->fs & DC_ACCUM_APP) 688 { 689 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, pRect); 690 } 691 if (pdc->fs & DC_ACCUM_WMGR) 692 { 693 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, pRect); 694 } 695 } 696 697 DWORD 698 APIENTRY 699 NtGdiGetBoundsRect( 700 IN HDC hdc, 701 OUT LPRECT prc, 702 IN DWORD flags) 703 { 704 DWORD ret; 705 PDC pdc; 706 RECT rc; 707 708 /* Lock the DC */ 709 if (!(pdc = DC_LockDc(hdc))) return 0; 710 711 if (!(flags & DCB_WINDOWMGR)) 712 { 713 rc = pdc->erclBoundsApp; 714 715 if (RECTL_bIsEmptyRect(&rc)) 716 { 717 rc.left = rc.top = rc.right = rc.bottom = 0; 718 ret = DCB_RESET; 719 } 720 else 721 { 722 RECTL rcRgn; 723 if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc); 724 if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn)) 725 { 726 REGION_GetRgnBox(pdc->prgnVis, &rcRgn); 727 } 728 rc.left = max( rc.left, 0 ); 729 rc.top = max( rc.top, 0 ); 730 rc.right = min( rc.right, rcRgn.right - rcRgn.left ); 731 rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top ); 732 DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top); 733 DPRINT("rc l %d t %d\n",rc.left,rc.top); 734 DPRINT(" r %d b %d\n",rc.right,rc.bottom); 735 ret = DCB_SET; 736 } 737 IntDPtoLP( pdc, &rc, 2 ); 738 DPRINT("rc1 l %d t %d\n",rc.left,rc.top); 739 DPRINT(" r %d b %d\n",rc.right,rc.bottom); 740 } 741 else 742 { 743 rc = pdc->erclBounds; 744 ret = DCB_SET; 745 } 746 747 /* Copy the rect to the caller */ 748 _SEH2_TRY 749 { 750 ProbeForWrite(prc, sizeof(RECT), 1); 751 *prc = rc; 752 } 753 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 754 { 755 ret = 0; 756 } 757 _SEH2_END; 758 759 if (flags & DCB_RESET) 760 { 761 if (!(flags & DCB_WINDOWMGR)) 762 { 763 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX; 764 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN; 765 } 766 else 767 { 768 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX; 769 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN; 770 } 771 } 772 773 DC_UnlockDc(pdc); 774 return ret; 775 } 776 777 DWORD 778 APIENTRY 779 NtGdiSetBoundsRect( 780 IN HDC hdc, 781 IN LPRECT prc, 782 IN DWORD flags) 783 { 784 DWORD ret; 785 PDC pdc; 786 RECTL rcl; 787 788 /* Verify arguments */ 789 if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0; 790 791 /* Lock the DC */ 792 if (!(pdc = DC_LockDc(hdc))) return 0; 793 794 /* Get the return value */ 795 ret = DCB_RESET; /* we don't have device-specific bounds */ 796 ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) | 797 (RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET ); 798 ret |= (flags & DCB_WINDOWMGR); 799 800 if (flags & DCB_RESET) 801 { 802 if (!(flags & DCB_WINDOWMGR)) 803 { 804 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX; 805 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN; 806 } 807 else 808 { 809 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX; 810 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN; 811 } 812 } 813 814 if (flags & DCB_ACCUMULATE && prc != NULL) 815 { 816 /* Capture the rect */ 817 _SEH2_TRY 818 { 819 ProbeForRead(prc, sizeof(RECT), 1); 820 rcl = *prc; 821 } 822 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 823 { 824 DC_UnlockDc(pdc); 825 _SEH2_YIELD(return 0;) 826 } 827 _SEH2_END; 828 829 RECTL_vMakeWellOrdered(&rcl); 830 831 if (!(flags & DCB_WINDOWMGR)) 832 { 833 IntLPtoDP( pdc, (POINT *)&rcl, 2 ); 834 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl); 835 } 836 else 837 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl); 838 } 839 840 if (flags & DCB_ENABLE) 841 { 842 if (!(flags & DCB_WINDOWMGR)) 843 pdc->fs |= DC_ACCUM_APP; 844 else 845 pdc->fs |= DC_ACCUM_WMGR; 846 } 847 if (flags & DCB_DISABLE) 848 { 849 if (!(flags & DCB_WINDOWMGR)) 850 pdc->fs &= ~DC_ACCUM_APP; 851 else 852 pdc->fs &= ~DC_ACCUM_WMGR; 853 } 854 DC_UnlockDc(pdc); 855 return ret; 856 } 857 858 /* Translates a COLORREF to the right color in the specified DC color space */ 859 ULONG 860 TranslateCOLORREF(PDC pdc, COLORREF crColor) 861 { 862 PSURFACE psurfDC; 863 PPALETTE ppalDC; 864 ULONG index, ulColor, iBitmapFormat; 865 EXLATEOBJ exlo; 866 867 /* Get the DC surface */ 868 psurfDC = pdc->dclevel.pSurface; 869 870 /* If no surface is selected, use the default bitmap */ 871 if (!psurfDC) 872 psurfDC = psurfDefaultBitmap; 873 874 /* Check what color type this is */ 875 switch (crColor >> 24) 876 { 877 case 0x00: /* RGB color */ 878 break; 879 880 case 0x01: /* PALETTEINDEX */ 881 index = crColor & 0xFFFFFF; 882 ppalDC = pdc->dclevel.ppal; 883 if (index >= ppalDC->NumColors) index = 0; 884 885 /* Get the RGB value */ 886 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index); 887 break; 888 889 case 0x02: /* PALETTERGB */ 890 891 if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE]) 892 { 893 /* First find the nearest index in the dc palette */ 894 ppalDC = pdc->dclevel.ppal; 895 index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF); 896 897 /* Get the RGB value */ 898 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index); 899 } 900 else 901 { 902 /* Use the pure color */ 903 crColor = crColor & 0x00FFFFFF; 904 } 905 break; 906 907 case 0x10: /* DIBINDEX */ 908 /* Mask the value to match the target bpp */ 909 iBitmapFormat = psurfDC->SurfObj.iBitmapFormat; 910 if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1; 911 else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf; 912 else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF; 913 else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF; 914 else index = crColor & 0xFFFFFF; 915 return index; 916 917 default: 918 DPRINT("Unsupported color type %u passed\n", crColor >> 24); 919 crColor &= 0xFFFFFF; 920 } 921 922 /* Initialize an XLATEOBJ from RGB to the target surface */ 923 EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurfDC->ppal, 0xFFFFFF, 0, 0); 924 925 /* Translate the color to the target format */ 926 ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor); 927 928 /* Cleanup the XLATEOBJ */ 929 EXLATEOBJ_vCleanup(&exlo); 930 931 return ulColor; 932 } 933 934 935