Fix the case of product and company names.
[wine] / dlls / gdi / mfdrv / init.c
1 /*
2  * Metafile driver initialisation functions
3  *
4  * Copyright 1996 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22 #include <string.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wine/winbase16.h"
27 #include "gdi.h"
28 #include "wownt32.h"
29 #include "mfdrv/metafiledrv.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
33
34 static const DC_FUNCTIONS MFDRV_Funcs =
35 {
36     NULL,                            /* pAbortDoc */
37     MFDRV_AbortPath,                 /* pAbortPath */
38     NULL,                            /* pAngleArc */
39     MFDRV_Arc,                       /* pArc */
40     NULL,                            /* pArcTo */
41     MFDRV_BeginPath,                 /* pBeginPath */
42     MFDRV_BitBlt,                    /* pBitBlt */
43     NULL,                            /* pChoosePixelFormat */
44     MFDRV_Chord,                     /* pChord */
45     MFDRV_CloseFigure,               /* pCloseFigure */
46     NULL,                            /* pCreateBitmap */
47     NULL,                            /* pCreateDC */
48     NULL,                            /* pCreateDIBSection */
49     NULL,                            /* pDeleteBitmap */
50     NULL,                            /* pDeleteDC */
51     NULL,                            /* pDescribePixelFormat */
52     NULL,                            /* pDeviceCapabilities */
53     MFDRV_Ellipse,                   /* pEllipse */
54     NULL,                            /* pEndDoc */
55     NULL,                            /* pEndPage */
56     MFDRV_EndPath,                   /* pEndPath */
57     NULL,                            /* pEnumDeviceFonts */
58     MFDRV_ExcludeClipRect,           /* pExcludeClipRect */
59     NULL,                            /* pExtDeviceMode */
60     MFDRV_ExtEscape,                 /* pExtEscape */
61     MFDRV_ExtFloodFill,              /* pExtFloodFill */
62     MFDRV_ExtSelectClipRgn,          /* pExtSelectClipRgn */
63     MFDRV_ExtTextOut,                /* pExtTextOut */
64     MFDRV_FillPath,                  /* pFillPath */
65     MFDRV_FillRgn,                   /* pFillRgn */
66     MFDRV_FlattenPath,               /* pFlattenPath */
67     MFDRV_FrameRgn,                  /* pFrameRgn */
68     NULL,                            /* pGdiComment */
69     NULL,                            /* pGetBitmapBits */
70     NULL,                            /* pGetCharWidth */
71     NULL,                            /* pGetDCOrgEx */
72     NULL,                            /* pGetDIBColorTable */
73     NULL,                            /* pGetDIBits */
74     MFDRV_GetDeviceCaps,             /* pGetDeviceCaps */
75     NULL,                            /* pGetDeviceGammaRamp */
76     NULL,                            /* pGetNearestColor */
77     NULL,                            /* pGetPixel */
78     NULL,                            /* pGetPixelFormat */
79     NULL,                            /* pGetSystemPaletteEntries */
80     NULL,                            /* pGetTextExtentPoint */
81     NULL,                            /* pGetTextMetrics */
82     MFDRV_IntersectClipRect,         /* pIntersectClipRect */
83     MFDRV_InvertRgn,                 /* pInvertRgn */
84     MFDRV_LineTo,                    /* pLineTo */
85     NULL,                            /* pModifyWorldTransform */
86     MFDRV_MoveTo,                    /* pMoveTo */
87     MFDRV_OffsetClipRgn,             /* pOffsetClipRgn */
88     MFDRV_OffsetViewportOrg,         /* pOffsetViewportOrg */
89     MFDRV_OffsetWindowOrg,           /* pOffsetWindowOrg */
90     MFDRV_PaintRgn,                  /* pPaintRgn */
91     MFDRV_PatBlt,                    /* pPatBlt */
92     MFDRV_Pie,                       /* pPie */
93     MFDRV_PolyBezier,                /* pPolyBezier */
94     MFDRV_PolyBezierTo,              /* pPolyBezierTo */
95     NULL,                            /* pPolyDraw */
96     MFDRV_PolyPolygon,               /* pPolyPolygon */
97     NULL,                            /* pPolyPolyline */
98     MFDRV_Polygon,                   /* pPolygon */
99     MFDRV_Polyline,                  /* pPolyline */
100     NULL,                            /* pPolylineTo */
101     NULL,                            /* pRealizeDefaultPalette */
102     MFDRV_RealizePalette,            /* pRealizePalette */
103     MFDRV_Rectangle,                 /* pRectangle */
104     NULL,                            /* pResetDC */
105     MFDRV_RestoreDC,                 /* pRestoreDC */
106     MFDRV_RoundRect,                 /* pRoundRect */
107     MFDRV_SaveDC,                    /* pSaveDC */
108     MFDRV_ScaleViewportExt,          /* pScaleViewportExt */
109     MFDRV_ScaleWindowExt,            /* pScaleWindowExt */
110     MFDRV_SelectBitmap,              /* pSelectBitmap */
111     MFDRV_SelectBrush,               /* pSelectBrush */
112     MFDRV_SelectClipPath,            /* pSelectClipPath */
113     MFDRV_SelectFont,                /* pSelectFont */
114     MFDRV_SelectPalette,             /* pSelectPalette */
115     MFDRV_SelectPen,                 /* pSelectPen */
116     NULL,                            /* pSetBitmapBits */
117     MFDRV_SetBkColor,                /* pSetBkColor */
118     MFDRV_SetBkMode,                 /* pSetBkMode */
119     NULL,                            /* pSetDCOrg */
120     NULL,                            /* pSetDIBColorTable */
121     NULL,                            /* pSetDIBits */
122     MFDRV_SetDIBitsToDevice,         /* pSetDIBitsToDevice */
123     NULL,                            /* pSetDeviceClipping */
124     NULL,                            /* pSetDeviceGammaRamp */
125     MFDRV_SetMapMode,                /* pSetMapMode */
126     MFDRV_SetMapperFlags,            /* pSetMapperFlags */
127     MFDRV_SetPixel,                  /* pSetPixel */
128     NULL,                            /* pSetPixelFormat */
129     MFDRV_SetPolyFillMode,           /* pSetPolyFillMode */
130     MFDRV_SetROP2,                   /* pSetROP2 */
131     MFDRV_SetRelAbs,                 /* pSetRelAbs */
132     MFDRV_SetStretchBltMode,         /* pSetStretchBltMode */
133     MFDRV_SetTextAlign,              /* pSetTextAlign */
134     MFDRV_SetTextCharacterExtra,     /* pSetTextCharacterExtra */
135     MFDRV_SetTextColor,              /* pSetTextColor */
136     MFDRV_SetTextJustification,      /* pSetTextJustification */
137     MFDRV_SetViewportExt,            /* pSetViewportExt */
138     MFDRV_SetViewportOrg,            /* pSetViewportOrg */
139     MFDRV_SetWindowExt,              /* pSetWindowExt */
140     MFDRV_SetWindowOrg,              /* pSetWindowOrg */
141     NULL,                            /* pSetWorldTransform */
142     NULL,                            /* pStartDoc */
143     NULL,                            /* pStartPage */
144     MFDRV_StretchBlt,                /* pStretchBlt */
145     MFDRV_StretchDIBits,             /* pStretchDIBits */
146     MFDRV_StrokeAndFillPath,         /* pStrokeAndFillPath */
147     MFDRV_StrokePath,                /* pStrokePath */
148     NULL,                            /* pSwapBuffers */
149     MFDRV_WidenPath                  /* pWidenPath */
150 };
151
152
153
154 /**********************************************************************
155  *           MFDRV_AllocMetaFile
156  */
157 static DC *MFDRV_AllocMetaFile(void)
158 {
159     DC *dc;
160     METAFILEDRV_PDEVICE *physDev;
161
162     if (!(dc = DC_AllocDC( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
163
164     physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
165     if (!physDev)
166     {
167         GDI_FreeObject( dc->hSelf, dc );
168         return NULL;
169     }
170     dc->physDev = (PHYSDEV)physDev;
171     physDev->hdc = dc->hSelf;
172     physDev->dc = dc;
173
174     if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
175     {
176         HeapFree( GetProcessHeap(), 0, physDev );
177         GDI_FreeObject( dc->hSelf, dc );
178         return NULL;
179     }
180
181     physDev->nextHandle = 0;
182     physDev->hFile = 0;
183
184     physDev->mh->mtHeaderSize   = sizeof(METAHEADER) / sizeof(WORD);
185     physDev->mh->mtVersion      = 0x0300;
186     physDev->mh->mtSize         = physDev->mh->mtHeaderSize;
187     physDev->mh->mtNoObjects    = 0;
188     physDev->mh->mtMaxRecord    = 0;
189     physDev->mh->mtNoParameters = 0;
190
191     return dc;
192 }
193
194
195 /**********************************************************************
196  *           MFDRV_DeleteDC
197  */
198 static BOOL MFDRV_DeleteDC( PHYSDEV dev )
199 {
200     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
201     DC *dc = physDev->dc;
202
203     if (physDev->mh) HeapFree( GetProcessHeap(), 0, physDev->mh );
204     HeapFree( GetProcessHeap(), 0, physDev );
205     dc->physDev = NULL;
206     GDI_FreeObject( dc->hSelf, dc );
207     return TRUE;
208 }
209
210
211 /**********************************************************************
212  *           CreateMetaFileA   (GDI32.@)
213  *
214  *  Create a new DC and associate it with a metafile. Pass a filename
215  *  to create a disk-based metafile, NULL to create a memory metafile.
216  *
217  * RETURNS
218  *  A handle to the metafile DC if successful, NULL on failure.
219  */
220 HDC WINAPI CreateMetaFileA( LPCSTR filename ) /* [in] Filename of disk metafile */
221 {
222     HDC ret;
223     DC *dc;
224     METAFILEDRV_PDEVICE *physDev;
225     HANDLE hFile;
226
227     TRACE("'%s'\n", filename );
228
229     if (!(dc = MFDRV_AllocMetaFile())) return 0;
230     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
231
232     if (filename)  /* disk based metafile */
233     {
234         physDev->mh->mtType = METAFILE_DISK;
235         if ((hFile = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
236                                 CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
237             MFDRV_DeleteDC( dc->physDev );
238             return 0;
239         }
240         if (!WriteFile( hFile, (LPSTR)physDev->mh, sizeof(*physDev->mh), NULL,
241                         NULL )) {
242             MFDRV_DeleteDC( dc->physDev );
243             return 0;
244         }
245         physDev->hFile = hFile;
246
247         /* Grow METAHEADER to include filename */
248         physDev->mh = MF_CreateMetaHeaderDisk(physDev->mh, filename);
249     }
250     else  /* memory based metafile */
251         physDev->mh->mtType = METAFILE_MEMORY;
252
253     TRACE("returning %p\n", dc->hSelf);
254     ret = dc->hSelf;
255     GDI_ReleaseObj( dc->hSelf );
256     return ret;
257 }
258
259 /**********************************************************************
260  *          CreateMetaFileW   (GDI32.@)
261  */
262 HDC WINAPI CreateMetaFileW(LPCWSTR filename)
263 {
264     LPSTR filenameA;
265     DWORD len;
266     HDC hReturnDC;
267
268     if (!filename) return CreateMetaFileA(NULL);
269
270     len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
271     filenameA = HeapAlloc( GetProcessHeap(), 0, len );
272     WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL );
273
274     hReturnDC = CreateMetaFileA(filenameA);
275
276     HeapFree( GetProcessHeap(), 0, filenameA );
277
278     return hReturnDC;
279 }
280
281
282 /**********************************************************************
283  *          MFDRV_CloseMetaFile
284  */
285 static DC *MFDRV_CloseMetaFile( HDC hdc )
286 {
287     DC *dc;
288     METAFILEDRV_PDEVICE *physDev;
289
290     TRACE("(%p)\n", hdc );
291
292     if (!(dc = (DC *) GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
293     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
294
295     /* Construct the end of metafile record - this is documented
296      * in SDK Knowledgebase Q99334.
297      */
298
299     if (!MFDRV_MetaParam0(dc->physDev, META_EOF))
300     {
301         MFDRV_DeleteDC( dc->physDev );
302         return 0;
303     }
304
305     if (physDev->mh->mtType == METAFILE_DISK)  /* disk based metafile */
306     {
307         if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) {
308             MFDRV_DeleteDC( dc->physDev );
309             return 0;
310         }
311
312         physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */
313         if (!WriteFile(physDev->hFile, (LPSTR)physDev->mh,
314                        sizeof(*physDev->mh), NULL, NULL)) {
315             MFDRV_DeleteDC( dc->physDev );
316             return 0;
317         }
318         CloseHandle(physDev->hFile);
319         physDev->mh->mtType = METAFILE_DISK;
320     }
321
322     return dc;
323 }
324
325 /******************************************************************
326  *           CloseMetaFile     (GDI.126)
327  */
328 HMETAFILE16 WINAPI CloseMetaFile16(
329                                    HDC16 hdc /* [in] Metafile DC to close */
330 )
331 {
332     HMETAFILE16 hmf;
333     METAFILEDRV_PDEVICE *physDev;
334     DC *dc = MFDRV_CloseMetaFile(HDC_32(hdc));
335     if (!dc) return 0;
336     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
337
338     /* Now allocate a global handle for the metafile */
339
340     hmf = MF_Create_HMETAFILE16( physDev->mh );
341
342     physDev->mh = NULL;  /* So it won't be deleted */
343     MFDRV_DeleteDC( dc->physDev );
344     return hmf;
345 }
346
347 /******************************************************************
348  *           CloseMetaFile   (GDI32.@)
349  *
350  *  Stop recording graphics operations in metafile associated with
351  *  hdc and retrieve metafile.
352  *
353  * RETURNS
354  *  Handle of newly created metafile on success, NULL on failure.
355  */
356 HMETAFILE WINAPI CloseMetaFile(
357                                    HDC hdc /* [in] Metafile DC to close */
358 )
359 {
360     HMETAFILE hmf;
361     METAFILEDRV_PDEVICE *physDev;
362     DC *dc = MFDRV_CloseMetaFile(hdc);
363     if (!dc) return 0;
364     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
365
366     /* Now allocate a global handle for the metafile */
367
368     hmf = MF_Create_HMETAFILE( physDev->mh );
369
370     physDev->mh = NULL;  /* So it won't be deleted */
371     MFDRV_DeleteDC( dc->physDev );
372     return hmf;
373 }
374
375
376 /******************************************************************
377  *         MFDRV_WriteRecord
378  *
379  * Warning: this function can change the pointer to the metafile header.
380  */
381 BOOL MFDRV_WriteRecord( PHYSDEV dev, METARECORD *mr, DWORD rlen)
382 {
383     DWORD len, size;
384     METAHEADER *mh;
385     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
386
387     switch(physDev->mh->mtType)
388     {
389     case METAFILE_MEMORY:
390         len = physDev->mh->mtSize * 2 + rlen;
391         /* reallocate memory if needed */
392         size = HeapSize( GetProcessHeap(), 0, physDev->mh );
393         if (len > size)
394         {
395             /*expand size*/
396             size += size / 2 + rlen;
397             mh = HeapReAlloc( GetProcessHeap(), 0, physDev->mh, size);
398             if (!mh) return FALSE;
399             physDev->mh = mh;
400             TRACE("Reallocated metafile: new size is %ld\n",size);
401         }
402         memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
403         break;
404     case METAFILE_DISK:
405         TRACE("Writing record to disk\n");
406         if (!WriteFile(physDev->hFile, (char *)mr, rlen, NULL, NULL))
407             return FALSE;
408         break;
409     default:
410         ERR("Unknown metafile type %d\n", physDev->mh->mtType );
411         return FALSE;
412     }
413
414     physDev->mh->mtSize += rlen / 2;
415     physDev->mh->mtMaxRecord = max(physDev->mh->mtMaxRecord, rlen / 2);
416     return TRUE;
417 }
418
419
420 /******************************************************************
421  *         MFDRV_MetaParam0
422  */
423
424 BOOL MFDRV_MetaParam0(PHYSDEV dev, short func)
425 {
426     char buffer[8];
427     METARECORD *mr = (METARECORD *)&buffer;
428
429     mr->rdSize = 3;
430     mr->rdFunction = func;
431     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
432 }
433
434
435 /******************************************************************
436  *         MFDRV_MetaParam1
437  */
438 BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1)
439 {
440     char buffer[8];
441     METARECORD *mr = (METARECORD *)&buffer;
442
443     mr->rdSize = 4;
444     mr->rdFunction = func;
445     *(mr->rdParm) = param1;
446     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
447 }
448
449
450 /******************************************************************
451  *         MFDRV_MetaParam2
452  */
453 BOOL MFDRV_MetaParam2(PHYSDEV dev, short func, short param1, short param2)
454 {
455     char buffer[10];
456     METARECORD *mr = (METARECORD *)&buffer;
457
458     mr->rdSize = 5;
459     mr->rdFunction = func;
460     *(mr->rdParm) = param2;
461     *(mr->rdParm + 1) = param1;
462     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
463 }
464
465
466 /******************************************************************
467  *         MFDRV_MetaParam4
468  */
469
470 BOOL MFDRV_MetaParam4(PHYSDEV dev, short func, short param1, short param2,
471                       short param3, short param4)
472 {
473     char buffer[14];
474     METARECORD *mr = (METARECORD *)&buffer;
475
476     mr->rdSize = 7;
477     mr->rdFunction = func;
478     *(mr->rdParm) = param4;
479     *(mr->rdParm + 1) = param3;
480     *(mr->rdParm + 2) = param2;
481     *(mr->rdParm + 3) = param1;
482     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
483 }
484
485
486 /******************************************************************
487  *         MFDRV_MetaParam6
488  */
489
490 BOOL MFDRV_MetaParam6(PHYSDEV dev, short func, short param1, short param2,
491                       short param3, short param4, short param5, short param6)
492 {
493     char buffer[18];
494     METARECORD *mr = (METARECORD *)&buffer;
495
496     mr->rdSize = 9;
497     mr->rdFunction = func;
498     *(mr->rdParm) = param6;
499     *(mr->rdParm + 1) = param5;
500     *(mr->rdParm + 2) = param4;
501     *(mr->rdParm + 3) = param3;
502     *(mr->rdParm + 4) = param2;
503     *(mr->rdParm + 5) = param1;
504     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
505 }
506
507
508 /******************************************************************
509  *         MFDRV_MetaParam8
510  */
511 BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2,
512                       short param3, short param4, short param5,
513                       short param6, short param7, short param8)
514 {
515     char buffer[22];
516     METARECORD *mr = (METARECORD *)&buffer;
517
518     mr->rdSize = 11;
519     mr->rdFunction = func;
520     *(mr->rdParm) = param8;
521     *(mr->rdParm + 1) = param7;
522     *(mr->rdParm + 2) = param6;
523     *(mr->rdParm + 3) = param5;
524     *(mr->rdParm + 4) = param4;
525     *(mr->rdParm + 5) = param3;
526     *(mr->rdParm + 6) = param2;
527     *(mr->rdParm + 7) = param1;
528     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
529 }
530
531
532 /******************************************************************
533  *         MFDRV_AddHandleDC
534  *
535  * Note: this function assumes that we never delete objects.
536  * If we do someday, we'll need to maintain a table to re-use deleted
537  * handles.
538  */
539 int MFDRV_AddHandleDC( PHYSDEV dev )
540 {
541     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
542     physDev->mh->mtNoObjects++;
543     return physDev->nextHandle++;
544 }
545
546 /**********************************************************************
547  *           MFDRV_ExtEscape
548  */
549 INT MFDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
550                      INT cbOutput, LPVOID out_data )
551 {
552     METARECORD *mr;
553     DWORD len;
554     INT ret;
555
556     len = sizeof(*mr) + sizeof(WORD) + ((cbInput + 1) & ~1);
557     mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
558     mr->rdSize = len / 2;
559     mr->rdFunction = META_ESCAPE;
560     mr->rdParm[0] = nEscape;
561     mr->rdParm[1] = cbInput;
562     memcpy(&(mr->rdParm[2]), in_data, cbInput);
563     ret = MFDRV_WriteRecord( dev, mr, len);
564     HeapFree(GetProcessHeap(), 0, mr);
565     return ret;
566 }
567
568
569 /******************************************************************
570  *         MFDRV_GetDeviceCaps
571  *
572  *A very simple implementation that returns DT_METAFILE
573  */
574 INT MFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
575 {
576     switch(cap)
577     {
578     case TECHNOLOGY:
579         return DT_METAFILE;
580     case TEXTCAPS:
581         return 0;
582     default:
583         TRACE(" unsupported capability %d, will return 0\n", cap );
584     }
585     return 0;
586 }