mirror of
https://github.com/reactos/reactos.git
synced 2024-07-31 08:39:05 +00:00
[Win32k]
- Plug in the new dc attribute support and add the brush pen and region attribute support. svn path=/trunk/; revision=44796
This commit is contained in:
parent
a22d21e20c
commit
91cbcdc152
|
@ -128,4 +128,8 @@ PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo);
|
EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo);
|
||||||
|
|
||||||
|
PVOID FASTCALL AllocateObjectAttr(VOID);
|
||||||
|
|
||||||
|
VOID FASTCALL FreeObjectAttr(PVOID);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,20 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define GDIOBJATTRFREE 170
|
||||||
|
|
||||||
|
typedef struct _GDI_OBJ_ATTR_FREELIST
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry;
|
||||||
|
DWORD nEntries;
|
||||||
|
PVOID AttrList[GDIOBJATTRFREE];
|
||||||
|
} GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST;
|
||||||
|
|
||||||
|
typedef struct _GDI_OBJ_ATTR_ENTRY
|
||||||
|
{
|
||||||
|
RGN_ATTR Attr[GDIOBJATTRFREE];
|
||||||
|
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
|
||||||
|
|
||||||
static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
|
static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
|
||||||
{
|
{
|
||||||
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
|
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
|
||||||
|
@ -21,6 +35,134 @@ static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
|
||||||
{0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
|
{0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
FASTCALL
|
||||||
|
AllocateObjectAttr(VOID)
|
||||||
|
{
|
||||||
|
PTHREADINFO pti;
|
||||||
|
PPROCESSINFO ppi;
|
||||||
|
PVOID pAttr;
|
||||||
|
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
|
||||||
|
PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
if (pti->pgdiBrushAttr)
|
||||||
|
{
|
||||||
|
pAttr = pti->pgdiBrushAttr; // Get the free one.
|
||||||
|
pti->pgdiBrushAttr = NULL;
|
||||||
|
return pAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi = PsGetCurrentProcessWin32Process();
|
||||||
|
|
||||||
|
if (!ppi->pBrushAttrList) // If set point is null, allocate new group.
|
||||||
|
{
|
||||||
|
pGdiObjAttrEntry = EngAllocUserMem(sizeof(GDI_OBJ_ATTR_ENTRY), 0);
|
||||||
|
|
||||||
|
if (!pGdiObjAttrEntry)
|
||||||
|
{
|
||||||
|
DPRINT1("Attr Failed User Allocation!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("AllocObjectAttr User 0x%x\n",pGdiObjAttrEntry);
|
||||||
|
|
||||||
|
pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
|
||||||
|
sizeof(GDI_OBJ_ATTR_FREELIST),
|
||||||
|
GDITAG_BRUSH_FREELIST);
|
||||||
|
if ( !pGdiObjAttrFreeList )
|
||||||
|
{
|
||||||
|
EngFreeUserMem(pGdiObjAttrEntry);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(pGdiObjAttrFreeList, sizeof(GDI_OBJ_ATTR_FREELIST));
|
||||||
|
|
||||||
|
DPRINT("AllocObjectAttr Ex 0x%x\n",pGdiObjAttrFreeList);
|
||||||
|
|
||||||
|
InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
|
||||||
|
|
||||||
|
pGdiObjAttrFreeList->nEntries = GDIOBJATTRFREE;
|
||||||
|
// Start at the bottom up and set end of free list point.
|
||||||
|
ppi->pBrushAttrList = &pGdiObjAttrEntry->Attr[GDIOBJATTRFREE-1];
|
||||||
|
// Build the free attr list.
|
||||||
|
for ( i = 0; i < GDIOBJATTRFREE; i++)
|
||||||
|
{
|
||||||
|
pGdiObjAttrFreeList->AttrList[i] = &pGdiObjAttrEntry->Attr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pAttr = ppi->pBrushAttrList;
|
||||||
|
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
|
||||||
|
|
||||||
|
// Free the list when it is full!
|
||||||
|
if ( pGdiObjAttrFreeList->nEntries-- == 1)
|
||||||
|
{ // No more free entries, so yank the list.
|
||||||
|
RemoveEntryList( &pGdiObjAttrFreeList->Entry );
|
||||||
|
|
||||||
|
ExFreePoolWithTag( pGdiObjAttrFreeList, GDITAG_BRUSH_FREELIST );
|
||||||
|
|
||||||
|
if ( IsListEmpty( &ppi->GDIBrushAttrFreeList ) )
|
||||||
|
{
|
||||||
|
ppi->pBrushAttrList = NULL;
|
||||||
|
return pAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi->pBrushAttrList = pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1];
|
||||||
|
|
||||||
|
return pAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
FreeObjectAttr(PVOID pAttr)
|
||||||
|
{
|
||||||
|
PTHREADINFO pti;
|
||||||
|
PPROCESSINFO ppi;
|
||||||
|
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
|
||||||
|
|
||||||
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
|
if (!pti) return;
|
||||||
|
|
||||||
|
if (!pti->pgdiBrushAttr)
|
||||||
|
{ // If it is null, just cache it for the next time.
|
||||||
|
pti->pgdiBrushAttr = pAttr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi = PsGetCurrentProcessWin32Process();
|
||||||
|
|
||||||
|
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
|
||||||
|
|
||||||
|
// We add to the list of free entries, so this will grows!
|
||||||
|
if ( IsListEmpty(&ppi->GDIBrushAttrFreeList) ||
|
||||||
|
pGdiObjAttrFreeList->nEntries == GDIOBJATTRFREE )
|
||||||
|
{
|
||||||
|
pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
|
||||||
|
sizeof(GDI_OBJ_ATTR_FREELIST),
|
||||||
|
GDITAG_BRUSH_FREELIST);
|
||||||
|
if ( !pGdiObjAttrFreeList )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
|
||||||
|
pGdiObjAttrFreeList->nEntries = 0;
|
||||||
|
}
|
||||||
|
// Up count, save the entry and set end of free list point.
|
||||||
|
++pGdiObjAttrFreeList->nEntries; // Top Down...
|
||||||
|
pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1] = pAttr;
|
||||||
|
ppi->pBrushAttrList = pAttr;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
INTERNAL_CALL
|
INTERNAL_CALL
|
||||||
BRUSH_Cleanup(PVOID ObjectBody)
|
BRUSH_Cleanup(PVOID ObjectBody)
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
#define GDIDCATTRFREE 8
|
#define GDIDCATTRFREE 8
|
||||||
|
|
||||||
typedef struct _GDI_DC_ATTR_FREELIST
|
typedef struct _GDI_DC_ATTR_FREELIST
|
||||||
|
@ -159,35 +158,31 @@ DC_AllocateDcAttr(HDC hDC)
|
||||||
{
|
{
|
||||||
PVOID NewMem = NULL;
|
PVOID NewMem = NULL;
|
||||||
PDC pDC;
|
PDC pDC;
|
||||||
HANDLE Pid = NtCurrentProcess();
|
|
||||||
ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
|
|
||||||
|
|
||||||
NTSTATUS Status = ZwAllocateVirtualMemory(Pid,
|
|
||||||
&NewMem,
|
|
||||||
0,
|
|
||||||
&MemSize,
|
|
||||||
MEM_COMMIT|MEM_RESERVE,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
{
|
{
|
||||||
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
|
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
|
||||||
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
||||||
|
|
||||||
|
NewMem = AllocateDcAttr();
|
||||||
|
|
||||||
// FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
|
// FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
|
if (NewMem)
|
||||||
{
|
{
|
||||||
RtlZeroMemory(NewMem, MemSize);
|
RtlZeroMemory(NewMem, sizeof(DC_ATTR));
|
||||||
Entry->UserData = NewMem;
|
Entry->UserData = NewMem;
|
||||||
DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
|
DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("DC_ATTR not allocated!\n");
|
DPRINT1("DC_ATTR not allocated!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
pDC = DC_LockDc(hDC);
|
pDC = DC_LockDc(hDC);
|
||||||
ASSERT(pDC->pdcattr == &pDC->dcattr);
|
ASSERT(pDC->pdcattr == &pDC->dcattr);
|
||||||
if(NewMem)
|
if (NewMem)
|
||||||
{
|
{
|
||||||
pDC->pdcattr = NewMem; // Store pointer
|
pDC->pdcattr = NewMem; // Store pointer
|
||||||
}
|
}
|
||||||
|
@ -198,7 +193,6 @@ VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
DC_FreeDcAttr(HDC DCToFree )
|
DC_FreeDcAttr(HDC DCToFree )
|
||||||
{
|
{
|
||||||
HANDLE Pid = NtCurrentProcess();
|
|
||||||
PDC pDC = DC_LockDc(DCToFree);
|
PDC pDC = DC_LockDc(DCToFree);
|
||||||
if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object!
|
if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object!
|
||||||
pDC->pdcattr = &pDC->dcattr;
|
pDC->pdcattr = &pDC->dcattr;
|
||||||
|
@ -208,18 +202,10 @@ DC_FreeDcAttr(HDC DCToFree )
|
||||||
{
|
{
|
||||||
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
|
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
|
||||||
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
||||||
if(Entry->UserData)
|
if (Entry->UserData)
|
||||||
{
|
{
|
||||||
ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE;
|
FreeDcAttr(Entry->UserData);
|
||||||
NTSTATUS Status = ZwFreeVirtualMemory(Pid,
|
Entry->UserData = NULL;
|
||||||
&Entry->UserData,
|
|
||||||
&MemSize,
|
|
||||||
MEM_RELEASE);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("DC_FreeDC DC_ATTR 0x%x\n", Entry->UserData);
|
|
||||||
Entry->UserData = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
@ -264,7 +250,7 @@ DCU_SyncDcAttrtoUser(PDC dc)
|
||||||
CopytoUserDcAttr( dc, pdcattr);
|
CopytoUserDcAttr( dc, pdcattr);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
// LOL! DCU_ Sync hDc Attr to User,,, need it speeled out for you?
|
||||||
BOOL
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
DCU_SynchDcAttrtoUser(HDC hDC)
|
DCU_SynchDcAttrtoUser(HDC hDC)
|
||||||
|
|
Loading…
Reference in a new issue