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