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