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