- 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:
James Tabor 2009-12-28 18:10:03 +00:00
parent a22d21e20c
commit 91cbcdc152
3 changed files with 160 additions and 28 deletions

View file

@ -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

View file

@ -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)

View file

@ -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)