2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Functions for creation and destruction of DCs
5 * FILE: subsystem/win32/win32k/objects/dcobjs.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
17 DC_vUpdateFillBrush(PDC pdc
)
19 PDC_ATTR pdcattr
= pdc
->pdcattr
;
24 /* ROS HACK, should use surf xlate */
25 pxlo
= pdc
->rosdc
.XlatePen
;
27 /* Check if the brush handle has changed */
28 if (pdcattr
->hbrush
!= pdc
->dclevel
.pbrFill
->BaseObject
.hHmgr
)
30 /* Try to lock the new brush */
31 pbrFill
= BRUSH_ShareLockBrush(pdcattr
->hbrush
);
34 /* Unlock old brush, set new brush */
35 BRUSH_ShareUnlockBrush(pdc
->dclevel
.pbrFill
);
36 pdc
->dclevel
.pbrFill
= pbrFill
;
38 /* Update eboFill, realizing it, if needed */
39 EBRUSHOBJ_vUpdate(&pdc
->eboFill
, pbrFill
, pxlo
);
43 /* Invalid brush handle, restore old one */
44 pdcattr
->hbrush
= pdc
->dclevel
.pbrFill
->BaseObject
.hHmgr
;
48 /* Check for DC brush */
49 if (pdcattr
->hbrush
== StockObjects
[DC_BRUSH
])
51 /* Translate the color to the target format */
52 iSolidColor
= XLATEOBJ_iXlate(pxlo
, pdcattr
->crPenClr
);
54 /* Update the eboFill's solid color */
55 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboFill
, iSolidColor
);
59 pdcattr
->ulDirty_
&= ~(DIRTY_FILL
| DC_BRUSH_DIRTY
);
64 DC_vUpdateLineBrush(PDC pdc
)
66 PDC_ATTR pdcattr
= pdc
->pdcattr
;
71 /* ROS HACK, should use surf xlate */
72 pxlo
= pdc
->rosdc
.XlatePen
;
74 /* Check if the pen handle has changed */
75 if (pdcattr
->hpen
!= pdc
->dclevel
.pbrLine
->BaseObject
.hHmgr
)
77 /* Try to lock the new pen */
78 pbrLine
= BRUSH_ShareLockBrush(pdcattr
->hpen
);
81 /* Unlock old brush, set new brush */
82 BRUSH_ShareUnlockBrush(pdc
->dclevel
.pbrLine
);
83 pdc
->dclevel
.pbrLine
= pbrLine
;
85 /* Update eboLine, realizing it, if needed */
86 EBRUSHOBJ_vUpdate(&pdc
->eboLine
, pbrLine
, pxlo
);
90 /* Invalid pen handle, restore old one */
91 pdcattr
->hpen
= pdc
->dclevel
.pbrLine
->BaseObject
.hHmgr
;
95 /* Check for DC pen */
96 if (pdcattr
->hpen
== StockObjects
[DC_PEN
])
98 /* Translate the color to the target format */
99 iSolidColor
= XLATEOBJ_iXlate(pxlo
, pdcattr
->crPenClr
);
101 /* Update the eboLine's solid color */
102 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboLine
, iSolidColor
);
106 pdcattr
->ulDirty_
&= ~DIRTY_LINE
;
111 DC_vUpdateTextBrush(PDC pdc
)
113 PDC_ATTR pdcattr
= pdc
->pdcattr
;
117 /* ROS HACK, should use surf xlate */
118 pxlo
= pdc
->rosdc
.XlatePen
;
120 /* Translate the color to the target format */
121 iSolidColor
= XLATEOBJ_iXlate(pxlo
, pdcattr
->crForegroundClr
);
123 /* Update the eboText's solid color */
124 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboText
, iSolidColor
);
127 pdcattr
->ulDirty_
&= ~DIRTY_TEXT
;
132 DC_vUpdateBackgroundBrush(PDC pdc
)
134 PDC_ATTR pdcattr
= pdc
->pdcattr
;
138 /* ROS HACK, should use surf xlate */
139 pxlo
= pdc
->rosdc
.XlatePen
;
141 /* Translate the color to the target format */
142 iSolidColor
= XLATEOBJ_iXlate(pxlo
, pdcattr
->crBackgroundClr
);
144 /* Update the eboBackground's solid color */
145 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboBackground
, iSolidColor
);
148 pdcattr
->ulDirty_
&= ~DIRTY_BACKGROUND
;
156 BOOL ForceBackground
)
159 HPALETTE oldPal
= NULL
;
162 // FIXME: mark the palette as a [fore\back]ground pal
163 pdc
= DC_LockDc(hDC
);
169 /* Check if this is a valid palette handle */
170 ppal
= PALETTE_LockPalette(hpal
);
177 /* Is this a valid palette for this depth? */
178 if ((pdc
->rosdc
.bitsPerPixel
<= 8 && ppal
->Mode
== PAL_INDEXED
) ||
179 (pdc
->rosdc
.bitsPerPixel
> 8 && ppal
->Mode
!= PAL_INDEXED
))
181 oldPal
= pdc
->dclevel
.hpal
;
182 pdc
->dclevel
.hpal
= hpal
;
184 else if (pdc
->rosdc
.bitsPerPixel
> 8 && ppal
->Mode
== PAL_INDEXED
)
186 oldPal
= pdc
->dclevel
.hpal
;
187 pdc
->dclevel
.hpal
= hpal
;
190 PALETTE_UnlockPalette(ppal
);
208 if (pDC
== NULL
|| hBrush
== NULL
) return NULL
;
210 pdcattr
= pDC
->pdcattr
;
212 pbrush
= BRUSH_LockBrush(hBrush
);
215 SetLastWin32Error(ERROR_INVALID_HANDLE
);
219 DC_vSelectFillBrush(pDC
, pbrush
);
221 XlateObj
= IntGdiCreateBrushXlate(pDC
, pbrush
, &bFailed
);
222 BRUSH_UnlockBrush(pbrush
);
228 hOrgBrush
= pdcattr
->hbrush
;
229 pdcattr
->hbrush
= hBrush
;
231 if (pDC
->rosdc
.XlateBrush
!= NULL
)
233 EngDeleteXlate(pDC
->rosdc
.XlateBrush
);
235 pDC
->rosdc
.XlateBrush
= XlateObj
;
237 pdcattr
->ulDirty_
&= ~DC_BRUSH_DIRTY
;
254 if (pDC
== NULL
|| hPen
== NULL
) return NULL
;
256 pdcattr
= pDC
->pdcattr
;
258 pbrushPen
= PEN_LockPen(hPen
);
259 if (pbrushPen
== NULL
)
264 DC_vSelectLineBrush(pDC
, pbrushPen
);
266 XlateObj
= IntGdiCreateBrushXlate(pDC
, pbrushPen
, &bFailed
);
267 PEN_UnlockPen(pbrushPen
);
270 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
274 hOrgPen
= pdcattr
->hpen
;
275 pdcattr
->hpen
= hPen
;
277 if (pDC
->rosdc
.XlatePen
!= NULL
)
279 EngDeleteXlate(pDC
->rosdc
.XlatePen
);
281 pdcattr
->ulDirty_
&= ~DC_PEN_DIRTY
;
283 pDC
->rosdc
.XlatePen
= XlateObj
;
301 if (hDC
== NULL
|| hBrush
== NULL
) return NULL
;
303 pDC
= DC_LockDc(hDC
);
309 hOrgBrush
= IntGdiSelectBrush(pDC
,hBrush
);
328 if (hDC
== NULL
|| hPen
== NULL
) return NULL
;
330 pDC
= DC_LockDc(hDC
);
336 hOrgPen
= IntGdiSelectPen(pDC
, hPen
);
355 PSURFACE psurfBmp
, psurfOld
;
360 if (hDC
== NULL
|| hBmp
== NULL
) return NULL
;
362 pDC
= DC_LockDc(hDC
);
367 pdcattr
= pDC
->pdcattr
;
369 /* must be memory dc to select bitmap */
370 if (pDC
->dctype
!= DC_TYPE_MEMORY
)
376 psurfBmp
= SURFACE_LockSurface(hBmp
);
383 /* Get the handle for the old bitmap */
384 psurfOld
= pDC
->dclevel
.pSurface
;
385 hOrgBmp
= psurfOld
? psurfOld
->BaseObject
.hHmgr
: NULL
;
387 /* FIXME: ros hack */
388 hOrgBmp
= pDC
->rosdc
.hBitmap
;
390 pDC
->rosdc
.hBitmap
= hBmp
;
392 /* Release the old bitmap, reference the new */
393 DC_vSelectSurface(pDC
, psurfBmp
);
395 // If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
398 // if we're working with a DIB, get the palette
399 // [fixme: only create if the selected palette is null]
400 if (psurfBmp
->hSecure
)
402 // pDC->rosdc.bitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
403 pDC
->rosdc
.bitsPerPixel
= BitsPerFormat(psurfBmp
->SurfObj
.iBitmapFormat
);
407 pDC
->rosdc
.bitsPerPixel
= BitsPerFormat(psurfBmp
->SurfObj
.iBitmapFormat
);
410 /* FIXME; improve by using a region without a handle and selecting it */
411 hVisRgn
= NtGdiCreateRectRgn(0,
413 psurfBmp
->SurfObj
.sizlBitmap
.cx
,
414 psurfBmp
->SurfObj
.sizlBitmap
.cy
);
416 /* Release the exclusive lock */
417 SURFACE_UnlockSurface(psurfBmp
);
419 /* Regenerate the XLATEOBJs. (hack!) */
420 pbrush
= BRUSH_LockBrush(pdcattr
->hbrush
);
423 if (pDC
->rosdc
.XlateBrush
)
425 EngDeleteXlate(pDC
->rosdc
.XlateBrush
);
427 pDC
->rosdc
.XlateBrush
= IntGdiCreateBrushXlate(pDC
, pbrush
, &bFailed
);
428 BRUSH_UnlockBrush(pbrush
);
431 pbrush
= PEN_LockPen(pdcattr
->hpen
);
434 if (pDC
->rosdc
.XlatePen
)
436 EngDeleteXlate(pDC
->rosdc
.XlatePen
);
438 pDC
->rosdc
.XlatePen
= IntGdiCreateBrushXlate(pDC
, pbrush
, &bFailed
);
439 PEN_UnlockPen(pbrush
);
446 GdiSelectVisRgn(hDC
, hVisRgn
);
447 GreDeleteObject(hVisRgn
);
462 BOOL success
= FALSE
;
466 pdc
= DC_LockDc(hDC
);
469 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
472 pdcattr
= pdc
->pdcattr
;
474 pPath
= PATH_LockPath(pdc
->dclevel
.hPath
);
481 /* Check that path is closed */
482 if (pPath
->state
!= PATH_Closed
)
484 SetLastWin32Error(ERROR_CAN_NOT_COMPLETE
);
488 /* Construct a region from the path */
489 else if (PATH_PathToRegion(pPath
, pdcattr
->jFillMode
, &hrgnPath
))
491 success
= GdiExtSelectClipRgn(pdc
, hrgnPath
, Mode
) != ERROR
;
492 GreDeleteObject( hrgnPath
);
496 PATH_EmptyPath(pPath
);
498 /* FIXME: Should this function delete the path even if it failed? */
501 PATH_UnlockPath(pPath
);
509 NtGdiGetDCObject(HDC hDC
, INT ObjectType
)
515 /* From Wine: GetCurrentObject does not SetLastError() on a null object */
516 if(!hDC
) return NULL
;
518 if(!(pdc
= DC_LockDc(hDC
)))
520 SetLastWin32Error(ERROR_INVALID_HANDLE
);
523 pdcattr
= pdc
->pdcattr
;
525 if (pdcattr
->ulDirty_
& DC_BRUSH_DIRTY
)
526 IntGdiSelectBrush(pdc
, pdcattr
->hbrush
);
528 if (pdcattr
->ulDirty_
& DC_PEN_DIRTY
)
529 IntGdiSelectPen(pdc
, pdcattr
->hpen
);
533 case GDI_OBJECT_TYPE_EXTPEN
:
534 case GDI_OBJECT_TYPE_PEN
:
535 SelObject
= pdcattr
->hpen
;
538 case GDI_OBJECT_TYPE_BRUSH
:
539 SelObject
= pdcattr
->hbrush
;
542 case GDI_OBJECT_TYPE_PALETTE
:
543 SelObject
= pdc
->dclevel
.hpal
;
546 case GDI_OBJECT_TYPE_FONT
:
547 SelObject
= pdcattr
->hlfntNew
;
550 case GDI_OBJECT_TYPE_BITMAP
:
551 SelObject
= pdc
->rosdc
.hBitmap
;
554 case GDI_OBJECT_TYPE_COLORSPACE
:
555 DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_COLORSPACE not supported yet!\n");
556 // SelObject = dc->dclevel.pColorSpace.BaseObject.hHmgr; ?
562 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
576 OUT OPTIONAL PVOID pvBuf
)