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"
40 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
42 /* convert points to paper size units (10th of a millimeter) */
43 static inline int paper_size_from_points( float size
)
45 return size
* 254 / 72;
48 /************************************************************************
52 * Updates dm1 with some fields from dm2
55 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA
*dm1
, PSDRV_DEVMODEA
*dm2
,
58 /* some sanity checks here on dm2 */
60 if(dm2
->dmPublic
.dmFields
& DM_ORIENTATION
) {
61 dm1
->dmPublic
.u1
.s1
.dmOrientation
= dm2
->dmPublic
.u1
.s1
.dmOrientation
;
62 TRACE("Changing orientation to %d (%s)\n",
63 dm1
->dmPublic
.u1
.s1
.dmOrientation
,
64 dm1
->dmPublic
.u1
.s1
.dmOrientation
== DMORIENT_PORTRAIT
?
66 (dm1
->dmPublic
.u1
.s1
.dmOrientation
== DMORIENT_LANDSCAPE
?
67 "Landscape" : "unknown"));
70 /* NB PaperWidth is always < PaperLength */
71 if(dm2
->dmPublic
.dmFields
& DM_PAPERSIZE
) {
74 LIST_FOR_EACH_ENTRY(page
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
75 if(page
->WinPage
== dm2
->dmPublic
.u1
.s1
.dmPaperSize
)
78 if(&page
->entry
!= &pi
->ppd
->PageSizes
) {
79 dm1
->dmPublic
.u1
.s1
.dmPaperSize
= dm2
->dmPublic
.u1
.s1
.dmPaperSize
;
80 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= paper_size_from_points( page
->PaperDimension
->x
);
81 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= paper_size_from_points( page
->PaperDimension
->y
);
82 dm1
->dmPublic
.dmFields
&= ~(DM_PAPERLENGTH
| DM_PAPERWIDTH
);
83 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
84 TRACE("Changing page to %s %d x %d\n", page
->FullName
,
85 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
,
86 dm1
->dmPublic
.u1
.s1
.dmPaperLength
);
88 TRACE("Trying to change to unsupported pagesize %d\n",
89 dm2
->dmPublic
.u1
.s1
.dmPaperSize
);
91 } else if((dm2
->dmPublic
.dmFields
& DM_PAPERLENGTH
) &&
92 (dm2
->dmPublic
.dmFields
& DM_PAPERWIDTH
)) {
93 dm1
->dmPublic
.u1
.s1
.dmPaperLength
= dm2
->dmPublic
.u1
.s1
.dmPaperLength
;
94 dm1
->dmPublic
.u1
.s1
.dmPaperWidth
= dm2
->dmPublic
.u1
.s1
.dmPaperWidth
;
95 TRACE("Changing PaperLength|Width to %dx%d\n",
96 dm2
->dmPublic
.u1
.s1
.dmPaperLength
,
97 dm2
->dmPublic
.u1
.s1
.dmPaperWidth
);
98 dm1
->dmPublic
.dmFields
&= ~DM_PAPERSIZE
;
99 dm1
->dmPublic
.dmFields
|= (DM_PAPERLENGTH
| DM_PAPERWIDTH
);
100 } else if(dm2
->dmPublic
.dmFields
& (DM_PAPERLENGTH
| DM_PAPERWIDTH
)) {
101 /* You might think that this would be allowed if dm1 is in custom size
102 mode, but apparently Windows reverts to standard paper mode even in
104 FIXME("Trying to change only paperlength or paperwidth\n");
105 dm1
->dmPublic
.dmFields
&= ~(DM_PAPERLENGTH
| DM_PAPERWIDTH
);
106 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
109 if(dm2
->dmPublic
.dmFields
& DM_SCALE
) {
110 dm1
->dmPublic
.u1
.s1
.dmScale
= dm2
->dmPublic
.u1
.s1
.dmScale
;
111 TRACE("Changing Scale to %d\n", dm2
->dmPublic
.u1
.s1
.dmScale
);
114 if(dm2
->dmPublic
.dmFields
& DM_COPIES
) {
115 dm1
->dmPublic
.u1
.s1
.dmCopies
= dm2
->dmPublic
.u1
.s1
.dmCopies
;
116 TRACE("Changing Copies to %d\n", dm2
->dmPublic
.u1
.s1
.dmCopies
);
119 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
123 LIST_FOR_EACH_ENTRY( slot
, &pi
->ppd
->InputSlots
, INPUTSLOT
, entry
)
124 if(slot
->WinBin
== dm2
->dmPublic
.u1
.s1
.dmDefaultSource
)
127 if (&slot
->entry
!= &pi
->ppd
->InputSlots
)
129 dm1
->dmPublic
.u1
.s1
.dmDefaultSource
= dm2
->dmPublic
.u1
.s1
.dmDefaultSource
;
130 TRACE("Changing bin to '%s'\n", slot
->FullName
);
133 TRACE("Trying to change to unsupported bin %d\n", dm2
->dmPublic
.u1
.s1
.dmDefaultSource
);
136 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
137 dm1
->dmPublic
.u1
.s1
.dmDefaultSource
= dm2
->dmPublic
.u1
.s1
.dmDefaultSource
;
138 if (dm2
->dmPublic
.dmFields
& DM_PRINTQUALITY
)
139 dm1
->dmPublic
.u1
.s1
.dmPrintQuality
= dm2
->dmPublic
.u1
.s1
.dmPrintQuality
;
140 if (dm2
->dmPublic
.dmFields
& DM_COLOR
)
141 dm1
->dmPublic
.dmColor
= dm2
->dmPublic
.dmColor
;
142 if (dm2
->dmPublic
.dmFields
& DM_DUPLEX
&& pi
->ppd
->DefaultDuplex
&& pi
->ppd
->DefaultDuplex
->WinDuplex
!= 0)
143 dm1
->dmPublic
.dmDuplex
= dm2
->dmPublic
.dmDuplex
;
144 if (dm2
->dmPublic
.dmFields
& DM_YRESOLUTION
)
145 dm1
->dmPublic
.dmYResolution
= dm2
->dmPublic
.dmYResolution
;
146 if (dm2
->dmPublic
.dmFields
& DM_TTOPTION
)
147 dm1
->dmPublic
.dmTTOption
= dm2
->dmPublic
.dmTTOption
;
148 if (dm2
->dmPublic
.dmFields
& DM_COLLATE
)
149 dm1
->dmPublic
.dmCollate
= dm2
->dmPublic
.dmCollate
;
150 if (dm2
->dmPublic
.dmFields
& DM_FORMNAME
)
151 lstrcpynA((LPSTR
)dm1
->dmPublic
.dmFormName
, (LPCSTR
)dm2
->dmPublic
.dmFormName
, CCHFORMNAME
);
152 if (dm2
->dmPublic
.dmFields
& DM_BITSPERPEL
)
153 dm1
->dmPublic
.dmBitsPerPel
= dm2
->dmPublic
.dmBitsPerPel
;
154 if (dm2
->dmPublic
.dmFields
& DM_PELSWIDTH
)
155 dm1
->dmPublic
.dmPelsWidth
= dm2
->dmPublic
.dmPelsWidth
;
156 if (dm2
->dmPublic
.dmFields
& DM_PELSHEIGHT
)
157 dm1
->dmPublic
.dmPelsHeight
= dm2
->dmPublic
.dmPelsHeight
;
158 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFLAGS
)
159 dm1
->dmPublic
.u2
.dmDisplayFlags
= dm2
->dmPublic
.u2
.dmDisplayFlags
;
160 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFREQUENCY
)
161 dm1
->dmPublic
.dmDisplayFrequency
= dm2
->dmPublic
.dmDisplayFrequency
;
162 if (dm2
->dmPublic
.dmFields
& DM_POSITION
)
163 dm1
->dmPublic
.u1
.s2
.dmPosition
= dm2
->dmPublic
.u1
.s2
.dmPosition
;
164 if (dm2
->dmPublic
.dmFields
& DM_LOGPIXELS
)
165 dm1
->dmPublic
.dmLogPixels
= dm2
->dmPublic
.dmLogPixels
;
166 if (dm2
->dmPublic
.dmFields
& DM_ICMMETHOD
)
167 dm1
->dmPublic
.dmICMMethod
= dm2
->dmPublic
.dmICMMethod
;
168 if (dm2
->dmPublic
.dmFields
& DM_ICMINTENT
)
169 dm1
->dmPublic
.dmICMIntent
= dm2
->dmPublic
.dmICMIntent
;
170 if (dm2
->dmPublic
.dmFields
& DM_MEDIATYPE
)
171 dm1
->dmPublic
.dmMediaType
= dm2
->dmPublic
.dmMediaType
;
172 if (dm2
->dmPublic
.dmFields
& DM_DITHERTYPE
)
173 dm1
->dmPublic
.dmDitherType
= dm2
->dmPublic
.dmDitherType
;
174 if (dm2
->dmPublic
.dmFields
& DM_PANNINGWIDTH
)
175 dm1
->dmPublic
.dmPanningWidth
= dm2
->dmPublic
.dmPanningWidth
;
176 if (dm2
->dmPublic
.dmFields
& DM_PANNINGHEIGHT
)
177 dm1
->dmPublic
.dmPanningHeight
= dm2
->dmPublic
.dmPanningHeight
;
186 PSDRV_DEVMODEA
*dlgdm
;
189 /****************************************************************
192 * Dialog proc for 'Paper' propsheet
194 static INT_PTR CALLBACK
PSDRV_PaperDlgProc(HWND hwnd
, UINT msg
,
195 WPARAM wParam
, LPARAM lParam
)
204 di
= (PSDRV_DLGINFO
*)((PROPSHEETPAGEA
*)lParam
)->lParam
;
205 SetWindowLongPtrW(hwnd
, DWLP_USER
, (LONG_PTR
)di
);
208 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
209 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_INSERTSTRING
, i
,
210 (LPARAM
)ps
->FullName
);
211 if(di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmPaperSize
== ps
->WinPage
)
215 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_SETCURSEL
, Cursel
, 0);
217 CheckRadioButton(hwnd
, IDD_ORIENT_PORTRAIT
, IDD_ORIENT_LANDSCAPE
,
218 di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmOrientation
==
219 DMORIENT_PORTRAIT
? IDD_ORIENT_PORTRAIT
:
220 IDD_ORIENT_LANDSCAPE
);
222 if(!di
->pi
->ppd
->Duplexes
) {
223 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX
), SW_HIDE
);
224 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX_NAME
), SW_HIDE
);
227 for(duplex
= di
->pi
->ppd
->Duplexes
, i
= 0; duplex
; duplex
= duplex
->next
, i
++) {
228 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_INSERTSTRING
, i
,
229 (LPARAM
)(duplex
->FullName
? duplex
->FullName
: duplex
->Name
));
230 if(di
->pi
->Devmode
->dmPublic
.dmDuplex
== duplex
->WinDuplex
)
233 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_SETCURSEL
, Cursel
, 0);
238 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
239 switch(LOWORD(wParam
)) {
241 if(HIWORD(wParam
) == LBN_SELCHANGE
) {
242 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), LB_GETCURSEL
, 0, 0);
244 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
245 if(i
>= Cursel
) break;
248 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel
, ps
->WinPage
);
249 di
->dlgdm
->dmPublic
.u1
.s1
.dmPaperSize
= ps
->WinPage
;
250 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
253 case IDD_ORIENT_PORTRAIT
:
254 case IDD_ORIENT_LANDSCAPE
:
255 TRACE("Setting orientation to %s\n", wParam
== IDD_ORIENT_PORTRAIT
?
256 "portrait" : "landscape");
257 di
->dlgdm
->dmPublic
.u1
.s1
.dmOrientation
= wParam
== IDD_ORIENT_PORTRAIT
?
258 DMORIENT_PORTRAIT
: DMORIENT_LANDSCAPE
;
259 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
262 if(HIWORD(wParam
) == CBN_SELCHANGE
) {
263 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), CB_GETCURSEL
, 0, 0);
264 for(i
= 0, duplex
= di
->pi
->ppd
->Duplexes
; i
< Cursel
; i
++, duplex
= duplex
->next
)
266 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel
, duplex
->WinDuplex
);
267 di
->dlgdm
->dmPublic
.dmDuplex
= duplex
->WinDuplex
;
268 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
276 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
277 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
278 switch(nmhdr
->code
) {
280 *di
->pi
->Devmode
= *di
->dlgdm
;
281 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, PSNRET_NOERROR
);
297 static void (WINAPI
*pInitCommonControls
) (void);
298 static HPROPSHEETPAGE (WINAPI
*pCreatePropertySheetPage
) (LPCPROPSHEETPAGEW
);
299 static int (WINAPI
*pPropertySheet
) (LPCPROPSHEETHEADERW
);
301 static PRINTERINFO
*PSDRV_FindPrinterInfoA(LPCSTR name
)
303 int len
= MultiByteToWideChar( CP_ACP
, 0, name
, -1, NULL
, 0 );
304 WCHAR
*nameW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
307 MultiByteToWideChar( CP_ACP
, 0, name
, -1, nameW
, len
);
308 pi
= PSDRV_FindPrinterInfo( nameW
);
309 HeapFree( GetProcessHeap(), 0, nameW
);
314 /******************************************************************
315 * PSDRV_ExtDeviceMode
317 * Retrieves or modifies device-initialization information for the PostScript
318 * driver, or displays a driver-supplied dialog box for configuring the driver.
321 * lpszDriver -- Driver name
322 * hwnd -- Parent window for the dialog box
323 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
324 * lpszDevice -- Device name
325 * lpszPort -- Port name
326 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
327 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
328 * wMode -- Operation to perform. Can be a combination if > 0.
329 * (0) -- Returns number of bytes required by DEVMODE structure
330 * DM_UPDATE (1) -- Write current settings to environment and initialization file
331 * DM_COPY (2) -- Write current settings to lpdmOutput
332 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
333 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
336 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
337 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
338 * A return value less than zero is returned if a non-dialog operation fails.
342 * Just returns default devmode at the moment. No use of initialization file.
344 INT
PSDRV_ExtDeviceMode(LPSTR lpszDriver
, HWND hwnd
, LPDEVMODEA lpdmOutput
,
345 LPSTR lpszDevice
, LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
346 LPSTR lpszProfile
, DWORD dwMode
)
348 PRINTERINFO
*pi
= PSDRV_FindPrinterInfoA(lpszDevice
);
351 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
352 lpszDriver
, hwnd
, lpdmOutput
, lpszDevice
, lpszPort
, lpdmInput
, debugstr_a(lpszProfile
), dwMode
);
354 /* If dwMode == 0, return size of DEVMODE structure */
356 return pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
;
358 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
359 if((dwMode
& DM_MODIFY
) && lpdmInput
) {
360 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput
->dmFields
);
361 PSDRV_MergeDevmodes(pi
->Devmode
, (PSDRV_DEVMODEA
*)lpdmInput
, pi
);
364 /* If DM_PROMPT is set, present modal dialog box */
365 if(dwMode
& DM_PROMPT
) {
366 HINSTANCE hinstComctl32
;
367 HPROPSHEETPAGE hpsp
[1];
369 PROPSHEETHEADERW psh
;
371 PSDRV_DEVMODEA dlgdm
;
372 static const WCHAR PAPERW
[] = {'P','A','P','E','R','\0'};
373 static const WCHAR SetupW
[] = {'S','e','t','u','p','\0'};
375 hinstComctl32
= LoadLibraryA("comctl32.dll");
376 pInitCommonControls
= (void*)GetProcAddress(hinstComctl32
,
377 "InitCommonControls");
378 pCreatePropertySheetPage
= (void*)GetProcAddress(hinstComctl32
,
379 "CreatePropertySheetPageW");
380 pPropertySheet
= (void*)GetProcAddress(hinstComctl32
, "PropertySheetW");
381 memset(&psp
,0,sizeof(psp
));
382 dlgdm
= *pi
->Devmode
;
385 psp
.dwSize
= sizeof(psp
);
386 psp
.hInstance
= PSDRV_hInstance
;
387 psp
.u
.pszTemplate
= PAPERW
;
388 psp
.u2
.pszIcon
= NULL
;
389 psp
.pfnDlgProc
= PSDRV_PaperDlgProc
;
390 psp
.lParam
= (LPARAM
)&di
;
391 hpsp
[0] = pCreatePropertySheetPage(&psp
);
393 memset(&psh
, 0, sizeof(psh
));
394 psh
.dwSize
= sizeof(psh
);
395 psh
.pszCaption
= SetupW
;
397 psh
.hwndParent
= hwnd
;
398 psh
.u3
.phpage
= hpsp
;
400 pPropertySheet(&psh
);
404 /* If DM_UPDATE is set, should write settings to environment and initialization file */
405 if(dwMode
& DM_UPDATE
)
406 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
408 /* If DM_COPY is set, should write settings to lpdmOutput */
409 if((dwMode
& DM_COPY
) || (dwMode
& DM_UPDATE
)) {
411 memcpy(lpdmOutput
, pi
->Devmode
, pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
);
413 FIXME("lpdmOutput is NULL what should we do??\n");
417 /***********************************************************************
418 * PSDRV_DeviceCapabilities
420 * Retrieves the capabilities of a printer device driver.
423 * lpszDriver -- printer driver name
424 * lpszDevice -- printer name
425 * lpszPort -- port name
426 * fwCapability -- device capability
427 * lpszOutput -- output buffer
428 * lpDevMode -- device data buffer
431 * Result depends on the setting of fwCapability. -1 indicates failure.
433 DWORD
PSDRV_DeviceCapabilities(LPSTR lpszDriver
, LPCSTR lpszDevice
, LPCSTR lpszPort
,
434 WORD fwCapability
, LPSTR lpszOutput
, LPDEVMODEA lpDevMode
)
439 pi
= PSDRV_FindPrinterInfoA(lpszDevice
);
441 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver
), debugstr_a(lpszDevice
),
442 debugstr_a(lpszPort
), fwCapability
, lpszOutput
, lpDevMode
);
445 ERR("no printer info for %s %s, return 0!\n",
446 debugstr_a(lpszDriver
), debugstr_a(lpszDevice
));
450 lpdm
= lpDevMode
? lpDevMode
: (DEVMODEA
*)pi
->Devmode
;
452 switch(fwCapability
) {
457 WORD
*wp
= (WORD
*)lpszOutput
;
460 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
462 TRACE("DC_PAPERS: %u\n", ps
->WinPage
);
464 if(lpszOutput
!= NULL
)
473 POINT16
*pt
= (POINT16
*)lpszOutput
;
476 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
478 TRACE("DC_PAPERSIZE: %f x %f\n", ps
->PaperDimension
->x
, ps
->PaperDimension
->y
);
480 if(lpszOutput
!= NULL
) {
481 pt
->x
= paper_size_from_points( ps
->PaperDimension
->x
);
482 pt
->y
= paper_size_from_points( ps
->PaperDimension
->y
);
492 char *cp
= lpszOutput
;
495 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
497 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps
->FullName
));
499 if(lpszOutput
!= NULL
) {
500 lstrcpynA(cp
, ps
->FullName
, 64);
508 return pi
->ppd
->LandscapeOrientation
? pi
->ppd
->LandscapeOrientation
: 90;
513 WORD
*wp
= (WORD
*)lpszOutput
;
516 LIST_FOR_EACH_ENTRY( slot
, &pi
->ppd
->InputSlots
, INPUTSLOT
, entry
)
519 if (lpszOutput
!= NULL
)
520 *wp
++ = slot
->WinBin
;
528 char *cp
= lpszOutput
;
531 LIST_FOR_EACH_ENTRY( slot
, &pi
->ppd
->InputSlots
, INPUTSLOT
, entry
)
534 if (lpszOutput
!= NULL
)
536 lstrcpynA( cp
, slot
->FullName
, 24 );
544 FIXME("DC_BINADJUST: stub.\n");
545 return DCBA_FACEUPNONE
;
547 case DC_ENUMRESOLUTIONS
:
549 LONG
*lp
= (LONG
*)lpszOutput
;
551 if(lpszOutput
!= NULL
) {
552 lp
[0] = pi
->ppd
->DefaultResolution
;
553 lp
[1] = pi
->ppd
->DefaultResolution
;
558 /* Windows returns 9999 too */
560 TRACE("DC_COPIES: returning 9999\n");
564 return lpdm
->dmDriverVersion
;
566 case DC_DATATYPE_PRODUCED
:
567 FIXME("DATA_TYPE_PRODUCED: stub.\n");
568 return -1; /* simulate that the driver supports 'RAW' */
572 if(pi
->ppd
->DefaultDuplex
&& pi
->ppd
->DefaultDuplex
->WinDuplex
!= 0)
574 TRACE("DC_DUPLEX: returning %d\n", ret
);
577 case DC_EMF_COMPLIANT
:
578 FIXME("DC_EMF_COMPLIANT: stub.\n");
579 return -1; /* simulate that the driver do not support EMF */
582 return lpdm
->dmDriverExtra
;
585 return lpdm
->dmFields
;
587 case DC_FILEDEPENDENCIES
:
588 FIXME("DC_FILEDEPENDENCIES: stub.\n");
596 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
598 if (ps
->PaperDimension
->x
> x
) x
= ps
->PaperDimension
->x
;
599 if (ps
->PaperDimension
->y
> y
) y
= ps
->PaperDimension
->y
;
601 return MAKELONG( paper_size_from_points(x
), paper_size_from_points(y
) );
607 float x
= 1e6
, y
= 1e6
;
609 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
611 if (ps
->PaperDimension
->x
< x
) x
= ps
->PaperDimension
->x
;
612 if (ps
->PaperDimension
->y
< y
) y
= ps
->PaperDimension
->y
;
614 return MAKELONG( paper_size_from_points(x
), paper_size_from_points(y
) );
621 FIXME("DC_TRUETYPE: stub\n");
625 return lpdm
->dmSpecVersion
;
627 /* We'll just return false here, very few printers can collate anyway */
629 TRACE("DC_COLLATE: returning FALSE\n");
632 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
634 return (pi
->ppd
->ColorDevice
!= CD_False
) ? TRUE
: FALSE
;
636 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
637 case DC_MANUFACTURER
:
638 FIXME("DC_MANUFACTURER: stub\n");
641 /* Identification number of the printer model for use with ICM (Win9x only) */
643 FIXME("DC_MODEL: stub\n");
646 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
647 case DC_STAPLE
: /* WINVER >= 0x0500 */
648 FIXME("DC_STAPLE: stub\n");
651 /* Returns an array of 64-character string buffers containing the names of the paper forms
652 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
655 case DC_MEDIAREADY
: /* WINVER >= 0x0500 */
656 FIXME("DC_MEDIAREADY: stub\n");
659 /* Returns an array of 64-character string buffers containing the names of the supported
660 * media types, unless pOutput is NULL. The return value is the number of supported.
661 * media types (XP only)
663 case DC_MEDIATYPENAMES
: /* WINVER >= 0x0501 */
664 FIXME("DC_MEDIATYPENAMES: stub\n");
667 /* Returns an array of DWORD values which represent the supported media types, unless
668 * pOutput is NULL. The return value is the number of supported media types. (XP only)
670 case DC_MEDIATYPES
: /* WINVER >= 0x0501 */
671 FIXME("DC_MEDIATYPES: stub\n");
674 /* Returns an array of DWORD values, each representing a supported number of document
675 * pages per printed page, unless pOutput is NULL. The return value is the number of
676 * array entries. (Win2k/XP only)
679 FIXME("DC_NUP: stub\n");
682 /* Returns an array of 32-character string buffers containing a list of printer description
683 * languages supported by the printer, unless pOutput is NULL. The return value is
684 * number of array entries. (Win2k/XP only)
687 case DC_PERSONALITY
: /* WINVER >= 0x0500 */
688 FIXME("DC_PERSONALITY: stub\n");
691 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
692 case DC_PRINTERMEM
: /* WINVER >= 0x0500 */
693 FIXME("DC_PRINTERMEM: stub\n");
696 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
697 case DC_PRINTRATE
: /* WINVER >= 0x0500 */
698 FIXME("DC_PRINTRATE: stub\n");
701 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
702 case DC_PRINTRATEPPM
: /* WINVER >= 0x0500 */
703 FIXME("DC_PRINTRATEPPM: stub\n");
706 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
707 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
709 case DC_PRINTRATEUNIT
: /* WINVER >= 0x0500 */
710 FIXME("DC_PRINTRATEUNIT: stub\n");
714 FIXME("Unsupported capability %d\n", fwCapability
);
723 HPROPSHEETPAGE hPages
[10];
726 INT
PSDRV_ExtDeviceModePropSheet(HWND hwnd
, LPSTR lpszDevice
, LPSTR lpszPort
,
729 EDMPS
*ps
= pPropSheet
;
732 psp
->dwSize
= sizeof(psp
);
733 psp
->hInstance
= 0x1234;