* Sync up to trunk head (r65095).
[reactos.git] / win32ss / gdi / gdi32 / objects / metafile.c
1 #include <precomp.h>
2 #include <debug.h>
3
4 /* DEFINES *******************************************************************/
5
6
7 /* PRIVATE DATA **************************************************************/
8
9 PMF_ENTRY hMF_List = NULL;
10 DWORD hMFCount = 0;
11
12 /* INTERNAL FUNCTIONS ********************************************************/
13
14 BOOL
15 MF_CreateMFDC ( HGDIOBJ hMDC,
16 PMETAFILEDC pmfDC )
17 {
18 PMF_ENTRY pMFME;
19
20 pMFME = LocalAlloc(LMEM_ZEROINIT, sizeof(MF_ENTRY));
21 if (!pMFME)
22 {
23 return FALSE;
24 }
25
26 if (hMF_List == NULL)
27 {
28 hMF_List = pMFME;
29 InitializeListHead(&hMF_List->List);
30 }
31 else
32 InsertTailList(&hMF_List->List, &pMFME->List);
33
34 pMFME->hmDC = hMDC;
35 pMFME->pmfDC = pmfDC;
36
37 hMFCount++;
38 return TRUE;
39 }
40
41
42 PMETAFILEDC
43 MF_GetMFDC ( HGDIOBJ hMDC )
44 {
45 PMF_ENTRY pMFME = hMF_List;
46
47 do
48 {
49 if ( pMFME->hmDC == hMDC ) return pMFME->pmfDC;
50 pMFME = (PMF_ENTRY) pMFME->List.Flink;
51 }
52 while ( pMFME != hMF_List );
53
54 return NULL;
55 }
56
57
58 BOOL
59 MF_DeleteMFDC ( HGDIOBJ hMDC )
60 {
61 PMF_ENTRY pMFME = hMF_List;
62
63 do
64 {
65 if ( pMFME->hmDC == hMDC)
66 {
67 RemoveEntryList(&pMFME->List);
68 LocalFree ( pMFME );
69 hMFCount--;
70 if (!hMFCount) hMF_List = NULL;
71 return TRUE;
72 }
73 pMFME = (PMF_ENTRY) pMFME->List.Flink;
74 }
75 while ( pMFME != hMF_List );
76
77 return FALSE;
78 }
79
80 /* FUNCTIONS *****************************************************************/
81
82 /*
83 * @unimplemented
84 */
85 HMETAFILE
86 WINAPI
87 CloseMetaFile(
88 HDC a0
89 )
90 {
91 return 0;
92 }
93
94
95 /*
96 * @implemented
97 */
98 HMETAFILE
99 WINAPI
100 CopyMetaFileW(
101 HMETAFILE hmfSrc,
102 LPCWSTR lpszFile
103 )
104 {
105 return NULL;
106 }
107
108
109 /*
110 * @implemented
111 */
112 HMETAFILE
113 WINAPI
114 CopyMetaFileA(
115 HMETAFILE hmfSrc,
116 LPCSTR lpszFile
117 )
118 {
119 NTSTATUS Status;
120 PWSTR lpszFileW;
121 HMETAFILE rc = 0;
122
123 Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
124 if (!NT_SUCCESS (Status))
125 SetLastError (RtlNtStatusToDosError(Status));
126 else
127 {
128 rc = CopyMetaFileW( hmfSrc, lpszFileW );
129 HEAP_free ( lpszFileW );
130 }
131
132 return rc;
133 }
134
135
136 /*
137 * @implemented
138 */
139 HDC
140 WINAPI
141 CreateMetaFileW(
142 LPCWSTR lpszFile
143 )
144 {
145 HANDLE hFile;
146 HDC hmDC;
147 PMETAFILEDC pmfDC = LocalAlloc(LMEM_ZEROINIT, sizeof(METAFILEDC));
148 if (!pmfDC) return NULL;
149
150 pmfDC->mh.mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD);
151 pmfDC->mh.mtVersion = 0x0300;
152 pmfDC->mh.mtSize = pmfDC->mh.mtHeaderSize;
153
154 pmfDC->hPen = GetStockObject(BLACK_PEN);
155 pmfDC->hBrush = GetStockObject(WHITE_BRUSH);
156 pmfDC->hFont = GetStockObject(DEVICE_DEFAULT_FONT);
157 pmfDC->hBitmap = GetStockObject(DEFAULT_BITMAP);
158 pmfDC->hPalette = GetStockObject(DEFAULT_PALETTE);
159
160 if (lpszFile) /* disk based metafile */
161 {
162 pmfDC->mh.mtType = METAFILE_DISK;
163
164 if(!GetFullPathName( lpszFile,
165 MAX_PATH,
166 (LPTSTR) &pmfDC->Filename,
167 (LPTSTR*) &lpszFile))
168 {
169 LocalFree(pmfDC);
170 return NULL;
171 }
172
173 if ((hFile = CreateFileW(pmfDC->Filename, GENERIC_WRITE, 0, NULL,
174 CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE)
175 {
176 LocalFree(pmfDC);
177 return NULL;
178 }
179
180 if (!WriteFile( hFile, &pmfDC->mh, sizeof(pmfDC->mh), &pmfDC->dwWritten, NULL ))
181 {
182 LocalFree(pmfDC);
183 return NULL;
184 }
185 pmfDC->hFile = hFile;
186 }
187 else /* memory based metafile */
188 pmfDC->mh.mtType = METAFILE_MEMORY;
189
190 hmDC = NtGdiCreateClientObj ( GDI_OBJECT_TYPE_METADC );
191
192 MF_CreateMFDC ( hmDC, pmfDC );
193
194 return hmDC;
195 }
196
197
198 /*
199 * @implemented
200 */
201 HDC
202 WINAPI
203 CreateMetaFileA(
204 LPCSTR lpszFile
205 )
206 {
207 NTSTATUS Status;
208 PWSTR lpszFileW;
209 HDC rc = 0;
210
211 Status = HEAP_strdupA2W ( &lpszFileW, lpszFile );
212 if (!NT_SUCCESS (Status))
213 SetLastError (RtlNtStatusToDosError(Status));
214 else
215 {
216 rc = CreateMetaFileW( lpszFileW );
217 HEAP_free ( lpszFileW );
218 }
219 return rc;
220 }
221
222
223 /*
224 * @unimplemented
225 */
226 BOOL
227 WINAPI
228 DeleteMetaFile(
229 HMETAFILE a0
230 )
231 {
232 return FALSE;
233 }
234
235
236 /*
237 * @implemented
238 */
239 HMETAFILE
240 WINAPI
241 GetMetaFileW(
242 LPCWSTR lpszMetaFile
243 )
244 {
245 return NULL;
246 }
247
248
249 /*
250 * @implemented
251 */
252 HMETAFILE
253 WINAPI
254 GetMetaFileA(
255 LPCSTR lpszMetaFile
256 )
257 {
258 NTSTATUS Status;
259 LPWSTR lpszMetaFileW;
260 HMETAFILE rc = 0;
261
262 Status = HEAP_strdupA2W ( &lpszMetaFileW, lpszMetaFile );
263 if (!NT_SUCCESS (Status))
264 SetLastError (RtlNtStatusToDosError(Status));
265 else
266 {
267 rc = GetMetaFileW( lpszMetaFileW );
268 HEAP_free ( lpszMetaFileW );
269 }
270
271 return rc;
272 }
273
274
275 /*
276 * @unimplemented
277 */
278 UINT
279 WINAPI
280 GetMetaFileBitsEx(
281 HMETAFILE a0,
282 UINT a1,
283 LPVOID a2
284 )
285 {
286 UNIMPLEMENTED;
287 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
288 return 0;
289 }
290
291 /*
292 * @unimplemented
293 */
294 HMETAFILE
295 WINAPI
296 SetMetaFileBitsEx(
297 UINT size,
298 CONST BYTE *lpData
299 )
300 {
301 const METAHEADER *mh_in = (const METAHEADER *)lpData;
302
303 if (size & 1) return 0;
304
305 if (!size || mh_in->mtType != METAFILE_MEMORY || mh_in->mtVersion != 0x300 ||
306 mh_in->mtHeaderSize != sizeof(METAHEADER) / 2)
307 {
308 DPRINT1("SetMetaFileBitsEx failed: %lu,%lu,0x&lx,%lu\n",
309 size, mh_in->mtType, mh_in->mtVersion, mh_in->mtHeaderSize);
310 SetLastError(ERROR_INVALID_DATA);
311 return 0;
312 }
313
314 UNIMPLEMENTED;
315 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
316 return 0;
317 }
318
319 /*
320 * @implemented
321 */
322 BOOL
323 WINAPI
324 GdiIsPlayMetafileDC(HDC hDC)
325 {
326 PLDC pLDC = GdiGetLDC(hDC);
327 if ( pLDC )
328 {
329 if ( pLDC->Flags & LDC_PLAY_MFDC ) return TRUE;
330 }
331 return FALSE;
332 }
333
334 /*
335 * @unimplemented
336 */
337 BOOL
338 WINAPI
339 PlayMetaFile(
340 HDC a0,
341 HMETAFILE a1
342 )
343 {
344 UNIMPLEMENTED;
345 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
346 return FALSE;
347 }
348
349 /*
350 * @unimplemented
351 */
352 BOOL
353 WINAPI
354 PlayMetaFileRecord(
355 HDC a0,
356 LPHANDLETABLE a1,
357 LPMETARECORD a2,
358 UINT a3
359 )
360 {
361 UNIMPLEMENTED;
362 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
363 return FALSE;
364 }
365
366 /*
367 * @unimplemented
368 */
369 BOOL
370 WINAPI
371 EnumMetaFile(
372 HDC a0,
373 HMETAFILE a1,
374 MFENUMPROC a2,
375 LPARAM a3
376 )
377 {
378 UNIMPLEMENTED;
379 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
380 return FALSE;
381 }
382
383 /*
384 * @unimplemented
385 */
386 UINT
387 WINAPI
388 GetWinMetaFileBits(
389 HENHMETAFILE a0,
390 UINT a1,
391 LPBYTE a2,
392 INT a3,
393 HDC a4
394 )
395 {
396 UNIMPLEMENTED;
397 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
398 return 0;
399 }
400
401 /*
402 * @unimplemented
403 */
404 HENHMETAFILE
405 WINAPI
406 SetWinMetaFileBits(
407 UINT a0,
408 CONST BYTE *a1,
409 HDC a2,
410 CONST METAFILEPICT *a3)
411 {
412 UNIMPLEMENTED;
413 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
414 return 0;
415 }
416
417 /*
418 * @implemented
419 */
420 BOOL
421 WINAPI
422 GdiIsMetaFileDC(HDC hDC)
423 {
424 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
425 {
426 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
427 return TRUE;
428 else
429 {
430 PLDC pLDC = GdiGetLDC(hDC);
431 if ( !pLDC )
432 {
433 SetLastError(ERROR_INVALID_HANDLE);
434 return FALSE;
435 }
436 if ( pLDC->iType == LDC_EMFLDC) return TRUE;
437 }
438 }
439 return FALSE;
440 }
441
442 /*
443 * @implemented
444 */
445 BOOL
446 WINAPI
447 GdiIsMetaPrintDC(HDC hDC)
448 {
449
450 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
451 {
452 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
453 return FALSE;
454 else
455 {
456 PLDC pLDC = GdiGetLDC(hDC);
457 if ( !pLDC )
458 {
459 SetLastError(ERROR_INVALID_HANDLE);
460 return FALSE;
461 }
462 if ( pLDC->Flags & LDC_META_PRINT) return TRUE;
463 }
464 }
465 return FALSE;
466 }
467
468 /*
469 * @unimplemented
470 */
471 METAFILEPICT *
472 WINAPI
473 GdiCreateLocalMetaFilePict(HENHMETAFILE hmo)
474 {
475 UNIMPLEMENTED;
476 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
477 return 0;
478 }
479
480 /*
481 * @unimplemented
482 */
483 HANDLE
484 WINAPI
485 GdiConvertMetaFilePict(HGLOBAL hMem)
486 {
487 UNIMPLEMENTED;
488 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
489 return 0;
490 }