From 91cbcdc152ccfc144829e016d0a3902584d13be9 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 28 Dec 2009 18:10:03 +0000 Subject: [PATCH] [Win32k] - Plug in the new dc attribute support and add the brush pen and region attribute support. svn path=/trunk/; revision=44796 --- .../subsystems/win32/win32k/include/brush.h | 4 + .../subsystems/win32/win32k/objects/brush.c | 142 ++++++++++++++++++ .../subsystems/win32/win32k/objects/dcattr.c | 42 ++---- 3 files changed, 160 insertions(+), 28 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/brush.h b/reactos/subsystems/win32/win32k/include/brush.h index 2541fb9b23b..db7c5fbf082 100644 --- a/reactos/subsystems/win32/win32k/include/brush.h +++ b/reactos/subsystems/win32/win32k/include/brush.h @@ -128,4 +128,8 @@ PVOID NTAPI EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo); +PVOID FASTCALL AllocateObjectAttr(VOID); + +VOID FASTCALL FreeObjectAttr(PVOID); + #endif diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index 07cb63e1bc2..6e827fa7bae 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -11,6 +11,20 @@ #define NDEBUG #include +#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] = { {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 */ }; + +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 INTERNAL_CALL BRUSH_Cleanup(PVOID ObjectBody) diff --git a/reactos/subsystems/win32/win32k/objects/dcattr.c b/reactos/subsystems/win32/win32k/objects/dcattr.c index b5705003dff..c5de942f7aa 100644 --- a/reactos/subsystems/win32/win32k/objects/dcattr.c +++ b/reactos/subsystems/win32/win32k/objects/dcattr.c @@ -11,7 +11,6 @@ #define NDEBUG #include - #define GDIDCATTRFREE 8 typedef struct _GDI_DC_ATTR_FREELIST @@ -159,35 +158,31 @@ DC_AllocateDcAttr(HDC hDC) { PVOID NewMem = NULL; 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(); { INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC); PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index]; + + NewMem = AllocateDcAttr(); + // FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData - if (NT_SUCCESS(Status)) + + if (NewMem) { - RtlZeroMemory(NewMem, MemSize); - Entry->UserData = NewMem; - DPRINT("DC_ATTR allocated! 0x%x\n",NewMem); + RtlZeroMemory(NewMem, sizeof(DC_ATTR)); + Entry->UserData = NewMem; + DPRINT("DC_ATTR allocated! 0x%x\n",NewMem); } else { - DPRINT("DC_ATTR not allocated!\n"); + DPRINT1("DC_ATTR not allocated!\n"); } } KeLeaveCriticalRegion(); pDC = DC_LockDc(hDC); ASSERT(pDC->pdcattr == &pDC->dcattr); - if(NewMem) + if (NewMem) { pDC->pdcattr = NewMem; // Store pointer } @@ -198,7 +193,6 @@ VOID FASTCALL DC_FreeDcAttr(HDC DCToFree ) { - HANDLE Pid = NtCurrentProcess(); PDC pDC = DC_LockDc(DCToFree); if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object! pDC->pdcattr = &pDC->dcattr; @@ -208,18 +202,10 @@ DC_FreeDcAttr(HDC DCToFree ) { INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree); PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index]; - if(Entry->UserData) + if (Entry->UserData) { - ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE; - NTSTATUS Status = ZwFreeVirtualMemory(Pid, - &Entry->UserData, - &MemSize, - MEM_RELEASE); - if (NT_SUCCESS(Status)) - { - DPRINT("DC_FreeDC DC_ATTR 0x%x\n", Entry->UserData); - Entry->UserData = NULL; - } + FreeDcAttr(Entry->UserData); + Entry->UserData = NULL; } } KeLeaveCriticalRegion(); @@ -264,7 +250,7 @@ DCU_SyncDcAttrtoUser(PDC dc) CopytoUserDcAttr( dc, pdcattr); return TRUE; } - +// LOL! DCU_ Sync hDc Attr to User,,, need it speeled out for you? BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC hDC)