7 GreDPtoLP(HDC hdc
, LPPOINT lpPoints
, INT nCount
)
10 if (!(dc
= DC_LockDc(hdc
)))
12 EngSetLastError(ERROR_INVALID_HANDLE
);
15 IntDPtoLP(dc
, lpPoints
, nCount
);
21 GreLPtoDP(HDC hdc
, LPPOINT lpPoints
, INT nCount
)
24 if (!(dc
= DC_LockDc(hdc
)))
26 EngSetLastError(ERROR_INVALID_HANDLE
);
29 IntLPtoDP(dc
, lpPoints
, nCount
);
39 if (!(dc
= DC_LockDc(hdc
)))
41 EngSetLastError(ERROR_INVALID_HANDLE
);
44 lBkMode
= dc
->pdcattr
->lBkMode
;
50 GreGetBkColor(HDC hdc
)
54 if (!(dc
= DC_LockDc(hdc
)))
56 EngSetLastError(ERROR_INVALID_HANDLE
);
59 crBk
= dc
->pdcattr
->ulBackgroundClr
;
65 GreGetMapMode(HDC hdc
)
69 if (!(dc
= DC_LockDc(hdc
)))
71 EngSetLastError(ERROR_INVALID_HANDLE
);
74 iMapMode
= dc
->pdcattr
->iMapMode
;
80 GreGetTextColor(HDC hdc
)
83 ULONG ulForegroundClr
;
84 if (!(dc
= DC_LockDc(hdc
)))
86 EngSetLastError(ERROR_INVALID_HANDLE
);
89 ulForegroundClr
= dc
->pdcattr
->ulForegroundClr
;
91 return ulForegroundClr
;
95 IntGdiSetBkColor(HDC hDC
, COLORREF color
)
102 if (!(dc
= DC_LockDc(hDC
)))
104 EngSetLastError(ERROR_INVALID_HANDLE
);
107 pdcattr
= dc
->pdcattr
;
109 oldColor
= pdcattr
->ulBackgroundClr
;
110 pdcattr
->ulBackgroundClr
= color
;
112 if (pdcattr
->crBackgroundClr
!= color
)
114 pdcattr
->ulDirty_
|= (DIRTY_BACKGROUND
|DIRTY_LINE
|DIRTY_FILL
); // Clear Flag if set.
115 pdcattr
->crBackgroundClr
= color
;
117 hBrush
= pdcattr
->hbrush
;
119 NtGdiSelectBrush(hDC
, hBrush
);
124 IntGdiSetBkMode(HDC hDC
, INT Mode
)
130 if (!(dc
= DC_LockDc(hDC
)))
132 EngSetLastError(ERROR_INVALID_HANDLE
);
135 pdcattr
= dc
->pdcattr
;
136 oldMode
= pdcattr
->lBkMode
;
137 pdcattr
->jBkMode
= Mode
;
138 pdcattr
->lBkMode
= Mode
;
145 IntGdiSetTextAlign(HDC hDC
,
155 EngSetLastError(ERROR_INVALID_HANDLE
);
158 pdcattr
= dc
->pdcattr
;
159 prevAlign
= pdcattr
->lTextAlign
;
160 pdcattr
->lTextAlign
= Mode
;
161 if (pdcattr
->dwLayout
& LAYOUT_RTL
)
163 if ((Mode
& TA_CENTER
) != TA_CENTER
) Mode
^= TA_RIGHT
;
165 pdcattr
->flTextAlign
= Mode
& TA_MASK
;
172 IntGdiSetTextColor(HDC hDC
,
179 pdc
= DC_LockDc(hDC
);
182 EngSetLastError(ERROR_INVALID_HANDLE
);
185 pdcattr
= pdc
->pdcattr
;
187 crOldColor
= (COLORREF
) pdcattr
->ulForegroundClr
;
188 pdcattr
->ulForegroundClr
= (ULONG
)color
;
190 if (pdcattr
->crForegroundClr
!= color
)
192 pdcattr
->ulDirty_
|= (DIRTY_TEXT
|DIRTY_LINE
|DIRTY_FILL
);
193 pdcattr
->crForegroundClr
= color
;
196 DC_vUpdateTextBrush(pdc
);
197 DC_vUpdateLineBrush(pdc
);
198 DC_vUpdateFillBrush(pdc
);
206 IntSetDCBrushColor(HDC hdc
, COLORREF crColor
)
208 COLORREF OldColor
= CLR_INVALID
;
210 if (!(dc
= DC_LockDc(hdc
)))
212 EngSetLastError(ERROR_INVALID_HANDLE
);
217 OldColor
= (COLORREF
) dc
->pdcattr
->ulBrushClr
;
218 dc
->pdcattr
->ulBrushClr
= (ULONG
) crColor
;
220 if ( dc
->pdcattr
->crBrushClr
!= crColor
)
222 dc
->pdcattr
->ulDirty_
|= DIRTY_FILL
;
223 dc
->pdcattr
->crBrushClr
= crColor
;
237 PDC pdc
= DC_LockDc(hdc
);
240 EngSetLastError(ERROR_INVALID_HANDLE
);
246 *pptOut
= pdc
->pdcattr
->ptlBrushOrigin
;
249 pdc
->pdcattr
->ptlBrushOrigin
.x
= x
;
250 pdc
->pdcattr
->ptlBrushOrigin
.y
= y
;
252 DC_vSetBrushOrigin(pdc
, x
, y
);
259 IntSetDCPenColor(HDC hdc
, COLORREF crColor
)
263 if (!(dc
= DC_LockDc(hdc
)))
265 EngSetLastError(ERROR_INVALID_PARAMETER
);
269 OldColor
= (COLORREF
)dc
->pdcattr
->ulPenClr
;
270 dc
->pdcattr
->ulPenClr
= (ULONG
)crColor
;
272 if (dc
->pdcattr
->crPenClr
!= crColor
)
274 dc
->pdcattr
->ulDirty_
|= DIRTY_LINE
;
275 dc
->pdcattr
->crPenClr
= crColor
;
283 GreSetStretchBltMode(HDC hDC
, int iStretchMode
)
289 pdc
= DC_LockDc(hDC
);
292 pdcattr
= pdc
->pdcattr
;
293 oSMode
= pdcattr
->lStretchBltMode
;
294 pdcattr
->lStretchBltMode
= iStretchMode
;
296 // Wine returns an error here. We set the default.
297 if ((iStretchMode
<= 0) || (iStretchMode
> MAXSTRETCHBLTMODE
)) iStretchMode
= WHITEONBLACK
;
299 pdcattr
->jStretchBltMode
= iStretchMode
;
306 GreGetGraphicsMode(HDC hdc
)
310 if (!(dc
= DC_LockDc(hdc
)))
312 EngSetLastError(ERROR_INVALID_HANDLE
);
315 GraphicsMode
= dc
->pdcattr
->iGraphicsMode
;
322 DCU_SetDcUndeletable(HDC hDC
)
324 PDC dc
= DC_LockDc(hDC
);
327 EngSetLastError(ERROR_INVALID_HANDLE
);
331 dc
->fs
|= DC_FLAG_PERMANENT
;
338 IntIsPrimarySurface(SURFOBJ
*SurfObj
)
340 if (PrimarySurface
.pSurface
== NULL
)
344 return SurfObj
->hsurf
== PrimarySurface
.pSurface
; // <- FIXME: WTF?
350 IntSetDefaultRegion(PDC pdc
)
354 RECTL rclWnd
, rclClip
;
356 IntGdiReleaseRaoRgn(pdc
);
360 rclWnd
.right
= pdc
->dclevel
.sizl
.cx
;
361 rclWnd
.bottom
= pdc
->dclevel
.sizl
.cy
;
364 //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
365 if (pdc
->ppdev
->flFlags
& PDEV_META_DEVICE
)
367 pSurface
= pdc
->dclevel
.pSurface
;
368 if (pSurface
&& pSurface
->flags
& PDEV_SURFACE
)
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
;
376 //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
380 if (prgn
&& prgn
!= prgnDefault
)
382 REGION_SetRectRgn( prgn
,
390 prgn
= IntSysCreateRectpRgn( rclClip
.left
,
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
.x
= pdc
->dcattr
.ptlBrushOrigin
.x
;
405 pdc
->ptlFillOrigin
.y
= pdc
->dcattr
.ptlBrushOrigin
.y
;
409 pdc
->prgnVis
= prgnDefault
;
415 NtGdiCancelDC(HDC hDC
)
423 IntGdiSetHookFlags(HDC hDC
, WORD Flags
)
426 DC
*dc
= DC_LockDc(hDC
);
430 EngSetLastError(ERROR_INVALID_HANDLE
);
434 wRet
= dc
->fs
& DC_FLAG_DIRTY_RAO
; // FIXME: Wrong flag!
436 /* Info in "Undocumented Windows" is slightly confusing. */
437 DPRINT("DC %p, Flags %04x\n", hDC
, Flags
);
439 if (Flags
& DCHF_INVALIDATEVISRGN
)
441 /* hVisRgn has to be updated */
442 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
444 else if (Flags
& DCHF_VALIDATEVISRGN
|| 0 == Flags
)
446 //dc->fs &= ~DC_FLAG_DIRTY_RAO;
466 DWORD SafeResult
= 0;
467 NTSTATUS Status
= STATUS_SUCCESS
;
471 EngSetLastError(ERROR_INVALID_PARAMETER
);
475 pdc
= DC_LockDc(hDC
);
478 EngSetLastError(ERROR_INVALID_HANDLE
);
481 pdcattr
= pdc
->pdcattr
;
489 SafeResult
= pdcattr
->lRelAbs
;
492 case GdiGetBreakExtra
:
493 SafeResult
= pdcattr
->lBreakExtra
;
496 case GdiGerCharBreak
:
497 SafeResult
= pdcattr
->cBreak
;
500 case GdiGetArcDirection
:
501 if (pdcattr
->dwLayout
& LAYOUT_RTL
)
502 SafeResult
= AD_CLOCKWISE
- ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0);
504 SafeResult
= ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0) + AD_COUNTERCLOCKWISE
;
507 case GdiGetEMFRestorDc
:
508 SafeResult
= pdc
->dclevel
.lSaveDepth
;
511 case GdiGetFontLanguageInfo
:
512 SafeResult
= IntGetFontLanguageInfo(pdc
);
516 SafeResult
= pdc
->dctype
;
520 SafeResult
= pdcattr
->iMapMode
;
523 case GdiGetTextCharExtra
:
524 SafeResult
= pdcattr
->lTextExtra
;
528 EngSetLastError(ERROR_INVALID_PARAMETER
);
537 ProbeForWrite(Result
, sizeof(DWORD
), 1);
538 *Result
= SafeResult
;
540 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
542 Status
= _SEH2_GetExceptionCode();
546 if (!NT_SUCCESS(Status
))
548 SetLastNtError(Status
);
557 _Success_(return != FALSE
)
560 NtGdiGetAndSetDCDword(
564 _Out_ DWORD
*pdwResult
)
570 DWORD SafeResult
= 0;
571 NTSTATUS Status
= STATUS_SUCCESS
;
575 EngSetLastError(ERROR_INVALID_PARAMETER
);
579 pdc
= DC_LockDc(hdc
);
582 EngSetLastError(ERROR_INVALID_HANDLE
);
585 pdcattr
= pdc
->pdcattr
;
589 case GdiGetSetCopyCount
:
590 SafeResult
= pdc
->ulCopyCount
;
591 pdc
->ulCopyCount
= dwIn
;
594 case GdiGetSetTextAlign
:
595 SafeResult
= pdcattr
->lTextAlign
;
596 pdcattr
->lTextAlign
= dwIn
;
597 // pdcattr->flTextAlign = dwIn; // Flags!
600 case GdiGetSetRelAbs
:
601 SafeResult
= pdcattr
->lRelAbs
;
602 pdcattr
->lRelAbs
= dwIn
;
605 case GdiGetSetTextCharExtra
:
606 SafeResult
= pdcattr
->lTextExtra
;
607 pdcattr
->lTextExtra
= dwIn
;
610 case GdiGetSetSelectFont
:
613 case GdiGetSetMapperFlagsInternal
:
616 EngSetLastError(ERROR_INVALID_PARAMETER
);
620 SafeResult
= pdcattr
->flFontMapper
;
621 pdcattr
->flFontMapper
= dwIn
;
624 case GdiGetSetMapMode
:
625 SafeResult
= IntGdiSetMapMode(pdc
, dwIn
);
628 case GdiGetSetArcDirection
:
629 if (dwIn
!= AD_COUNTERCLOCKWISE
&& dwIn
!= AD_CLOCKWISE
)
631 EngSetLastError(ERROR_INVALID_PARAMETER
);
635 if (pdcattr
->dwLayout
& LAYOUT_RTL
) // Right to Left
637 SafeResult
= AD_CLOCKWISE
- ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0);
638 if (dwIn
== AD_CLOCKWISE
)
640 pdc
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
;
643 pdc
->dclevel
.flPath
|= DCPATH_CLOCKWISE
;
645 else // Left to Right
647 SafeResult
= ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0) +
649 if (dwIn
== AD_COUNTERCLOCKWISE
)
651 pdc
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
;
654 pdc
->dclevel
.flPath
|= DCPATH_CLOCKWISE
;
659 EngSetLastError(ERROR_INVALID_PARAMETER
);
668 ProbeForWrite(pdwResult
, sizeof(DWORD
), 1);
669 *pdwResult
= SafeResult
;
671 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
673 Status
= _SEH2_GetExceptionCode();
677 if (!NT_SUCCESS(Status
))
679 SetLastNtError(Status
);
690 IntUpdateBoundsRect(PDC pdc
, PRECTL pRect
)
692 if (pdc
->fs
& DC_ACCUM_APP
)
694 RECTL_bUnionRect(&pdc
->erclBoundsApp
, &pdc
->erclBoundsApp
, pRect
);
696 if (pdc
->fs
& DC_ACCUM_WMGR
)
698 RECTL_bUnionRect(&pdc
->erclBounds
, &pdc
->erclBounds
, pRect
);
714 if (!(pdc
= DC_LockDc(hdc
))) return 0;
716 if (!(flags
& DCB_WINDOWMGR
))
718 rc
= pdc
->erclBoundsApp
;
720 if (RECTL_bIsEmptyRect(&rc
))
722 rc
.left
= rc
.top
= rc
.right
= rc
.bottom
= 0;
728 if (pdc
->fs
& DC_FLAG_DIRTY_RAO
) CLIPPING_UpdateGCRegion(pdc
);
729 if(!REGION_GetRgnBox(pdc
->prgnRao
, &rcRgn
))
731 REGION_GetRgnBox(pdc
->prgnVis
, &rcRgn
);
733 rc
.left
= max( rc
.left
, 0 );
734 rc
.top
= max( rc
.top
, 0 );
735 rc
.right
= min( rc
.right
, rcRgn
.right
- rcRgn
.left
);
736 rc
.bottom
= min( rc
.bottom
, rcRgn
.bottom
- rcRgn
.top
);
737 DPRINT("Rao dc %p r %d b %d\n",pdc
,rcRgn
.right
- rcRgn
.left
, rcRgn
.bottom
- rcRgn
.top
);
738 DPRINT("rc l %d t %d\n",rc
.left
,rc
.top
);
739 DPRINT(" r %d b %d\n",rc
.right
,rc
.bottom
);
742 IntDPtoLP( pdc
, &rc
, 2 );
743 DPRINT("rc1 l %d t %d\n",rc
.left
,rc
.top
);
744 DPRINT(" r %d b %d\n",rc
.right
,rc
.bottom
);
748 rc
= pdc
->erclBounds
;
752 /* Copy the rect to the caller */
755 ProbeForWrite(prc
, sizeof(RECT
), 1);
758 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
764 if (flags
& DCB_RESET
)
766 if (!(flags
& DCB_WINDOWMGR
))
768 pdc
->erclBoundsApp
.left
= pdc
->erclBoundsApp
.top
= INT_MAX
;
769 pdc
->erclBoundsApp
.right
= pdc
->erclBoundsApp
.bottom
= INT_MIN
;
773 pdc
->erclBounds
.left
= pdc
->erclBounds
.top
= INT_MAX
;
774 pdc
->erclBounds
.right
= pdc
->erclBounds
.bottom
= INT_MIN
;
793 /* Verify arguments */
794 if ((flags
& DCB_ENABLE
) && (flags
& DCB_DISABLE
)) return 0;
797 if (!(pdc
= DC_LockDc(hdc
))) return 0;
799 /* Get the return value */
800 ret
= DCB_RESET
; /* we don't have device-specific bounds */
801 ret
= (pdc
->fs
& (DC_ACCUM_APP
|DC_ACCUM_WMGR
) ? DCB_ENABLE
: DCB_DISABLE
) |
802 (RECTL_bIsEmptyRect(&pdc
->erclBoundsApp
) ? ret
& DCB_SET
: DCB_SET
);
803 ret
|= (flags
& DCB_WINDOWMGR
);
805 if (flags
& DCB_RESET
)
807 if (!(flags
& DCB_WINDOWMGR
))
809 pdc
->erclBoundsApp
.left
= pdc
->erclBoundsApp
.top
= INT_MAX
;
810 pdc
->erclBoundsApp
.right
= pdc
->erclBoundsApp
.bottom
= INT_MIN
;
814 pdc
->erclBounds
.left
= pdc
->erclBounds
.top
= INT_MAX
;
815 pdc
->erclBounds
.right
= pdc
->erclBounds
.bottom
= INT_MIN
;
819 if (flags
& DCB_ACCUMULATE
&& prc
!= NULL
)
821 /* Capture the rect */
824 ProbeForRead(prc
, sizeof(RECT
), 1);
827 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
830 _SEH2_YIELD(return 0;)
834 RECTL_vMakeWellOrdered(&rcl
);
836 if (!(flags
& DCB_WINDOWMGR
))
838 IntLPtoDP( pdc
, (POINT
*)&rcl
, 2 );
839 RECTL_bUnionRect(&pdc
->erclBoundsApp
, &pdc
->erclBoundsApp
, &rcl
);
842 RECTL_bUnionRect(&pdc
->erclBounds
, &pdc
->erclBounds
, &rcl
);
845 if (flags
& DCB_ENABLE
)
847 if (!(flags
& DCB_WINDOWMGR
))
848 pdc
->fs
|= DC_ACCUM_APP
;
850 pdc
->fs
|= DC_ACCUM_WMGR
;
852 if (flags
& DCB_DISABLE
)
854 if (!(flags
& DCB_WINDOWMGR
))
855 pdc
->fs
&= ~DC_ACCUM_APP
;
857 pdc
->fs
&= ~DC_ACCUM_WMGR
;
863 /* Translates a COLORREF to the right color in the specified DC color space */
865 TranslateCOLORREF(PDC pdc
, COLORREF crColor
)
869 ULONG index
, ulColor
, iBitmapFormat
;
872 /* Get the DC surface */
873 psurfDC
= pdc
->dclevel
.pSurface
;
875 /* If no surface is selected, use the default bitmap */
877 psurfDC
= psurfDefaultBitmap
;
879 /* Check what color type this is */
880 switch (crColor
>> 24)
882 case 0x00: /* RGB color */
885 case 0x01: /* PALETTEINDEX */
886 index
= crColor
& 0xFFFFFF;
887 ppalDC
= pdc
->dclevel
.ppal
;
888 if (index
>= ppalDC
->NumColors
) index
= 0;
890 /* Get the RGB value */
891 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, index
);
894 case 0x02: /* PALETTERGB */
896 if (pdc
->dclevel
.hpal
!= StockObjects
[DEFAULT_PALETTE
])
898 /* First find the nearest index in the dc palette */
899 ppalDC
= pdc
->dclevel
.ppal
;
900 index
= PALETTE_ulGetNearestIndex(ppalDC
, crColor
& 0xFFFFFF);
902 /* Get the RGB value */
903 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, index
);
907 /* Use the pure color */
908 crColor
= crColor
& 0x00FFFFFF;
912 case 0x10: /* DIBINDEX */
913 /* Mask the value to match the target bpp */
914 iBitmapFormat
= psurfDC
->SurfObj
.iBitmapFormat
;
915 if (iBitmapFormat
== BMF_1BPP
) index
= crColor
& 0x1;
916 else if (iBitmapFormat
== BMF_4BPP
) index
= crColor
& 0xf;
917 else if (iBitmapFormat
== BMF_8BPP
) index
= crColor
& 0xFF;
918 else if (iBitmapFormat
== BMF_16BPP
) index
= crColor
& 0xFFFF;
919 else index
= crColor
& 0xFFFFFF;
923 DPRINT("Unsupported color type %u passed\n", crColor
>> 24);
927 /* Initialize an XLATEOBJ from RGB to the target surface */
928 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, psurfDC
->ppal
, 0xFFFFFF, 0, 0);
930 /* Translate the color to the target format */
931 ulColor
= XLATEOBJ_iXlate(&exlo
.xlo
, crColor
);
933 /* Cleanup the XLATEOBJ */
934 EXLATEOBJ_vCleanup(&exlo
);