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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
32 #include "wine/debug.h"
36 #include "wine/wingdi16.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
44 /************************************************************************
48 * Updates dm1 with some fields from dm2
51 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA
*dm1
, PSDRV_DEVMODEA
*dm2
,
54 /* some sanity checks here on dm2 */
56 if(dm2
->dmPublic
.dmFields
& DM_ORIENTATION
) {
57 dm1
->dmPublic
.u1
.s1
.dmOrientation
= dm2
->dmPublic
.u1
.s1
.dmOrientation
;
58 TRACE("Changing orientation to %d (%s)\n",
59 dm1
->dmPublic
.u1
.s1
.dmOrientation
,
60 dm1
->dmPublic
.u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
?
62 (dm1
->dmPublic
.u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
?
63 "Landscape" : "unknown"));
66 /* NB PaperWidth is always < PaperLength */
67 if(dm2
->dmPublic
.dmFields
& DM_PAPERSIZE
) {
70 LIST_FOR_EACH_ENTRY(page
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
71 if(page
->WinPage
== dm2
->dmPublic
.u1
.s1
.dmPaperSize
)
74 if(&page
->entry
!= &pi
->ppd
->PageSizes
) {
75 dm1
->dmPublic
.u1
.s1
.dmPaperSize
= dm2
->dmPublic
.u1
.s1
.dmPaperSize
;
76 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= page
->PaperDimension
->x
*
78 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= page
->PaperDimension
->y
*
80 dm1
->dmPublic
.dmFields
&= ~(DM_PAPERLENGTH
| DM_PAPERWIDTH
);
81 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
82 TRACE("Changing page to %s %d x %d\n", page
->FullName
,
83 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
,
84 dm1
->dmPublic
.u1
.s1
.dmPaperLength
);
86 TRACE("Trying to change to unsupported pagesize %d\n",
87 dm2
->dmPublic
.u1
.s1
.dmPaperSize
);
89 } else if((dm2
->dmPublic
.dmFields
& DM_PAPERLENGTH
) &&
90 (dm2
->dmPublic
.dmFields
& DM_PAPERWIDTH
)) {
91 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= dm2
->dmPublic
.u1
.s1
.dmPaperLength
;
92 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= dm2
->dmPublic
.u1
.s1
.dmPaperWidth
;
93 TRACE("Changing PaperLength|Width to %dx%d\n",
94 dm2
->dmPublic
.u1
.s1
.dmPaperLength
,
95 dm2
->dmPublic
.u1
.s1
.dmPaperWidth
);
96 dm1
->dmPublic
.dmFields
&= ~DM_PAPERSIZE
;
97 dm1
->dmPublic
.dmFields
|= (DM_PAPERLENGTH
| DM_PAPERWIDTH
);
98 } else if(dm2
->dmPublic
.dmFields
& (DM_PAPERLENGTH
| DM_PAPERWIDTH
)) {
99 /* You might think that this would be allowed if dm1 is in custom size
100 mode, but apparently Windows reverts to standard paper mode even in
102 FIXME("Trying to change only paperlength or paperwidth\n");
103 dm1
->dmPublic
.dmFields
&= ~(DM_PAPERLENGTH
| DM_PAPERWIDTH
);
104 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
107 if(dm2
->dmPublic
.dmFields
& DM_SCALE
) {
108 dm1
->dmPublic
.u1
.s1
.dmScale
= dm2
->dmPublic
.u1
.s1
.dmScale
;
109 TRACE("Changing Scale to %d\n", dm2
->dmPublic
.u1
.s1
.dmScale
);
112 if(dm2
->dmPublic
.dmFields
& DM_COPIES
) {
113 dm1
->dmPublic
.u1
.s1
.dmCopies
= dm2
->dmPublic
.u1
.s1
.dmCopies
;
114 TRACE("Changing Copies to %d\n", dm2
->dmPublic
.u1
.s1
.dmCopies
);
117 if(dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
) {
120 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
) {
121 if(slot
->WinBin
== dm2
->dmPublic
.u1
.s1
.dmDefaultSource
)
125 dm1
->dmPublic
.u1
.s1
.dmDefaultSource
= dm2
->dmPublic
.u1
.s1
.dmDefaultSource
;
126 TRACE("Changing bin to '%s'\n", slot
->FullName
);
128 TRACE("Trying to change to unsupported bin %d\n",
129 dm2
->dmPublic
.u1
.s1
.dmDefaultSource
);
133 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
134 dm1
->dmPublic
.u1
.s1
.dmDefaultSource
= dm2
->dmPublic
.u1
.s1
.dmDefaultSource
;
135 if (dm2
->dmPublic
.dmFields
& DM_PRINTQUALITY
)
136 dm1
->dmPublic
.u1
.s1
.dmPrintQuality
= dm2
->dmPublic
.u1
.s1
.dmPrintQuality
;
137 if (dm2
->dmPublic
.dmFields
& DM_COLOR
)
138 dm1
->dmPublic
.dmColor
= dm2
->dmPublic
.dmColor
;
139 if (dm2
->dmPublic
.dmFields
& DM_DUPLEX
&& pi
->ppd
->DefaultDuplex
&& pi
->ppd
->DefaultDuplex
->WinDuplex
!= 0)
140 dm1
->dmPublic
.dmDuplex
= dm2
->dmPublic
.dmDuplex
;
141 if (dm2
->dmPublic
.dmFields
& DM_YRESOLUTION
)
142 dm1
->dmPublic
.dmYResolution
= dm2
->dmPublic
.dmYResolution
;
143 if (dm2
->dmPublic
.dmFields
& DM_TTOPTION
)
144 dm1
->dmPublic
.dmTTOption
= dm2
->dmPublic
.dmTTOption
;
145 if (dm2
->dmPublic
.dmFields
& DM_COLLATE
)
146 dm1
->dmPublic
.dmCollate
= dm2
->dmPublic
.dmCollate
;
147 if (dm2
->dmPublic
.dmFields
& DM_FORMNAME
)
148 lstrcpynA((LPSTR
)dm1
->dmPublic
.dmFormName
, (LPCSTR
)dm2
->dmPublic
.dmFormName
, CCHFORMNAME
);
149 if (dm2
->dmPublic
.dmFields
& DM_BITSPERPEL
)
150 dm1
->dmPublic
.dmBitsPerPel
= dm2
->dmPublic
.dmBitsPerPel
;
151 if (dm2
->dmPublic
.dmFields
& DM_PELSWIDTH
)
152 dm1
->dmPublic
.dmPelsWidth
= dm2
->dmPublic
.dmPelsWidth
;
153 if (dm2
->dmPublic
.dmFields
& DM_PELSHEIGHT
)
154 dm1
->dmPublic
.dmPelsHeight
= dm2
->dmPublic
.dmPelsHeight
;
155 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFLAGS
)
156 dm1
->dmPublic
.u2
.dmDisplayFlags
= dm2
->dmPublic
.u2
.dmDisplayFlags
;
157 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFREQUENCY
)
158 dm1
->dmPublic
.dmDisplayFrequency
= dm2
->dmPublic
.dmDisplayFrequency
;
159 if (dm2
->dmPublic
.dmFields
& DM_POSITION
)
160 dm1
->dmPublic
.u1
.s2
.dmPosition
= dm2
->dmPublic
.u1
.s2
.dmPosition
;
161 if (dm2
->dmPublic
.dmFields
& DM_LOGPIXELS
)
162 dm1
->dmPublic
.dmLogPixels
= dm2
->dmPublic
.dmLogPixels
;
163 if (dm2
->dmPublic
.dmFields
& DM_ICMMETHOD
)
164 dm1
->dmPublic
.dmICMMethod
= dm2
->dmPublic
.dmICMMethod
;
165 if (dm2
->dmPublic
.dmFields
& DM_ICMINTENT
)
166 dm1
->dmPublic
.dmICMIntent
= dm2
->dmPublic
.dmICMIntent
;
167 if (dm2
->dmPublic
.dmFields
& DM_MEDIATYPE
)
168 dm1
->dmPublic
.dmMediaType
= dm2
->dmPublic
.dmMediaType
;
169 if (dm2
->dmPublic
.dmFields
& DM_DITHERTYPE
)
170 dm1
->dmPublic
.dmDitherType
= dm2
->dmPublic
.dmDitherType
;
171 if (dm2
->dmPublic
.dmFields
& DM_PANNINGWIDTH
)
172 dm1
->dmPublic
.dmPanningWidth
= dm2
->dmPublic
.dmPanningWidth
;
173 if (dm2
->dmPublic
.dmFields
& DM_PANNINGHEIGHT
)
174 dm1
->dmPublic
.dmPanningHeight
= dm2
->dmPublic
.dmPanningHeight
;
180 /****************************************************************
183 * Dialog proc for 'Paper' propsheet
185 static INT_PTR CALLBACK
PSDRV_PaperDlgProc(HWND hwnd
, UINT msg
,
186 WPARAM wParam
, LPARAM lParam
)
195 di
= (PSDRV_DLGINFO
*)((PROPSHEETPAGEA
*)lParam
)->lParam
;
196 SetWindowLongPtrW(hwnd
, DWLP_USER
, (LONG_PTR
)di
);
199 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
200 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_INSERTSTRING
, i
,
201 (LPARAM
)ps
->FullName
);
202 if(di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmPaperSize
== ps
->WinPage
)
206 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_SETCURSEL
, Cursel
, 0);
208 CheckRadioButton(hwnd
, IDD_ORIENT_PORTRAIT
, IDD_ORIENT_LANDSCAPE
,
209 di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmOrientation
==
210 DMORIENT_PORTRAIT
? IDD_ORIENT_PORTRAIT
:
211 IDD_ORIENT_LANDSCAPE
);
213 if(!di
->pi
->ppd
->Duplexes
) {
214 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX
), SW_HIDE
);
215 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX_NAME
), SW_HIDE
);
218 for(duplex
= di
->pi
->ppd
->Duplexes
, i
= 0; duplex
; duplex
= duplex
->next
, i
++) {
219 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_INSERTSTRING
, i
,
220 (LPARAM
)(duplex
->FullName
? duplex
->FullName
: duplex
->Name
));
221 if(di
->pi
->Devmode
->dmPublic
.dmDuplex
== duplex
->WinDuplex
)
224 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_SETCURSEL
, Cursel
, 0);
229 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
230 switch(LOWORD(wParam
)) {
232 if(HIWORD(wParam
) == LBN_SELCHANGE
) {
233 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), LB_GETCURSEL
, 0, 0);
235 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
236 if(i
>= Cursel
) break;
239 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel
, ps
->WinPage
);
240 di
->dlgdm
->dmPublic
.u1
.s1
.dmPaperSize
= ps
->WinPage
;
241 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
244 case IDD_ORIENT_PORTRAIT
:
245 case IDD_ORIENT_LANDSCAPE
:
246 TRACE("Setting orientation to %s\n", wParam
== IDD_ORIENT_PORTRAIT
?
247 "portrait" : "landscape");
248 di
->dlgdm
->dmPublic
.u1
.s1
.dmOrientation
= wParam
== IDD_ORIENT_PORTRAIT
?
249 DMORIENT_PORTRAIT
: DMORIENT_LANDSCAPE
;
250 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
253 if(HIWORD(wParam
) == CBN_SELCHANGE
) {
254 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), CB_GETCURSEL
, 0, 0);
255 for(i
= 0, duplex
= di
->pi
->ppd
->Duplexes
; i
< Cursel
; i
++, duplex
= duplex
->next
)
257 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel
, duplex
->WinDuplex
);
258 di
->dlgdm
->dmPublic
.dmDuplex
= duplex
->WinDuplex
;
259 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
267 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
268 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
269 switch(nmhdr
->code
) {
271 *di
->pi
->Devmode
= *di
->dlgdm
;
272 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, PSNRET_NOERROR
);
288 static void (WINAPI
*pInitCommonControls
) (void);
289 static HPROPSHEETPAGE (WINAPI
*pCreatePropertySheetPage
) (LPCPROPSHEETPAGEW
);
290 static int (WINAPI
*pPropertySheet
) (LPCPROPSHEETHEADERW
);
293 /******************************************************************
294 * PSDRV_ExtDeviceMode
296 * Retrieves or modifies device-initialization information for the PostScript
297 * driver, or displays a driver-supplied dialog box for configuring the driver.
300 * lpszDriver -- Driver name
301 * hwnd -- Parent window for the dialog box
302 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
303 * lpszDevice -- Device name
304 * lpszPort -- Port name
305 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
306 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
307 * wMode -- Operation to perform. Can be a combination if > 0.
308 * (0) -- Returns number of bytes required by DEVMODE structure
309 * DM_UPDATE (1) -- Write current settings to environment and initialization file
310 * DM_COPY (2) -- Write current settings to lpdmOutput
311 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
312 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
315 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
316 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
317 * A return value less than zero is returned if a non-dialog operation fails.
321 * Just returns default devmode at the moment. No use of initialization file.
323 INT CDECL
PSDRV_ExtDeviceMode(LPSTR lpszDriver
, HWND hwnd
, LPDEVMODEA lpdmOutput
,
324 LPSTR lpszDevice
, LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
325 LPSTR lpszProfile
, DWORD dwMode
)
327 PRINTERINFO
*pi
= PSDRV_FindPrinterInfo(lpszDevice
);
330 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
331 lpszDriver
, hwnd
, lpdmOutput
, lpszDevice
, lpszPort
, lpdmInput
, debugstr_a(lpszProfile
), dwMode
);
333 /* If dwMode == 0, return size of DEVMODE structure */
335 return pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
;
337 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
338 if((dwMode
& DM_MODIFY
) && lpdmInput
) {
339 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput
->dmFields
);
340 PSDRV_MergeDevmodes(pi
->Devmode
, (PSDRV_DEVMODEA
*)lpdmInput
, pi
);
343 /* If DM_PROMPT is set, present modal dialog box */
344 if(dwMode
& DM_PROMPT
) {
345 HINSTANCE hinstComctl32
;
346 HPROPSHEETPAGE hpsp
[1];
348 PROPSHEETHEADERW psh
;
350 PSDRV_DEVMODEA
*dlgdm
;
351 static const WCHAR PAPERW
[] = {'P','A','P','E','R','\0'};
352 static const WCHAR SetupW
[] = {'S','e','t','u','p','\0'};
354 hinstComctl32
= LoadLibraryA("comctl32.dll");
355 pInitCommonControls
= (void*)GetProcAddress(hinstComctl32
,
356 "InitCommonControls");
357 pCreatePropertySheetPage
= (void*)GetProcAddress(hinstComctl32
,
358 "CreatePropertySheetPageW");
359 pPropertySheet
= (void*)GetProcAddress(hinstComctl32
, "PropertySheetW");
360 memset(&psp
,0,sizeof(psp
));
361 dlgdm
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*dlgdm
) );
362 *dlgdm
= *pi
->Devmode
;
363 di
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*di
) );
366 psp
.dwSize
= sizeof(psp
);
367 psp
.hInstance
= PSDRV_hInstance
;
368 psp
.u
.pszTemplate
= PAPERW
;
369 psp
.u2
.pszIcon
= NULL
;
370 psp
.pfnDlgProc
= PSDRV_PaperDlgProc
;
371 psp
.lParam
= (LPARAM
)di
;
372 hpsp
[0] = pCreatePropertySheetPage(&psp
);
374 memset(&psh
, 0, sizeof(psh
));
375 psh
.dwSize
= sizeof(psh
);
376 psh
.pszCaption
= SetupW
;
378 psh
.hwndParent
= HWND_32(hwnd
);
379 psh
.u3
.phpage
= hpsp
;
381 pPropertySheet(&psh
);
385 /* If DM_UPDATE is set, should write settings to environment and initialization file */
386 if(dwMode
& DM_UPDATE
)
387 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
389 /* If DM_COPY is set, should write settings to lpdmOutput */
390 if((dwMode
& DM_COPY
) || (dwMode
& DM_UPDATE
)) {
392 memcpy(lpdmOutput
, pi
->Devmode
, pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
);
394 FIXME("lpdmOutput is NULL what should we do??\n");
398 /***********************************************************************
399 * PSDRV_DeviceCapabilities
401 * Retrieves the capabilities of a printer device driver.
404 * lpszDriver -- printer driver name
405 * lpszDevice -- printer name
406 * lpszPort -- port name
407 * fwCapability -- device capability
408 * lpszOutput -- output buffer
409 * lpDevMode -- device data buffer
412 * Result depends on the setting of fwCapability. -1 indicates failure.
414 DWORD CDECL
PSDRV_DeviceCapabilities(LPSTR lpszDriver
, LPCSTR lpszDevice
, LPCSTR lpszPort
,
415 WORD fwCapability
, LPSTR lpszOutput
, LPDEVMODEA lpDevMode
)
420 pi
= PSDRV_FindPrinterInfo(lpszDevice
);
422 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver
), debugstr_a(lpszDevice
),
423 debugstr_a(lpszPort
), fwCapability
, lpszOutput
, lpDevMode
);
426 ERR("no printer info for %s %s, return 0!\n",
427 debugstr_a(lpszDriver
), debugstr_a(lpszDevice
));
431 lpdm
= lpDevMode
? lpDevMode
: (DEVMODEA
*)pi
->Devmode
;
433 switch(fwCapability
) {
438 WORD
*wp
= (WORD
*)lpszOutput
;
441 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
443 TRACE("DC_PAPERS: %u\n", ps
->WinPage
);
445 if(lpszOutput
!= NULL
)
454 POINT16
*pt
= (POINT16
*)lpszOutput
;
457 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
459 TRACE("DC_PAPERSIZE: %f x %f\n", ps
->PaperDimension
->x
, ps
->PaperDimension
->y
);
461 if(lpszOutput
!= NULL
) {
462 pt
->x
= ps
->PaperDimension
->x
* 254.0 / 72.0;
463 pt
->y
= ps
->PaperDimension
->y
* 254.0 / 72.0;
473 char *cp
= lpszOutput
;
476 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
478 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps
->FullName
));
480 if(lpszOutput
!= NULL
) {
481 lstrcpynA(cp
, ps
->FullName
, 64);
489 return pi
->ppd
->LandscapeOrientation
? pi
->ppd
->LandscapeOrientation
: 90;
494 WORD
*wp
= (WORD
*)lpszOutput
;
497 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
498 if(lpszOutput
!= NULL
)
499 *wp
++ = slot
->WinBin
;
506 char *cp
= lpszOutput
;
509 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
510 if(lpszOutput
!= NULL
) {
511 lstrcpynA(cp
, slot
->FullName
, 24);
518 FIXME("DC_BINADJUST: stub.\n");
519 return DCBA_FACEUPNONE
;
521 case DC_ENUMRESOLUTIONS
:
523 LONG
*lp
= (LONG
*)lpszOutput
;
525 if(lpszOutput
!= NULL
) {
526 lp
[0] = pi
->ppd
->DefaultResolution
;
527 lp
[1] = pi
->ppd
->DefaultResolution
;
532 /* Windows returns 9999 too */
534 TRACE("DC_COPIES: returning 9999\n");
538 return lpdm
->dmDriverVersion
;
540 case DC_DATATYPE_PRODUCED
:
541 FIXME("DATA_TYPE_PRODUCED: stub.\n");
542 return -1; /* simulate that the driver supports 'RAW' */
546 if(pi
->ppd
->DefaultDuplex
&& pi
->ppd
->DefaultDuplex
->WinDuplex
!= 0)
548 TRACE("DC_DUPLEX: returning %d\n", ret
);
551 case DC_EMF_COMPLIANT
:
552 FIXME("DC_EMF_COMPLIANT: stub.\n");
553 return -1; /* simulate that the driver do not support EMF */
556 return lpdm
->dmDriverExtra
;
559 return lpdm
->dmFields
;
561 case DC_FILEDEPENDENCIES
:
562 FIXME("DC_FILEDEPENDENCIES: stub.\n");
569 ptMax
.x
= ptMax
.y
= 0;
571 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
573 if(ps
->PaperDimension
->x
> ptMax
.x
)
574 ptMax
.x
= ps
->PaperDimension
->x
;
575 if(ps
->PaperDimension
->y
> ptMax
.y
)
576 ptMax
.y
= ps
->PaperDimension
->y
;
578 return MAKELONG(ptMax
.x
* 254.0 / 72.0, ptMax
.y
* 254.0 / 72.0 );
585 ptMin
.x
= ptMin
.y
= -1;
587 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
589 if(ptMin
.x
== -1 || ps
->PaperDimension
->x
< ptMin
.x
)
590 ptMin
.x
= ps
->PaperDimension
->x
;
591 if(ptMin
.y
== -1 || ps
->PaperDimension
->y
< ptMin
.y
)
592 ptMin
.y
= ps
->PaperDimension
->y
;
594 return MAKELONG(ptMin
.x
* 254.0 / 72.0, ptMin
.y
* 254.0 / 72.0);
601 FIXME("DC_TRUETYPE: stub\n");
605 return lpdm
->dmSpecVersion
;
607 /* We'll just return false here, very few printers can collate anyway */
609 TRACE("DC_COLLATE: returning FALSE\n");
612 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
614 return (pi
->ppd
->ColorDevice
!= CD_False
) ? TRUE
: FALSE
;
616 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
617 case DC_MANUFACTURER
:
618 FIXME("DC_MANUFACTURER: stub\n");
621 /* Identification number of the printer model for use with ICM (Win9x only) */
623 FIXME("DC_MODEL: stub\n");
626 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
627 case DC_STAPLE
: /* WINVER >= 0x0500 */
628 FIXME("DC_STAPLE: stub\n");
631 /* Returns an array of 64-character string buffers containing the names of the paper forms
632 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
635 case DC_MEDIAREADY
: /* WINVER >= 0x0500 */
636 FIXME("DC_MEDIAREADY: stub\n");
639 /* Returns an array of 64-character string buffers containing the names of the supported
640 * media types, unless pOutput is NULL. The return value is the number of supported.
641 * media types (XP only)
643 case DC_MEDIATYPENAMES
: /* WINVER >= 0x0501 */
644 FIXME("DC_MEDIATYPENAMES: stub\n");
647 /* Returns an array of DWORD values which represent the supported media types, unless
648 * pOutput is NULL. The return value is the number of supported media types. (XP only)
650 case DC_MEDIATYPES
: /* WINVER >= 0x0501 */
651 FIXME("DC_MEDIATYPES: stub\n");
654 /* Returns an array of DWORD values, each representing a supported number of document
655 * pages per printed page, unless pOutput is NULL. The return value is the number of
656 * array entries. (Win2k/XP only)
659 FIXME("DC_NUP: stub\n");
662 /* Returns an array of 32-character string buffers containing a list of printer description
663 * languages supported by the printer, unless pOutput is NULL. The return value is
664 * number of array entries. (Win2k/XP only)
667 case DC_PERSONALITY
: /* WINVER >= 0x0500 */
668 FIXME("DC_PERSONALITY: stub\n");
671 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
672 case DC_PRINTERMEM
: /* WINVER >= 0x0500 */
673 FIXME("DC_PRINTERMEM: stub\n");
676 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
677 case DC_PRINTRATE
: /* WINVER >= 0x0500 */
678 FIXME("DC_PRINTRATE: stub\n");
681 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
682 case DC_PRINTRATEPPM
: /* WINVER >= 0x0500 */
683 FIXME("DC_PRINTRATEPPM: stub\n");
686 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
687 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
689 case DC_PRINTRATEUNIT
: /* WINVER >= 0x0500 */
690 FIXME("DC_PRINTRATEUNIT: stub\n");
694 FIXME("Unsupported capability %d\n", fwCapability
);
703 HPROPSHEETPAGE hPages
[10];
706 INT
PSDRV_ExtDeviceModePropSheet(HWND hwnd
, LPSTR lpszDevice
, LPSTR lpszPort
,
709 EDMPS
*ps
= pPropSheet
;
712 psp
->dwSize
= sizeof(psp
);
713 psp
->hInstance
= 0x1234;