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