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 pgO->nXLeft = nXLeft; 473 pgO->nYLeft = nYLeft; 474 pgO->nWidth = nWidth; 475 pgO->nHeight = nHeight; 476 pgO->dwRop = dwRop; 477 /* Snapshot attributes */ 478 pgO->hbrush = pdcattr->hbrush; 479 pgO->crForegroundClr = pdcattr->crForegroundClr; 480 pgO->crBackgroundClr = pdcattr->crBackgroundClr; 481 pgO->crBrushClr = pdcattr->crBrushClr; 482 pgO->ulForegroundClr = pdcattr->ulForegroundClr; 483 pgO->ulBackgroundClr = pdcattr->ulBackgroundClr; 484 pgO->ulBrushClr = pdcattr->ulBrushClr; 485 return TRUE; 486 } 487 } 488 return NtGdiPatBlt( hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop); 489 } 490 491 BOOL 492 WINAPI 493 PolyPatBlt( 494 _In_ HDC hdc, 495 _In_ DWORD dwRop, 496 _In_ PPOLYPATBLT pPoly, 497 _In_ DWORD nCount, 498 _In_ DWORD dwMode) 499 { 500 UINT i; 501 BOOL bResult; 502 HBRUSH hbrOld; 503 PDC_ATTR pdcattr; 504 505 /* Handle meta DCs */ 506 if ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) || 507 (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE)) 508 { 509 if (!GdiValidateHandle(hdc)) 510 { 511 return FALSE; 512 } 513 514 /* Save the current DC brush */ 515 hbrOld = SelectObject(hdc, GetStockObject(DC_BRUSH)); 516 517 /* Assume success */ 518 bResult = TRUE; 519 520 /* Loop all rect */ 521 for (i = 0; i < nCount; i++) 522 { 523 /* Select the brush for this rect */ 524 SelectObject(hdc, pPoly[i].hBrush); 525 526 /* Do the PatBlt operation for this rect */ 527 bResult &= PatBlt(hdc, 528 pPoly[i].nXLeft, 529 pPoly[i].nYLeft, 530 pPoly[i].nWidth, 531 pPoly[i].nHeight, 532 dwRop); 533 } 534 535 /* Restore the old brush */ 536 SelectObject(hdc, hbrOld); 537 538 return bResult; 539 } 540 541 /* Get the DC attribute */ 542 pdcattr = GdiGetDcAttr(hdc); 543 if (nCount && pdcattr && !(pdcattr->ulDirty_ & DC_DIBSECTION)) 544 { 545 PGDIBSPPATBLT pgO; 546 PTEB pTeb = NtCurrentTeb(); 547 548 pgO = GdiAllocBatchCommand(hdc, GdiBCPolyPatBlt); 549 if (pgO) 550 { 551 USHORT cjSize = sizeof(GDIBSPPATBLT) + (nCount-1) * sizeof(PATRECT); 552 553 if ((pTeb->GdiTebBatch.Offset + cjSize) <= GDIBATCHBUFSIZE) 554 { 555 pgO->Count = nCount; 556 pgO->Mode = dwMode; 557 pgO->rop4 = dwRop; 558 /* Snapshot attributes */ 559 pgO->crForegroundClr = pdcattr->crForegroundClr; 560 pgO->crBackgroundClr = pdcattr->crBackgroundClr; 561 pgO->crBrushClr = pdcattr->crBrushClr; 562 pgO->ulForegroundClr = pdcattr->ulForegroundClr; 563 pgO->ulBackgroundClr = pdcattr->ulBackgroundClr; 564 pgO->ulBrushClr = pdcattr->ulBrushClr; 565 RtlCopyMemory(pgO->pRect, pPoly, nCount * sizeof(PATRECT)); 566 // Recompute offset, remember one is already accounted for in the structure. 567 pTeb->GdiTebBatch.Offset += (nCount-1) * sizeof(PATRECT); 568 return TRUE; 569 } 570 } 571 } 572 return NtGdiPolyPatBlt(hdc, dwRop, pPoly, nCount, dwMode); 573 } 574 575 /* 576 * @implemented 577 */ 578 BOOL 579 WINAPI 580 StretchBlt( 581 _In_ HDC hdcDest, 582 _In_ INT xDest, 583 _In_ INT yDest, 584 _In_ INT cxDest, 585 _In_ INT cyDest, 586 _In_opt_ HDC hdcSrc, 587 _In_ INT xSrc, 588 _In_ INT ySrc, 589 _In_ INT cxSrc, 590 _In_ INT cySrc, 591 _In_ DWORD dwRop) 592 { 593 HANDLE_METADC(BOOL, 594 StretchBlt, 595 FALSE, 596 hdcDest, 597 xDest, 598 yDest, 599 cxDest, 600 cyDest, 601 hdcSrc, 602 xSrc, 603 ySrc, 604 cxSrc, 605 cySrc, 606 dwRop); 607 608 return NtGdiStretchBlt(hdcDest, 609 xDest, 610 yDest, 611 cxDest, 612 cyDest, 613 hdcSrc, 614 xSrc, 615 ySrc, 616 cxSrc, 617 cySrc, 618 dwRop, 619 0); 620 } 621 622 623 /* 624 * @implemented 625 */ 626 BOOL 627 WINAPI 628 MaskBlt( 629 _In_ HDC hdcDest, 630 _In_ INT xDest, 631 _In_ INT yDest, 632 _In_ INT cx, 633 _In_ INT cy, 634 _In_ HDC hdcSrc, 635 _In_ INT xSrc, 636 _In_ INT ySrc, 637 _In_ HBITMAP hbmMask, 638 _In_ INT xMask, 639 _In_ INT yMask, 640 _In_ DWORD dwRop) 641 { 642 HANDLE_METADC(BOOL, 643 MaskBlt, 644 FALSE, 645 hdcDest, 646 xDest, 647 yDest, 648 cx, 649 cy, 650 hdcSrc, 651 xSrc, 652 ySrc, 653 hbmMask, 654 xMask, 655 yMask, 656 dwRop); 657 658 return NtGdiMaskBlt(hdcDest, 659 xDest, 660 yDest, 661 cx, 662 cy, 663 hdcSrc, 664 xSrc, 665 ySrc, 666 hbmMask, 667 xMask, 668 yMask, 669 dwRop, 670 GetBkColor(hdcSrc)); 671 } 672 673 674 /* 675 * @implemented 676 */ 677 BOOL 678 WINAPI 679 PlgBlt( 680 _In_ HDC hdcDest, 681 _In_reads_(3) const POINT * ppt, 682 _In_ HDC hdcSrc, 683 _In_ INT xSrc, 684 _In_ INT ySrc, 685 _In_ INT cx, 686 _In_ INT cy, 687 _In_opt_ HBITMAP hbmMask, 688 _In_ INT xMask, 689 _In_ INT yMask) 690 { 691 HANDLE_METADC(BOOL, 692 PlgBlt, 693 FALSE, 694 hdcDest, 695 ppt, 696 hdcSrc, 697 xSrc, 698 ySrc, 699 cx, 700 cy, 701 hbmMask, 702 xMask, 703 yMask); 704 705 return NtGdiPlgBlt(hdcDest, 706 (LPPOINT)ppt, 707 hdcSrc, 708 xSrc, 709 ySrc, 710 cx, 711 cy, 712 hbmMask, 713 xMask, 714 yMask, 715 GetBkColor(hdcSrc)); 716 } 717 718 BOOL 719 WINAPI 720 GdiAlphaBlend( 721 _In_ HDC hdcDst, 722 _In_ INT xDst, 723 _In_ INT yDst, 724 _In_ INT cxDst, 725 _In_ INT cyDst, 726 _In_ HDC hdcSrc, 727 _In_ INT xSrc, 728 _In_ INT ySrc, 729 _In_ INT cxSrc, 730 _In_ INT cySrc, 731 _In_ BLENDFUNCTION blendfn) 732 { 733 if (hdcSrc == NULL ) return FALSE; 734 735 if (GDI_HANDLE_GET_TYPE(hdcSrc) == GDI_OBJECT_TYPE_METADC) return FALSE; 736 737 HANDLE_METADC(BOOL, 738 AlphaBlend, 739 FALSE, 740 hdcDst, 741 xDst, 742 yDst, 743 cxDst, 744 cyDst, 745 hdcSrc, 746 xSrc, 747 ySrc, 748 cxSrc, 749 cySrc, 750 blendfn); 751 752 return NtGdiAlphaBlend(hdcDst, 753 xDst, 754 yDst, 755 cxDst, 756 cyDst, 757 hdcSrc, 758 xSrc, 759 ySrc, 760 cxSrc, 761 cySrc, 762 blendfn, 763 0); 764 } 765 766 767 /* 768 * @implemented 769 */ 770 BOOL 771 WINAPI 772 GdiTransparentBlt( 773 _In_ HDC hdcDst, 774 _In_ INT xDst, 775 _In_ INT yDst, 776 _In_ INT cxDst, 777 _In_ INT cyDst, 778 _In_ HDC hdcSrc, 779 _In_ INT xSrc, 780 _In_ INT ySrc, 781 _In_ INT cxSrc, 782 _In_ INT cySrc, 783 _In_ UINT crTransparent) 784 { 785 HANDLE_METADC(BOOL, 786 TransparentBlt, 787 FALSE, 788 hdcDst, 789 xDst, 790 yDst, 791 cxDst, 792 cyDst, 793 hdcSrc, 794 xSrc, 795 ySrc, 796 cxSrc, 797 cySrc, 798 crTransparent); 799 800 /* FIXME some part need be done in user mode */ 801 return NtGdiTransparentBlt(hdcDst, xDst, yDst, cxDst, cyDst, hdcSrc, xSrc, ySrc, cxSrc, cySrc, crTransparent); 802 } 803 804 /* 805 * @implemented 806 */ 807 BOOL 808 WINAPI 809 GdiGradientFill( 810 _In_ HDC hdc, 811 _In_reads_(nVertex) PTRIVERTEX pVertex, 812 _In_ ULONG nVertex, 813 _In_ PVOID pMesh, 814 _In_ ULONG nCount, 815 _In_ ULONG ulMode) 816 { 817 HANDLE_METADC(BOOL, GradientFill, FALSE, hdc, pVertex, nVertex, pMesh, nCount, ulMode); 818 819 /* FIXME some part need be done in user mode */ 820 return NtGdiGradientFill(hdc, pVertex, nVertex, pMesh, nCount, ulMode); 821 } 822