2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS win32 subsystem
4 * PURPOSE: Functions for brushes
5 * FILE: subsystem/win32/win32k/objects/brush.c
14 #define GDIOBJATTRFREE 170
16 typedef struct _GDI_OBJ_ATTR_FREELIST
20 PVOID AttrList
[GDIOBJATTRFREE
];
21 } GDI_OBJ_ATTR_FREELIST
, *PGDI_OBJ_ATTR_FREELIST
;
23 typedef struct _GDI_OBJ_ATTR_ENTRY
25 RGN_ATTR Attr
[GDIOBJATTRFREE
];
26 } GDI_OBJ_ATTR_ENTRY
, *PGDI_OBJ_ATTR_ENTRY
;
30 IntGdiSetBrushOwner(PBRUSH pbr
, ULONG ulOwner
)
33 if (pbr
->flAttrs
& BR_IS_GLOBAL
) return TRUE
;
35 if ((ulOwner
== GDI_OBJ_HMGR_PUBLIC
) || ulOwner
== GDI_OBJ_HMGR_NONE
)
37 // Deny user access to User Data.
38 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, NULL
);
39 // FIXME: deallocate brush attr
42 if (ulOwner
== GDI_OBJ_HMGR_POWNED
)
44 // Allow user access to User Data.
45 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, pbr
->pBrushAttr
);
46 // FIXME: Allocate brush attr
49 GDIOBJ_vSetObjectOwner(&pbr
->BaseObject
, ulOwner
);
56 GreSetBrushOwner(HBRUSH hBrush
, ULONG ulOwner
)
61 pbrush
= BRUSH_ShareLockBrush(hBrush
);
62 Ret
= IntGdiSetBrushOwner(pbrush
, ulOwner
);
63 BRUSH_ShareUnlockBrush(pbrush
);
69 BRUSH_bAllocBrushAttr(PBRUSH pbr
)
72 BRUSH_ATTR
*pBrushAttr
;
74 ppi
= PsGetCurrentProcessWin32Process();
77 pBrushAttr
= GdiPoolAllocate(ppi
->pPoolDcAttr
);
80 DPRINT1("Could not allocate brush attr\n");
84 /* Copy the content from the kernel mode dc attr */
85 pbr
->pBrushAttr
= pBrushAttr
;
86 *pbr
->pBrushAttr
= pbr
->BrushAttr
;
88 /* Set the object attribute in the handle table */
89 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, pBrushAttr
);
91 DPRINT("BRUSH_bAllocBrushAttr: pbr=%p, pbr->pdcattr=%p\n", pbr
, pbr
->pBrushAttr
);
98 BRUSH_vFreeBrushAttr(PBRUSH pbr
)
103 if (pbrush
->pBrushAttr
== &pbrush
->BrushAttr
) return;
105 /* Reset the object attribute in the handle table */
106 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, NULL
);
108 /* Free memory from the process gdi pool */
109 ppi
= PsGetCurrentProcessWin32Process();
111 GdiPoolFree(ppi
->pPoolBrushAttr
, pbr
->pBrushAttr
);
113 /* Reset to kmode brush attribute */
114 pbr
->pBrushAttr
= &pbr
->BrushAttr
;
119 BRUSH_Cleanup(PVOID ObjectBody
)
121 PBRUSH pbrush
= (PBRUSH
)ObjectBody
;
122 if (pbrush
->hbmPattern
)
124 GreSetObjectOwner(pbrush
->hbmPattern
, GDI_OBJ_HMGR_POWNED
);
125 GreDeleteObject(pbrush
->hbmPattern
);
128 /* Check if there is a usermode attribute */
129 if (pbrush
->pBrushAttr
!= &pbrush
->BrushAttr
)
131 BRUSH_vFreeBrushAttr(pbrush
);
134 /* Free the kmode styles array of EXTPENS */
137 ExFreePool(pbrush
->pStyle
);
145 BRUSH_GetObject(PBRUSH pbrush
, INT cjSize
, LPLOGBRUSH plogbrush
)
147 /* Check if only size is requested */
148 if (plogbrush
== NULL
) return sizeof(LOGBRUSH
);
150 /* Check if size is ok */
151 if (cjSize
== 0) return 0;
154 plogbrush
->lbColor
= pbrush
->BrushAttr
.lbColor
;
157 plogbrush
->lbHatch
= 0;
159 /* Get the type of style */
160 if (pbrush
->flAttrs
& BR_IS_SOLID
)
162 plogbrush
->lbStyle
= BS_SOLID
;
164 else if (pbrush
->flAttrs
& BR_IS_NULL
)
166 plogbrush
->lbStyle
= BS_NULL
; // BS_HOLLOW
168 else if (pbrush
->flAttrs
& BR_IS_HATCH
)
170 plogbrush
->lbStyle
= BS_HATCHED
;
171 plogbrush
->lbHatch
= pbrush
->ulStyle
;
173 else if (pbrush
->flAttrs
& BR_IS_DIB
)
175 plogbrush
->lbStyle
= BS_DIBPATTERN
;
176 plogbrush
->lbHatch
= (ULONG_PTR
)pbrush
->hbmClient
;
178 else if (pbrush
->flAttrs
& BR_IS_BITMAP
)
180 plogbrush
->lbStyle
= BS_PATTERN
;
184 plogbrush
->lbStyle
= 0; // ???
188 else if (pbrush->flAttrs & )
190 plogbrush->lbStyle = BS_INDEXED;
192 else if (pbrush->flAttrs & )
194 plogbrush->lbStyle = BS_DIBPATTERNPT;
199 return sizeof(LOGBRUSH
);
204 IntGdiCreateDIBBrush(
205 CONST BITMAPINFO
*BitmapInfo
,
208 CONST VOID
*PackedDIB
)
216 if (BitmapInfo
->bmiHeader
.biSize
< sizeof(BITMAPINFOHEADER
))
218 EngSetLastError(ERROR_INVALID_PARAMETER
);
222 DataPtr
= (ULONG_PTR
)BitmapInfo
+ DIB_BitmapInfoSize(BitmapInfo
, ColorSpec
);
224 hPattern
= DIB_CreateDIBSection(NULL
, BitmapInfo
, ColorSpec
, &pvDIBits
, NULL
, 0, 0);
225 if (hPattern
== NULL
)
227 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
230 RtlCopyMemory(pvDIBits
,
232 DIB_GetDIBImageBytes(BitmapInfo
->bmiHeader
.biWidth
,
233 BitmapInfo
->bmiHeader
.biHeight
,
234 BitmapInfo
->bmiHeader
.biBitCount
* BitmapInfo
->bmiHeader
.biPlanes
));
236 pbrush
= BRUSH_AllocBrushWithHandle();
239 GreDeleteObject(hPattern
);
240 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
243 hBrush
= pbrush
->BaseObject
.hHmgr
;
245 pbrush
->flAttrs
|= BR_IS_BITMAP
| BR_IS_DIB
;
246 pbrush
->hbmPattern
= hPattern
;
247 pbrush
->hbmClient
= (HBITMAP
)PackedDIB
;
248 /* FIXME: Fill in the rest of fields!!! */
250 GreSetObjectOwner(hPattern
, GDI_OBJ_HMGR_PUBLIC
);
252 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
259 IntGdiCreateHatchBrush(
266 if (Style
< 0 || Style
>= NB_HATCH_STYLES
)
271 pbrush
= BRUSH_AllocBrushWithHandle();
274 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
277 hBrush
= pbrush
->BaseObject
.hHmgr
;
279 pbrush
->flAttrs
|= BR_IS_HATCH
;
280 pbrush
->BrushAttr
.lbColor
= Color
& 0xFFFFFF;
281 pbrush
->ulStyle
= Style
;
283 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
290 IntGdiCreatePatternBrush(
297 hPattern
= BITMAP_CopyBitmap(hBitmap
);
298 if (hPattern
== NULL
)
300 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
304 pbrush
= BRUSH_AllocBrushWithHandle();
307 GreDeleteObject(hPattern
);
308 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
311 hBrush
= pbrush
->BaseObject
.hHmgr
;
313 pbrush
->flAttrs
|= BR_IS_BITMAP
;
314 pbrush
->hbmPattern
= hPattern
;
315 /* FIXME: Fill in the rest of fields!!! */
317 GreSetObjectOwner(hPattern
, GDI_OBJ_HMGR_PUBLIC
);
319 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
326 IntGdiCreateSolidBrush(
332 pbrush
= BRUSH_AllocBrushWithHandle();
335 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
338 hBrush
= pbrush
->BaseObject
.hHmgr
;
340 pbrush
->flAttrs
|= BR_IS_SOLID
;
342 pbrush
->BrushAttr
.lbColor
= Color
& 0x00FFFFFF;
343 /* FIXME: Fill in the rest of fields!!! */
345 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
352 IntGdiCreateNullBrush(VOID
)
357 pbrush
= BRUSH_AllocBrushWithHandle();
360 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
363 hBrush
= pbrush
->BaseObject
.hHmgr
;
365 pbrush
->flAttrs
|= BR_IS_NULL
;
366 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
373 IntGdiSetSolidBrushColor(HBRUSH hBrush
, COLORREF Color
)
377 pbrush
= BRUSH_ShareLockBrush(hBrush
);
378 if (pbrush
->flAttrs
& BR_IS_SOLID
)
380 pbrush
->BrushAttr
.lbColor
= Color
& 0xFFFFFF;
382 BRUSH_ShareUnlockBrush(pbrush
);
386 /* PUBLIC FUNCTIONS ***********************************************************/
391 IN PVOID BitmapInfoAndData
,
393 IN UINT BitmapInfoSize
,
398 BITMAPINFO
*SafeBitmapInfoAndData
;
399 NTSTATUS Status
= STATUS_SUCCESS
;
402 SafeBitmapInfoAndData
= EngAllocMem(FL_ZERO_MEMORY
, BitmapInfoSize
, TAG_DIB
);
403 if (SafeBitmapInfoAndData
== NULL
)
405 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
411 ProbeForRead(BitmapInfoAndData
, BitmapInfoSize
, 1);
412 RtlCopyMemory(SafeBitmapInfoAndData
, BitmapInfoAndData
, BitmapInfoSize
);
414 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
416 Status
= _SEH2_GetExceptionCode();
420 if (!NT_SUCCESS(Status
))
422 EngFreeMem(SafeBitmapInfoAndData
);
423 SetLastNtError(Status
);
427 hBrush
= IntGdiCreateDIBBrush(SafeBitmapInfoAndData
,
432 EngFreeMem(SafeBitmapInfoAndData
);
439 NtGdiCreateHatchBrushInternal(
444 return IntGdiCreateHatchBrush(Style
, Color
);
449 NtGdiCreatePatternBrushInternal(
454 return IntGdiCreatePatternBrush(hBitmap
);
459 NtGdiCreateSolidBrush(COLORREF Color
,
460 IN OPTIONAL HBRUSH hbr
)
462 return IntGdiCreateSolidBrush(Color
);