2 * PostScript driver initialization functions
4 * Copyright 1998 Huw D M Davies
11 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(psdrv
);
20 static BOOL
PSDRV_CreateDC( DC
*dc
, LPCSTR driver
, LPCSTR device
,
21 LPCSTR output
, const DEVMODEA
* initData
);
22 static BOOL
PSDRV_DeleteDC( DC
*dc
);
24 static const DC_FUNCTIONS PSDRV_Funcs
=
27 NULL
, /* pAbortPath */
31 NULL
, /* pBeginPath */
33 NULL
, /* pBitmapBits */
34 NULL
, /* pChoosePixelFormat */
35 PSDRV_Chord
, /* pChord */
36 NULL
, /* pCloseFigure */
37 NULL
, /* pCreateBitmap */
38 PSDRV_CreateDC
, /* pCreateDC */
39 NULL
, /* pCreateDIBSection */
40 NULL
, /* pCreateDIBSection16 */
41 PSDRV_DeleteDC
, /* pDeleteDC */
42 NULL
, /* pDeleteObject */
43 NULL
, /* pDescribePixelFormat */
44 PSDRV_DeviceCapabilities
, /* pDeviceCapabilities */
45 PSDRV_Ellipse
, /* pEllipse */
46 PSDRV_EndDoc
, /* pEndDoc */
47 PSDRV_EndPage
, /* pEndPage */
49 PSDRV_EnumDeviceFonts
, /* pEnumDeviceFonts */
50 PSDRV_Escape
, /* pEscape */
51 NULL
, /* pExcludeClipRect */
52 PSDRV_ExtDeviceMode
, /* pExtDeviceMode */
53 NULL
, /* pExtFloodFill */
54 PSDRV_ExtTextOut
, /* pExtTextOut */
57 NULL
, /* pFlattenPath */
59 PSDRV_GetCharWidth
, /* pGetCharWidth */
60 NULL
, /* pGetDCOrgEx */
62 NULL
, /* pGetPixelFormat */
63 PSDRV_GetTextExtentPoint
, /* pGetTextExtentPoint */
64 PSDRV_GetTextMetrics
, /* pGetTextMetrics */
65 NULL
, /* pIntersectClipRect */
66 NULL
, /* pInvertRgn */
67 PSDRV_LineTo
, /* pLineTo */
69 NULL
, /* pOffsetClipRgn */
70 NULL
, /* pOffsetViewportOrg (optional) */
71 NULL
, /* pOffsetWindowOrg (optional) */
73 PSDRV_PatBlt
, /* pPatBlt */
75 NULL
, /* pPolyBezier */
76 NULL
, /* pPolyBezierTo */
78 PSDRV_PolyPolygon
, /* pPolyPolygon */
79 PSDRV_PolyPolyline
, /* pPolyPolyline */
80 PSDRV_Polygon
, /* pPolygon */
81 PSDRV_Polyline
, /* pPolyline */
82 NULL
, /* pPolylineTo */
83 NULL
, /* pRealizePalette */
84 PSDRV_Rectangle
, /* pRectangle */
85 NULL
, /* pRestoreDC */
86 PSDRV_RoundRect
, /* pRoundRect */
88 NULL
, /* pScaleViewportExt (optional) */
89 NULL
, /* pScaleWindowExt (optional) */
90 NULL
, /* pSelectClipPath */
91 NULL
, /* pSelectClipRgn */
92 PSDRV_SelectObject
, /* pSelectObject */
93 NULL
, /* pSelectPalette */
94 PSDRV_SetBkColor
, /* pSetBkColor */
95 NULL
, /* pSetBkMode */
96 PSDRV_SetDeviceClipping
, /* pSetDeviceClipping */
97 NULL
, /* pSetDIBitsToDevice */
98 NULL
, /* pSetMapMode (optional) */
99 NULL
, /* pSetMapperFlags */
100 PSDRV_SetPixel
, /* pSetPixel */
101 NULL
, /* pSetPixelFormat */
102 NULL
, /* pSetPolyFillMode */
104 NULL
, /* pSetRelAbs */
105 NULL
, /* pSetStretchBltMode */
106 NULL
, /* pSetTextAlign */
107 NULL
, /* pSetTextCharacterExtra */
108 PSDRV_SetTextColor
, /* pSetTextColor */
109 NULL
, /* pSetTextJustification */
110 NULL
, /* pSetViewportExt (optional) */
111 NULL
, /* pSetViewportOrg (optional) */
112 NULL
, /* pSetWindowExt (optional) */
113 NULL
, /* pSetWindowOrg (optional) */
114 PSDRV_StartDoc
, /* pStartDoc */
115 PSDRV_StartPage
, /* pStartPage */
116 NULL
, /* pStretchBlt */
117 PSDRV_StretchDIBits
, /* pStretchDIBits */
118 NULL
, /* pStrokeAndFillPath */
119 NULL
, /* pStrokePath */
120 NULL
, /* pSwapBuffers */
121 NULL
/* pWidenPath */
125 /* Default entries for devcaps */
127 static DeviceCaps PSDRV_DevCaps
= {
129 /* technology */ DT_RASPRINTER
,
142 /* curveCaps */ CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
|
143 CC_WIDE
| CC_STYLED
| CC_WIDESTYLED
| CC_INTERIORS
|
145 /* lineCaps */ LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
146 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
,
147 /* polygoalnCaps */ PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
|
148 PC_SCANLINE
| PC_WIDE
| PC_STYLED
| PC_WIDESTYLED
|
150 /* textCaps */ TC_CR_ANY
, /* psdrv 0x59f7 */
151 /* clipCaps */ CP_RECTANGLE
,
152 /* rasterCaps */ RC_BITBLT
| RC_BITMAP64
| RC_GDI20_OUTPUT
|
153 RC_DIBTODEV
| RC_STRETCHBLT
|
154 RC_STRETCHDIB
, /* psdrv 0x6e99 */
159 /* logPixelsX */ 600,
160 /* logPixelsY */ 600,
162 /* palette size */ 0,
165 static PSDRV_DEVMODEA DefaultDevmode
=
168 /* dmDeviceName */ "Wine PostScript Driver",
169 /* dmSpecVersion */ 0x30a,
170 /* dmDriverVersion */ 0x001,
171 /* dmSize */ sizeof(DEVMODEA
),
172 /* dmDriverExtra */ 0,
173 /* dmFields */ DM_ORIENTATION
| DM_PAPERSIZE
| DM_SCALE
|
174 DM_COPIES
| DM_DEFAULTSOURCE
| DM_COLOR
|
175 DM_DUPLEX
| DM_YRESOLUTION
| DM_TTOPTION
,
178 /* dmOrientation */ DMORIENT_PORTRAIT
,
179 /* dmPaperSize */ DMPAPER_A4
,
180 /* dmPaperLength */ 2969,
181 /* dmPaperWidth */ 2101
184 /* dmScale */ 100, /* ?? */
186 /* dmDefaultSource */ DMBIN_AUTO
,
187 /* dmPrintQuality */ 0,
188 /* dmColor */ DMCOLOR_MONOCHROME
,
190 /* dmYResolution */ 0,
191 /* dmTTOption */ DMTT_SUBDEV
,
194 /* dmUnusedPadding */ 0,
195 /* dmBitsPerPel */ 0,
197 /* dmPelsHeight */ 0,
198 /* dmDisplayFlags */ 0,
199 /* dmDisplayFrequency */ 0,
203 /* dmDitherType */ 0,
206 /* dmPanningWidth */ 0,
207 /* dmPanningHeight */ 0
213 /* ppdfilename */ "default.ppd",
214 /* numInstalledOptions */ 0
218 HANDLE PSDRV_Heap
= 0;
220 static HANDLE PSDRV_DefaultFont
= 0;
221 static LOGFONTA DefaultLogFont
= {
222 100, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
, 0, 0,
223 DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, ""
226 /*********************************************************************
229 * Initializes font metrics and registers driver. Called from GDI_Init()
232 BOOL WINAPI
PSDRV_Init( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
234 static int process_count
= 0;
236 TRACE("(0x%4x, 0x%08lx, %p)\n", hinst
, reason
, reserved
);
239 case DLL_PROCESS_ATTACH
:
240 if (!process_count
++) {
241 /* FIXME: return FALSE if we fail any of these steps */
242 PSDRV_Heap
= HeapCreate(0, 0x10000, 0);
243 PSDRV_GetFontMetrics();
244 PSDRV_DefaultFont
= CreateFontIndirectA(&DefaultLogFont
);
245 /* Register driver as "WINEPS", "WINEPS.DLL" and "WINEPS.DRV"
246 to allow an easy configuring for users */
247 DRIVER_RegisterDriver( "WINEPS", &PSDRV_Funcs
);
248 DRIVER_RegisterDriver( "WINEPS.DLL", &PSDRV_Funcs
);
249 DRIVER_RegisterDriver( "WINEPS.DRV", &PSDRV_Funcs
);
252 case DLL_PROCESS_DETACH
:
253 if (!--process_count
) {
254 DeleteObject( PSDRV_DefaultFont
);
255 HeapDestroy( PSDRV_Heap
);
256 DRIVER_UnregisterDriver( "WINEPS" );
257 DRIVER_UnregisterDriver( "WINEPS.DLL" );
258 DRIVER_UnregisterDriver( "WINEPS.DRV" );
267 /**********************************************************************
270 static BOOL
PSDRV_CreateDC( DC
*dc
, LPCSTR driver
, LPCSTR device
,
271 LPCSTR output
, const DEVMODEA
* initData
)
273 PSDRV_PDEVICE
*physDev
;
277 /* If no device name was specified, retrieve the device name
278 * from the DEVMODE structure from the DC's physDev.
279 * (See CreateCompatibleDC) */
280 if ( !device
&& dc
->physDev
)
282 physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
283 device
= physDev
->Devmode
->dmPublic
.dmDeviceName
;
285 pi
= PSDRV_FindPrinterInfo(device
);
287 TRACE("(%s %s %s %p)\n", driver
, device
, output
, initData
);
289 if(!pi
) return FALSE
;
292 MESSAGE("To use WINEPS you need to install some AFM files.\n");
296 physDev
= (PSDRV_PDEVICE
*)HeapAlloc( PSDRV_Heap
, HEAP_ZERO_MEMORY
,
298 if (!physDev
) return FALSE
;
299 dc
->physDev
= physDev
;
303 physDev
->Devmode
= (PSDRV_DEVMODEA
*)HeapAlloc( PSDRV_Heap
, 0,
304 sizeof(PSDRV_DEVMODEA
) );
305 if(!physDev
->Devmode
) {
306 HeapFree( PSDRV_Heap
, 0, physDev
);
310 memcpy( physDev
->Devmode
, pi
->Devmode
, sizeof(PSDRV_DEVMODEA
) );
313 PSDRV_MergeDevmodes(physDev
->Devmode
, (PSDRV_DEVMODEA
*)initData
, pi
);
317 devCaps
= HeapAlloc( PSDRV_Heap
, 0, sizeof(PSDRV_DevCaps
) );
318 memcpy(devCaps
, &PSDRV_DevCaps
, sizeof(PSDRV_DevCaps
));
320 if(physDev
->Devmode
->dmPublic
.u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
) {
321 devCaps
->horzSize
= physDev
->Devmode
->dmPublic
.u1
.s1
.dmPaperWidth
/ 10;
322 devCaps
->vertSize
= physDev
->Devmode
->dmPublic
.u1
.s1
.dmPaperLength
/ 10;
324 devCaps
->horzSize
= physDev
->Devmode
->dmPublic
.u1
.s1
.dmPaperLength
/ 10;
325 devCaps
->vertSize
= physDev
->Devmode
->dmPublic
.u1
.s1
.dmPaperWidth
/ 10;
328 devCaps
->horzRes
= physDev
->pi
->ppd
->DefaultResolution
*
329 devCaps
->horzSize
/ 25.4;
330 devCaps
->vertRes
= physDev
->pi
->ppd
->DefaultResolution
*
331 devCaps
->vertSize
/ 25.4;
333 /* Are aspect[XY] and logPixels[XY] correct? */
334 /* Need to handle different res in x and y => fix ppd */
335 devCaps
->aspectX
= devCaps
->logPixelsX
=
336 physDev
->pi
->ppd
->DefaultResolution
;
337 devCaps
->aspectY
= devCaps
->logPixelsY
=
338 physDev
->pi
->ppd
->DefaultResolution
;
339 devCaps
->aspectXY
= (int)hypot( (double)devCaps
->aspectX
,
340 (double)devCaps
->aspectY
);
342 if(physDev
->pi
->ppd
->ColorDevice
) {
343 devCaps
->bitsPixel
= 8;
344 devCaps
->numColors
= 256;
345 /* FIXME are these values OK? */
350 dc
->devCaps
= devCaps
;
352 dc
->hVisRgn
= CreateRectRgn(0, 0, dc
->devCaps
->horzRes
,
353 dc
->devCaps
->vertRes
);
355 dc
->hFont
= PSDRV_DefaultFont
;
356 physDev
->job
.output
= output
?
357 HEAP_strdupA( PSDRV_Heap
, 0, output
) :
358 HEAP_strdupA( PSDRV_Heap
, 0, "LPT1:" ); /* HACK */
359 physDev
->job
.hJob
= 0;
364 /**********************************************************************
367 static BOOL
PSDRV_DeleteDC( DC
*dc
)
369 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
373 HeapFree( PSDRV_Heap
, 0, physDev
->Devmode
);
374 HeapFree( PSDRV_Heap
, 0, physDev
->job
.output
);
375 HeapFree( PSDRV_Heap
, 0, (void *)dc
->devCaps
);
376 HeapFree( PSDRV_Heap
, 0, physDev
);
385 /**********************************************************************
386 * PSDRV_FindPrinterInfo
388 PRINTERINFO
*PSDRV_FindPrinterInfo(LPCSTR name
)
390 static PRINTERINFO
*PSDRV_PrinterList
;
391 DWORD type
= REG_BINARY
, needed
, res
;
392 PRINTERINFO
*pi
= PSDRV_PrinterList
, **last
= &PSDRV_PrinterList
;
396 TRACE("'%s'\n", name
);
398 for( ; pi
; last
= &pi
->next
, pi
= pi
->next
) {
399 if(!strcmp(pi
->FriendlyName
, name
))
403 pi
= *last
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*pi
) );
404 pi
->FriendlyName
= HEAP_strdupA( PSDRV_Heap
, 0, name
);
405 res
= DrvGetPrinterData16((LPSTR
)name
, (LPSTR
)INT_PD_DEFAULT_DEVMODE
, &type
,
408 if(res
== ERROR_INVALID_PRINTER_NAME
|| needed
!= sizeof(DefaultDevmode
)) {
409 pi
->Devmode
= HeapAlloc( PSDRV_Heap
, 0, sizeof(DefaultDevmode
) );
410 memcpy(pi
->Devmode
, &DefaultDevmode
, sizeof(DefaultDevmode
) );
411 DrvSetPrinterData16((LPSTR
)name
, (LPSTR
)INT_PD_DEFAULT_DEVMODE
,
412 REG_BINARY
, (LPBYTE
)&DefaultDevmode
, sizeof(DefaultDevmode
) );
414 /* need to do something here AddPrinter?? */
416 pi
->Devmode
= HeapAlloc( PSDRV_Heap
, 0, needed
);
417 DrvGetPrinterData16((LPSTR
)name
, (LPSTR
)INT_PD_DEFAULT_DEVMODE
, &type
,
418 (LPBYTE
)pi
->Devmode
, needed
, &needed
);
421 PROFILE_GetWineIniString("psdrv", "ppdfile", "default.ppd",
422 pi
->Devmode
->dmDrvPrivate
.ppdFileName
, 256);
423 pi
->ppd
= PSDRV_ParsePPD(pi
->Devmode
->dmDrvPrivate
.ppdFileName
);
425 HeapFree(PSDRV_Heap
, 0, pi
->FriendlyName
);
426 HeapFree(PSDRV_Heap
, 0, pi
->Devmode
);
427 HeapFree(PSDRV_Heap
, 0, pi
);
429 MESSAGE("Couldn't find PPD file '%s', expect a crash now!\n",
430 pi
->Devmode
->dmDrvPrivate
.ppdFileName
);
437 for(font
= pi
->ppd
->InstalledFonts
; font
; font
= font
->next
) {
438 afm
= PSDRV_FindAFMinList(PSDRV_AFMFontList
, font
->Name
);
441 "Couldn't find AFM file for installed printer font '%s' - ignoring\n",
444 PSDRV_AddAFMtoList(&pi
->Fonts
, afm
);