Moved a few non-standard headers into their respective dlls.
[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 "debugtools.h"
15
16 DEFAULT_DEBUG_CHANNEL(metafile)
17
18 #include <string.h>
19
20 static const DC_FUNCTIONS MFDRV_Funcs =
21 {
22     NULL,                            /* pAbortDoc */
23     MFDRV_AbortPath,                 /* pAbortPath */
24     NULL,                            /* pAngleArc */
25     MFDRV_Arc,                       /* pArc */
26     NULL,                            /* pArcTo */
27     MFDRV_BeginPath,                 /* pBeginPath */
28     MFDRV_BitBlt,                    /* pBitBlt */
29     NULL,                            /* pBitmapBits */  
30     NULL,                            /* pChoosePixelFormat */
31     MFDRV_Chord,                     /* pChord */
32     MFDRV_CloseFigure,               /* pCloseFigure */
33     NULL,                            /* pCreateBitmap */
34     NULL, /* no implementation */    /* pCreateDC */
35     NULL,                            /* pCreateDIBSection */
36     NULL,                            /* pCreateDIBSection16 */
37     NULL, /* no implementation */    /* pDeleteDC */
38     NULL,                            /* pDeleteObject */
39     NULL,                            /* pDescribePixelFormat */
40     NULL,                            /* pDeviceCapabilities */
41     MFDRV_Ellipse,                   /* pEllipse */
42     NULL,                            /* pEndDoc */
43     NULL,                            /* pEndPage */
44     MFDRV_EndPath,                   /* pEndPath */
45     NULL,                            /* pEnumDeviceFonts */
46     NULL,                            /* pEscape */
47     MFDRV_ExcludeClipRect,           /* pExcludeClipRect */
48     NULL,                            /* pExtDeviceMode */
49     MFDRV_ExtFloodFill,              /* pExtFloodFill */
50     MFDRV_ExtTextOut,                /* pExtTextOut */
51     MFDRV_FillPath,                  /* pFillPath */
52     MFDRV_FillRgn,                   /* pFillRgn */
53     MFDRV_FlattenPath,               /* pFlattenPath */
54     MFDRV_FrameRgn,                  /* pFrameRgn */
55     NULL,                            /* pGetCharWidth */
56     NULL,                            /* pGetDCOrgEx */
57     NULL, /* no implementation */    /* pGetPixel */
58     NULL,                            /* pGetPixelFormat */
59     NULL,                            /* pGetTextExtentPoint */
60     NULL,                            /* pGetTextMetrics */
61     MFDRV_IntersectClipRect,         /* pIntersectClipRect */
62     MFDRV_InvertRgn,                 /* pInvertRgn */
63     MFDRV_LineTo,                    /* pLineTo */
64     MFDRV_MoveToEx,                  /* pMoveToEx */
65     MFDRV_OffsetClipRgn,             /* pOffsetClipRgn */
66     MFDRV_OffsetViewportOrg,         /* pOffsetViewportOrg */
67     MFDRV_OffsetWindowOrg,           /* pOffsetWindowOrg */
68     MFDRV_PaintRgn,                  /* pPaintRgn */
69     MFDRV_PatBlt,                    /* pPatBlt */
70     MFDRV_Pie,                       /* pPie */
71     MFDRV_PolyBezier,                /* pPolyBezier */
72     MFDRV_PolyBezierTo,              /* pPolyBezierTo */
73     NULL,                            /* pPolyDraw */
74     MFDRV_PolyPolygon,               /* pPolyPolygon */
75     NULL,                            /* pPolyPolyline */
76     MFDRV_Polygon,                   /* pPolygon */
77     MFDRV_Polyline,                  /* pPolyline */
78     NULL,                            /* pPolylineTo */
79     NULL,                            /* pRealizePalette */
80     MFDRV_Rectangle,                 /* pRectangle */
81     MFDRV_RestoreDC,                 /* pRestoreDC */
82     MFDRV_RoundRect,                 /* pRoundRect */
83     MFDRV_SaveDC,                    /* pSaveDC */
84     MFDRV_ScaleViewportExt,          /* pScaleViewportExt */
85     MFDRV_ScaleWindowExt,            /* pScaleWindowExt */
86     MFDRV_SelectClipPath,            /* pSelectClipPath */
87     NULL,                            /* pSelectClipRgn */
88     MFDRV_SelectObject,              /* pSelectObject */
89     NULL,                            /* pSelectPalette */
90     MFDRV_SetBkColor,                /* pSetBkColor */
91     MFDRV_SetBkMode,                 /* pSetBkMode */
92     NULL,                            /* pSetDeviceClipping */
93     MFDRV_SetDIBitsToDevice,         /* pSetDIBitsToDevice */
94     MFDRV_SetMapMode,                /* pSetMapMode */
95     MFDRV_SetMapperFlags,            /* pSetMapperFlags */
96     MFDRV_SetPixel,                  /* pSetPixel */
97     NULL,                            /* pSetPixelFormat */
98     MFDRV_SetPolyFillMode,           /* pSetPolyFillMode */
99     MFDRV_SetROP2,                   /* pSetROP2 */
100     MFDRV_SetRelAbs,                 /* pSetRelAbs */
101     MFDRV_SetStretchBltMode,         /* pSetStretchBltMode */
102     MFDRV_SetTextAlign,              /* pSetTextAlign */
103     MFDRV_SetTextCharacterExtra,     /* pSetTextCharacterExtra */
104     MFDRV_SetTextColor,              /* pSetTextColor */
105     MFDRV_SetTextJustification,      /* pSetTextJustification */
106     MFDRV_SetViewportExt,            /* pSetViewportExt */
107     MFDRV_SetViewportOrg,            /* pSetViewportOrg */
108     MFDRV_SetWindowExt,              /* pSetWindowExt */
109     MFDRV_SetWindowOrg,              /* pSetWindowOrg */
110     NULL,                            /* pStartDoc */
111     NULL,                            /* pStartPage */
112     MFDRV_StretchBlt,                /* pStretchBlt */
113     MFDRV_StretchDIBits,             /* pStretchDIBits */
114     MFDRV_StrokeAndFillPath,         /* pStrokeAndFillPath */
115     MFDRV_StrokePath,                /* pStrokePath */
116     NULL,                            /* pSwapBuffers */
117     MFDRV_WidenPath                  /* pWidenPath */
118 };
119
120
121
122 /**********************************************************************
123  *           MFDRV_AllocMetaFile
124  */
125 static DC *MFDRV_AllocMetaFile(void)
126 {
127     DC *dc;
128     METAFILEDRV_PDEVICE *physDev;
129     
130     if (!(dc = DC_AllocDC( &MFDRV_Funcs ))) return NULL;
131     dc->header.wMagic = METAFILE_DC_MAGIC;
132
133     physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
134     if (!physDev)
135     {
136         GDI_HEAP_FREE( dc->hSelf );
137         return NULL;
138     }
139     dc->physDev = physDev;
140
141     if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
142     {
143         HeapFree( GetProcessHeap(), 0, physDev );
144         GDI_HEAP_FREE( dc->hSelf );
145         return NULL;
146     }
147
148     physDev->nextHandle = 0;
149     physDev->hFile = 0;
150
151     physDev->mh->mtHeaderSize   = sizeof(METAHEADER) / sizeof(WORD);
152     physDev->mh->mtVersion      = 0x0300;
153     physDev->mh->mtSize         = physDev->mh->mtHeaderSize;
154     physDev->mh->mtNoObjects    = 0;
155     physDev->mh->mtMaxRecord    = 0;
156     physDev->mh->mtNoParameters = 0;
157
158     return dc;
159 }
160
161
162 /**********************************************************************
163  *           MFDRV_DeleteDC
164  */
165 static BOOL MFDRV_DeleteDC( DC *dc )
166 {
167     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
168     
169     if (physDev->mh) HeapFree( GetProcessHeap(), 0, physDev->mh );
170     HeapFree( GetProcessHeap(), 0, physDev );
171     dc->physDev = NULL;
172     GDI_FreeObject(dc->hSelf);
173     return TRUE;
174 }
175
176 /**********************************************************************
177  *           CreateMetaFile16   (GDI.125)
178  *
179  *  Create a new DC and associate it with a metafile. Pass a filename
180  *  to create a disk-based metafile, NULL to create a memory metafile.
181  *
182  * RETURNS
183  *  A handle to the metafile DC if successful, NULL on failure.
184  */
185 HDC16 WINAPI CreateMetaFile16( 
186                               LPCSTR filename /* Filename of disk metafile */
187 )
188 {
189     DC *dc;
190     METAFILEDRV_PDEVICE *physDev;
191     HFILE hFile;
192
193     TRACE("'%s'\n", filename );
194
195     if (!(dc = MFDRV_AllocMetaFile())) return 0;
196     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
197     
198     if (filename)  /* disk based metafile */
199     {
200         physDev->mh->mtType = METAFILE_DISK;
201         if ((hFile = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
202                                 CREATE_ALWAYS, 0, -1)) == HFILE_ERROR) {
203             MFDRV_DeleteDC( dc );
204             return 0;
205         }
206         if (!WriteFile( hFile, (LPSTR)physDev->mh, sizeof(*physDev->mh), NULL,
207                         NULL )) {
208             MFDRV_DeleteDC( dc );
209             return 0;
210         }
211         physDev->hFile = hFile;
212
213         /* Grow METAHEADER to include filename */
214         physDev->mh = MF_CreateMetaHeaderDisk(physDev->mh, filename);
215     }
216     else  /* memory based metafile */
217         physDev->mh->mtType = METAFILE_MEMORY;
218         
219     TRACE("returning %04x\n", dc->hSelf);
220     return dc->hSelf;
221 }
222
223 /**********************************************************************
224  *           CreateMetaFileA   (GDI32.51)
225  */
226 HDC WINAPI CreateMetaFileA( 
227                               LPCSTR filename /* Filename of disk metafile */
228 )
229 {
230   return CreateMetaFile16( filename );
231 }
232
233 /**********************************************************************
234  *          CreateMetaFileW   (GDI32.52)
235  */
236 HDC WINAPI CreateMetaFileW(LPCWSTR filename)
237 {
238     LPSTR filenameA;
239     HDC hReturnDC;
240
241     filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
242
243     hReturnDC = CreateMetaFileA(filenameA);
244
245     HeapFree( GetProcessHeap(), 0, filenameA );
246
247     return hReturnDC;
248 }
249
250
251 /**********************************************************************
252  *          MFDRV_CloseMetaFile
253  */
254 static DC *MFDRV_CloseMetaFile( HDC hdc ) 
255 {
256     DC *dc;
257     METAFILEDRV_PDEVICE *physDev;
258     
259     TRACE("(%04x)\n", hdc );
260
261     if (!(dc = (DC *) GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
262     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
263
264     /* Construct the end of metafile record - this is documented
265      * in SDK Knowledgebase Q99334.
266      */
267
268     if (!MFDRV_MetaParam0(dc, META_EOF))
269     {
270         MFDRV_DeleteDC( dc );
271         return 0;
272     }   
273
274     if (physDev->mh->mtType == METAFILE_DISK)  /* disk based metafile */
275     {
276         if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) {
277             MFDRV_DeleteDC( dc );
278             return 0;
279         }
280
281         physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */
282         if (!WriteFile(physDev->hFile, (LPSTR)physDev->mh,
283                        sizeof(*physDev->mh), NULL, NULL)) {
284             MFDRV_DeleteDC( dc );
285             return 0;
286         }
287         CloseHandle(physDev->hFile);
288         physDev->mh->mtType = METAFILE_DISK;
289     }
290
291     return dc;
292 }
293
294 /******************************************************************
295  *           CloseMetaFile16   (GDI.126)
296  */
297 HMETAFILE16 WINAPI CloseMetaFile16( 
298                                    HDC16 hdc /* Metafile DC to close */
299 )
300 {
301     HMETAFILE16 hmf;
302     METAFILEDRV_PDEVICE *physDev;
303     DC *dc = MFDRV_CloseMetaFile(hdc);
304     if (!dc) return 0;
305     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
306
307     /* Now allocate a global handle for the metafile */
308
309     hmf = MF_Create_HMETAFILE16( physDev->mh );
310
311     physDev->mh = NULL;  /* So it won't be deleted */
312     MFDRV_DeleteDC( dc );
313     return hmf;
314 }
315
316 /******************************************************************
317  *           CloseMetaFile   (GDI32.17)
318  *
319  *  Stop recording graphics operations in metafile associated with
320  *  hdc and retrieve metafile.
321  *
322  * RETURNS
323  *  Handle of newly created metafile on success, NULL on failure.
324  */
325 HMETAFILE WINAPI CloseMetaFile( 
326                                    HDC hdc /* Metafile DC to close */
327 )
328 {
329     HMETAFILE hmf;
330     METAFILEDRV_PDEVICE *physDev;
331     DC *dc = MFDRV_CloseMetaFile(hdc);
332     if (!dc) return 0;
333     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
334
335     /* Now allocate a global handle for the metafile */
336
337     hmf = MF_Create_HMETAFILE( physDev->mh );
338
339     physDev->mh = NULL;  /* So it won't be deleted */
340     MFDRV_DeleteDC( dc );
341     return hmf;
342 }
343
344
345 /******************************************************************
346  *         MFDRV_WriteRecord
347  *
348  * Warning: this function can change the pointer to the metafile header.
349  */
350 BOOL MFDRV_WriteRecord( DC *dc, METARECORD *mr, DWORD rlen)
351 {
352     DWORD len;
353     METAHEADER *mh;
354     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
355
356     switch(physDev->mh->mtType)
357     {
358     case METAFILE_MEMORY:
359         len = physDev->mh->mtSize * 2 + rlen;
360         mh = HeapReAlloc( GetProcessHeap(), 0, physDev->mh, len );
361         if (!mh) return FALSE;
362         physDev->mh = mh;
363         memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
364         break;
365     case METAFILE_DISK:
366         TRACE("Writing record to disk\n");
367         if (!WriteFile(physDev->hFile, (char *)mr, rlen, NULL, NULL))
368             return FALSE;
369         break;
370     default:
371         ERR("Unknown metafile type %d\n", physDev->mh->mtType );
372         return FALSE;
373     }
374
375     physDev->mh->mtSize += rlen / 2;
376     physDev->mh->mtMaxRecord = max(physDev->mh->mtMaxRecord, rlen / 2);
377     return TRUE;
378 }
379
380
381 /******************************************************************
382  *         MFDRV_MetaParam0
383  */
384
385 BOOL MFDRV_MetaParam0(DC *dc, short func)
386 {
387     char buffer[8];
388     METARECORD *mr = (METARECORD *)&buffer;
389     
390     mr->rdSize = 3;
391     mr->rdFunction = func;
392     return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
393 }
394
395
396 /******************************************************************
397  *         MFDRV_MetaParam1
398  */
399 BOOL MFDRV_MetaParam1(DC *dc, short func, short param1)
400 {
401     char buffer[8];
402     METARECORD *mr = (METARECORD *)&buffer;
403     
404     mr->rdSize = 4;
405     mr->rdFunction = func;
406     *(mr->rdParm) = param1;
407     return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
408 }
409
410
411 /******************************************************************
412  *         MFDRV_MetaParam2
413  */
414 BOOL MFDRV_MetaParam2(DC *dc, short func, short param1, short param2)
415 {
416     char buffer[10];
417     METARECORD *mr = (METARECORD *)&buffer;
418     
419     mr->rdSize = 5;
420     mr->rdFunction = func;
421     *(mr->rdParm) = param2;
422     *(mr->rdParm + 1) = param1;
423     return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
424 }
425
426
427 /******************************************************************
428  *         MFDRV_MetaParam4
429  */
430
431 BOOL MFDRV_MetaParam4(DC *dc, short func, short param1, short param2, 
432                       short param3, short param4)
433 {
434     char buffer[14];
435     METARECORD *mr = (METARECORD *)&buffer;
436     
437     mr->rdSize = 7;
438     mr->rdFunction = func;
439     *(mr->rdParm) = param4;
440     *(mr->rdParm + 1) = param3;
441     *(mr->rdParm + 2) = param2;
442     *(mr->rdParm + 3) = param1;
443     return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
444 }
445
446
447 /******************************************************************
448  *         MFDRV_MetaParam6
449  */
450
451 BOOL MFDRV_MetaParam6(DC *dc, short func, short param1, short param2, 
452                       short param3, short param4, short param5, short param6)
453 {
454     char buffer[18];
455     METARECORD *mr = (METARECORD *)&buffer;
456     
457     mr->rdSize = 9;
458     mr->rdFunction = func;
459     *(mr->rdParm) = param6;
460     *(mr->rdParm + 1) = param5;
461     *(mr->rdParm + 2) = param4;
462     *(mr->rdParm + 3) = param3;
463     *(mr->rdParm + 4) = param2;
464     *(mr->rdParm + 5) = param1;
465     return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
466 }
467
468
469 /******************************************************************
470  *         MFDRV_MetaParam8
471  */
472 BOOL MFDRV_MetaParam8(DC *dc, short func, short param1, short param2, 
473                       short param3, short param4, short param5,
474                       short param6, short param7, short param8)
475 {
476     char buffer[22];
477     METARECORD *mr = (METARECORD *)&buffer;
478     
479     mr->rdSize = 11;
480     mr->rdFunction = func;
481     *(mr->rdParm) = param8;
482     *(mr->rdParm + 1) = param7;
483     *(mr->rdParm + 2) = param6;
484     *(mr->rdParm + 3) = param5;
485     *(mr->rdParm + 4) = param4;
486     *(mr->rdParm + 5) = param3;
487     *(mr->rdParm + 6) = param2;
488     *(mr->rdParm + 7) = param1;
489     return MFDRV_WriteRecord( dc, mr, mr->rdSize * 2);
490 }
491
492
493 /******************************************************************
494  *         MFDRV_AddHandleDC
495  *
496  * Note: this function assumes that we never delete objects.
497  * If we do someday, we'll need to maintain a table to re-use deleted
498  * handles.
499  */
500 int MFDRV_AddHandleDC( DC *dc )
501 {
502     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
503     physDev->mh->mtNoObjects++;
504     return physDev->nextHandle++;
505 }
506
507