1 #include <precomp.h> 2 3 4 /* 5 * @implemented 6 */ 7 BOOL 8 WINAPI 9 LineTo( 10 _In_ HDC hdc, 11 _In_ INT x, 12 _In_ INT y ) 13 { 14 HANDLE_METADC(BOOL, LineTo, FALSE, hdc, x, y); 15 16 return NtGdiLineTo(hdc, x, y); 17 } 18 19 20 BOOL 21 WINAPI 22 MoveToEx( 23 _In_ HDC hdc, 24 _In_ INT x, 25 _In_ INT y, 26 _Out_opt_ LPPOINT ppt) 27 { 28 PDC_ATTR pdcattr; 29 30 HANDLE_METADC(BOOL, MoveTo, FALSE, hdc, x, y, ppt); 31 32 /* Get the DC attribute */ 33 pdcattr = GdiGetDcAttr(hdc); 34 if (pdcattr == NULL) 35 { 36 SetLastError(ERROR_INVALID_PARAMETER); 37 return FALSE; 38 } 39 40 if (ppt) 41 { 42 if ( pdcattr->ulDirty_ & DIRTY_PTLCURRENT ) // Double hit! 43 { 44 ppt->x = pdcattr->ptfxCurrent.x; // ret prev before change. 45 ppt->y = pdcattr->ptfxCurrent.y; 46 DPtoLP (hdc, ppt, 1); // reconvert back. 47 } 48 else 49 { 50 ppt->x = pdcattr->ptlCurrent.x; 51 ppt->y = pdcattr->ptlCurrent.y; 52 } 53 } 54 55 pdcattr->ptlCurrent.x = x; 56 pdcattr->ptlCurrent.y = y; 57 58 pdcattr->ulDirty_ &= ~DIRTY_PTLCURRENT; 59 pdcattr->ulDirty_ |= ( DIRTY_PTFXCURRENT|DIRTY_STYLESTATE); // Set dirty 60 return TRUE; 61 } 62 63 64 /* 65 * @implemented 66 */ 67 BOOL 68 WINAPI 69 Ellipse( 70 _In_ HDC hdc, 71 _In_ INT left, 72 _In_ INT top, 73 _In_ INT right, 74 _In_ INT bottom) 75 { 76 HANDLE_METADC(BOOL, Ellipse, FALSE, hdc, left, top, right, bottom); 77 78 return NtGdiEllipse(hdc, left, top, right, bottom); 79 } 80 81 82 /* 83 * @implemented 84 */ 85 BOOL 86 WINAPI 87 Rectangle( 88 _In_ HDC hdc, 89 _In_ INT left, 90 _In_ INT top, 91 _In_ INT right, 92 _In_ INT bottom) 93 { 94 HANDLE_METADC(BOOL, Rectangle, FALSE, hdc, left, top, right, bottom); 95 96 return NtGdiRectangle(hdc, left, top, right, bottom); 97 } 98 99 100 /* 101 * @implemented 102 */ 103 BOOL 104 WINAPI 105 RoundRect( 106 _In_ HDC hdc, 107 _In_ INT left, 108 _In_ INT top, 109 _In_ INT right, 110 _In_ INT bottom, 111 _In_ INT width, 112 _In_ INT height) 113 { 114 HANDLE_METADC(BOOL, RoundRect, FALSE, hdc, left, top, right, bottom, width, height); 115 116 return NtGdiRoundRect(hdc, left, top, right, bottom, width, height); 117 } 118 119 120 /* 121 * @implemented 122 */ 123 COLORREF 124 WINAPI 125 GetPixel( 126 _In_ HDC hdc, 127 _In_ INT x, 128 _In_ INT y) 129 { 130 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) return CLR_INVALID; 131 if (!GdiValidateHandle((HGDIOBJ) hdc)) return CLR_INVALID; 132 return NtGdiGetPixel(hdc, x, y); 133 } 134 135 136 /* 137 * @implemented 138 */ 139 COLORREF 140 WINAPI 141 SetPixel( 142 _In_ HDC hdc, 143 _In_ INT x, 144 _In_ INT y, 145 _In_ COLORREF crColor) 146 { 147 HANDLE_METADC(COLORREF, SetPixel, CLR_INVALID, hdc, x, y, crColor); 148 149 return NtGdiSetPixel(hdc, x, y, crColor); 150 } 151 152 153 /* 154 * @implemented 155 */ 156 BOOL 157 WINAPI 158 SetPixelV( 159 _In_ HDC hdc, 160 _In_ INT x, 161 _In_ INT y, 162 _In_ COLORREF crColor) 163 { 164 return SetPixel(hdc, x, y, crColor) != CLR_INVALID; 165 } 166 167 168 /* 169 * @implemented 170 */ 171 BOOL 172 WINAPI 173 FillRgn( 174 _In_ HDC hdc, 175 _In_ HRGN hrgn, 176 _In_ HBRUSH hbr) 177 { 178 179 if ((hrgn == NULL) || (hbr == NULL)) 180 return FALSE; 181 182 HANDLE_METADC(BOOL, FillRgn, FALSE, hdc, hrgn, hbr); 183 184 return NtGdiFillRgn(hdc, hrgn, hbr); 185 } 186 187 188 /* 189 * @implemented 190 */ 191 BOOL 192 WINAPI 193 FrameRgn( 194 _In_ HDC hdc, 195 _In_ HRGN hrgn, 196 _In_ HBRUSH hbr, 197 _In_ INT nWidth, 198 _In_ INT nHeight) 199 { 200 201 if ((hrgn == NULL) || (hbr == NULL)) 202 return FALSE; 203 204 HANDLE_METADC(BOOL, FrameRgn, FALSE, hdc, hrgn, hbr, nWidth, nHeight); 205 206 return NtGdiFrameRgn(hdc, hrgn, hbr, nWidth, nHeight); 207 } 208 209 210 /* 211 * @implemented 212 */ 213 BOOL 214 WINAPI 215 InvertRgn( 216 _In_ HDC hdc, 217 _In_ HRGN hrgn) 218 { 219 220 if (hrgn == NULL) 221 return FALSE; 222 223 HANDLE_METADC(BOOL, InvertRgn, FALSE, hdc, hrgn); 224 225 return NtGdiInvertRgn(hdc, hrgn); 226 } 227 228 229 /* 230 * @implemented 231 */ 232 BOOL 233 WINAPI 234 PaintRgn( 235 _In_ HDC hdc, 236 _In_ HRGN hrgn) 237 { 238 return FillRgn(hdc, hrgn, GetCurrentObject(hdc, OBJ_BRUSH)); 239 } 240 241 242 /* 243 * @implemented 244 */ 245 BOOL 246 WINAPI 247 PolyBezier( 248 _In_ HDC hdc, 249 _In_reads_(cpt) const POINT *apt, 250 _In_ DWORD cpt) 251 { 252 HANDLE_METADC(BOOL, PolyBezier, FALSE, hdc, apt, cpt); 253 254 return NtGdiPolyPolyDraw(hdc ,(PPOINT)apt, &cpt, 1, GdiPolyBezier); 255 } 256 257 258 /* 259 * @implemented 260 */ 261 BOOL 262 WINAPI 263 PolyBezierTo( 264 _In_ HDC hdc, 265 _In_reads_(cpt) const POINT *apt, 266 _In_ DWORD cpt) 267 { 268 HANDLE_METADC(BOOL, PolyBezierTo, FALSE, hdc, apt, cpt); 269 270 return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, &cpt, 1, GdiPolyBezierTo); 271 } 272 273 274 /* 275 * @implemented 276 */ 277 BOOL 278 WINAPI 279 PolyDraw( 280 _In_ HDC hdc, 281 _In_reads_(cpt) const POINT *apt, 282 _In_reads_(cpt) const BYTE *aj, 283 _In_ INT cpt) 284 { 285 HANDLE_METADC(BOOL, PolyDraw, FALSE, hdc, apt, aj, cpt); 286 287 return NtGdiPolyDraw(hdc, (PPOINT)apt, (PBYTE)aj, cpt); 288 } 289 290 291 /* 292 * @implemented 293 */ 294 BOOL 295 WINAPI 296 Polygon( 297 _In_ HDC hdc, 298 _In_reads_(cpt) const POINT *apt, 299 _In_ INT cpt) 300 { 301 HANDLE_METADC(BOOL, Polygon, FALSE, hdc, apt, cpt); 302 303 return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, (PULONG)&cpt, 1, GdiPolyPolygon); 304 } 305 306 307 /* 308 * @implemented 309 */ 310 BOOL 311 WINAPI 312 Polyline( 313 _In_ HDC hdc, 314 _In_reads_(cpt) const POINT *apt, 315 _In_ INT cpt) 316 { 317 HANDLE_METADC(BOOL, Polyline, FALSE, hdc, apt, cpt); 318 319 return NtGdiPolyPolyDraw(hdc, (PPOINT)apt, (PULONG)&cpt, 1, GdiPolyPolyLine); 320 } 321 322 323 /* 324 * @implemented 325 */ 326 BOOL 327 WINAPI 328 PolylineTo( 329 _In_ HDC hdc, 330 _In_reads_(cpt) const POINT *apt, 331 _In_ DWORD cpt) 332 { 333 HANDLE_METADC(BOOL, PolylineTo, FALSE, hdc, apt, cpt); 334 335 return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, &cpt, 1, GdiPolyLineTo); 336 } 337 338 339 /* 340 * @implemented 341 */ 342 BOOL 343 WINAPI 344 PolyPolygon( 345 _In_ HDC hdc, 346 _In_ const POINT *apt, 347 _In_reads_(csz) const INT *asz, 348 _In_ INT csz) 349 { 350 HANDLE_METADC(BOOL, PolyPolygon, FALSE, hdc, apt, asz, csz); 351 352 return NtGdiPolyPolyDraw(hdc, (PPOINT)apt, (PULONG)asz, csz, GdiPolyPolygon); 353 } 354 355 356 /* 357 * @implemented 358 */ 359 BOOL 360 WINAPI 361 PolyPolyline( 362 _In_ HDC hdc, 363 _In_ CONST POINT *apt, 364 _In_reads_(csz) CONST DWORD *asz, 365 _In_ DWORD csz) 366 { 367 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 368 return FALSE; 369 370 HANDLE_METADC(BOOL, PolyPolyline, FALSE, hdc, apt, asz, csz); 371 372 return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, (PULONG)asz, csz, GdiPolyPolyLine); 373 } 374 375 376 /* 377 * @implemented 378 */ 379 BOOL 380 WINAPI 381 ExtFloodFill( 382 _In_ HDC hdc, 383 _In_ INT xStart, 384 _In_ INT yStart, 385 _In_ COLORREF crFill, 386 _In_ UINT fuFillType) 387 { 388 HANDLE_METADC(BOOL, ExtFloodFill, FALSE, hdc, xStart, yStart, crFill, fuFillType); 389 390 return NtGdiExtFloodFill(hdc, xStart, yStart, crFill, fuFillType); 391 } 392 393 394 /* 395 * @implemented 396 */ 397 BOOL 398 WINAPI 399 FloodFill( 400 _In_ HDC hdc, 401 _In_ INT xStart, 402 _In_ INT yStart, 403 _In_ COLORREF crFill) 404 { 405 return ExtFloodFill(hdc, xStart, yStart, crFill, FLOODFILLBORDER); 406 } 407 408 /* 409 * @implemented 410 */ 411 BOOL 412 WINAPI 413 BitBlt( 414 _In_ HDC hdcDest, 415 _In_ INT xDest, 416 _In_ INT yDest, 417 _In_ INT cx, 418 _In_ INT cy, 419 _In_opt_ HDC hdcSrc, 420 _In_ INT xSrc, 421 _In_ INT ySrc, 422 _In_ DWORD dwRop) 423 { 424 /* Use PatBlt for no source blt, like windows does */ 425 if (!ROP_USES_SOURCE(dwRop)) 426 { 427 return PatBlt(hdcDest, xDest, yDest, cx, cy, dwRop); 428 } 429 430 /* For meta DCs we use StretchBlt */ 431 HANDLE_METADC(BOOL, 432 StretchBlt, 433 FALSE, 434 hdcDest, 435 xDest, 436 yDest, 437 cx, 438 cx, 439 hdcSrc, 440 xSrc, 441 ySrc, 442 cx, 443 cx, 444 dwRop); 445 446 return NtGdiBitBlt(hdcDest, xDest, yDest, cx, cy, hdcSrc, xSrc, ySrc, dwRop, 0, 0); 447 } 448 449 BOOL 450 WINAPI 451 PatBlt( 452 _In_ HDC hdc, 453 _In_ INT nXLeft, 454 _In_ INT nYLeft, 455 _In_ INT nWidth, 456 _In_ INT nHeight, 457 _In_ DWORD dwRop) 458 { 459 PDC_ATTR pdcattr; 460 461 HANDLE_METADC(BOOL, PatBlt, FALSE, hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop); 462 463 /* Get the DC attribute */ 464 pdcattr = GdiGetDcAttr(hdc); 465 if (pdcattr && !(pdcattr->ulDirty_ & DC_DIBSECTION)) 466 { 467 PGDIBSPATBLT pgO; 468 469 pgO = GdiAllocBatchCommand(hdc, GdiBCPatBlt); 470 if (pgO) 471 { 472 pdcattr->ulDirty_ |= DC_MODE_DIRTY; 473 pgO->nXLeft = nXLeft; 474 pgO->nYLeft = nYLeft; 475 pgO->nWidth = nWidth; 476 pgO->nHeight = nHeight; 477 pgO->dwRop = dwRop; 478 /* Snapshot attributes */ 479 pgO->hbrush = pdcattr->hbrush; 480 pgO->crForegroundClr = pdcattr->crForegroundClr; 481 pgO->crBackgroundClr = pdcattr->crBackgroundClr; 482 pgO->crBrushClr = pdcattr->crBrushClr; 483 pgO->ulForegroundClr = pdcattr->ulForegroundClr; 484 pgO->ulBackgroundClr = pdcattr->ulBackgroundClr; 485 pgO->ulBrushClr = pdcattr->ulBrushClr; 486 return TRUE; 487 } 488 } 489 return NtGdiPatBlt( hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop); 490 } 491 492 BOOL 493 WINAPI 494 PolyPatBlt( 495 _In_ HDC hdc, 496 _In_ DWORD dwRop, 497 _In_ PPOLYPATBLT pPoly, 498 _In_ DWORD nCount, 499 _In_ DWORD dwMode) 500 { 501 UINT i; 502 BOOL bResult; 503 HBRUSH hbrOld; 504 PDC_ATTR pdcattr; 505 506 /* Handle meta DCs */ 507 if ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) || 508 (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE)) 509 { 510 if (!GdiValidateHandle(hdc)) 511 { 512 return FALSE; 513 } 514 515 /* Save the current DC brush */ 516 hbrOld = SelectObject(hdc, GetStockObject(DC_BRUSH)); 517 518 /* Assume success */ 519 bResult = TRUE; 520 521 /* Loop all rect */ 522 for (i = 0; i < nCount; i++) 523 { 524 /* Select the brush for this rect */ 525 SelectObject(hdc, pPoly[i].hBrush); 526 527 /* Do the PatBlt operation for this rect */ 528 bResult &= PatBlt(hdc, 529 pPoly[i].nXLeft, 530 pPoly[i].nYLeft, 531 pPoly[i].nWidth, 532 pPoly[i].nHeight, 533 dwRop); 534 } 535 536 /* Restore the old brush */ 537 SelectObject(hdc, hbrOld); 538 539 return bResult; 540 } 541 542 /* Get the DC attribute */ 543 pdcattr = GdiGetDcAttr(hdc); 544 if (nCount && pdcattr && !(pdcattr->ulDirty_ & DC_DIBSECTION)) 545 { 546 PGDIBSPPATBLT pgO; 547 PTEB pTeb = NtCurrentTeb(); 548 549 pgO = GdiAllocBatchCommand(hdc, GdiBCPolyPatBlt); 550 if (pgO) 551 { 552 USHORT cjSize = 0; 553 if (nCount > 1) cjSize = (nCount-1) * sizeof(PATRECT); 554 555 if ((pTeb->GdiTebBatch.Offset + cjSize) <= GDIBATCHBUFSIZE) 556 { 557 pdcattr->ulDirty_ |= DC_MODE_DIRTY; 558 pgO->Count = nCount; 559 pgO->Mode = dwMode; 560 pgO->rop4 = dwRop; 561 /* Snapshot attributes */ 562 pgO->crForegroundClr = pdcattr->crForegroundClr; 563 pgO->crBackgroundClr = pdcattr->crBackgroundClr; 564 pgO->crBrushClr = pdcattr->crBrushClr; 565 pgO->ulForegroundClr = pdcattr->ulForegroundClr; 566 pgO->ulBackgroundClr = pdcattr->ulBackgroundClr; 567 pgO->ulBrushClr = pdcattr->ulBrushClr; 568 RtlCopyMemory(pgO->pRect, pPoly, nCount * sizeof(PATRECT)); 569 // Recompute offset and return size, remember one is already accounted for in the structure. 570 pTeb->GdiTebBatch.Offset += cjSize; 571 ((PGDIBATCHHDR)pgO)->Size += cjSize; 572 return TRUE; 573 } 574 // Reset offset and count then fall through 575 pTeb->GdiTebBatch.Offset -= sizeof(GDIBSPPATBLT); 576 pTeb->GdiBatchCount--; 577 } 578 } 579 return NtGdiPolyPatBlt(hdc, dwRop, pPoly, nCount, dwMode); 580 } 581 582 /* 583 * @implemented 584 */ 585 BOOL 586 WINAPI 587 StretchBlt( 588 _In_ HDC hdcDest, 589 _In_ INT xDest, 590 _In_ INT yDest, 591 _In_ INT cxDest, 592 _In_ INT cyDest, 593 _In_opt_ HDC hdcSrc, 594 _In_ INT xSrc, 595 _In_ INT ySrc, 596 _In_ INT cxSrc, 597 _In_ INT cySrc, 598 _In_ DWORD dwRop) 599 { 600 HANDLE_METADC(BOOL, 601 StretchBlt, 602 FALSE, 603 hdcDest, 604 xDest, 605 yDest, 606 cxDest, 607 cyDest, 608 hdcSrc, 609 xSrc, 610 ySrc, 611 cxSrc, 612 cySrc, 613 dwRop); 614 615 return NtGdiStretchBlt(hdcDest, 616 xDest, 617 yDest, 618 cxDest, 619 cyDest, 620 hdcSrc, 621 xSrc, 622 ySrc, 623 cxSrc, 624 cySrc, 625 dwRop, 626 0); 627 } 628 629 630 /* 631 * @implemented 632 */ 633 BOOL 634 WINAPI 635 MaskBlt( 636 _In_ HDC hdcDest, 637 _In_ INT xDest, 638 _In_ INT yDest, 639 _In_ INT cx, 640 _In_ INT cy, 641 _In_ HDC hdcSrc, 642 _In_ INT xSrc, 643 _In_ INT ySrc, 644 _In_ HBITMAP hbmMask, 645 _In_ INT xMask, 646 _In_ INT yMask, 647 _In_ DWORD dwRop) 648 { 649 HANDLE_METADC(BOOL, 650 MaskBlt, 651 FALSE, 652 hdcDest, 653 xDest, 654 yDest, 655 cx, 656 cy, 657 hdcSrc, 658 xSrc, 659 ySrc, 660 hbmMask, 661 xMask, 662 yMask, 663 dwRop); 664 665 return NtGdiMaskBlt(hdcDest, 666 xDest, 667 yDest, 668 cx, 669 cy, 670 hdcSrc, 671 xSrc, 672 ySrc, 673 hbmMask, 674 xMask, 675 yMask, 676 dwRop, 677 GetBkColor(hdcSrc)); 678 } 679 680 681 /* 682 * @implemented 683 */ 684 BOOL 685 WINAPI 686 PlgBlt( 687 _In_ HDC hdcDest, 688 _In_reads_(3) const POINT * ppt, 689 _In_ HDC hdcSrc, 690 _In_ INT xSrc, 691 _In_ INT ySrc, 692 _In_ INT cx, 693 _In_ INT cy, 694 _In_opt_ HBITMAP hbmMask, 695 _In_ INT xMask, 696 _In_ INT yMask) 697 { 698 HANDLE_METADC(BOOL, 699 PlgBlt, 700 FALSE, 701 hdcDest, 702 ppt, 703 hdcSrc, 704 xSrc, 705 ySrc, 706 cx, 707 cy, 708 hbmMask, 709 xMask, 710 yMask); 711 712 return NtGdiPlgBlt(hdcDest, 713 (LPPOINT)ppt, 714 hdcSrc, 715 xSrc, 716 ySrc, 717 cx, 718 cy, 719 hbmMask, 720 xMask, 721 yMask, 722 GetBkColor(hdcSrc)); 723 } 724 725 BOOL 726 WINAPI 727 GdiAlphaBlend( 728 _In_ HDC hdcDst, 729 _In_ INT xDst, 730 _In_ INT yDst, 731 _In_ INT cxDst, 732 _In_ INT cyDst, 733 _In_ HDC hdcSrc, 734 _In_ INT xSrc, 735 _In_ INT ySrc, 736 _In_ INT cxSrc, 737 _In_ INT cySrc, 738 _In_ BLENDFUNCTION blendfn) 739 { 740 if (hdcSrc == NULL ) return FALSE; 741 742 if (GDI_HANDLE_GET_TYPE(hdcSrc) == GDI_OBJECT_TYPE_METADC) return FALSE; 743 744 HANDLE_METADC(BOOL, 745 AlphaBlend, 746 FALSE, 747 hdcDst, 748 xDst, 749 yDst, 750 cxDst, 751 cyDst, 752 hdcSrc, 753 xSrc, 754 ySrc, 755 cxSrc, 756 cySrc, 757 blendfn); 758 759 return NtGdiAlphaBlend(hdcDst, 760 xDst, 761 yDst, 762 cxDst, 763 cyDst, 764 hdcSrc, 765 xSrc, 766 ySrc, 767 cxSrc, 768 cySrc, 769 blendfn, 770 0); 771 } 772 773 774 /* 775 * @implemented 776 */ 777 BOOL 778 WINAPI 779 GdiTransparentBlt( 780 _In_ HDC hdcDst, 781 _In_ INT xDst, 782 _In_ INT yDst, 783 _In_ INT cxDst, 784 _In_ INT cyDst, 785 _In_ HDC hdcSrc, 786 _In_ INT xSrc, 787 _In_ INT ySrc, 788 _In_ INT cxSrc, 789 _In_ INT cySrc, 790 _In_ UINT crTransparent) 791 { 792 HANDLE_METADC(BOOL, 793 TransparentBlt, 794 FALSE, 795 hdcDst, 796 xDst, 797 yDst, 798 cxDst, 799 cyDst, 800 hdcSrc, 801 xSrc, 802 ySrc, 803 cxSrc, 804 cySrc, 805 crTransparent); 806 807 /* FIXME some part need be done in user mode */ 808 return NtGdiTransparentBlt(hdcDst, xDst, yDst, cxDst, cyDst, hdcSrc, xSrc, ySrc, cxSrc, cySrc, crTransparent); 809 } 810 811 /* 812 * @implemented 813 */ 814 BOOL 815 WINAPI 816 GdiGradientFill( 817 _In_ HDC hdc, 818 _In_reads_(nVertex) PTRIVERTEX pVertex, 819 _In_ ULONG nVertex, 820 _In_ PVOID pMesh, 821 _In_ ULONG nCount, 822 _In_ ULONG ulMode) 823 { 824 HANDLE_METADC(BOOL, GradientFill, FALSE, hdc, pVertex, nVertex, pMesh, nCount, ulMode); 825 826 /* FIXME some part need be done in user mode */ 827 return NtGdiGradientFill(hdc, pVertex, nVertex, pMesh, nCount, ulMode); 828 } 829