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_vCleanup(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
);
143 BRUSH_GetObject(PBRUSH pbrush
, INT cjSize
, LPLOGBRUSH plogbrush
)
145 /* Check if only size is requested */
146 if (plogbrush
== NULL
) return sizeof(LOGBRUSH
);
148 /* Check if size is ok */
149 if (cjSize
== 0) return 0;
152 plogbrush
->lbColor
= pbrush
->BrushAttr
.lbColor
;
155 plogbrush
->lbHatch
= 0;
157 /* Get the type of style */
158 if (pbrush
->flAttrs
& BR_IS_SOLID
)
160 plogbrush
->lbStyle
= BS_SOLID
;
162 else if (pbrush
->flAttrs
& BR_IS_NULL
)
164 plogbrush
->lbStyle
= BS_NULL
; // BS_HOLLOW
166 else if (pbrush
->flAttrs
& BR_IS_HATCH
)
168 plogbrush
->lbStyle
= BS_HATCHED
;
169 plogbrush
->lbHatch
= pbrush
->ulStyle
;
171 else if (pbrush
->flAttrs
& BR_IS_DIB
)
173 plogbrush
->lbStyle
= BS_DIBPATTERN
;
174 plogbrush
->lbHatch
= (ULONG_PTR
)pbrush
->hbmClient
;
176 else if (pbrush
->flAttrs
& BR_IS_BITMAP
)
178 plogbrush
->lbStyle
= BS_PATTERN
;
182 plogbrush
->lbStyle
= 0; // ???
186 else if (pbrush->flAttrs & )
188 plogbrush->lbStyle = BS_INDEXED;
190 else if (pbrush->flAttrs & )
192 plogbrush->lbStyle = BS_DIBPATTERNPT;
197 return sizeof(LOGBRUSH
);
202 IntGdiCreateDIBBrush(
203 CONST BITMAPINFO
*BitmapInfo
,
206 CONST VOID
*PackedDIB
)
214 if (BitmapInfo
->bmiHeader
.biSize
< sizeof(BITMAPINFOHEADER
))
216 EngSetLastError(ERROR_INVALID_PARAMETER
);
220 DataPtr
= (ULONG_PTR
)BitmapInfo
+ DIB_BitmapInfoSize(BitmapInfo
, ColorSpec
);
222 hPattern
= DIB_CreateDIBSection(NULL
, BitmapInfo
, ColorSpec
, &pvDIBits
, NULL
, 0, 0);
223 if (hPattern
== NULL
)
225 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
228 RtlCopyMemory(pvDIBits
,
230 DIB_GetDIBImageBytes(BitmapInfo
->bmiHeader
.biWidth
,
231 BitmapInfo
->bmiHeader
.biHeight
,
232 BitmapInfo
->bmiHeader
.biBitCount
* BitmapInfo
->bmiHeader
.biPlanes
));
234 pbrush
= BRUSH_AllocBrushWithHandle();
237 GreDeleteObject(hPattern
);
238 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
241 hBrush
= pbrush
->BaseObject
.hHmgr
;
243 pbrush
->flAttrs
|= BR_IS_BITMAP
| BR_IS_DIB
;
244 pbrush
->hbmPattern
= hPattern
;
245 pbrush
->hbmClient
= (HBITMAP
)PackedDIB
;
246 /* FIXME: Fill in the rest of fields!!! */
248 GreSetObjectOwner(hPattern
, GDI_OBJ_HMGR_PUBLIC
);
250 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
257 IntGdiCreateHatchBrush(
264 if (Style
< 0 || Style
>= NB_HATCH_STYLES
)
269 pbrush
= BRUSH_AllocBrushWithHandle();
272 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
275 hBrush
= pbrush
->BaseObject
.hHmgr
;
277 pbrush
->flAttrs
|= BR_IS_HATCH
;
278 pbrush
->BrushAttr
.lbColor
= Color
& 0xFFFFFF;
279 pbrush
->ulStyle
= Style
;
281 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
288 IntGdiCreatePatternBrush(
295 hPattern
= BITMAP_CopyBitmap(hBitmap
);
296 if (hPattern
== NULL
)
298 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
302 pbrush
= BRUSH_AllocBrushWithHandle();
305 GreDeleteObject(hPattern
);
306 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
309 hBrush
= pbrush
->BaseObject
.hHmgr
;
311 pbrush
->flAttrs
|= BR_IS_BITMAP
;
312 pbrush
->hbmPattern
= hPattern
;
313 /* FIXME: Fill in the rest of fields!!! */
315 GreSetObjectOwner(hPattern
, GDI_OBJ_HMGR_PUBLIC
);
317 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
324 IntGdiCreateSolidBrush(
330 pbrush
= BRUSH_AllocBrushWithHandle();
333 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
336 hBrush
= pbrush
->BaseObject
.hHmgr
;
338 pbrush
->flAttrs
|= BR_IS_SOLID
;
340 pbrush
->BrushAttr
.lbColor
= Color
& 0x00FFFFFF;
341 /* FIXME: Fill in the rest of fields!!! */
343 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
350 IntGdiCreateNullBrush(VOID
)
355 pbrush
= BRUSH_AllocBrushWithHandle();
358 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
361 hBrush
= pbrush
->BaseObject
.hHmgr
;
363 pbrush
->flAttrs
|= BR_IS_NULL
;
364 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
371 IntGdiSetSolidBrushColor(HBRUSH hBrush
, COLORREF Color
)
375 pbrush
= BRUSH_ShareLockBrush(hBrush
);
376 if (pbrush
->flAttrs
& BR_IS_SOLID
)
378 pbrush
->BrushAttr
.lbColor
= Color
& 0xFFFFFF;
380 BRUSH_ShareUnlockBrush(pbrush
);
384 /* PUBLIC FUNCTIONS ***********************************************************/
389 IN PVOID BitmapInfoAndData
,
391 IN UINT BitmapInfoSize
,
396 BITMAPINFO
*SafeBitmapInfoAndData
;
397 NTSTATUS Status
= STATUS_SUCCESS
;
400 SafeBitmapInfoAndData
= EngAllocMem(FL_ZERO_MEMORY
, BitmapInfoSize
, TAG_DIB
);
401 if (SafeBitmapInfoAndData
== NULL
)
403 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
409 ProbeForRead(BitmapInfoAndData
, BitmapInfoSize
, 1);
410 RtlCopyMemory(SafeBitmapInfoAndData
, BitmapInfoAndData
, BitmapInfoSize
);
412 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
414 Status
= _SEH2_GetExceptionCode();
418 if (!NT_SUCCESS(Status
))
420 EngFreeMem(SafeBitmapInfoAndData
);
421 SetLastNtError(Status
);
425 hBrush
= IntGdiCreateDIBBrush(SafeBitmapInfoAndData
,
430 EngFreeMem(SafeBitmapInfoAndData
);
437 NtGdiCreateHatchBrushInternal(
442 return IntGdiCreateHatchBrush(Style
, Color
);
447 NtGdiCreatePatternBrushInternal(
452 return IntGdiCreatePatternBrush(hBitmap
);
457 NtGdiCreateSolidBrush(COLORREF Color
,
458 IN OPTIONAL HBRUSH hbr
)
460 return IntGdiCreateSolidBrush(Color
);