Merge from amd64 branch:
[reactos.git] / reactos / subsystems / win32 / win32k / objects / dcattr.c
1 /*
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)
7 */
8
9 #include <w32k.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14
15 VOID
16 FASTCALL
17 DC_AllocateDcAttr(HDC hDC)
18 {
19 PVOID NewMem = NULL;
20 PDC pDC;
21 HANDLE Pid = NtCurrentProcess();
22 ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
23
24 NTSTATUS Status = ZwAllocateVirtualMemory(Pid,
25 &NewMem,
26 0,
27 &MemSize,
28 MEM_COMMIT|MEM_RESERVE,
29 PAGE_READWRITE);
30 KeEnterCriticalRegion();
31 {
32 INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
33 PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
34 // FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
35 if (NT_SUCCESS(Status))
36 {
37 RtlZeroMemory(NewMem, MemSize);
38 Entry->UserData = NewMem;
39 DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
40 }
41 else
42 {
43 DPRINT("DC_ATTR not allocated!\n");
44 }
45 }
46 KeLeaveCriticalRegion();
47 pDC = DC_LockDc(hDC);
48 ASSERT(pDC->pdcattr == &pDC->dcattr);
49 if(NewMem)
50 {
51 pDC->pdcattr = NewMem; // Store pointer
52 }
53 DC_UnlockDc(pDC);
54 }
55
56 VOID
57 FASTCALL
58 DC_FreeDcAttr(HDC DCToFree )
59 {
60 HANDLE Pid = NtCurrentProcess();
61 PDC pDC = DC_LockDc(DCToFree);
62 if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object!
63 pDC->pdcattr = &pDC->dcattr;
64 DC_UnlockDc(pDC);
65
66 KeEnterCriticalRegion();
67 {
68 INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
69 PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
70 if(Entry->UserData)
71 {
72 ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE;
73 NTSTATUS Status = ZwFreeVirtualMemory(Pid,
74 &Entry->UserData,
75 &MemSize,
76 MEM_RELEASE);
77 if (NT_SUCCESS(Status))
78 {
79 DPRINT("DC_FreeDC DC_ATTR 0x%x\n", Entry->UserData);
80 Entry->UserData = NULL;
81 }
82 }
83 }
84 KeLeaveCriticalRegion();
85 }
86
87
88 static
89 VOID
90 CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
91 {
92 NTSTATUS Status = STATUS_SUCCESS;
93 dc->dcattr.mxWorldToDevice = dc->dclevel.mxWorldToDevice;
94 dc->dcattr.mxDeviceToWorld = dc->dclevel.mxDeviceToWorld;
95 dc->dcattr.mxWorldToPage = dc->dclevel.mxWorldToPage;
96
97 _SEH2_TRY
98 {
99 ProbeForWrite( pdcattr,
100 sizeof(DC_ATTR),
101 1);
102 RtlCopyMemory( pdcattr,
103 &dc->dcattr,
104 sizeof(DC_ATTR));
105 }
106 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
107 {
108 Status = _SEH2_GetExceptionCode();
109 ASSERT(FALSE);
110 }
111 _SEH2_END;
112 }
113
114 // FIXME: wtf? 2 functions, where one has a typo in the name????
115 BOOL
116 FASTCALL
117 DCU_SyncDcAttrtoUser(PDC dc)
118 {
119 PDC_ATTR pdcattr = dc->pdcattr;
120
121 if (pdcattr == &dc->dcattr) return TRUE; // No need to copy self.
122 ASSERT(pdcattr);
123 CopytoUserDcAttr( dc, pdcattr);
124 return TRUE;
125 }
126
127 BOOL
128 FASTCALL
129 DCU_SynchDcAttrtoUser(HDC hDC)
130 {
131 BOOL Ret;
132 PDC pDC = DC_LockDc ( hDC );
133 if (!pDC) return FALSE;
134 Ret = DCU_SyncDcAttrtoUser(pDC);
135 DC_UnlockDc( pDC );
136 return Ret;
137 }
138