-Fixed MESSAGE functions that were thunking down to 16 bits implementation.
[wine] / graphics / metafiledrv / init.c
1 /*
2  * Metafile driver initialisation functions
3  *
4  * Copyright 1996 Alexandre Julliard
5  */
6
7 #include "metafiledrv.h"
8 #include "dc.h"
9 #include "heap.h"
10 #include "global.h"
11 #include "metafile.h"
12 #include "debug.h"
13
14 #include <string.h>
15
16 static const DC_FUNCTIONS MFDRV_Funcs =
17 {
18     MFDRV_Arc,                       /* pArc */
19     MFDRV_BitBlt,                    /* pBitBlt */
20     NULL,                            /* pBitmapBits */  
21     MFDRV_Chord,                     /* pChord */
22     NULL,                            /* pCreateBitmap */
23     NULL, /* no implementation */    /* pCreateDC */
24     NULL, /* no implementation */    /* pDeleteDC */
25     NULL,                            /* pDeleteObject */
26     MFDRV_Ellipse,                   /* pEllipse */
27     NULL,                            /* pEnumDeviceFonts */
28     NULL,                            /* pEscape */
29     NULL,                            /* pExcludeClipRect */
30     NULL,                            /* pExcludeVisRect */
31     MFDRV_ExtFloodFill,              /* pExtFloodFill */
32     MFDRV_ExtTextOut,                /* pExtTextOut */
33     NULL,                            /* pGetCharWidth */
34     NULL, /* no implementation */    /* pGetPixel */
35     NULL,                            /* pGetTextExtentPoint */
36     NULL,                            /* pGetTextMetrics */
37     NULL,                            /* pIntersectClipRect */
38     NULL,                            /* pIntersectVisRect */
39     MFDRV_LineTo,                    /* pLineTo */
40     NULL,                            /* pLoadOEMResource */
41     MFDRV_MoveToEx,                  /* pMoveToEx */
42     NULL,                            /* pOffsetClipRgn */
43     MFDRV_OffsetViewportOrg,         /* pOffsetViewportOrg */
44     MFDRV_OffsetWindowOrg,           /* pOffsetWindowOrg */
45     MFDRV_PaintRgn,                  /* pPaintRgn */
46     MFDRV_PatBlt,                    /* pPatBlt */
47     MFDRV_Pie,                       /* pPie */
48     MFDRV_PolyPolygon,               /* pPolyPolygon */
49     NULL,                            /* pPolyPolyline */
50     MFDRV_Polygon,                   /* pPolygon */
51     MFDRV_Polyline,                  /* pPolyline */
52     NULL,                            /* pPolyBezier */
53     NULL,                            /* pRealizePalette */
54     MFDRV_Rectangle,                 /* pRectangle */
55     NULL,                            /* pRestoreDC */
56     MFDRV_RoundRect,                 /* pRoundRect */
57     NULL,                            /* pSaveDC */
58     MFDRV_ScaleViewportExt,          /* pScaleViewportExt */
59     MFDRV_ScaleWindowExt,            /* pScaleWindowExt */
60     NULL,                            /* pSelectClipRgn */
61     MFDRV_SelectObject,              /* pSelectObject */
62     NULL,                            /* pSelectPalette */
63     MFDRV_SetBkColor,                /* pSetBkColor */
64     NULL,                            /* pSetBkMode */
65     NULL,                            /* pSetDeviceClipping */
66     NULL,                            /* pSetDIBitsToDevice */
67     MFDRV_SetMapMode,                /* pSetMapMode */
68     NULL,                            /* pSetMapperFlags */
69     MFDRV_SetPixel,                  /* pSetPixel */
70     NULL,                            /* pSetPolyFillMode */
71     NULL,                            /* pSetROP2 */
72     NULL,                            /* pSetRelAbs */
73     NULL,                            /* pSetStretchBltMode */
74     NULL,                            /* pSetTextAlign */
75     NULL,                            /* pSetTextCharacterExtra */
76     MFDRV_SetTextColor,              /* pSetTextColor */
77     NULL,                            /* pSetTextJustification */
78     MFDRV_SetViewportExt,            /* pSetViewportExt */
79     MFDRV_SetViewportOrg,            /* pSetViewportOrg */
80     MFDRV_SetWindowExt,              /* pSetWindowExt */
81     MFDRV_SetWindowOrg,              /* pSetWindowOrg */
82     MFDRV_StretchBlt,                /* pStretchBlt */
83     NULL                             /* pStretchDIBits */
84 };
85
86
87
88 /**********************************************************************
89  *           MFDRV_AllocMetaFile
90  */
91 static DC *MFDRV_AllocMetaFile(void)
92 {
93     DC *dc;
94     METAFILEDRV_PDEVICE *physDev;
95     
96     if (!(dc = DC_AllocDC( &MFDRV_Funcs ))) return NULL;
97     dc->header.wMagic = METAFILE_DC_MAGIC;
98
99     physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(SystemHeap,0,sizeof(*physDev));
100     if (!physDev)
101     {
102         GDI_HEAP_FREE( dc->hSelf );
103         return NULL;
104     }
105     dc->physDev = physDev;
106
107     if (!(physDev->mh = HeapAlloc( SystemHeap, 0, sizeof(*physDev->mh) )))
108     {
109         HeapFree( SystemHeap, 0, physDev );
110         GDI_HEAP_FREE( dc->hSelf );
111         return NULL;
112     }
113
114     physDev->nextHandle = 0;
115
116     physDev->mh->mtHeaderSize   = sizeof(METAHEADER) / sizeof(WORD);
117     physDev->mh->mtVersion      = 0x0300;
118     physDev->mh->mtSize         = physDev->mh->mtHeaderSize;
119     physDev->mh->mtNoObjects    = 0;
120     physDev->mh->mtMaxRecord    = 0;
121     physDev->mh->mtNoParameters = 0;
122
123 /*    DC_InitDC( dc ); */
124     return dc;
125 }
126
127
128 /**********************************************************************
129 *            MFDRV_DeleteDC
130  */
131 static BOOL32 MFDRV_DeleteDC( DC *dc )
132 {
133     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
134     
135     if (physDev->mh) HeapFree( SystemHeap, 0, physDev->mh );
136     HeapFree( SystemHeap, 0, physDev );
137     dc->physDev = NULL;
138     GDI_FreeObject(dc->hSelf);
139     return TRUE;
140 }
141
142
143 /**********************************************************************
144  *           CreateMetaFile16   (GDI.125)
145  *
146  *  Create a new DC and associate it with a metafile. Pass a filename
147  *  to create a disk-based metafile, NULL to create a memory metafile.
148  *
149  * RETURNS
150  *  A handle to the metafile DC if successful, NULL on failure.
151  */
152 HDC16 WINAPI CreateMetaFile16( 
153                               LPCSTR filename /* Filename of disk metafile */
154 )
155 {
156     DC *dc;
157     METAFILEDRV_PDEVICE *physDev;
158     HFILE32 hFile;
159
160     TRACE(metafile, "'%s'\n", filename );
161
162     if (!(dc = MFDRV_AllocMetaFile())) return 0;
163     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
164     
165     if (filename)  /* disk based metafile */
166     {
167         physDev->mh->mtType = METAFILE_DISK;
168         if ((hFile = _lcreat32( filename, 0 )) == HFILE_ERROR32)
169         {
170             MFDRV_DeleteDC( dc );
171             return 0;
172         }
173         if (_lwrite32( hFile, (LPSTR)physDev->mh,
174                        sizeof(*physDev->mh)) == HFILE_ERROR32)
175         {
176             MFDRV_DeleteDC( dc );
177             return 0;
178         }
179         physDev->mh->mtNoParameters = hFile; /* store file descriptor here */
180                                     /* windows probably uses this too*/
181     }
182     else  /* memory based metafile */
183         physDev->mh->mtType = METAFILE_MEMORY;
184
185     TRACE(metafile, "returning %04x\n", dc->hSelf);
186     return dc->hSelf;
187 }
188
189 /**********************************************************************
190  *           CreateMetaFile32A   (GDI32.51)
191  */
192 HDC32 WINAPI CreateMetaFile32A( 
193                               LPCSTR filename /* Filename of disk metafile */
194 )
195 {
196   return CreateMetaFile16( filename );
197 }
198
199 /**********************************************************************
200  *          CreateMetaFile32W   (GDI32.52)
201  */
202 HDC32 WINAPI CreateMetaFile32W(LPCWSTR filename)
203 {
204     LPSTR filenameA;
205     HDC32 hReturnDC;
206
207     filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
208
209     hReturnDC = CreateMetaFile32A(filenameA);
210
211     HeapFree( GetProcessHeap(), 0, filenameA );
212
213     return hReturnDC;
214 }
215
216 static DC *METAFILE_CloseMetaFile( HDC32 hdc ) 
217 {
218     DC *dc;
219     HFILE32 hFile;
220     METAFILEDRV_PDEVICE *physDev;
221     
222     TRACE(metafile, "(%04x)\n", hdc );
223
224     if (!(dc = (DC *) GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
225     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
226
227     /* Construct the end of metafile record - this is documented
228      * in SDK Knowledgebase Q99334.
229      */
230
231     if (!MF_MetaParam0(dc, META_EOF))
232     {
233         MFDRV_DeleteDC( dc );
234         return 0;
235     }   
236
237     if (physDev->mh->mtType == METAFILE_DISK)  /* disk based metafile */
238     {
239         hFile = physDev->mh->mtNoParameters;
240         physDev->mh->mtNoParameters = 0;
241         if (_llseek32(hFile, 0L, 0) == HFILE_ERROR32)
242         {
243             MFDRV_DeleteDC( dc );
244             return 0;
245         }
246         if (_lwrite32( hFile, (LPSTR)physDev->mh,
247                        sizeof(*physDev->mh)) == HFILE_ERROR32)
248         {
249             MFDRV_DeleteDC( dc );
250             return 0;
251         }
252         _lclose32(hFile);
253     }
254
255     return dc;
256 }
257
258 /******************************************************************
259  *           CloseMetaFile16   (GDI.126)
260  */
261 HMETAFILE16 WINAPI CloseMetaFile16( 
262                                    HDC16 hdc /* Metafile DC to close */
263 )
264 {
265     HMETAFILE16 hmf;
266     METAFILEDRV_PDEVICE *physDev;
267     DC *dc = METAFILE_CloseMetaFile(hdc);
268     if (!dc) return 0;
269     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
270
271     /* Now allocate a global handle for the metafile */
272
273     hmf = GLOBAL_CreateBlock( GMEM_MOVEABLE, physDev->mh,
274                               physDev->mh->mtSize * sizeof(WORD),
275                               GetCurrentPDB(), FALSE, FALSE, FALSE, NULL );
276     physDev->mh = NULL;  /* So it won't be deleted */
277     MFDRV_DeleteDC( dc );
278     return hmf;
279 }
280
281 /******************************************************************
282  *           CloseMetaFile32   (GDI32.17)
283  *
284  *  Stop recording graphics operations in metafile associated with
285  *  hdc and retrieve metafile.
286  *
287  * RETURNS
288  *  Handle of newly created metafile on success, NULL on failure.
289  */
290 HMETAFILE32 WINAPI CloseMetaFile32( 
291                                    HDC32 hdc /* Metafile DC to close */
292 )
293 {
294   return CloseMetaFile16(hdc);
295 }
296
297
298 /******************************************************************
299  *           DeleteMetaFile16   (GDI.127)
300  */
301 BOOL16 WINAPI DeleteMetaFile16( 
302                                HMETAFILE16 hmf 
303                                /* Handle of memory metafile to delete */
304 )
305 {
306     return !GlobalFree16( hmf );
307 }
308
309 /******************************************************************
310  *          DeleteMetaFile32  (GDI32.69)
311  *
312  *  Delete a memory-based metafile.
313  */
314
315 BOOL32 WINAPI DeleteMetaFile32(
316               HMETAFILE32 hmf
317 ) {
318   return !GlobalFree16( hmf );
319 }
320
321 /********************************************************************
322
323        Enhanced Metafile driver initializations
324
325        This possibly  should be moved to their own file/directory
326        at some point.
327
328 **********************************************************************/
329
330 /**********************************************************************
331  *          CreateEnhMetaFile32A   (GDI32.41)
332 */
333 HDC32 WINAPI CreateEnhMetaFile32A( 
334     HDC32 hdc, /* optional reference DC */
335     LPCSTR filename, /* optional filename for disk metafiles */
336     const RECT32 *rect, /* optional bounding rectangle */
337     LPCSTR description /* optional description */ 
338     )
339 {
340 #if 0
341     DC *dc;
342     METAFILEDRV_PDEVICE *physDev;
343     HFILE32 hFile;
344
345     if (!(dc = MFDRV_AllocMetaFile())) return 0;
346     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
347     
348     if (filename)  /* disk based metafile */
349     {
350         physDev->mh->mtType = METAFILE_DISK;
351         if ((hFile = _lcreat32( filename, 0 )) == HFILE_ERROR32)
352         {
353             MFDRV_DeleteDC( dc );
354             return 0;
355         }
356         if (_lwrite32( hFile, (LPSTR)physDev->mh,
357                        sizeof(*physDev->mh)) == HFILE_ERROR32)
358         {
359             MFDRV_DeleteDC( dc );
360             return 0;
361         }
362         physDev->mh->mtNoParameters = hFile; /* store file descriptor here */
363                                     /* windows probably uses this too*/
364     }
365     else  /* memory based metafile */
366         physDev->mh->mtType = METAFILE_MEMORY;
367
368     TRACE(metafile, "returning %04x\n", dc->hSelf);
369     return dc->hSelf;
370 #endif
371
372     FIXME(metafile, "(0x%lx,%s,%p,%s): stub\n",
373          (DWORD)hdc, filename, rect, description);
374
375     return 0;
376 }
377
378 /**********************************************************************
379  *          CreateEnhMetaFile32W   (GDI32.42)
380  */
381 HDC32 WINAPI CreateEnhMetaFile32W(
382     HDC32         hdc,        /* optional reference DC */
383     LPCWSTR       filename,   /* optional filename for disk metafiles */
384     const RECT32* rect,       /* optional bounding rectangle */
385     LPCWSTR       description /* optional description */ 
386     )
387 {
388     LPSTR filenameA;
389     LPSTR descriptionA;
390     HDC32 hReturnDC;
391
392     filenameA    = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
393     descriptionA = HEAP_strdupWtoA( GetProcessHeap(), 0, description );
394
395     hReturnDC = CreateEnhMetaFile32A(hdc,
396                                     filenameA,
397                                     rect,
398                                     descriptionA);
399
400     HeapFree( GetProcessHeap(), 0, filenameA );
401     HeapFree( GetProcessHeap(), 0, descriptionA );
402
403     return hReturnDC;
404 }
405
406 HENHMETAFILE32 WINAPI CloseEnhMetaFile( HDC32 hdc /* metafile DC */ )
407 {
408   /* write EMR_EOF(0x0, 0x10, 0x14) */
409   return 0;
410 }
411
412