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 GdiGetSetEPSPrintingEscape: 589 SafeResult = pdc->fs & DC_EPSPRINTINGESCAPE; 590 pdc->fs &= ~DC_EPSPRINTINGESCAPE; 591 break; 592 593 case GdiGetSetCopyCount: 594 SafeResult = pdc->ulCopyCount; 595 pdc->ulCopyCount = dwIn; 596 break; 597 598 case GdiGetSetTextAlign: 599 SafeResult = pdcattr->lTextAlign; 600 pdcattr->lTextAlign = dwIn; 601 // pdcattr->flTextAlign = dwIn; // Flags! 602 break; 603 604 case GdiGetSetRelAbs: 605 SafeResult = pdcattr->lRelAbs; 606 pdcattr->lRelAbs = dwIn; 607 break; 608 609 case GdiGetSetTextCharExtra: 610 SafeResult = pdcattr->lTextExtra; 611 pdcattr->lTextExtra = dwIn; 612 break; 613 614 case GdiGetSetSelectFont: 615 break; 616 617 case GdiGetSetMapperFlagsInternal: 618 if (dwIn & ~1) 619 { 620 EngSetLastError(ERROR_INVALID_PARAMETER); 621 Ret = FALSE; 622 break; 623 } 624 SafeResult = pdcattr->flFontMapper; 625 pdcattr->flFontMapper = dwIn; 626 break; 627 628 case GdiGetSetMapMode: 629 SafeResult = IntGdiSetMapMode(pdc, dwIn); 630 break; 631 632 case GdiGetSetArcDirection: 633 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE) 634 { 635 EngSetLastError(ERROR_INVALID_PARAMETER); 636 Ret = FALSE; 637 break; 638 } 639 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left 640 { 641 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0); 642 if (dwIn == AD_CLOCKWISE) 643 { 644 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; 645 break; 646 } 647 pdc->dclevel.flPath |= DCPATH_CLOCKWISE; 648 } 649 else // Left to Right 650 { 651 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + 652 AD_COUNTERCLOCKWISE; 653 if (dwIn == AD_COUNTERCLOCKWISE) 654 { 655 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; 656 break; 657 } 658 pdc->dclevel.flPath |= DCPATH_CLOCKWISE; 659 } 660 break; 661 662 default: 663 EngSetLastError(ERROR_INVALID_PARAMETER); 664 Ret = FALSE; 665 break; 666 } 667 668 if (Ret) 669 { 670 _SEH2_TRY 671 { 672 ProbeForWrite(pdwResult, sizeof(DWORD), 1); 673 *pdwResult = SafeResult; 674 } 675 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 676 { 677 Status = _SEH2_GetExceptionCode(); 678 } 679 _SEH2_END; 680 681 if (!NT_SUCCESS(Status)) 682 { 683 SetLastNtError(Status); 684 Ret = FALSE; 685 } 686 } 687 688 DC_UnlockDc(pdc); 689 return Ret; 690 } 691 692 VOID 693 FASTCALL 694 IntUpdateBoundsRect(PDC pdc, PRECTL pRect) 695 { 696 if (pdc->fs & DC_ACCUM_APP) 697 { 698 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, pRect); 699 } 700 if (pdc->fs & DC_ACCUM_WMGR) 701 { 702 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, pRect); 703 } 704 } 705 706 DWORD 707 APIENTRY 708 NtGdiGetBoundsRect( 709 IN HDC hdc, 710 OUT LPRECT prc, 711 IN DWORD flags) 712 { 713 DWORD ret; 714 PDC pdc; 715 RECT rc; 716 717 /* Lock the DC */ 718 if (!(pdc = DC_LockDc(hdc))) return 0; 719 720 if (!(flags & DCB_WINDOWMGR)) 721 { 722 rc = pdc->erclBoundsApp; 723 724 if (RECTL_bIsEmptyRect(&rc)) 725 { 726 rc.left = rc.top = rc.right = rc.bottom = 0; 727 ret = DCB_RESET; 728 } 729 else 730 { 731 RECTL rcRgn; 732 if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc); 733 if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn)) 734 { 735 REGION_GetRgnBox(pdc->prgnVis, &rcRgn); 736 } 737 rc.left = max( rc.left, 0 ); 738 rc.top = max( rc.top, 0 ); 739 rc.right = min( rc.right, rcRgn.right - rcRgn.left ); 740 rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top ); 741 DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top); 742 DPRINT("rc l %d t %d\n",rc.left,rc.top); 743 DPRINT(" r %d b %d\n",rc.right,rc.bottom); 744 ret = DCB_SET; 745 } 746 IntDPtoLP(pdc, (PPOINTL)&rc, 2); 747 DPRINT("rc1 l %d t %d\n",rc.left,rc.top); 748 DPRINT(" r %d b %d\n",rc.right,rc.bottom); 749 } 750 else 751 { 752 rc = pdc->erclBounds; 753 ret = DCB_SET; 754 } 755 756 /* Copy the rect to the caller */ 757 _SEH2_TRY 758 { 759 ProbeForWrite(prc, sizeof(RECT), 1); 760 *prc = rc; 761 } 762 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 763 { 764 ret = 0; 765 } 766 _SEH2_END; 767 768 if (flags & DCB_RESET) 769 { 770 if (!(flags & DCB_WINDOWMGR)) 771 { 772 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX; 773 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN; 774 } 775 else 776 { 777 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX; 778 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN; 779 } 780 } 781 782 DC_UnlockDc(pdc); 783 return ret; 784 } 785 786 DWORD 787 APIENTRY 788 NtGdiSetBoundsRect( 789 IN HDC hdc, 790 IN LPRECT prc, 791 IN DWORD flags) 792 { 793 DWORD ret; 794 PDC pdc; 795 RECTL rcl; 796 797 /* Verify arguments */ 798 if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0; 799 800 /* Lock the DC */ 801 if (!(pdc = DC_LockDc(hdc))) return 0; 802 803 /* Get the return value */ 804 ret = DCB_RESET; /* we don't have device-specific bounds */ 805 ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) | 806 (RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET ); 807 ret |= (flags & DCB_WINDOWMGR); 808 809 if (flags & DCB_RESET) 810 { 811 if (!(flags & DCB_WINDOWMGR)) 812 { 813 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX; 814 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN; 815 } 816 else 817 { 818 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX; 819 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN; 820 } 821 } 822 823 if (flags & DCB_ACCUMULATE && prc != NULL) 824 { 825 /* Capture the rect */ 826 _SEH2_TRY 827 { 828 ProbeForRead(prc, sizeof(RECT), 1); 829 rcl = *prc; 830 } 831 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 832 { 833 DC_UnlockDc(pdc); 834 _SEH2_YIELD(return 0;) 835 } 836 _SEH2_END; 837 838 RECTL_vMakeWellOrdered(&rcl); 839 840 if (!(flags & DCB_WINDOWMGR)) 841 { 842 IntLPtoDP( pdc, (POINT *)&rcl, 2 ); 843 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl); 844 } 845 else 846 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl); 847 } 848 849 if (flags & DCB_ENABLE) 850 { 851 if (!(flags & DCB_WINDOWMGR)) 852 pdc->fs |= DC_ACCUM_APP; 853 else 854 pdc->fs |= DC_ACCUM_WMGR; 855 } 856 if (flags & DCB_DISABLE) 857 { 858 if (!(flags & DCB_WINDOWMGR)) 859 pdc->fs &= ~DC_ACCUM_APP; 860 else 861 pdc->fs &= ~DC_ACCUM_WMGR; 862 } 863 DC_UnlockDc(pdc); 864 return ret; 865 } 866 867 /* Translates a COLORREF to the right color in the specified DC color space */ 868 ULONG 869 TranslateCOLORREF(PDC pdc, COLORREF crColor) 870 { 871 PSURFACE psurfDC; 872 PPALETTE ppalDC; 873 ULONG index, ulColor, iBitmapFormat; 874 EXLATEOBJ exlo; 875 876 /* Get the DC surface */ 877 psurfDC = pdc->dclevel.pSurface; 878 879 /* If no surface is selected, use the default bitmap */ 880 if (!psurfDC) 881 psurfDC = psurfDefaultBitmap; 882 883 /* Check what color type this is */ 884 switch (crColor >> 24) 885 { 886 case 0x00: /* RGB color */ 887 break; 888 889 case 0x01: /* PALETTEINDEX */ 890 index = crColor & 0xFFFFFF; 891 ppalDC = pdc->dclevel.ppal; 892 if (index >= ppalDC->NumColors) index = 0; 893 894 /* Get the RGB value */ 895 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index); 896 break; 897 898 case 0x02: /* PALETTERGB */ 899 900 if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE]) 901 { 902 /* First find the nearest index in the dc palette */ 903 ppalDC = pdc->dclevel.ppal; 904 index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF); 905 906 /* Get the RGB value */ 907 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index); 908 } 909 else 910 { 911 /* Use the pure color */ 912 crColor = crColor & 0x00FFFFFF; 913 } 914 break; 915 916 case 0x10: /* DIBINDEX */ 917 /* Mask the value to match the target bpp */ 918 iBitmapFormat = psurfDC->SurfObj.iBitmapFormat; 919 if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1; 920 else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf; 921 else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF; 922 else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF; 923 else index = crColor & 0xFFFFFF; 924 return index; 925 926 default: 927 DPRINT("Unsupported color type %u passed\n", crColor >> 24); 928 crColor &= 0xFFFFFF; 929 } 930 931 /* Initialize an XLATEOBJ from RGB to the target surface */ 932 EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurfDC->ppal, 0xFFFFFF, 0, 0); 933 934 /* Translate the color to the target format */ 935 ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor); 936 937 /* Cleanup the XLATEOBJ */ 938 EXLATEOBJ_vCleanup(&exlo); 939 940 return ulColor; 941 } 942 943 944