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"
33 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
36 /************************************************************************
40 * Updates dm1 with some fields from dm2
43 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA
*dm1
, PSDRV_DEVMODEA
*dm2
,
46 /* some sanity checks here on dm2 */
48 if(dm2
->dmPublic
.dmFields
& DM_ORIENTATION
)
49 dm1
->dmPublic
.u1
.s1
.dmOrientation
= dm2
->dmPublic
.u1
.s1
.dmOrientation
;
51 /* NB PaperWidth is always < PaperLength */
53 if(dm2
->dmPublic
.dmFields
& DM_PAPERSIZE
) {
56 for(page
= pi
->ppd
->PageSizes
; page
; page
= page
->next
) {
57 if(page
->WinPage
== dm2
->dmPublic
.u1
.s1
.dmPaperSize
)
61 dm1
->dmPublic
.u1
.s1
.dmPaperSize
= dm2
->dmPublic
.u1
.s1
.dmPaperSize
;
62 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= page
->PaperDimension
->x
*
64 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= page
->PaperDimension
->y
*
66 TRACE("Changing page to %s %d x %d\n", page
->FullName
,
67 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
,
68 dm1
->dmPublic
.u1
.s1
.dmPaperLength
);
70 TRACE("Trying to change to unsupported pagesize %d\n",
71 dm2
->dmPublic
.u1
.s1
.dmPaperSize
);
75 if(dm2
->dmPublic
.dmFields
& DM_PAPERLENGTH
) {
76 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= dm2
->dmPublic
.u1
.s1
.dmPaperLength
;
77 TRACE("Changing PaperLength to %d\n",
78 dm2
->dmPublic
.u1
.s1
.dmPaperLength
);
79 FIXME("Changing PaperLength. Do we adjust PaperSize?\n");
82 if(dm2
->dmPublic
.dmFields
& DM_PAPERWIDTH
) {
83 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= dm2
->dmPublic
.u1
.s1
.dmPaperWidth
;
84 TRACE("Changing PaperWidth to %d\n",
85 dm2
->dmPublic
.u1
.s1
.dmPaperWidth
);
86 FIXME("Changing PaperWidth. Do we adjust PaperSize?\n");
89 if(dm2
->dmPublic
.dmFields
& DM_SCALE
) {
90 dm1
->dmPublic
.dmScale
= dm2
->dmPublic
.dmScale
;
91 TRACE("Changing Scale to %d\n", dm2
->dmPublic
.dmScale
);
94 if(dm2
->dmPublic
.dmFields
& DM_COPIES
) {
95 dm1
->dmPublic
.dmCopies
= dm2
->dmPublic
.dmCopies
;
96 TRACE("Changing Copies to %d\n", dm2
->dmPublic
.dmCopies
);
99 if(dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
) {
102 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
) {
103 if(slot
->WinBin
== dm2
->dmPublic
.dmDefaultSource
)
107 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
108 TRACE("Changing bin to '%s'\n", slot
->FullName
);
110 TRACE("Trying to change to unsupported bin %d\n",
111 dm2
->dmPublic
.dmDefaultSource
);
115 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
116 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
117 if (dm2
->dmPublic
.dmFields
& DM_PRINTQUALITY
)
118 dm1
->dmPublic
.dmPrintQuality
= dm2
->dmPublic
.dmPrintQuality
;
119 if (dm2
->dmPublic
.dmFields
& DM_COLOR
)
120 dm1
->dmPublic
.dmColor
= dm2
->dmPublic
.dmColor
;
121 if (dm2
->dmPublic
.dmFields
& DM_DUPLEX
)
122 dm1
->dmPublic
.dmDuplex
= dm2
->dmPublic
.dmDuplex
;
123 if (dm2
->dmPublic
.dmFields
& DM_YRESOLUTION
)
124 dm1
->dmPublic
.dmYResolution
= dm2
->dmPublic
.dmYResolution
;
125 if (dm2
->dmPublic
.dmFields
& DM_TTOPTION
)
126 dm1
->dmPublic
.dmTTOption
= dm2
->dmPublic
.dmTTOption
;
127 if (dm2
->dmPublic
.dmFields
& DM_COLLATE
)
128 dm1
->dmPublic
.dmCollate
= dm2
->dmPublic
.dmCollate
;
129 if (dm2
->dmPublic
.dmFields
& DM_FORMNAME
)
130 lstrcpynA(dm1
->dmPublic
.dmFormName
, dm2
->dmPublic
.dmFormName
, CCHFORMNAME
);
131 if (dm2
->dmPublic
.dmFields
& DM_BITSPERPEL
)
132 dm1
->dmPublic
.dmBitsPerPel
= dm2
->dmPublic
.dmBitsPerPel
;
133 if (dm2
->dmPublic
.dmFields
& DM_PELSWIDTH
)
134 dm1
->dmPublic
.dmPelsWidth
= dm2
->dmPublic
.dmPelsWidth
;
135 if (dm2
->dmPublic
.dmFields
& DM_PELSHEIGHT
)
136 dm1
->dmPublic
.dmPelsHeight
= dm2
->dmPublic
.dmPelsHeight
;
137 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFLAGS
)
138 dm1
->dmPublic
.dmDisplayFlags
= dm2
->dmPublic
.dmDisplayFlags
;
139 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFREQUENCY
)
140 dm1
->dmPublic
.dmDisplayFrequency
= dm2
->dmPublic
.dmDisplayFrequency
;
141 if (dm2
->dmPublic
.dmFields
& DM_POSITION
)
142 dm1
->dmPublic
.u1
.dmPosition
= dm2
->dmPublic
.u1
.dmPosition
;
143 if (dm2
->dmPublic
.dmFields
& DM_LOGPIXELS
)
144 dm1
->dmPublic
.dmLogPixels
= dm2
->dmPublic
.dmLogPixels
;
145 if (dm2
->dmPublic
.dmFields
& DM_ICMMETHOD
)
146 dm1
->dmPublic
.dmICMMethod
= dm2
->dmPublic
.dmICMMethod
;
147 if (dm2
->dmPublic
.dmFields
& DM_ICMINTENT
)
148 dm1
->dmPublic
.dmICMIntent
= dm2
->dmPublic
.dmICMIntent
;
149 if (dm2
->dmPublic
.dmFields
& DM_MEDIATYPE
)
150 dm1
->dmPublic
.dmMediaType
= dm2
->dmPublic
.dmMediaType
;
151 if (dm2
->dmPublic
.dmFields
& DM_DITHERTYPE
)
152 dm1
->dmPublic
.dmDitherType
= dm2
->dmPublic
.dmDitherType
;
153 if (dm2
->dmPublic
.dmFields
& DM_PANNINGWIDTH
)
154 dm1
->dmPublic
.dmPanningWidth
= dm2
->dmPublic
.dmPanningWidth
;
155 if (dm2
->dmPublic
.dmFields
& DM_PANNINGHEIGHT
)
156 dm1
->dmPublic
.dmPanningHeight
= dm2
->dmPublic
.dmPanningHeight
;
162 /**************************************************************
163 * AdvancedSetupDialog [WINEPS16.93]
166 WORD WINAPI
PSDRV_AdvancedSetupDialog16(HWND16 hwnd
, HANDLE16 hDriver
,
167 LPDEVMODEA devin
, LPDEVMODEA devout
)
170 TRACE("hwnd = %04x, hDriver = %04x devin=%p devout=%p\n", hwnd
,
171 hDriver
, devin
, devout
);
175 /****************************************************************
178 * Dialog proc for 'Paper' propsheet
180 BOOL WINAPI
PSDRV_PaperDlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM
190 di
= (PSDRV_DLGINFO
*)((PROPSHEETPAGEA
*)lParam
)->lParam
;
191 SetWindowLongA(hwnd
, DWL_USER
, (LONG
)di
);
193 for(ps
= di
->pi
->ppd
->PageSizes
, i
= 0; ps
; ps
= ps
->next
, i
++) {
194 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_INSERTSTRING
, i
,
195 (LPARAM
)ps
->FullName
);
196 if(di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmPaperSize
== ps
->WinPage
)
199 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_SETCURSEL
, Cursel
, 0);
201 CheckRadioButton(hwnd
, IDD_ORIENT_PORTRAIT
, IDD_ORIENT_LANDSCAPE
,
202 di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmOrientation
==
203 DMORIENT_PORTRAIT
? IDD_ORIENT_PORTRAIT
:
204 IDD_ORIENT_LANDSCAPE
);
208 di
= (PSDRV_DLGINFO
*)GetWindowLongA(hwnd
, DWL_USER
);
209 switch(LOWORD(wParam
)) {
211 if(HIWORD(wParam
) == LBN_SELCHANGE
) {
212 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), LB_GETCURSEL
, 0, 0);
213 for(i
= 0, ps
= di
->pi
->ppd
->PageSizes
; i
< Cursel
; i
++, ps
= ps
->next
)
215 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel
,
217 di
->dlgdm
->dmPublic
.u1
.s1
.dmPaperSize
= ps
->WinPage
;
220 case IDD_ORIENT_PORTRAIT
:
221 case IDD_ORIENT_LANDSCAPE
:
222 TRACE("Setting orientation to %s\n", wParam
== IDD_ORIENT_PORTRAIT
?
223 "portrait" : "landscape");
224 di
->dlgdm
->dmPublic
.u1
.s1
.dmOrientation
= wParam
== IDD_ORIENT_PORTRAIT
?
225 DMORIENT_PORTRAIT
: DMORIENT_LANDSCAPE
;
232 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
233 di
= (PSDRV_DLGINFO
*)GetWindowLongA(hwnd
, DWL_USER
);
234 switch(nmhdr
->code
) {
236 memcpy(di
->pi
->Devmode
, di
->dlgdm
, sizeof(PSDRV_DEVMODEA
));
237 SetWindowLongA(hwnd
, DWL_MSGRESULT
, PSNRET_NOERROR
);
255 static void (WINAPI
*pInitCommonControls
) (void);
256 static HPROPSHEETPAGE (WINAPI
*pCreatePropertySheetPage
) (LPCPROPSHEETPAGEA
);
257 static int (WINAPI
*pPropertySheet
) (LPCPROPSHEETHEADERA
);
259 /***************************************************************
260 * ExtDeviceMode [WINEPS16.90]
262 * Just returns default devmode at the moment
264 INT16 WINAPI
PSDRV_ExtDeviceMode16(HWND16 hwnd
, HANDLE16 hDriver
,
265 LPDEVMODEA lpdmOutput
, LPSTR lpszDevice
,
266 LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
267 LPSTR lpszProfile
, WORD fwMode
)
269 PRINTERINFO
*pi
= PSDRV_FindPrinterInfo(lpszDevice
);
272 TRACE("(hwnd=%04x, hDriver=%04x, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
273 hwnd
, hDriver
, lpdmOutput
, lpszDevice
, lpszPort
, lpdmInput
, lpszProfile
,
277 return sizeof(DEVMODEA
); /* Just copy dmPublic bit of PSDRV_DEVMODE */
279 if((fwMode
& DM_MODIFY
) && lpdmInput
) {
280 TRACE("DM_MODIFY set. devIn->dmFields = %08lx\n", lpdmInput
->dmFields
);
281 PSDRV_MergeDevmodes(pi
->Devmode
, (PSDRV_DEVMODEA
*)lpdmInput
, pi
);
284 if(fwMode
& DM_PROMPT
) {
285 HINSTANCE hinstComctl32
, hinstWineps32
= LoadLibraryA("WINEPS");
286 HPROPSHEETPAGE hpsp
[1];
288 PROPSHEETHEADERA psh
;
290 PSDRV_DEVMODEA
*dlgdm
;
292 hinstComctl32
= LoadLibraryA("comctl32.dll");
293 pInitCommonControls
= (void*)GetProcAddress(hinstComctl32
,
294 "InitCommonControls");
295 pCreatePropertySheetPage
= (void*)GetProcAddress(hinstComctl32
,
296 "CreatePropertySheetPage");
297 pPropertySheet
= (void*)GetProcAddress(hinstComctl32
, "PropertySheet");
298 memset(&psp
,0,sizeof(psp
));
299 dlgdm
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*dlgdm
) );
300 memcpy(dlgdm
, pi
->Devmode
, sizeof(*dlgdm
));
301 di
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*di
) );
304 psp
.dwSize
= sizeof(psp
);
305 psp
.hInstance
= hinstWineps32
;
306 psp
.u
.pszTemplate
= "PAPER";
307 psp
.u2
.pszIcon
= NULL
;
308 psp
.pfnDlgProc
= PSDRV_PaperDlgProc
;
309 psp
.lParam
= (LPARAM
)di
;
310 hpsp
[0] = pCreatePropertySheetPage(&psp
);
312 memset(&psh
, 0, sizeof(psh
));
313 psh
.dwSize
= sizeof(psh
);
314 psh
.pszCaption
= "Setup";
316 psh
.hwndParent
= hwnd
;
317 psh
.u3
.phpage
= hpsp
;
319 pPropertySheet(&psh
);
322 if(fwMode
& DM_UPDATE
)
323 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
325 if((fwMode
& DM_COPY
) || (fwMode
& DM_UPDATE
)) {
326 memcpy(lpdmOutput
, pi
->Devmode
, sizeof(DEVMODEA
));
331 /**************************************************************
333 * PSDRV_ExtDeviceMode
335 INT
PSDRV_ExtDeviceMode(LPSTR lpszDriver
, HWND hwnd
, LPDEVMODEA lpdmOutput
,
336 LPSTR lpszDevice
, LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
337 LPSTR lpszProfile
, DWORD dwMode
)
339 return PSDRV_ExtDeviceMode16(hwnd
, 0, lpdmOutput
, lpszDevice
, lpszPort
,
340 lpdmInput
, lpszProfile
, dwMode
);
343 /***********************************************************************
344 * DeviceCapabilities [WINEPS16.91]
347 DWORD WINAPI
PSDRV_DeviceCapabilities16(LPCSTR lpszDevice
, LPCSTR lpszPort
,
348 WORD fwCapability
, LPSTR lpszOutput
,
349 LPDEVMODEA lpDevMode
)
353 pi
= PSDRV_FindPrinterInfo(lpszDevice
);
355 TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability
, pi
);
359 ERR("no printerinfo for %s, return 0!\n",lpszDevice
);
364 lpdm
= lpDevMode
? lpDevMode
: (DEVMODEA
*)pi
->Devmode
;
366 switch(fwCapability
) {
371 WORD
*wp
= (WORD
*)lpszOutput
;
374 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++)
375 if(lpszOutput
!= NULL
)
383 POINT16
*pt
= (POINT16
*)lpszOutput
;
386 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++)
387 if(lpszOutput
!= NULL
) {
388 pt
->x
= ps
->PaperDimension
->x
* 254.0 / 72.0;
389 pt
->y
= ps
->PaperDimension
->y
* 254.0 / 72.0;
398 char *cp
= lpszOutput
;
401 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++)
402 if(lpszOutput
!= NULL
) {
403 lstrcpynA(cp
, ps
->FullName
, 64);
410 return pi
->ppd
->LandscapeOrientation
? pi
->ppd
->LandscapeOrientation
: 90;
415 WORD
*wp
= (WORD
*)lpszOutput
;
418 /* We explicitly list DMBIN_AUTO first; actually while win9x does this
419 win2000 lists DMBIN_FORMSOURCE instead. */
421 if(lpszOutput
!= NULL
)
424 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
425 if(lpszOutput
!= NULL
)
426 *wp
++ = slot
->WinBin
;
433 char *cp
= lpszOutput
;
436 /* Add an entry corresponding to DMBIN_AUTO, see DC_BINS */
438 if(lpszOutput
!= NULL
) {
439 strcpy(cp
, "Automatically Select");
443 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
444 if(lpszOutput
!= NULL
) {
445 lstrcpynA(cp
, slot
->FullName
, 24);
452 FIXME("DC_BINADJUST: stub.\n");
453 return DCBA_FACEUPNONE
;
455 case DC_ENUMRESOLUTIONS
:
457 LONG
*lp
= (LONG
*)lpszOutput
;
459 if(lpszOutput
!= NULL
) {
460 lp
[0] = (LONG
)pi
->ppd
->DefaultResolution
;
461 lp
[1] = (LONG
)pi
->ppd
->DefaultResolution
;
467 FIXME("DC_COPIES: returning %d. Is this correct?\n", lpdm
->dmCopies
);
468 return lpdm
->dmCopies
;
471 return lpdm
->dmDriverVersion
;
473 case DC_DATATYPE_PRODUCED
:
474 FIXME("DATA_TYPE_PRODUCED: stub.\n");
475 return -1; /* simulate that the driver supports 'RAW' */
478 FIXME("DC_DUPLEX: returning %d. Is this correct?\n", lpdm
->dmDuplex
);
479 return lpdm
->dmDuplex
;
481 case DC_EMF_COMPLIANT
:
482 FIXME("DC_EMF_COMPLIANT: stub.\n");
483 return -1; /* simulate that the driver do not support EMF */
486 return lpdm
->dmDriverExtra
;
489 return lpdm
->dmFields
;
491 case DC_FILEDEPENDENCIES
:
492 FIXME("DC_FILEDEPENDENCIES: stub.\n");
500 ptMax
.x
= ptMax
.y
= 0;
502 if(lpszOutput
== NULL
)
506 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++) {
507 if(ps
->PaperDimension
->x
> ptMax
.x
)
508 ptMax
.x
= ps
->PaperDimension
->x
;
509 if(ps
->PaperDimension
->y
> ptMax
.y
)
510 ptMax
.y
= ps
->PaperDimension
->y
;
512 *((POINT
*)lpszOutput
) = ptMax
;
521 ptMax
.x
= ptMax
.y
= 0;
523 if(lpszOutput
== NULL
)
527 for(ps
= pi
->ppd
->PageSizes
; ps
; ps
= ps
->next
, i
++) {
528 if(ps
->PaperDimension
->x
> ptMax
.x
)
529 ptMax
.x
= ps
->PaperDimension
->x
;
530 if(ps
->PaperDimension
->y
> ptMax
.y
)
531 ptMax
.y
= ps
->PaperDimension
->y
;
533 *((POINT
*)lpszOutput
) = ptMax
;
541 FIXME("DC_TRUETYPE: stub\n");
545 return lpdm
->dmSpecVersion
;
548 FIXME("Unsupported capability %d\n", fwCapability
);
553 /**************************************************************
555 * PSDRV_DeviceCapabilities
557 DWORD
PSDRV_DeviceCapabilities(LPSTR lpszDriver
, LPCSTR lpszDevice
,
558 LPCSTR lpszPort
, WORD fwCapability
,
559 LPSTR lpszOutput
, LPDEVMODEA lpdm
)
561 return PSDRV_DeviceCapabilities16(lpszDevice
, lpszPort
, fwCapability
,
565 /***************************************************************
566 * DeviceMode [WINEPS16.13]
569 void WINAPI
PSDRV_DeviceMode16(HWND16 hwnd
, HANDLE16 hDriver
,
570 LPSTR lpszDevice
, LPSTR lpszPort
)
572 PSDRV_ExtDeviceMode16( hwnd
, hDriver
, NULL
, lpszDevice
, lpszPort
, NULL
,
581 HPROPSHEETPAGE hPages
[10];
584 INT
PSDRV_ExtDeviceModePropSheet(HWND hwnd
, LPSTR lpszDevice
, LPSTR lpszPort
,
587 EDMPS
*ps
= pPropSheet
;
590 psp
->dwSize
= sizeof(psp
);
591 psp
->hInstance
= 0x1234;