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_AllocateDcAttr(HDC hDC
)
163 INT Index
= GDI_HANDLE_GET_INDEX((HGDIOBJ
)hDC
);
164 PGDI_TABLE_ENTRY Entry
= &GdiHandleTable
->Entries
[Index
];
166 NewMem
= AllocateDcAttr();
168 // FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
172 RtlZeroMemory(NewMem
, sizeof(DC_ATTR
));
173 Entry
->UserData
= NewMem
;
174 DPRINT("DC_ATTR allocated! 0x%x\n",NewMem
);
178 DPRINT1("DC_ATTR not allocated!\n");
181 pDC
= DC_LockDc(hDC
);
182 ASSERT(pDC
->pdcattr
== &pDC
->dcattr
);
185 pDC
->pdcattr
= NewMem
; // Store pointer
192 DC_FreeDcAttr(HDC DCToFree
)
194 PDC pDC
= DC_LockDc(DCToFree
);
195 if (pDC
->pdcattr
== &pDC
->dcattr
) return; // Internal DC object!
196 pDC
->pdcattr
= &pDC
->dcattr
;
200 INT Index
= GDI_HANDLE_GET_INDEX((HGDIOBJ
)DCToFree
);
201 PGDI_TABLE_ENTRY Entry
= &GdiHandleTable
->Entries
[Index
];
204 FreeDcAttr(Entry
->UserData
);
205 Entry
->UserData
= NULL
;
213 CopytoUserDcAttr(PDC dc
, PDC_ATTR pdcattr
)
215 NTSTATUS Status
= STATUS_SUCCESS
;
216 dc
->dcattr
.mxWorldToDevice
= dc
->dclevel
.mxWorldToDevice
;
217 dc
->dcattr
.mxDeviceToWorld
= dc
->dclevel
.mxDeviceToWorld
;
218 dc
->dcattr
.mxWorldToPage
= dc
->dclevel
.mxWorldToPage
;
222 ProbeForWrite( pdcattr
,
225 RtlCopyMemory( pdcattr
,
229 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
231 Status
= _SEH2_GetExceptionCode();
237 // FIXME: wtf? 2 functions, where one has a typo in the name????
240 DCU_SyncDcAttrtoUser(PDC dc
)
242 PDC_ATTR pdcattr
= dc
->pdcattr
;
244 if (pdcattr
== &dc
->dcattr
) return TRUE
; // No need to copy self.
246 CopytoUserDcAttr( dc
, pdcattr
);
249 // LOL! DCU_ Sync hDc Attr to User,,, need it speeled out for you?
252 DCU_SynchDcAttrtoUser(HDC hDC
)
255 PDC pDC
= DC_LockDc ( hDC
);
256 if (!pDC
) return FALSE
;
257 Ret
= DCU_SyncDcAttrtoUser(pDC
);