10 if (!(dc
= DC_LockDc(hdc
)))
12 EngSetLastError(ERROR_INVALID_HANDLE
);
15 return dc
->pdcattr
->lBkMode
;
19 GreGetMapMode(HDC hdc
)
22 if (!(dc
= DC_LockDc(hdc
)))
24 EngSetLastError(ERROR_INVALID_HANDLE
);
27 return dc
->pdcattr
->iMapMode
;
31 GreGetTextColor(HDC hdc
)
34 if (!(dc
= DC_LockDc(hdc
)))
36 EngSetLastError(ERROR_INVALID_HANDLE
);
39 return dc
->pdcattr
->ulForegroundClr
;
43 IntGdiSetBkColor(HDC hDC
, COLORREF color
)
50 if (!(dc
= DC_LockDc(hDC
)))
52 EngSetLastError(ERROR_INVALID_HANDLE
);
55 pdcattr
= dc
->pdcattr
;
56 oldColor
= pdcattr
->crBackgroundClr
;
57 pdcattr
->crBackgroundClr
= color
;
58 pdcattr
->ulBackgroundClr
= (ULONG
)color
;
59 pdcattr
->ulDirty_
|= DIRTY_BACKGROUND
|DIRTY_LINE
|DIRTY_FILL
; // Clear Flag if set.
60 hBrush
= pdcattr
->hbrush
;
62 NtGdiSelectBrush(hDC
, hBrush
);
67 IntGdiSetBkMode(HDC hDC
, INT Mode
)
73 if (!(dc
= DC_LockDc(hDC
)))
75 EngSetLastError(ERROR_INVALID_HANDLE
);
78 pdcattr
= dc
->pdcattr
;
79 oldMode
= pdcattr
->lBkMode
;
80 pdcattr
->jBkMode
= Mode
;
81 pdcattr
->lBkMode
= Mode
;
88 IntGdiSetTextAlign(HDC hDC
,
98 EngSetLastError(ERROR_INVALID_HANDLE
);
101 pdcattr
= dc
->pdcattr
;
102 prevAlign
= pdcattr
->lTextAlign
;
103 pdcattr
->lTextAlign
= Mode
;
110 IntGdiSetTextColor(HDC hDC
,
117 pdc
= DC_LockDc(hDC
);
120 EngSetLastError(ERROR_INVALID_HANDLE
);
123 pdcattr
= pdc
->pdcattr
;
125 // What about ulForegroundClr, like in gdi32?
126 crOldColor
= pdcattr
->crForegroundClr
;
127 pdcattr
->crForegroundClr
= color
;
128 DC_vUpdateTextBrush(pdc
);
136 IntSetDCBrushColor(HDC hdc
, COLORREF crColor
)
138 COLORREF OldColor
= CLR_INVALID
;
140 if (!(dc
= DC_LockDc(hdc
)))
142 EngSetLastError(ERROR_INVALID_HANDLE
);
147 OldColor
= (COLORREF
) dc
->pdcattr
->ulBrushClr
;
148 dc
->pdcattr
->ulBrushClr
= (ULONG
) crColor
;
150 if ( dc
->pdcattr
->crBrushClr
!= crColor
)
152 dc
->pdcattr
->ulDirty_
|= DIRTY_FILL
;
153 dc
->pdcattr
->crBrushClr
= crColor
;
160 IntSetDCPenColor(HDC hdc
, COLORREF crColor
)
164 if (!(dc
= DC_LockDc(hdc
)))
166 EngSetLastError(ERROR_INVALID_PARAMETER
);
170 OldColor
= (COLORREF
)dc
->pdcattr
->ulPenClr
;
171 dc
->pdcattr
->ulPenClr
= (ULONG
)crColor
;
173 if (dc
->pdcattr
->crPenClr
!= crColor
)
175 dc
->pdcattr
->ulDirty_
|= DIRTY_LINE
;
176 dc
->pdcattr
->crPenClr
= crColor
;
184 GreSetStretchBltMode(HDC hDC
, int iStretchMode
)
190 pdc
= DC_LockDc(hDC
);
193 pdcattr
= pdc
->pdcattr
;
194 oSMode
= pdcattr
->lStretchBltMode
;
195 pdcattr
->lStretchBltMode
= iStretchMode
;
197 // Wine returns an error here. We set the default.
198 if ((iStretchMode
<= 0) || (iStretchMode
> MAXSTRETCHBLTMODE
)) iStretchMode
= WHITEONBLACK
;
200 pdcattr
->jStretchBltMode
= iStretchMode
;
207 DCU_SetDcUndeletable(HDC hDC
)
209 PDC dc
= DC_LockDc(hDC
);
212 EngSetLastError(ERROR_INVALID_HANDLE
);
216 dc
->fs
|= DC_FLAG_PERMANENT
;
223 IntIsPrimarySurface(SURFOBJ
*SurfObj
)
225 if (PrimarySurface
.pSurface
== NULL
)
229 return SurfObj
->hsurf
== PrimarySurface
.pSurface
; // <- FIXME: WTF?
235 IntSetDefaultRegion(PDC pdc
)
239 RECTL rclWnd
, rclClip
;
241 IntGdiReleaseRaoRgn(pdc
);
245 rclWnd
.right
= pdc
->dclevel
.sizl
.cx
;
246 rclWnd
.bottom
= pdc
->dclevel
.sizl
.cy
;
249 //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
250 if (pdc
->ppdev
->flFlags
& PDEV_META_DEVICE
)
252 pSurface
= pdc
->dclevel
.pSurface
;
253 if (pSurface
&& pSurface
->flags
& PDEV_SURFACE
)
255 rclClip
.left
+= pdc
->ppdev
->ptlOrigion
.x
;
256 rclClip
.top
+= pdc
->ppdev
->ptlOrigion
.y
;
257 rclClip
.right
+= pdc
->ppdev
->ptlOrigion
.x
;
258 rclClip
.bottom
+= pdc
->ppdev
->ptlOrigion
.y
;
261 //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
265 if (prgn
&& prgn
!= prgnDefault
)
267 REGION_SetRectRgn( prgn
,
275 prgn
= IntSysCreateRectpRgn( rclClip
.left
,
284 pdc
->ptlDCOrig
.x
= 0;
285 pdc
->ptlDCOrig
.y
= 0;
286 pdc
->erclWindow
= rclWnd
;
287 pdc
->erclClip
= rclClip
;
288 /* Might be an InitDC or DCE... */
289 pdc
->ptlFillOrigin
.x
= pdc
->dcattr
.VisRectRegion
.Rect
.right
;
290 pdc
->ptlFillOrigin
.y
= pdc
->dcattr
.VisRectRegion
.Rect
.bottom
;
294 pdc
->prgnVis
= prgnDefault
;
300 NtGdiCancelDC(HDC hDC
)
308 IntGdiSetHookFlags(HDC hDC
, WORD Flags
)
311 DC
*dc
= DC_LockDc(hDC
);
315 EngSetLastError(ERROR_INVALID_HANDLE
);
319 wRet
= dc
->fs
& DC_FLAG_DIRTY_RAO
; // FIXME: Wrong flag!
321 /* Info in "Undocumented Windows" is slightly confusing. */
322 DPRINT("DC %p, Flags %04x\n", hDC
, Flags
);
324 if (Flags
& DCHF_INVALIDATEVISRGN
)
326 /* hVisRgn has to be updated */
327 dc
->fs
|= DC_FLAG_DIRTY_RAO
;
329 else if (Flags
& DCHF_VALIDATEVISRGN
|| 0 == Flags
)
331 dc
->fs
&= ~DC_FLAG_DIRTY_RAO
;
351 DWORD SafeResult
= 0;
352 NTSTATUS Status
= STATUS_SUCCESS
;
356 EngSetLastError(ERROR_INVALID_PARAMETER
);
360 pdc
= DC_LockDc(hDC
);
363 EngSetLastError(ERROR_INVALID_HANDLE
);
366 pdcattr
= pdc
->pdcattr
;
374 SafeResult
= pdcattr
->lRelAbs
;
377 case GdiGetBreakExtra
:
378 SafeResult
= pdcattr
->lBreakExtra
;
381 case GdiGerCharBreak
:
382 SafeResult
= pdcattr
->cBreak
;
385 case GdiGetArcDirection
:
386 if (pdcattr
->dwLayout
& LAYOUT_RTL
)
387 SafeResult
= AD_CLOCKWISE
- ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0);
389 SafeResult
= ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0) + AD_COUNTERCLOCKWISE
;
392 case GdiGetEMFRestorDc
:
395 case GdiGetFontLanguageInfo
:
396 SafeResult
= IntGetFontLanguageInfo(pdc
);
400 SafeResult
= pdc
->dctype
;
404 SafeResult
= pdcattr
->iMapMode
;
407 case GdiGetTextCharExtra
:
408 SafeResult
= pdcattr
->lTextExtra
;
412 EngSetLastError(ERROR_INVALID_PARAMETER
);
421 ProbeForWrite(Result
, sizeof(DWORD
), 1);
422 *Result
= SafeResult
;
424 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
426 Status
= _SEH2_GetExceptionCode();
430 if (!NT_SUCCESS(Status
))
432 SetLastNtError(Status
);
441 _Success_(return != FALSE
)
444 NtGdiGetAndSetDCDword(
448 _Out_ DWORD
*pdwResult
)
454 DWORD SafeResult
= 0;
455 NTSTATUS Status
= STATUS_SUCCESS
;
459 EngSetLastError(ERROR_INVALID_PARAMETER
);
463 pdc
= DC_LockDc(hdc
);
466 EngSetLastError(ERROR_INVALID_HANDLE
);
469 pdcattr
= pdc
->pdcattr
;
473 case GdiGetSetCopyCount
:
474 SafeResult
= pdc
->ulCopyCount
;
475 pdc
->ulCopyCount
= dwIn
;
478 case GdiGetSetTextAlign
:
479 SafeResult
= pdcattr
->lTextAlign
;
480 pdcattr
->lTextAlign
= dwIn
;
481 // pdcattr->flTextAlign = dwIn; // Flags!
484 case GdiGetSetRelAbs
:
485 SafeResult
= pdcattr
->lRelAbs
;
486 pdcattr
->lRelAbs
= dwIn
;
489 case GdiGetSetTextCharExtra
:
490 SafeResult
= pdcattr
->lTextExtra
;
491 pdcattr
->lTextExtra
= dwIn
;
494 case GdiGetSetSelectFont
:
497 case GdiGetSetMapperFlagsInternal
:
500 EngSetLastError(ERROR_INVALID_PARAMETER
);
504 SafeResult
= pdcattr
->flFontMapper
;
505 pdcattr
->flFontMapper
= dwIn
;
508 case GdiGetSetMapMode
:
509 SafeResult
= IntGdiSetMapMode(pdc
, dwIn
);
512 case GdiGetSetArcDirection
:
513 if (dwIn
!= AD_COUNTERCLOCKWISE
&& dwIn
!= AD_CLOCKWISE
)
515 EngSetLastError(ERROR_INVALID_PARAMETER
);
519 if (pdcattr
->dwLayout
& LAYOUT_RTL
) // Right to Left
521 SafeResult
= AD_CLOCKWISE
- ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0);
522 if (dwIn
== AD_CLOCKWISE
)
524 pdc
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
;
527 pdc
->dclevel
.flPath
|= DCPATH_CLOCKWISE
;
529 else // Left to Right
531 SafeResult
= ((pdc
->dclevel
.flPath
& DCPATH_CLOCKWISE
) != 0) +
533 if (dwIn
== AD_COUNTERCLOCKWISE
)
535 pdc
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
;
538 pdc
->dclevel
.flPath
|= DCPATH_CLOCKWISE
;
543 EngSetLastError(ERROR_INVALID_PARAMETER
);
552 ProbeForWrite(pdwResult
, sizeof(DWORD
), 1);
553 *pdwResult
= SafeResult
;
555 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
557 Status
= _SEH2_GetExceptionCode();
561 if (!NT_SUCCESS(Status
))
563 SetLastNtError(Status
);
583 if (!(pdc
= DC_LockDc(hdc
))) return 0;
585 /* Get the return value */
586 ret
= pdc
->fs
& DC_ACCUM_APP
? DCB_ENABLE
: DCB_DISABLE
;
587 ret
|= RECTL_bIsEmptyRect(&pdc
->erclBoundsApp
) ? DCB_RESET
: DCB_SET
;
589 /* Copy the rect to the caller */
592 ProbeForWrite(prc
, sizeof(RECT
), 1);
593 *prc
= pdc
->erclBoundsApp
;
595 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
601 if (flags
& DCB_RESET
)
603 RECTL_vSetEmptyRect(&pdc
->erclBoundsApp
);
622 /* Verify arguments */
623 if ((flags
& DCB_ENABLE
) && (flags
& DCB_DISABLE
)) return 0;
626 if (!(pdc
= DC_LockDc(hdc
))) return 0;
628 /* Get the return value */
629 ret
= pdc
->fs
& DC_ACCUM_APP
? DCB_ENABLE
: DCB_DISABLE
;
630 ret
|= RECTL_bIsEmptyRect(&pdc
->erclBoundsApp
) ? DCB_RESET
: DCB_SET
;
632 if (flags
& DCB_RESET
)
634 RECTL_vSetEmptyRect(&pdc
->erclBoundsApp
);
637 if (flags
& DCB_ACCUMULATE
)
639 /* Capture the rect */
642 ProbeForRead(prc
, sizeof(RECT
), 1);
645 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
648 _SEH2_YIELD(return 0;)
652 RECTL_vMakeWellOrdered(&rcl
);
653 RECTL_bUnionRect(&pdc
->erclBoundsApp
, &pdc
->erclBoundsApp
, &rcl
);
656 if (flags
& DCB_ENABLE
) pdc
->fs
|= DC_ACCUM_APP
;
657 if (flags
& DCB_DISABLE
) pdc
->fs
&= ~DC_ACCUM_APP
;
662 /* Translates a COLORREF to the right color in the specified DC color space */
664 TranslateCOLORREF(PDC pdc
, COLORREF crColor
)
668 ULONG index
, ulColor
, iBitmapFormat
;
671 /* Get the DC surface */
672 psurfDC
= pdc
->dclevel
.pSurface
;
674 /* If no surface is selected, use the default bitmap */
676 psurfDC
= psurfDefaultBitmap
;
678 /* Check what color type this is */
679 switch (crColor
>> 24)
681 case 0x00: /* RGB color */
684 case 0x01: /* PALETTEINDEX */
685 index
= crColor
& 0xFFFFFF;
686 ppalDC
= pdc
->dclevel
.ppal
;
687 if (index
>= ppalDC
->NumColors
) index
= 0;
689 /* Get the RGB value */
690 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, index
);
693 case 0x02: /* PALETTERGB */
695 if (pdc
->dclevel
.hpal
!= StockObjects
[DEFAULT_PALETTE
])
697 /* First find the nearest index in the dc palette */
698 ppalDC
= pdc
->dclevel
.ppal
;
699 index
= PALETTE_ulGetNearestIndex(ppalDC
, crColor
& 0xFFFFFF);
701 /* Get the RGB value */
702 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, index
);
706 /* Use the pure color */
707 crColor
= crColor
& 0x00FFFFFF;
711 case 0x10: /* DIBINDEX */
712 /* Mask the value to match the target bpp */
713 iBitmapFormat
= psurfDC
->SurfObj
.iBitmapFormat
;
714 if (iBitmapFormat
== BMF_1BPP
) index
= crColor
& 0x1;
715 else if (iBitmapFormat
== BMF_4BPP
) index
= crColor
& 0xf;
716 else if (iBitmapFormat
== BMF_8BPP
) index
= crColor
& 0xFF;
717 else if (iBitmapFormat
== BMF_16BPP
) index
= crColor
& 0xFFFF;
718 else index
= crColor
& 0xFFFFFF;
722 DPRINT("Unsupported color type %u passed\n", crColor
>> 24);
726 /* Initialize an XLATEOBJ from RGB to the target surface */
727 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, psurfDC
->ppal
, 0xFFFFFF, 0, 0);
729 /* Translate the color to the target format */
730 ulColor
= XLATEOBJ_iXlate(&exlo
.xlo
, crColor
);
732 /* Cleanup the XLATEOBJ */
733 EXLATEOBJ_vCleanup(&exlo
);