[NtGDI] Support Clipboard Metafile
[reactos.git] / win32ss / gdi / ntgdi / metafile.c
1 /*
2 * PROJECT: ReactOS Win32k Subsystem
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: win32ss/gdi/ntgdi/metafile.c
5 * PURPOSE: Metafile Implementations, Metafile Clipboard Data Xfers
6 * PROGRAMMERS: ...
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <win32k.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 // Need to move this to NtGdiTyp.h
17 #define GDITAG_TYPE_EMF 'XEFM' // EnhMetaFile
18 #define GDITAG_TYPE_MFP '_PFM' // MetaFile Picture
19
20 // Internal Use
21 typedef struct _METATYPEOBJ
22 {
23 BASEOBJECT BaseObject;
24 DWORD iType;
25 DWORD mm;
26 DWORD xExt;
27 DWORD yExt;
28 ULONG cjData;
29 PBYTE pjData[4];
30 } METATYPEOBJ, *PMETATYPEOBJ;
31
32
33 //
34 // Plug Me in Somewhere? Clipboard cleanup?
35 //
36 VOID
37 FASTCALL
38 METATYPEOBJ__vCleanup(PVOID ObjectBody)
39 {
40 PMETATYPEOBJ pmto = (PMETATYPEOBJ)ObjectBody;
41 GDIOBJ_hInsertObject(&pmto->BaseObject, GDI_OBJ_HMGR_POWNED);
42 GDIOBJ_vDeleteObject(&pmto->BaseObject);
43 }
44
45 /* System Service Calls ******************************************************/
46
47 /*
48 * @implemented
49 */
50 HDC
51 APIENTRY
52 NtGdiCreateMetafileDC(IN HDC hdc)
53 {
54 //if (hdc)
55 /* Call the internal function to create an alternative info DC */
56 return GreCreateCompatibleDC(hdc, TRUE);
57 // No HDC call NtUser.
58 //return UserGetDesktopDC(DCTYPE_INFO, TRUE, FALSE);
59 }
60
61 /*
62 * @implemented
63 */
64 HANDLE
65 APIENTRY
66 NtGdiCreateServerMetaFile(
67 IN DWORD iType,
68 IN ULONG cjData,
69 IN PBYTE pjData,
70 IN DWORD mm,
71 IN DWORD xExt,
72 IN DWORD yExt
73 )
74 {
75 BOOL Pass = TRUE;
76 PMETATYPEOBJ pmto;
77
78 if ( ( iType == GDITAG_TYPE_EMF || iType == GDITAG_TYPE_MFP ) &&
79 cjData &&
80 pjData )
81 {
82 pmto = (PMETATYPEOBJ)GDIOBJ_AllocObjWithHandle(GDIObjType_META_TYPE, sizeof(METATYPEOBJ) + cjData);
83 if ( pmto )
84 {
85 pmto->iType = iType;
86 pmto->mm = mm;
87 pmto->xExt = xExt;
88 pmto->yExt = yExt;
89 pmto->cjData = cjData;
90
91 _SEH2_TRY
92 {
93 ProbeForRead( pjData, cjData, 1 );
94 RtlCopyMemory( pmto->pjData, pjData, cjData) ;
95 }
96 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
97 {
98 Pass = FALSE;
99 }
100 _SEH2_END;
101
102 if (Pass)
103 {
104 GDIOBJ_vSetObjectOwner(&pmto->BaseObject, GDI_OBJ_HMGR_PUBLIC);
105 GDIOBJ_vDereferenceObject ((POBJ)pmto);
106 return pmto->BaseObject.hHmgr;
107 }
108 else
109 {
110 GDIOBJ_vDeleteObject(&pmto->BaseObject);
111 }
112 }
113 }
114 return NULL;
115 }
116
117 /*
118 * @implemented
119 */
120 ULONG
121 APIENTRY
122 NtGdiGetServerMetaFileBits(
123 IN HANDLE hmo,
124 IN ULONG cjData,
125 OUT OPTIONAL PBYTE pjData,
126 OUT PDWORD piType,
127 OUT PDWORD pmm,
128 OUT PDWORD pxExt,
129 OUT PDWORD pyExt
130 )
131 {
132 ULONG cjRet = 0;
133 PMETATYPEOBJ pmto;
134
135 pmto = (PMETATYPEOBJ) GDIOBJ_ShareLockObj ((HGDIOBJ) hmo, GDIObjType_META_TYPE);
136
137 if (!pmto)
138 return 0;
139
140 if ( pmto->iType == GDITAG_TYPE_EMF || pmto->iType == GDITAG_TYPE_MFP )
141 {
142 cjRet = pmto->cjData;
143
144 if ( cjData )
145 {
146 if (cjData == pmto->cjData)
147 {
148 _SEH2_TRY
149 {
150 ProbeForWrite( piType, sizeof(DWORD), 1);
151 *piType = pmto->iType;
152
153 ProbeForWrite( pmm, sizeof(DWORD), 1);
154 *pmm = pmto->mm;
155
156 ProbeForWrite( pxExt, sizeof(DWORD), 1);
157 *pxExt = pmto->xExt;
158
159 ProbeForWrite( pyExt, sizeof(DWORD), 1);
160 *pyExt = pmto->yExt;
161
162 ProbeForWrite( pjData, cjData, 1 );
163 RtlCopyMemory( pjData, pmto->pjData, cjData) ;
164 }
165 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
166 {
167 cjRet = 0;
168 }
169 _SEH2_END;
170 }
171 else
172 {
173 cjRet = 0;
174 }
175 }
176 }
177
178 GDIOBJ_vDereferenceObject ((POBJ)pmto);
179 return cjRet;
180 }
181
182 /*
183 * @unimplemented
184 */
185 LONG
186 APIENTRY
187 NtGdiConvertMetafileRect(IN HDC hDC,
188 IN OUT PRECTL pRect)
189 {
190 UNIMPLEMENTED;
191 return 0;
192 }
193
194 /* EOF */