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)
16 DC_vUpdateFillBrush(PDC pdc
)
18 PDC_ATTR pdcattr
= pdc
->pdcattr
;
21 /* Check if the brush handle has changed */
22 if (pdcattr
->hbrush
!= pdc
->dclevel
.pbrFill
->BaseObject
.hHmgr
)
24 /* Try to lock the new brush */
25 pbrFill
= BRUSH_ShareLockBrush(pdcattr
->hbrush
);
28 /* Unlock old brush, set new brush */
29 BRUSH_ShareUnlockBrush(pdc
->dclevel
.pbrFill
);
30 pdc
->dclevel
.pbrFill
= pbrFill
;
32 /* Mark eboFill as dirty */
33 pdcattr
->ulDirty_
|= DIRTY_FILL
;
37 /* Invalid brush handle, restore old one */
38 pdcattr
->hbrush
= pdc
->dclevel
.pbrFill
->BaseObject
.hHmgr
;
42 /* Check if the EBRUSHOBJ needs update */
43 if (pdcattr
->ulDirty_
& DIRTY_FILL
)
46 EBRUSHOBJ_vUpdate(&pdc
->eboFill
, pdc
->dclevel
.pbrFill
, pdc
);
49 /* Check for DC brush */
50 if (pdcattr
->hbrush
== StockObjects
[DC_BRUSH
])
52 /* ROS HACK, should use surf xlate */
53 /* Update the eboFill's solid color */
54 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboFill
, pdcattr
->crPenClr
);
58 pdcattr
->ulDirty_
&= ~(DIRTY_FILL
| DC_BRUSH_DIRTY
);
63 DC_vUpdateLineBrush(PDC pdc
)
65 PDC_ATTR pdcattr
= pdc
->pdcattr
;
68 /* Check if the pen handle has changed */
69 if (pdcattr
->hpen
!= pdc
->dclevel
.pbrLine
->BaseObject
.hHmgr
)
71 /* Try to lock the new pen */
72 pbrLine
= PEN_ShareLockPen(pdcattr
->hpen
);
75 /* Unlock old brush, set new brush */
76 BRUSH_ShareUnlockBrush(pdc
->dclevel
.pbrLine
);
77 pdc
->dclevel
.pbrLine
= pbrLine
;
79 /* Mark eboLine as dirty */
80 pdcattr
->ulDirty_
|= DIRTY_LINE
;
84 /* Invalid pen handle, restore old one */
85 pdcattr
->hpen
= pdc
->dclevel
.pbrLine
->BaseObject
.hHmgr
;
89 /* Check if the EBRUSHOBJ needs update */
90 if (pdcattr
->ulDirty_
& DIRTY_LINE
)
93 EBRUSHOBJ_vUpdate(&pdc
->eboLine
, pdc
->dclevel
.pbrLine
, pdc
);
96 /* Check for DC pen */
97 if (pdcattr
->hpen
== StockObjects
[DC_PEN
])
99 /* Update the eboLine's solid color */
100 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboLine
, pdcattr
->crPenClr
);
104 pdcattr
->ulDirty_
&= ~(DIRTY_LINE
| DC_PEN_DIRTY
);
109 DC_vUpdateTextBrush(PDC pdc
)
111 PDC_ATTR pdcattr
= pdc
->pdcattr
;
113 if(pdcattr
->ulDirty_
& DIRTY_TEXT
)
114 EBRUSHOBJ_vUpdate(&pdc
->eboText
, pdc
->eboText
.pbrush
, pdc
);
116 /* Update the eboText's solid color */
117 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboText
, pdcattr
->crForegroundClr
);
120 pdcattr
->ulDirty_
&= ~DIRTY_TEXT
;
125 DC_vUpdateBackgroundBrush(PDC pdc
)
127 PDC_ATTR pdcattr
= pdc
->pdcattr
;
129 if(pdcattr
->ulDirty_
& DIRTY_BACKGROUND
)
130 EBRUSHOBJ_vUpdate(&pdc
->eboBackground
, pdc
->eboBackground
.pbrush
, pdc
);
132 /* Update the eboBackground's solid color */
133 EBRUSHOBJ_vSetSolidBrushColor(&pdc
->eboBackground
, pdcattr
->crBackgroundClr
);
136 pdcattr
->ulDirty_
&= ~DIRTY_BACKGROUND
;
144 BOOL ForceBackground
)
147 HPALETTE oldPal
= NULL
;
150 // FIXME: mark the palette as a [fore\back]ground pal
151 pdc
= DC_LockDc(hDC
);
157 /* Check if this is a valid palette handle */
158 ppal
= PALETTE_ShareLockPalette(hpal
);
165 // FIXME: This looks wrong
166 /* Is this a valid palette for this depth? */
167 if ((pdc
->rosdc
.bitsPerPixel
<= 8 && ppal
->Mode
== PAL_INDEXED
) ||
168 (pdc
->rosdc
.bitsPerPixel
> 8))
170 /* Get old palette, set new one */
171 oldPal
= pdc
->dclevel
.hpal
;
172 pdc
->dclevel
.hpal
= hpal
;
173 DC_vSelectPalette(pdc
, ppal
);
175 /* Mark the brushes invalid */
176 pdc
->pdcattr
->ulDirty_
|= DIRTY_FILL
| DIRTY_LINE
|
177 DIRTY_BACKGROUND
| DIRTY_TEXT
;
180 PALETTE_ShareUnlockPalette(ppal
);
198 if (hDC
== NULL
|| hBrush
== NULL
) return NULL
;
200 pDC
= DC_LockDc(hDC
);
206 /* Simply return the user mode value, without checking */
207 hOrgBrush
= pDC
->pdcattr
->hbrush
;
208 pDC
->pdcattr
->hbrush
= hBrush
;
209 DC_vUpdateFillBrush(pDC
);
228 if (hDC
== NULL
|| hPen
== NULL
) return NULL
;
230 pDC
= DC_LockDc(hDC
);
236 /* Simply return the user mode value, without checking */
237 hOrgPen
= pDC
->pdcattr
->hpen
;
238 pDC
->pdcattr
->hpen
= hPen
;
239 DC_vUpdateLineBrush(pDC
);
258 PSURFACE psurfBmp
, psurfOld
;
261 if (hDC
== NULL
|| hBmp
== NULL
) return NULL
;
263 pDC
= DC_LockDc(hDC
);
268 pdcattr
= pDC
->pdcattr
;
270 /* must be memory dc to select bitmap */
271 if (pDC
->dctype
!= DC_TYPE_MEMORY
)
277 psurfBmp
= SURFACE_LockSurface(hBmp
);
284 /* Get the handle for the old bitmap */
285 psurfOld
= pDC
->dclevel
.pSurface
;
286 hOrgBmp
= psurfOld
? psurfOld
->BaseObject
.hHmgr
: NULL
;
288 /* Release the old bitmap, reference the new */
289 DC_vSelectSurface(pDC
, psurfBmp
);
291 // If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
294 // if we're working with a DIB, get the palette
295 // [fixme: only create if the selected palette is null]
296 if (psurfBmp
->hSecure
)
298 // pDC->rosdc.bitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
299 pDC
->rosdc
.bitsPerPixel
= BitsPerFormat(psurfBmp
->SurfObj
.iBitmapFormat
);
300 /* Set DIBSECTION attribute */
301 pdcattr
->ulDirty_
|= DC_DIBSECTION
;
305 pDC
->rosdc
.bitsPerPixel
= BitsPerFormat(psurfBmp
->SurfObj
.iBitmapFormat
);
306 /* Restore DIBSECTION attribute */
307 pdcattr
->ulDirty_
&= ~DC_DIBSECTION
;
310 /* FIXME; improve by using a region without a handle and selecting it */
311 hVisRgn
= IntSysCreateRectRgn( 0,
313 psurfBmp
->SurfObj
.sizlBitmap
.cx
,
314 psurfBmp
->SurfObj
.sizlBitmap
.cy
);
316 /* Release the exclusive lock */
317 SURFACE_UnlockSurface(psurfBmp
);
319 /* Mark the brushes invalid */
320 pdcattr
->ulDirty_
|= DIRTY_FILL
| DIRTY_LINE
;
326 GdiSelectVisRgn(hDC
, hVisRgn
);
327 REGION_FreeRgnByHandle(hVisRgn
);
342 BOOL success
= FALSE
;
346 pdc
= DC_LockDc(hDC
);
349 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
352 pdcattr
= pdc
->pdcattr
;
354 pPath
= PATH_LockPath(pdc
->dclevel
.hPath
);
361 /* Check that path is closed */
362 if (pPath
->state
!= PATH_Closed
)
364 SetLastWin32Error(ERROR_CAN_NOT_COMPLETE
);
368 /* Construct a region from the path */
369 else if (PATH_PathToRegion(pPath
, pdcattr
->jFillMode
, &hrgnPath
))
371 success
= GdiExtSelectClipRgn(pdc
, hrgnPath
, Mode
) != ERROR
;
372 GreDeleteObject( hrgnPath
);
376 PATH_EmptyPath(pPath
);
378 /* FIXME: Should this function delete the path even if it failed? */
381 PATH_UnlockPath(pPath
);
389 NtGdiGetDCObject(HDC hDC
, INT ObjectType
)
395 /* From Wine: GetCurrentObject does not SetLastError() on a null object */
396 if(!hDC
) return NULL
;
398 if(!(pdc
= DC_LockDc(hDC
)))
400 SetLastWin32Error(ERROR_INVALID_HANDLE
);
403 pdcattr
= pdc
->pdcattr
;
405 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
406 DC_vUpdateFillBrush(pdc
);
408 if (pdcattr
->ulDirty_
& (DIRTY_LINE
| DC_PEN_DIRTY
))
409 DC_vUpdateLineBrush(pdc
);
413 case GDI_OBJECT_TYPE_EXTPEN
:
414 case GDI_OBJECT_TYPE_PEN
:
415 SelObject
= pdcattr
->hpen
;
418 case GDI_OBJECT_TYPE_BRUSH
:
419 SelObject
= pdcattr
->hbrush
;
422 case GDI_OBJECT_TYPE_PALETTE
:
423 SelObject
= pdc
->dclevel
.hpal
;
426 case GDI_OBJECT_TYPE_FONT
:
427 SelObject
= pdcattr
->hlfntNew
;
430 case GDI_OBJECT_TYPE_BITMAP
:
432 SURFACE
*psurf
= pdc
->dclevel
.pSurface
;
433 SelObject
= psurf
? psurf
->BaseObject
.hHmgr
: NULL
;
437 case GDI_OBJECT_TYPE_COLORSPACE
:
438 DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_COLORSPACE not supported yet!\n");
439 // SelObject = dc->dclevel.pColorSpace.BaseObject.hHmgr; ?
445 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
459 OUT OPTIONAL PVOID pvBuf
)