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
;
28 static const ULONG HatchBrushes
[NB_HATCH_STYLES
][8] =
30 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
31 {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
32 {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */
33 {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */
34 {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */
35 {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
40 IntGdiSetBrushOwner(PBRUSH pbr
, ULONG ulOwner
)
43 if (pbr
->flAttrs
& BR_IS_GLOBAL
) return TRUE
;
45 if ((ulOwner
== GDI_OBJ_HMGR_PUBLIC
) || ulOwner
== GDI_OBJ_HMGR_NONE
)
47 // Deny user access to User Data.
48 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, NULL
);
49 // FIXME: deallocate brush attr
52 if (ulOwner
== GDI_OBJ_HMGR_POWNED
)
54 // Allow user access to User Data.
55 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, pbr
->pBrushAttr
);
56 // FIXME: Allocate brush attr
59 GDIOBJ_vSetObjectOwner(&pbr
->BaseObject
, ulOwner
);
66 GreSetBrushOwner(HBRUSH hBrush
, ULONG ulOwner
)
71 pbrush
= BRUSH_ShareLockBrush(hBrush
);
72 Ret
= IntGdiSetBrushOwner(pbrush
, ulOwner
);
73 BRUSH_ShareUnlockBrush(pbrush
);
79 BRUSH_bAllocBrushAttr(PBRUSH pbr
)
82 BRUSH_ATTR
*pBrushAttr
;
84 ppi
= PsGetCurrentProcessWin32Process();
87 pBrushAttr
= GdiPoolAllocate(ppi
->pPoolDcAttr
);
90 DPRINT1("Could not allocate brush attr\n");
94 /* Copy the content from the kernel mode dc attr */
95 pbr
->pBrushAttr
= pBrushAttr
;
96 *pbr
->pBrushAttr
= pbr
->BrushAttr
;
98 /* Set the object attribute in the handle table */
99 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, pBrushAttr
);
101 DPRINT("BRUSH_bAllocBrushAttr: pbr=%p, pbr->pdcattr=%p\n", pbr
, pbr
->pBrushAttr
);
108 BRUSH_vFreeBrushAttr(PBRUSH pbr
)
113 if (pbrush
->pBrushAttr
== &pbrush
->BrushAttr
) return;
115 /* Reset the object attribute in the handle table */
116 GDIOBJ_vSetObjectAttr(&pbr
->BaseObject
, NULL
);
118 /* Free memory from the process gdi pool */
119 ppi
= PsGetCurrentProcessWin32Process();
121 GdiPoolFree(ppi
->pPoolBrushAttr
, pbr
->pBrushAttr
);
123 /* Reset to kmode brush attribute */
124 pbr
->pBrushAttr
= &pbr
->BrushAttr
;
129 BRUSH_Cleanup(PVOID ObjectBody
)
131 PBRUSH pbrush
= (PBRUSH
)ObjectBody
;
132 if (pbrush
->flAttrs
& (BR_IS_HATCH
| BR_IS_BITMAP
))
134 ASSERT(pbrush
->hbmPattern
);
135 GreSetObjectOwner(pbrush
->hbmPattern
, GDI_OBJ_HMGR_POWNED
);
136 GreDeleteObject(pbrush
->hbmPattern
);
139 /* Check if there is a usermode attribute */
140 if (pbrush
->pBrushAttr
!= &pbrush
->BrushAttr
)
142 BRUSH_vFreeBrushAttr(pbrush
);
145 /* Free the kmode styles array of EXTPENS */
148 ExFreePool(pbrush
->pStyle
);
156 BRUSH_GetObject(PBRUSH pbrush
, INT Count
, LPLOGBRUSH Buffer
)
158 if (Buffer
== NULL
) return sizeof(LOGBRUSH
);
159 if (Count
== 0) return 0;
162 Buffer
->lbColor
= pbrush
->BrushAttr
.lbColor
;
165 if ((pbrush
->flAttrs
& BR_IS_HATCH
)!=0)
167 /* FIXME: This is not the right value */
168 Buffer
->lbHatch
= (LONG
)pbrush
->hbmPattern
;
177 /* Get the type of style */
178 if ((pbrush
->flAttrs
& BR_IS_SOLID
)!=0)
180 Buffer
->lbStyle
= BS_SOLID
;
182 else if ((pbrush
->flAttrs
& BR_IS_NULL
)!=0)
184 Buffer
->lbStyle
= BS_NULL
; // BS_HOLLOW
186 else if ((pbrush
->flAttrs
& BR_IS_HATCH
)!=0)
188 Buffer
->lbStyle
= BS_HATCHED
;
190 else if ((pbrush
->flAttrs
& BR_IS_BITMAP
)!=0)
192 Buffer
->lbStyle
= BS_PATTERN
;
194 else if ((pbrush
->flAttrs
& BR_IS_DIB
)!=0)
196 Buffer
->lbStyle
= BS_DIBPATTERN
;
200 else if ((pbrush->flAttrs & )!=0)
202 Buffer->lbStyle = BS_INDEXED;
204 else if ((pbrush->flAttrs & )!=0)
206 Buffer->lbStyle = BS_DIBPATTERNPT;
211 return sizeof(LOGBRUSH
);
216 IntGdiCreateDIBBrush(
217 CONST BITMAPINFO
*BitmapInfo
,
220 CONST VOID
*PackedDIB
)
228 if (BitmapInfo
->bmiHeader
.biSize
< sizeof(BITMAPINFOHEADER
))
230 EngSetLastError(ERROR_INVALID_PARAMETER
);
234 DataPtr
= (ULONG_PTR
)BitmapInfo
+ DIB_BitmapInfoSize(BitmapInfo
, ColorSpec
);
236 hPattern
= DIB_CreateDIBSection(NULL
, BitmapInfo
, ColorSpec
, &pvDIBits
, NULL
, 0, 0);
237 if (hPattern
== NULL
)
239 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
242 RtlCopyMemory(pvDIBits
,
244 DIB_GetDIBImageBytes(BitmapInfo
->bmiHeader
.biWidth
,
245 BitmapInfo
->bmiHeader
.biHeight
,
246 BitmapInfo
->bmiHeader
.biBitCount
* BitmapInfo
->bmiHeader
.biPlanes
));
248 pbrush
= BRUSH_AllocBrushWithHandle();
251 GreDeleteObject(hPattern
);
252 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
255 hBrush
= pbrush
->BaseObject
.hHmgr
;
257 pbrush
->flAttrs
|= BR_IS_BITMAP
| BR_IS_DIB
;
258 pbrush
->hbmPattern
= hPattern
;
259 /* FIXME: Fill in the rest of fields!!! */
261 GreSetObjectOwner(hPattern
, GDI_OBJ_HMGR_PUBLIC
);
263 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
270 IntGdiCreateHatchBrush(
278 if (Style
< 0 || Style
>= NB_HATCH_STYLES
)
283 hPattern
= GreCreateBitmap(8, 8, 1, 1, (LPBYTE
)HatchBrushes
[Style
]);
284 if (hPattern
== NULL
)
286 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
290 pbrush
= BRUSH_AllocBrushWithHandle();
293 GreDeleteObject(hPattern
);
294 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
297 hBrush
= pbrush
->BaseObject
.hHmgr
;
299 pbrush
->flAttrs
|= BR_IS_HATCH
;
300 pbrush
->hbmPattern
= hPattern
;
301 pbrush
->BrushAttr
.lbColor
= Color
& 0xFFFFFF;
303 GreSetObjectOwner(hPattern
, GDI_OBJ_HMGR_PUBLIC
);
305 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
312 IntGdiCreatePatternBrush(
319 hPattern
= BITMAP_CopyBitmap(hBitmap
);
320 if (hPattern
== NULL
)
322 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
326 pbrush
= BRUSH_AllocBrushWithHandle();
329 GreDeleteObject(hPattern
);
330 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
333 hBrush
= pbrush
->BaseObject
.hHmgr
;
335 pbrush
->flAttrs
|= BR_IS_BITMAP
;
336 pbrush
->hbmPattern
= hPattern
;
337 /* FIXME: Fill in the rest of fields!!! */
339 GreSetObjectOwner(hPattern
, GDI_OBJ_HMGR_PUBLIC
);
341 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
348 IntGdiCreateSolidBrush(
354 pbrush
= BRUSH_AllocBrushWithHandle();
357 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
360 hBrush
= pbrush
->BaseObject
.hHmgr
;
362 pbrush
->flAttrs
|= BR_IS_SOLID
;
364 pbrush
->BrushAttr
.lbColor
= Color
& 0x00FFFFFF;
365 /* FIXME: Fill in the rest of fields!!! */
367 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
374 IntGdiCreateNullBrush(VOID
)
379 pbrush
= BRUSH_AllocBrushWithHandle();
382 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
385 hBrush
= pbrush
->BaseObject
.hHmgr
;
387 pbrush
->flAttrs
|= BR_IS_NULL
;
388 GDIOBJ_vUnlockObject(&pbrush
->BaseObject
);
395 IntGdiSetSolidBrushColor(HBRUSH hBrush
, COLORREF Color
)
399 pbrush
= BRUSH_ShareLockBrush(hBrush
);
400 if (pbrush
->flAttrs
& BR_IS_SOLID
)
402 pbrush
->BrushAttr
.lbColor
= Color
& 0xFFFFFF;
404 BRUSH_ShareUnlockBrush(pbrush
);
408 /* PUBLIC FUNCTIONS ***********************************************************/
413 IN PVOID BitmapInfoAndData
,
415 IN UINT BitmapInfoSize
,
420 BITMAPINFO
*SafeBitmapInfoAndData
;
421 NTSTATUS Status
= STATUS_SUCCESS
;
424 SafeBitmapInfoAndData
= EngAllocMem(FL_ZERO_MEMORY
, BitmapInfoSize
, TAG_DIB
);
425 if (SafeBitmapInfoAndData
== NULL
)
427 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
433 ProbeForRead(BitmapInfoAndData
, BitmapInfoSize
, 1);
434 RtlCopyMemory(SafeBitmapInfoAndData
, BitmapInfoAndData
, BitmapInfoSize
);
436 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
438 Status
= _SEH2_GetExceptionCode();
442 if (!NT_SUCCESS(Status
))
444 EngFreeMem(SafeBitmapInfoAndData
);
445 SetLastNtError(Status
);
449 hBrush
= IntGdiCreateDIBBrush(SafeBitmapInfoAndData
,
454 EngFreeMem(SafeBitmapInfoAndData
);
461 NtGdiCreateHatchBrushInternal(
466 return IntGdiCreateHatchBrush(Style
, Color
);
471 NtGdiCreatePatternBrushInternal(
476 return IntGdiCreatePatternBrush(hBitmap
);
481 NtGdiCreateSolidBrush(COLORREF Color
,
482 IN OPTIONAL HBRUSH hbr
)
484 return IntGdiCreateSolidBrush(Color
);