Fixed error handling in DGA_IDirectDraw2Impl_GetCaps().
[wine] / graphics / psdrv / init.c
1 /*
2  *      PostScript driver initialization functions
3  *
4  *      Copyright 1998 Huw D M Davies
5  *
6  */
7 #include <string.h>
8
9 #include "gdi.h"
10 #include "psdrv.h"
11 #include "debug.h"
12 #include "heap.h"
13 #include "winreg.h"
14 #include "winspool.h"
15 #include "winerror.h"
16
17 DEFAULT_DEBUG_CHANNEL(psdrv)
18
19 static BOOL PSDRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
20                                LPCSTR output, const DEVMODEA* initData );
21 static BOOL PSDRV_DeleteDC( DC *dc );
22
23 static const DC_FUNCTIONS PSDRV_Funcs =
24 {
25     NULL,                            /* pAbortDoc */
26     PSDRV_Arc,                       /* pArc */
27     NULL,                            /* pBitBlt */
28     NULL,                            /* pBitmapBits */
29     PSDRV_Chord,                     /* pChord */
30     NULL,                            /* pCreateBitmap */
31     PSDRV_CreateDC,                  /* pCreateDC */
32     NULL,                            /* pCreateDIBSection */
33     NULL,                            /* pCreateDIBSection16 */
34     PSDRV_DeleteDC,                  /* pDeleteDC */
35     NULL,                            /* pDeleteObject */
36     PSDRV_DeviceCapabilities,        /* pDeviceCapabilities */
37     PSDRV_Ellipse,                   /* pEllipse */
38     NULL,                            /* pEndDoc */
39     NULL,                            /* pEndPage */
40     PSDRV_EnumDeviceFonts,           /* pEnumDeviceFonts */
41     PSDRV_Escape,                    /* pEscape */
42     NULL,                            /* pExcludeClipRect */
43     PSDRV_ExtDeviceMode,             /* pExtDeviceMode */
44     NULL,                            /* pExtFloodFill */
45     PSDRV_ExtTextOut,                /* pExtTextOut */
46     NULL,                            /* pFillRgn */
47     NULL,                            /* pFrameRgn */
48     PSDRV_GetCharWidth,              /* pGetCharWidth */
49     NULL,                            /* pGetPixel */
50     PSDRV_GetTextExtentPoint,        /* pGetTextExtentPoint */
51     PSDRV_GetTextMetrics,            /* pGetTextMetrics */
52     NULL,                            /* pIntersectClipRect */
53     NULL,                            /* pInvertRgn */
54     PSDRV_LineTo,                    /* pLineTo */
55     NULL,                            /* pLoadOEMResource */
56     PSDRV_MoveToEx,                  /* pMoveToEx */
57     NULL,                            /* pOffsetClipRgn */
58     NULL,                            /* pOffsetViewportOrg (optional) */
59     NULL,                            /* pOffsetWindowOrg (optional) */
60     NULL,                            /* pPaintRgn */
61     NULL,                            /* pPatBlt */
62     PSDRV_Pie,                       /* pPie */
63     PSDRV_PolyPolygon,               /* pPolyPolygon */
64     PSDRV_PolyPolyline,              /* pPolyPolyline */
65     PSDRV_Polygon,                   /* pPolygon */
66     PSDRV_Polyline,                  /* pPolyline */
67     NULL,                            /* pPolyBezier */               
68     NULL,                            /* pRealizePalette */
69     PSDRV_Rectangle,                 /* pRectangle */
70     NULL,                            /* pRestoreDC */
71     PSDRV_RoundRect,                 /* pRoundRect */
72     NULL,                            /* pSaveDC */
73     NULL,                            /* pScaleViewportExt (optional) */
74     NULL,                            /* pScaleWindowExt (optional) */
75     NULL,                            /* pSelectClipRgn */
76     PSDRV_SelectObject,              /* pSelectObject */
77     NULL,                            /* pSelectPalette */
78     PSDRV_SetBkColor,                /* pSetBkColor */
79     NULL,                            /* pSetBkMode */
80     NULL,                            /* pSetDeviceClipping */
81     NULL,                            /* pSetDIBitsToDevice */
82     NULL,                            /* pSetMapMode (optional) */
83     NULL,                            /* pSetMapperFlags */
84     PSDRV_SetPixel,                  /* pSetPixel */
85     NULL,                            /* pSetPolyFillMode */
86     NULL,                            /* pSetROP2 */
87     NULL,                            /* pSetRelAbs */
88     NULL,                            /* pSetStretchBltMode */
89     NULL,                            /* pSetTextAlign */
90     NULL,                            /* pSetTextCharacterExtra */
91     PSDRV_SetTextColor,              /* pSetTextColor */
92     NULL,                            /* pSetTextJustification */
93     NULL,                            /* pSetViewportExt (optional) */
94     NULL,                            /* pSetViewportOrg (optional) */
95     NULL,                            /* pSetWindowExt (optional) */
96     NULL,                            /* pSetWindowOrg (optional) */
97     NULL,                            /* pStartDoc */
98     NULL,                            /* pStartPage */
99     NULL,                            /* pStretchBlt */
100     PSDRV_StretchDIBits              /* pStretchDIBits */
101 };
102
103
104 /* Default entries for devcaps */
105
106 static DeviceCaps PSDRV_DevCaps = {
107 /* version */           0, 
108 /* technology */        DT_RASPRINTER,
109 /* horzSize */          210,
110 /* vertSize */          297,
111 /* horzRes */           4961,
112 /* vertRes */           7016, 
113 /* bitsPixel */         1,
114 /* planes */            1,
115 /* numBrushes */        -1,
116 /* numPens */           10,
117 /* numMarkers */        0,
118 /* numFonts */          39,
119 /* numColors */         2,
120 /* pdeviceSize */       0,      
121 /* curveCaps */         CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
122                         CC_WIDE | CC_STYLED | CC_WIDESTYLED | CC_INTERIORS |
123                         CC_ROUNDRECT,
124 /* lineCaps */          LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
125                         LC_STYLED | LC_WIDESTYLED | LC_INTERIORS,
126 /* polygoalnCaps */     PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
127                         PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED |
128                         PC_INTERIORS,
129 /* textCaps */          TC_CR_ANY, /* psdrv 0x59f7 */
130 /* clipCaps */          CP_RECTANGLE,
131 /* rasterCaps */        RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT |
132                         RC_DIBTODEV | RC_STRETCHBLT |
133                         RC_STRETCHDIB, /* psdrv 0x6e99 */
134 /* aspectX */           600,
135 /* aspectY */           600,
136 /* aspectXY */          848,
137 /* pad1 */              { 0 },
138 /* logPixelsX */        600,
139 /* logPixelsY */        600, 
140 /* pad2 */              { 0 },
141 /* palette size */      0,
142 /* ..etc */             0, 0 };
143
144 static PSDRV_DEVMODEA DefaultDevmode = 
145 {
146   { /* dmPublic */
147 /* dmDeviceName */      "Wine PostScript Driver",
148 /* dmSpecVersion */     0x30a,
149 /* dmDriverVersion */   0x001,
150 /* dmSize */            sizeof(DEVMODEA),
151 /* dmDriverExtra */     0,
152 /* dmFields */          DM_ORIENTATION | DM_PAPERSIZE | DM_PAPERLENGTH |
153                         DM_PAPERWIDTH | DM_SCALE | DM_COPIES | 
154                         DM_DEFAULTSOURCE | DM_COLOR | DM_DUPLEX | 
155                         DM_YRESOLUTION | DM_TTOPTION,
156    { /* u1 */
157      { /* s1 */
158 /* dmOrientation */     DMORIENT_PORTRAIT,
159 /* dmPaperSize */       DMPAPER_A4,
160 /* dmPaperLength */     2969,
161 /* dmPaperWidth */      2101
162      }
163    },
164 /* dmScale */           100, /* ?? */
165 /* dmCopies */          1,
166 /* dmDefaultSource */   DMBIN_AUTO,
167 /* dmPrintQuality */    0,
168 /* dmColor */           DMCOLOR_MONOCHROME,
169 /* dmDuplex */          0,
170 /* dmYResolution */     0,
171 /* dmTTOption */        DMTT_SUBDEV,
172 /* dmCollate */         0,
173 /* dmFormName */        "",
174 /* dmUnusedPadding */   0,
175 /* dmBitsPerPel */      0,
176 /* dmPelsWidth */       0,
177 /* dmPelsHeight */      0,
178 /* dmDisplayFlags */    0,
179 /* dmDisplayFrequency */ 0
180   },
181   { /* dmDocPrivate */
182     0 /* dummy */
183   },
184   { /* dmDrvPrivate */
185 /* ppdfilename */       "default.ppd"
186   }
187 };
188
189 HANDLE PSDRV_Heap = 0;
190
191 static HANDLE PSDRV_DefaultFont = 0;
192 static LOGFONTA DefaultLogFont = {
193     100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0,
194     DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, ""
195 };
196
197 /*********************************************************************
198  *           PSDRV_Init
199  *
200  * Initializes font metrics and registers driver. Called from GDI_Init()
201  *
202  */
203 BOOL PSDRV_Init(void)
204 {
205     TRACE(psdrv, "\n");
206     PSDRV_Heap = HeapCreate(0, 0x10000, 0);
207     PSDRV_GetFontMetrics();
208     PSDRV_DefaultFont = CreateFontIndirectA(&DefaultLogFont);
209     return DRIVER_RegisterDriver( "WINEPS", &PSDRV_Funcs );
210 }
211
212 /**********************************************************************
213  *           PSDRV_CreateDC
214  */
215 static BOOL PSDRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
216                                LPCSTR output, const DEVMODEA* initData )
217 {
218     PSDRV_PDEVICE *physDev;
219     PRINTERINFO *pi;
220     DeviceCaps *devCaps;
221
222     /* If no device name was specified, retrieve the device name
223      * from the DEVMODE structure from the DC's physDev.
224      * (See CreateCompatibleDC) */
225     if ( !device && dc->physDev )
226     {
227         physDev = (PSDRV_PDEVICE *)dc->physDev;
228         device = physDev->Devmode->dmPublic.dmDeviceName;
229     }
230     pi = PSDRV_FindPrinterInfo(device);
231         
232     TRACE(psdrv, "(%s %s %s %p)\n", driver, device, output, initData);
233
234     if(!pi) return FALSE;
235
236     if(!pi->Fonts) {
237         MSG("To use WINEPS you need to install some AFM files.\n");
238         return FALSE;
239     }
240
241     physDev = (PSDRV_PDEVICE *)HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY,
242                                                      sizeof(*physDev) );
243     if (!physDev) return FALSE;
244     dc->physDev = physDev;
245
246     physDev->pi = pi;
247
248     physDev->Devmode = (PSDRV_DEVMODEA *)HeapAlloc( PSDRV_Heap, 0,
249                                                      sizeof(PSDRV_DEVMODEA) );
250     if(!physDev->Devmode) {
251         HeapFree( PSDRV_Heap, 0, physDev );
252         return FALSE;
253     }
254     
255     memcpy( physDev->Devmode, pi->Devmode, sizeof(PSDRV_DEVMODEA) );
256
257     if(initData) {
258         PSDRV_MergeDevmodes(physDev->Devmode, (PSDRV_DEVMODEA *)initData, pi);
259     }
260
261     
262     devCaps = HeapAlloc( PSDRV_Heap, 0, sizeof(PSDRV_DevCaps) );
263     memcpy(devCaps, &PSDRV_DevCaps, sizeof(PSDRV_DevCaps));
264
265     if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_PORTRAIT) {
266         devCaps->horzSize = physDev->Devmode->dmPublic.u1.s1.dmPaperWidth / 10;
267         devCaps->vertSize = physDev->Devmode->dmPublic.u1.s1.dmPaperLength / 10;
268     } else {
269         devCaps->horzSize = physDev->Devmode->dmPublic.u1.s1.dmPaperLength / 10;
270         devCaps->vertSize = physDev->Devmode->dmPublic.u1.s1.dmPaperWidth / 10;
271     }
272
273     devCaps->horzRes = physDev->pi->ppd->DefaultResolution * 
274       devCaps->horzSize / 25.4;
275     devCaps->vertRes = physDev->pi->ppd->DefaultResolution * 
276       devCaps->vertSize / 25.4;
277
278     /* Are aspect[XY] and logPixels[XY] correct? */
279     /* Need to handle different res in x and y => fix ppd */
280     devCaps->aspectX = devCaps->logPixelsX = 
281                                 physDev->pi->ppd->DefaultResolution;
282     devCaps->aspectY = devCaps->logPixelsY = 
283                                 physDev->pi->ppd->DefaultResolution;
284     devCaps->aspectXY = (int)hypot( (double)devCaps->aspectX, 
285                                     (double)devCaps->aspectY );
286
287     if(physDev->pi->ppd->ColorDevice) {
288         devCaps->bitsPixel = 8;
289         devCaps->numColors = 256;
290         /* FIXME are these values OK? */
291     }
292
293     /* etc */
294
295     dc->w.devCaps = devCaps;
296
297     dc->w.hVisRgn = CreateRectRgn(0, 0, dc->w.devCaps->horzRes,
298                             dc->w.devCaps->vertRes);
299     
300     dc->w.hFont = PSDRV_DefaultFont;
301     physDev->job.output = output ? HEAP_strdupA( PSDRV_Heap, 0, output ) :
302       NULL;
303     physDev->job.hJob = 0;
304     return TRUE;
305 }
306
307
308 /**********************************************************************
309  *           PSDRV_DeleteDC
310  */
311 static BOOL PSDRV_DeleteDC( DC *dc )
312 {
313     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
314     
315     TRACE(psdrv, "\n");
316
317     HeapFree( PSDRV_Heap, 0, physDev->Devmode );
318     HeapFree( PSDRV_Heap, 0, physDev->job.output );
319     HeapFree( PSDRV_Heap, 0, (void *)dc->w.devCaps );
320     HeapFree( PSDRV_Heap, 0, physDev );
321     dc->physDev = NULL;
322
323     return TRUE;
324 }
325
326
327         
328
329 /**********************************************************************
330  *              PSDRV_FindPrinterInfo
331  */
332 PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) 
333 {
334     static PRINTERINFO *PSDRV_PrinterList;
335     DWORD type = REG_BINARY, needed, res;
336     PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList;
337     FONTNAME *font;
338     AFM *afm;
339
340     TRACE(psdrv, "'%s'\n", name);
341     
342     for( ; pi; last = &pi->next, pi = pi->next) {
343         if(!strcmp(pi->FriendlyName, name))
344             return pi;
345     }
346
347     pi = *last = HeapAlloc( PSDRV_Heap, 0, sizeof(*pi) );
348     pi->FriendlyName = HEAP_strdupA( PSDRV_Heap, 0, name );
349     res = DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type,
350                             NULL, 0, &needed );
351
352     if(res == ERROR_INVALID_PRINTER_NAME) {
353         pi->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(DefaultDevmode) );
354         memcpy(pi->Devmode, &DefaultDevmode, sizeof(DefaultDevmode) );
355         DrvSetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE,
356                  REG_BINARY, (LPBYTE)&DefaultDevmode, sizeof(DefaultDevmode) );
357
358         /* need to do something here AddPrinter?? */
359     } else {
360         pi->Devmode = HeapAlloc( PSDRV_Heap, 0, needed );
361         DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type,
362                           (LPBYTE)pi->Devmode, needed, &needed);
363     }
364
365     pi->ppd = PSDRV_ParsePPD(pi->Devmode->dmDrvPrivate.ppdFileName);
366     if(!pi->ppd) {
367         HeapFree(PSDRV_Heap, 0, pi->FriendlyName);
368         HeapFree(PSDRV_Heap, 0, pi->Devmode);
369         HeapFree(PSDRV_Heap, 0, pi);
370         *last = NULL;
371         MSG("Couldn't find PPD file '%s', expect a crash now!\n",
372             pi->Devmode->dmDrvPrivate.ppdFileName);
373         return NULL;
374     }
375
376     pi->next = NULL;
377     pi->Fonts = NULL;
378
379     for(font = pi->ppd->InstalledFonts; font; font = font->next) {
380         afm = PSDRV_FindAFMinList(PSDRV_AFMFontList, font->Name);
381         if(!afm) {
382             MSG(
383          "Couldn't find AFM file for installed printer font '%s' - ignoring\n",
384          font->Name);
385         } else {
386             PSDRV_AddAFMtoList(&pi->Fonts, afm);
387         }
388     }
389
390     return pi;
391 }