2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Functions for creation and destruction of DCs
5 * FILE: subsystem/win32/win32k/objects/dcattr.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
14 #define GDIDCATTRFREE 8
16 typedef struct _GDI_DC_ATTR_FREELIST
20 PVOID AttrList
[GDIDCATTRFREE
];
21 } GDI_DC_ATTR_FREELIST
, *PGDI_DC_ATTR_FREELIST
;
23 typedef struct _GDI_DC_ATTR_ENTRY
25 DC_ATTR Attr
[GDIDCATTRFREE
];
26 } GDI_DC_ATTR_ENTRY
, *PGDI_DC_ATTR_ENTRY
;
36 PGDI_DC_ATTR_FREELIST pGdiDcAttrFreeList
;
37 PGDI_DC_ATTR_ENTRY pGdiDcAttrEntry
;
40 pti
= PsGetCurrentThreadWin32Thread();
43 pDc_Attr
= pti
->pgdiDcattr
; // Get the free one.
44 pti
->pgdiDcattr
= NULL
;
48 ppi
= PsGetCurrentProcessWin32Process();
50 if (!ppi
->pDCAttrList
) // If set point is null, allocate new group.
52 pGdiDcAttrEntry
= EngAllocUserMem(sizeof(GDI_DC_ATTR_ENTRY
), 0);
56 DPRINT1("DcAttr Failed User Allocation!\n");
60 DPRINT("AllocDcAttr User 0x%x\n",pGdiDcAttrEntry
);
62 pGdiDcAttrFreeList
= ExAllocatePoolWithTag( PagedPool
,
63 sizeof(GDI_DC_ATTR_FREELIST
),
65 if ( !pGdiDcAttrFreeList
)
67 EngFreeUserMem(pGdiDcAttrEntry
);
71 RtlZeroMemory(pGdiDcAttrFreeList
, sizeof(GDI_DC_ATTR_FREELIST
));
73 DPRINT("AllocDcAttr Ex 0x%x\n",pGdiDcAttrFreeList
);
75 InsertHeadList( &ppi
->GDIDcAttrFreeList
, &pGdiDcAttrFreeList
->Entry
);
77 pGdiDcAttrFreeList
->nEntries
= GDIDCATTRFREE
;
78 // Start at the bottom up and set end of free list point.
79 ppi
->pDCAttrList
= &pGdiDcAttrEntry
->Attr
[GDIDCATTRFREE
-1];
80 // Build the free attr list.
81 for ( i
= 0; i
< GDIDCATTRFREE
; i
++)
83 pGdiDcAttrFreeList
->AttrList
[i
] = &pGdiDcAttrEntry
->Attr
[i
];
87 pDc_Attr
= ppi
->pDCAttrList
;
88 pGdiDcAttrFreeList
= (PGDI_DC_ATTR_FREELIST
)ppi
->GDIDcAttrFreeList
.Flink
;
90 // Free the list when it is full!
91 if ( pGdiDcAttrFreeList
->nEntries
-- == 1)
92 { // No more free entries, so yank the list.
93 RemoveEntryList( &pGdiDcAttrFreeList
->Entry
);
95 ExFreePoolWithTag( pGdiDcAttrFreeList
, GDITAG_DC_FREELIST
);
97 if ( IsListEmpty( &ppi
->GDIDcAttrFreeList
) )
99 ppi
->pDCAttrList
= NULL
;
103 pGdiDcAttrFreeList
= (PGDI_DC_ATTR_FREELIST
)ppi
->GDIDcAttrFreeList
.Flink
;
106 ppi
->pDCAttrList
= pGdiDcAttrFreeList
->AttrList
[pGdiDcAttrFreeList
->nEntries
-1];
113 FreeDcAttr(PDC_ATTR pDc_Attr
)
117 PGDI_DC_ATTR_FREELIST pGdiDcAttrFreeList
;
119 pti
= PsGetCurrentThreadWin32Thread();
123 if (!pti
->pgdiDcattr
)
124 { // If it is null, just cache it for the next time.
125 pti
->pgdiDcattr
= pDc_Attr
;
129 ppi
= PsGetCurrentProcessWin32Process();
131 pGdiDcAttrFreeList
= (PGDI_DC_ATTR_FREELIST
)ppi
->GDIDcAttrFreeList
.Flink
;
133 // We add to the list of free entries, so this will grows!
134 if ( IsListEmpty(&ppi
->GDIDcAttrFreeList
) ||
135 pGdiDcAttrFreeList
->nEntries
== GDIDCATTRFREE
)
137 pGdiDcAttrFreeList
= ExAllocatePoolWithTag( PagedPool
,
138 sizeof(GDI_DC_ATTR_FREELIST
),
140 if ( !pGdiDcAttrFreeList
)
144 InsertHeadList( &ppi
->GDIDcAttrFreeList
, &pGdiDcAttrFreeList
->Entry
);
145 pGdiDcAttrFreeList
->nEntries
= 0;
147 // Up count, save the entry and set end of free list point.
148 ++pGdiDcAttrFreeList
->nEntries
; // Top Down...
149 pGdiDcAttrFreeList
->AttrList
[pGdiDcAttrFreeList
->nEntries
-1] = pDc_Attr
;
150 ppi
->pDCAttrList
= pDc_Attr
;
157 DC_AllocDcAttr(PDC pdc
)
159 DC_AllocateDcAttr(pdc
->BaseObject
.hHmgr
);
160 *pdc
->pdcattr
= pdc
->dcattr
;
164 // CHECK against current head
167 DC_AllocateDcAttr(HDC hDC
)
171 HANDLE Pid
= NtCurrentProcess();
172 ULONG MemSize
= sizeof(DC_ATTR
); //PAGE_SIZE it will allocate that size
174 NTSTATUS Status
= ZwAllocateVirtualMemory(Pid
,
178 MEM_COMMIT
|MEM_RESERVE
,
181 INT Index
= GDI_HANDLE_GET_INDEX((HGDIOBJ
)hDC
);
182 PGDI_TABLE_ENTRY Entry
= &GdiHandleTable
->Entries
[Index
];
183 // FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
184 if (NT_SUCCESS(Status
))
186 RtlZeroMemory(NewMem
, MemSize
);
187 Entry
->UserData
= NewMem
;
188 DPRINT("DC_ATTR allocated! 0x%x\n",NewMem
);
192 DPRINT("DC_ATTR not allocated!\n");
195 pDC
= DC_LockDc(hDC
);
196 ASSERT(pDC
->pdcattr
== &pDC
->dcattr
);
199 pDC
->pdcattr
= NewMem
; // Store pointer
206 DC_vFreeDcAttr(PDC pdc
)
208 HANDLE Pid
= NtCurrentProcess();
210 PGDI_TABLE_ENTRY pent
;
212 if (pdc
->pdcattr
== &pdc
->dcattr
)
214 // Internal DC object!
218 pdc
->pdcattr
= &pdc
->dcattr
;
220 Index
= GDI_HANDLE_GET_INDEX(pdc
->BaseObject
.hHmgr
);
221 pent
= &GdiHandleTable
->Entries
[Index
];
224 ULONG MemSize
= sizeof(DC_ATTR
);
225 NTSTATUS Status
= ZwFreeVirtualMemory(Pid
,
229 if (!NT_SUCCESS(Status
))
231 DPRINT1("DC_FreeDC failed to free DC_ATTR 0x%p\n", pent
->UserData
);
234 pent
->UserData
= NULL
;
241 CopytoUserDcAttr(PDC dc
, PDC_ATTR pdcattr
)
243 NTSTATUS Status
= STATUS_SUCCESS
;
244 dc
->dcattr
.mxWorldToDevice
= dc
->dclevel
.mxWorldToDevice
;
245 dc
->dcattr
.mxDeviceToWorld
= dc
->dclevel
.mxDeviceToWorld
;
246 dc
->dcattr
.mxWorldToPage
= dc
->dclevel
.mxWorldToPage
;
250 ProbeForWrite(pdcattr
, sizeof(DC_ATTR
), 1);
251 RtlCopyMemory(pdcattr
, &dc
->dcattr
, sizeof(DC_ATTR
));
253 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
255 Status
= _SEH2_GetExceptionCode();
261 // FIXME: wtf? 2 functions, where one has a typo in the name????
264 DCU_SyncDcAttrtoUser(PDC dc
)
266 PDC_ATTR pdcattr
= dc
->pdcattr
;
268 if (pdcattr
== &dc
->dcattr
) return TRUE
; // No need to copy self.
270 CopytoUserDcAttr( dc
, pdcattr
);
273 // LOL! DCU_ Sync hDc Attr to User,,, need it speeled out for you?
276 DCU_SynchDcAttrtoUser(HDC hDC
)
279 PDC pDC
= DC_LockDc ( hDC
);
280 if (!pDC
) return FALSE
;
281 Ret
= DCU_SyncDcAttrtoUser(pDC
);