2 * Exported functions from the PostScript driver.
4 * [Ext]DeviceMode, DeviceCapabilities, AdvancedSetupDialog.
6 * Will need ExtTextOut for winword6 (urgh!)
8 * Copyright 1998 Huw D M Davies
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
37 /************************************************************************
41 * Updates dm1 with some fields from dm2
44 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA
*dm1
, PSDRV_DEVMODEA
*dm2
,
47 /* some sanity checks here on dm2 */
49 if(dm2
->dmPublic
.dmFields
& DM_ORIENTATION
) {
50 dm1
->dmPublic
.u1
.s1
.dmOrientation
= dm2
->dmPublic
.u1
.s1
.dmOrientation
;
51 TRACE("Changing orientation to %d (%s)\n",
52 dm1
->dmPublic
.u1
.s1
.dmOrientation
,
53 dm1
->dmPublic
.u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
?
55 (dm1
->dmPublic
.u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
?
56 "Landscape" : "unknown"));
59 /* NB PaperWidth is always < PaperLength */
60 if(dm2
->dmPublic
.dmFields
& DM_PAPERSIZE
) {
63 for(page
= pi
->ppd
->PageSizes
; page
; page
= page
->next
) {
64 if(page
->WinPage
== dm2
->dmPublic
.u1
.s1
.dmPaperSize
)
68 dm1
->dmPublic
.u1
.s1
.dmPaperSize
= dm2
->dmPublic
.u1
.s1
.dmPaperSize
;
69 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= page
->PaperDimension
->x
*
71 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= page
->PaperDimension
->y
*
73 dm1
->dmPublic
.dmFields
&= ~(DM_PAPERLENGTH
| DM_PAPERWIDTH
);
74 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
75 TRACE("Changing page to %s %d x %d\n", page
->FullName
,
76 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
,
77 dm1
->dmPublic
.u1
.s1
.dmPaperLength
);
79 TRACE("Trying to change to unsupported pagesize %d\n",
80 dm2
->dmPublic
.u1
.s1
.dmPaperSize
);
82 } else if((dm2
->dmPublic
.dmFields
& DM_PAPERLENGTH
) &&
83 (dm2
->dmPublic
.dmFields
& DM_PAPERWIDTH
)) {
84 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= dm2
->dmPublic
.u1
.s1
.dmPaperLength
;
85 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= dm2
->dmPublic
.u1
.s1
.dmPaperWidth
;
86 TRACE("Changing PaperLength|Width to %dx%d\n",
87 dm2
->dmPublic
.u1
.s1
.dmPaperLength
,
88 dm2
->dmPublic
.u1
.s1
.dmPaperWidth
);
89 dm1
->dmPublic
.dmFields
&= ~DM_PAPERSIZE
;
90 dm1
->dmPublic
.dmFields
|= (DM_PAPERLENGTH
| DM_PAPERWIDTH
);
91 } else if(dm2
->dmPublic
.dmFields
& (DM_PAPERLENGTH
| DM_PAPERWIDTH
)) {
92 /* You might think that this would be allowed if dm1 is in custom size
93 mode, but apparently Windows reverts to standard paper mode even in
95 FIXME("Trying to change only paperlength or paperwidth\n");
96 dm1
->dmPublic
.dmFields
&= ~(DM_PAPERLENGTH
| DM_PAPERWIDTH
);
97 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
100 if(dm2
->dmPublic
.dmFields
& DM_SCALE
) {
101 dm1
->dmPublic
.dmScale
= dm2
->dmPublic
.dmScale
;
102 TRACE("Changing Scale to %d\n", dm2
->dmPublic
.dmScale
);
105 if(dm2
->dmPublic
.dmFields
& DM_COPIES
) {
106 dm1
->dmPublic
.dmCopies
= dm2
->dmPublic
.dmCopies
;
107 TRACE("Changing Copies to %d\n", dm2
->dmPublic
.dmCopies
);
110 if(dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
) {
113 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
) {
114 if(slot
->WinBin
== dm2
->dmPublic
.dmDefaultSource
)
118 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
119 TRACE("Changing bin to '%s'\n", slot
->FullName
);
121 TRACE("Trying to change to unsupported bin %d\n",
122 dm2
->dmPublic
.dmDefaultSource
);
126 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
127 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
128 if (dm2
->dmPublic
.dmFields
& DM_PRINTQUALITY
)
129 dm1
->dmPublic
.dmPrintQuality
= dm2
->dmPublic
.dmPrintQuality
;
130 if (dm2
->dmPublic
.dmFields
& DM_COLOR
)
131 dm1
->dmPublic
.dmColor
= dm2
->dmPublic
.dmColor
;
132 if (dm2
->dmPublic
.dmFields
& DM_DUPLEX
)
133 dm1
->dmPublic
.dmDuplex
= dm2
->dmPublic
.dmDuplex
;
134 if (dm2
->dmPublic
.dmFields
& DM_YRESOLUTION
)
135 dm1
->dmPublic
.dmYResolution
= dm2
->dmPublic
.dmYResolution
;
136 if (dm2
->dmPublic
.dmFields
& DM_TTOPTION
)
137 dm1
->dmPublic
.dmTTOption
= dm2
->dmPublic
.dmTTOption
;
138 if (dm2
->dmPublic
.dmFields
& DM_COLLATE
)
139 dm1
->dmPublic
.dmCollate
= dm2
->dmPublic
.dmCollate
;
140 if (dm2
->dmPublic
.dmFields
& DM_FORMNAME
)
141 lstrcpynA(dm1
->dmPublic
.dmFormName
, dm2
->dmPublic
.dmFormName
, CCHFORMNAME
);
142 if (dm2
->dmPublic
.dmFields
& DM_BITSPERPEL
)
143 dm1
->dmPublic
.dmBitsPerPel
= dm2
->dmPublic
.dmBitsPerPel
;
144 if (dm2
->dmPublic
.dmFields
& DM_PELSWIDTH
)
145 dm1
->dmPublic
.dmPelsWidth
= dm2
->dmPublic
.dmPelsWidth
;
146 if (dm2
->dmPublic
.dmFields
& DM_PELSHEIGHT
)
147 dm1
->dmPublic
.dmPelsHeight
= dm2
->dmPublic
.dmPelsHeight
;
148 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFLAGS
)
149 dm1
->dmPublic
.dmDisplayFlags
= dm2
->dmPublic
.dmDisplayFlags
;
150 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFREQUENCY
)
151 dm1
->dmPublic
.dmDisplayFrequency
= dm2
->dmPublic
.dmDisplayFrequency
;
152 if (dm2
->dmPublic
.dmFields
& DM_POSITION
)
153 dm1
->dmPublic
.u1
.dmPosition
= dm2
->dmPublic
.u1
.dmPosition
;
154 if (dm2
->dmPublic
.dmFields
& DM_LOGPIXELS
)
155 dm1
->dmPublic
.dmLogPixels
= dm2
->dmPublic
.dmLogPixels
;
156 if (dm2
->dmPublic
.dmFields
& DM_ICMMETHOD
)
157 dm1
->dmPublic
.dmICMMethod
= dm2
->dmPublic
.dmICMMethod
;
158 if (dm2
->dmPublic
.dmFields
& DM_ICMINTENT
)
159 dm1
->dmPublic
.dmICMIntent
= dm2
->dmPublic
.dmICMIntent
;
160 if (dm2
->dmPublic
.dmFields
& DM_MEDIATYPE
)
161 dm1
->dmPublic
.dmMediaType
= dm2
->dmPublic
.dmMediaType
;
162 if (dm2
->dmPublic
.dmFields
& DM_DITHERTYPE
)
163 dm1
->dmPublic
.dmDitherType
= dm2
->dmPublic
.dmDitherType
;
164 if (dm2
->dmPublic
.dmFields
& DM_PANNINGWIDTH
)
165 dm1
->dmPublic
.dmPanningWidth
= dm2
->dmPublic
.dmPanningWidth
;
166 if (dm2
->dmPublic
.dmFields
& DM_PANNINGHEIGHT
)
167 dm1
->dmPublic
.dmPanningHeight
= dm2
->dmPublic
.dmPanningHeight
;
173 /**************************************************************
174 * AdvancedSetupDialog [WINEPS16.93]
177 WORD WINAPI
PSDRV_AdvancedSetupDialog16(HWND16 hwnd
, HANDLE16 hDriver
,
178 LPDEVMODEA devin
, LPDEVMODEA devout
)
181 TRACE("hwnd = %04x, hDriver = %04x devin=%p devout=%p\n", hwnd
,
182 hDriver
, devin
, devout
);
186 /****************************************************************
189 * Dialog proc for 'Paper' propsheet
191 BOOL WINAPI
PSDRV_PaperDlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM
201 di
= (PSDRV_DLGINFO
*)((PROPSHEETPAGEA
*)lParam
)->lParam
;
202 SetWindowLongA(hwnd
, DWL_USER
, (LONG
)di
);
204 for(ps
= di
->pi
->ppd
->PageSizes
, i
= 0; ps
; ps
= ps
->next
, i
++) {
205 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_INSERTSTRING
, i
,
206 (LPARAM
)ps
->FullName
);
207 if(di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmPaperSize
== ps
->WinPage
)
210 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_SETCURSEL
, Cursel
, 0);
212 CheckRadioButton(hwnd
, IDD_ORIENT_PORTRAIT
, IDD_ORIENT_LANDSCAPE
,
213 di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmOrientation
==
214 DMORIENT_PORTRAIT
? IDD_ORIENT_PORTRAIT
:
215 IDD_ORIENT_LANDSCAPE
);
219 di
= (PSDRV_DLGINFO
*)GetWindowLongA(hwnd
, DWL_USER
);
220 switch(LOWORD(wParam
)) {
222 if(HIWORD(wParam
) == LBN_SELCHANGE
) {
223 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), LB_GETCURSEL
, 0, 0);
224 for(i
= 0, ps
= di
->pi
->ppd
->PageSizes
; i
< Cursel
; i
++, ps
= ps
->next
)
226 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel
,
228 di
->dlgdm
->dmPublic
.u1
.s1
.dmPaperSize
= ps
->WinPage
;
231 case IDD_ORIENT_PORTRAIT
:
232 case IDD_ORIENT_LANDSCAPE
:
233 TRACE("Setting orientation to %s\n", wParam
== IDD_ORIENT_PORTRAIT
?
234 "portrait" : "landscape");
235 di
->dlgdm
->dmPublic
.u1
.s1
.dmOrientation
= wParam
== IDD_ORIENT_PORTRAIT
?
236 DMORIENT_PORTRAIT
: DMORIENT_LANDSCAPE
;
243 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
244 di
= (PSDRV_DLGINFO
*)GetWindowLongA(hwnd
, DWL_USER
);
245 switch(nmhdr
->code
) {
247 memcpy(di
->pi
->Devmode
, di
->dlgdm
, sizeof(PSDRV_DEVMODEA
));
248 SetWindowLongA(hwnd
, DWL_MSGRESULT
, PSNRET_NOERROR
);
266 static void (WINAPI
*pInitCommonControls
) (void);
267 static HPROPSHEETPAGE (WINAPI
*pCreatePropertySheetPage
) (LPCPROPSHEETPAGEW
);
268 static int (WINAPI
*pPropertySheet
) (LPCPROPSHEETHEADERW
);
270 /***************************************************************
271 * ExtDeviceMode [WINEPS16.90]
273 * Just returns default devmode at the moment
275 INT16 WINAPI
PSDRV_ExtDeviceMode16(HWND16 hwnd
, HANDLE16 hDriver
,
276 LPDEVMODEA lpdmOutput
, LPSTR lpszDevice
,
277 LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
278 LPSTR lpszProfile
, WORD fwMode
)
280 PRINTERINFO
*pi
= PSDRV_FindPrinterInfo(lpszDevice
);
283 TRACE("(hwnd=%04x, hDriver=%04x, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
284 hwnd
, hDriver
, lpdmOutput
, lpszDevice
, lpszPort
, lpdmInput
, lpszProfile
,
288 return sizeof(DEVMODEA
); /* Just copy dmPublic bit of PSDRV_DEVMODE */
290 if((fwMode
& DM_MODIFY
) && lpdmInput
) {
291 TRACE("DM_MODIFY set. devIn->dmFields = %08lx\n", lpdmInput
->dmFields
);
292 PSDRV_MergeDevmodes(pi
->Devmode
, (PSDRV_DEVMODEA
*)lpdmInput
, pi
);
295 if(fwMode
& DM_PROMPT
) {
296 HINSTANCE hinstComctl32
, hinstWineps32
= LoadLibraryA("WINEPS");
297 HPROPSHEETPAGE hpsp
[1];
299 PROPSHEETHEADERW psh
;
301 PSDRV_DEVMODEA
*dlgdm
;
302 static const WCHAR PAPERW
[] = {'P','A','P','E','R','\0'};
303 static const WCHAR SetupW
[] = {'S','e','t','u','p','\0'};
305 hinstComctl32
= LoadLibraryA("comctl32.dll");
306 pInitCommonControls
= (void*)GetProcAddress(hinstComctl32
,
307 "InitCommonControls");
308 pCreatePropertySheetPage
= (void*)GetProcAddress(hinstComctl32
,
309 "CreatePropertySheetPageW");
310 pPropertySheet
= (void*)GetProcAddress(hinstComctl32
, "PropertySheetW");
311 memset(&psp
,0,sizeof(psp
));
312 dlgdm
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*dlgdm
) );
313 memcpy(dlgdm
, pi
->Devmode
, sizeof(*dlgdm
));
314 di
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*di
) );
317 psp
.dwSize
= sizeof(psp
);
318 psp
.hInstance
= hinstWineps32
;
319 psp
.u
.pszTemplate
= PAPERW
;
320 psp
.u2
.pszIcon
= NULL
;
321 psp
.pfnDlgProc
= PSDRV_PaperDlgProc
;
322 psp
.lParam
= (LPARAM
)di
;
323 hpsp
[0] = pCreatePropertySheetPage(&psp
);
325 memset(&psh
, 0, sizeof(psh
));
326 psh
.dwSize
= sizeof(psh
);
327 psh
.pszCaption
= SetupW
;
329 psh
.hwndParent
= HWND_32(hwnd
);
330 psh
.u3
.phpage
= hpsp
;
332 pPropertySheet(&psh
);
335 if(fwMode
& DM_UPDATE
)
336 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
338 if((fwMode
& DM_COPY
) || (fwMode
& DM_UPDATE
)) {
340 memcpy(lpdmOutput
, pi
->Devmode
, sizeof(DEVMODEA
));
342 FIXME("lpdmOutput is NULL what should we do??\n");
347 /**************************************************************
349 * PSDRV_ExtDeviceMode
351 INT
PSDRV_ExtDeviceMode(LPSTR lpszDriver
, HWND hwnd
, LPDEVMODEA lpdmOutput
,
352 LPSTR lpszDevice
, LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
353 LPSTR lpszProfile
, DWORD dwMode
)
355 return PSDRV_ExtDeviceMode16(HWND_16(hwnd
), 0, lpdmOutput
, lpszDevice
,
356 lpszPort
, lpdmInput
, lpszProfile
, dwMode
);
359 /***********************************************************************
360 * DeviceCapabilities [WINEPS16.91]
363 DWORD WINAPI
PSDRV_DeviceCapabilities16(LPCSTR lpszDevice
, LPCSTR lpszPort
,
364 WORD fwCapability
, LPSTR lpszOutput
,
365 LPDEVMODEA lpDevMode
)
369 pi
= PSDRV_FindPrinterInfo(lpszDevice
);
371 TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability
, pi
);
375 ERR("no printerinfo for %s, return 0!\n",lpszDevice
);
380 lpdm
= lpDevMode
? lpDevMode
: (DEVMODEA
*)pi
->Devmode
;
382 switch(fwCapability
) {
387 WORD
*wp
= (WORD
*)lpszOutput
;
390 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++)
391 if(lpszOutput
!= NULL
)
399 POINT16
*pt
= (POINT16
*)lpszOutput
;
402 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++)
403 if(lpszOutput
!= NULL
) {
404 pt
->x
= ps
->PaperDimension
->x
* 254.0 / 72.0;
405 pt
->y
= ps
->PaperDimension
->y
* 254.0 / 72.0;
414 char *cp
= lpszOutput
;
417 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++)
418 if(lpszOutput
!= NULL
) {
419 lstrcpynA(cp
, ps
->FullName
, 64);
426 return pi
->ppd
->LandscapeOrientation
? pi
->ppd
->LandscapeOrientation
: 90;
431 WORD
*wp
= (WORD
*)lpszOutput
;
434 /* We explicitly list DMBIN_AUTO first; actually while win9x does this
435 win2000 lists DMBIN_FORMSOURCE instead. */
437 if(lpszOutput
!= NULL
)
440 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
441 if(lpszOutput
!= NULL
)
442 *wp
++ = slot
->WinBin
;
449 char *cp
= lpszOutput
;
452 /* Add an entry corresponding to DMBIN_AUTO, see DC_BINS */
454 if(lpszOutput
!= NULL
) {
455 strcpy(cp
, "Automatically Select");
459 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
460 if(lpszOutput
!= NULL
) {
461 lstrcpynA(cp
, slot
->FullName
, 24);
468 FIXME("DC_BINADJUST: stub.\n");
469 return DCBA_FACEUPNONE
;
471 case DC_ENUMRESOLUTIONS
:
473 LONG
*lp
= (LONG
*)lpszOutput
;
475 if(lpszOutput
!= NULL
) {
476 lp
[0] = (LONG
)pi
->ppd
->DefaultResolution
;
477 lp
[1] = (LONG
)pi
->ppd
->DefaultResolution
;
483 FIXME("DC_COPIES: returning %d. Is this correct?\n", lpdm
->dmCopies
);
484 return lpdm
->dmCopies
;
487 return lpdm
->dmDriverVersion
;
489 case DC_DATATYPE_PRODUCED
:
490 FIXME("DATA_TYPE_PRODUCED: stub.\n");
491 return -1; /* simulate that the driver supports 'RAW' */
494 FIXME("DC_DUPLEX: returning %d. Is this correct?\n", lpdm
->dmDuplex
);
495 return lpdm
->dmDuplex
;
497 case DC_EMF_COMPLIANT
:
498 FIXME("DC_EMF_COMPLIANT: stub.\n");
499 return -1; /* simulate that the driver do not support EMF */
502 return lpdm
->dmDriverExtra
;
505 return lpdm
->dmFields
;
507 case DC_FILEDEPENDENCIES
:
508 FIXME("DC_FILEDEPENDENCIES: stub.\n");
516 ptMax
.x
= ptMax
.y
= 0;
518 if(lpszOutput
== NULL
)
522 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++) {
523 if(ps
->PaperDimension
->x
> ptMax
.x
)
524 ptMax
.x
= ps
->PaperDimension
->x
;
525 if(ps
->PaperDimension
->y
> ptMax
.y
)
526 ptMax
.y
= ps
->PaperDimension
->y
;
528 *((POINT
*)lpszOutput
) = ptMax
;
537 ptMax
.x
= ptMax
.y
= 0;
539 if(lpszOutput
== NULL
)
543 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++) {
544 if(ps
->PaperDimension
->x
> ptMax
.x
)
545 ptMax
.x
= ps
->PaperDimension
->x
;
546 if(ps
->PaperDimension
->y
> ptMax
.y
)
547 ptMax
.y
= ps
->PaperDimension
->y
;
549 *((POINT
*)lpszOutput
) = ptMax
;
557 FIXME("DC_TRUETYPE: stub\n");
561 return lpdm
->dmSpecVersion
;
564 FIXME("Unsupported capability %d\n", fwCapability
);
569 /**************************************************************
571 * PSDRV_DeviceCapabilities
573 DWORD
PSDRV_DeviceCapabilities(LPSTR lpszDriver
, LPCSTR lpszDevice
,
574 LPCSTR lpszPort
, WORD fwCapability
,
575 LPSTR lpszOutput
, LPDEVMODEA lpdm
)
577 return PSDRV_DeviceCapabilities16(lpszDevice
, lpszPort
, fwCapability
,
581 /***************************************************************
582 * DeviceMode [WINEPS16.13]
585 void WINAPI
PSDRV_DeviceMode16(HWND16 hwnd
, HANDLE16 hDriver
,
586 LPSTR lpszDevice
, LPSTR lpszPort
)
588 PSDRV_ExtDeviceMode16( hwnd
, hDriver
, NULL
, lpszDevice
, lpszPort
, NULL
,
597 HPROPSHEETPAGE hPages
[10];
600 INT
PSDRV_ExtDeviceModePropSheet(HWND hwnd
, LPSTR lpszDevice
, LPSTR lpszPort
,
603 EDMPS
*ps
= pPropSheet
;
606 psp
->dwSize
= sizeof(psp
);
607 psp
->hInstance
= 0x1234;