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"
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
.dmScale
= dm2
->dmPublic
.dmScale
;
109 TRACE("Changing Scale to %d\n", dm2
->dmPublic
.dmScale
);
112 if(dm2
->dmPublic
.dmFields
& DM_COPIES
) {
113 dm1
->dmPublic
.dmCopies
= dm2
->dmPublic
.dmCopies
;
114 TRACE("Changing Copies to %d\n", dm2
->dmPublic
.dmCopies
);
117 if(dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
) {
120 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
) {
121 if(slot
->WinBin
== dm2
->dmPublic
.dmDefaultSource
)
125 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
126 TRACE("Changing bin to '%s'\n", slot
->FullName
);
128 TRACE("Trying to change to unsupported bin %d\n",
129 dm2
->dmPublic
.dmDefaultSource
);
133 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
134 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
135 if (dm2
->dmPublic
.dmFields
& DM_PRINTQUALITY
)
136 dm1
->dmPublic
.dmPrintQuality
= dm2
->dmPublic
.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
.dmDisplayFlags
= dm2
->dmPublic
.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
.dmPosition
= dm2
->dmPublic
.u1
.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 /**************************************************************
181 * AdvancedSetupDialog [WINEPS16.93]
184 WORD WINAPI
PSDRV_AdvancedSetupDialog16(HWND16 hwnd
, HANDLE16 hDriver
,
185 LPDEVMODEA devin
, LPDEVMODEA devout
)
188 TRACE("hwnd = %04x, hDriver = %04x devin=%p devout=%p\n", hwnd
,
189 hDriver
, devin
, devout
);
193 /****************************************************************
196 * Dialog proc for 'Paper' propsheet
198 static INT_PTR CALLBACK
PSDRV_PaperDlgProc(HWND hwnd
, UINT msg
,
199 WPARAM wParam
, LPARAM lParam
)
208 di
= (PSDRV_DLGINFO
*)((PROPSHEETPAGEA
*)lParam
)->lParam
;
209 SetWindowLongPtrW(hwnd
, DWLP_USER
, (LONG_PTR
)di
);
212 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
213 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_INSERTSTRING
, i
,
214 (LPARAM
)ps
->FullName
);
215 if(di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmPaperSize
== ps
->WinPage
)
219 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_SETCURSEL
, Cursel
, 0);
221 CheckRadioButton(hwnd
, IDD_ORIENT_PORTRAIT
, IDD_ORIENT_LANDSCAPE
,
222 di
->pi
->Devmode
->dmPublic
.u1
.s1
.dmOrientation
==
223 DMORIENT_PORTRAIT
? IDD_ORIENT_PORTRAIT
:
224 IDD_ORIENT_LANDSCAPE
);
226 if(!di
->pi
->ppd
->Duplexes
) {
227 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX
), SW_HIDE
);
228 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX_NAME
), SW_HIDE
);
231 for(duplex
= di
->pi
->ppd
->Duplexes
, i
= 0; duplex
; duplex
= duplex
->next
, i
++) {
232 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_INSERTSTRING
, i
,
233 (LPARAM
)(duplex
->FullName
? duplex
->FullName
: duplex
->Name
));
234 if(di
->pi
->Devmode
->dmPublic
.dmDuplex
== duplex
->WinDuplex
)
237 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_SETCURSEL
, Cursel
, 0);
242 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
243 switch(LOWORD(wParam
)) {
245 if(HIWORD(wParam
) == LBN_SELCHANGE
) {
246 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), LB_GETCURSEL
, 0, 0);
248 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
249 if(i
>= Cursel
) break;
252 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel
,
254 di
->dlgdm
->dmPublic
.u1
.s1
.dmPaperSize
= ps
->WinPage
;
257 case IDD_ORIENT_PORTRAIT
:
258 case IDD_ORIENT_LANDSCAPE
:
259 TRACE("Setting orientation to %s\n", wParam
== IDD_ORIENT_PORTRAIT
?
260 "portrait" : "landscape");
261 di
->dlgdm
->dmPublic
.u1
.s1
.dmOrientation
= wParam
== IDD_ORIENT_PORTRAIT
?
262 DMORIENT_PORTRAIT
: DMORIENT_LANDSCAPE
;
265 if(HIWORD(wParam
) == CBN_SELCHANGE
) {
266 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), CB_GETCURSEL
, 0, 0);
267 for(i
= 0, duplex
= di
->pi
->ppd
->Duplexes
; i
< Cursel
; i
++, duplex
= duplex
->next
)
269 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel
,
271 di
->dlgdm
->dmPublic
.dmDuplex
= duplex
->WinDuplex
;
279 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
280 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
281 switch(nmhdr
->code
) {
283 memcpy(di
->pi
->Devmode
, di
->dlgdm
, sizeof(PSDRV_DEVMODEA
));
284 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, PSNRET_NOERROR
);
300 static void (WINAPI
*pInitCommonControls
) (void);
301 static HPROPSHEETPAGE (WINAPI
*pCreatePropertySheetPage
) (LPCPROPSHEETPAGEW
);
302 static int (WINAPI
*pPropertySheet
) (LPCPROPSHEETHEADERW
);
305 /******************************************************************
306 * PSDRV_ExtDeviceMode
308 * Retrieves or modifies device-initialization information for the PostScript
309 * driver, or displays a driver-supplied dialog box for configuring the driver.
312 * lpszDriver -- Driver name
313 * hwnd -- Parent window for the dialog box
314 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
315 * lpszDevice -- Device name
316 * lpszPort -- Port name
317 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
318 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
319 * wMode -- Operation to perform. Can be a combination if > 0.
320 * (0) -- Returns number of bytes required by DEVMODE structure
321 * DM_UPDATE (1) -- Write current settings to environment and initialization file
322 * DM_COPY (2) -- Write current settings to lpdmOutput
323 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
324 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
327 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
328 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
329 * A return value less than zero is returned if a non-dialog operation fails.
333 * Just returns default devmode at the moment. No use of initialization file.
335 INT
PSDRV_ExtDeviceMode(LPSTR lpszDriver
, HWND hwnd
, LPDEVMODEA lpdmOutput
,
336 LPSTR lpszDevice
, LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
337 LPSTR lpszProfile
, DWORD dwMode
)
339 PRINTERINFO
*pi
= PSDRV_FindPrinterInfo(lpszDevice
);
342 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
343 lpszDriver
, hwnd
, lpdmOutput
, lpszDevice
, lpszPort
, lpdmInput
, lpszProfile
, dwMode
);
345 /* If dwMode == 0, return size of DEVMODE structure */
347 return pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
;
349 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
350 if((dwMode
& DM_MODIFY
) && lpdmInput
) {
351 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput
->dmFields
);
352 PSDRV_MergeDevmodes(pi
->Devmode
, (PSDRV_DEVMODEA
*)lpdmInput
, pi
);
355 /* If DM_PROMPT is set, present modal dialog box */
356 if(dwMode
& DM_PROMPT
) {
357 HINSTANCE hinstComctl32
;
358 HPROPSHEETPAGE hpsp
[1];
360 PROPSHEETHEADERW psh
;
362 PSDRV_DEVMODEA
*dlgdm
;
363 static const WCHAR PAPERW
[] = {'P','A','P','E','R','\0'};
364 static const WCHAR SetupW
[] = {'S','e','t','u','p','\0'};
366 hinstComctl32
= LoadLibraryA("comctl32.dll");
367 pInitCommonControls
= (void*)GetProcAddress(hinstComctl32
,
368 "InitCommonControls");
369 pCreatePropertySheetPage
= (void*)GetProcAddress(hinstComctl32
,
370 "CreatePropertySheetPageW");
371 pPropertySheet
= (void*)GetProcAddress(hinstComctl32
, "PropertySheetW");
372 memset(&psp
,0,sizeof(psp
));
373 dlgdm
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*dlgdm
) );
374 memcpy(dlgdm
, pi
->Devmode
, sizeof(*dlgdm
));
375 di
= HeapAlloc( PSDRV_Heap
, 0, sizeof(*di
) );
378 psp
.dwSize
= sizeof(psp
);
379 psp
.hInstance
= PSDRV_hInstance
;
380 psp
.u
.pszTemplate
= PAPERW
;
381 psp
.u2
.pszIcon
= NULL
;
382 psp
.pfnDlgProc
= PSDRV_PaperDlgProc
;
383 psp
.lParam
= (LPARAM
)di
;
384 hpsp
[0] = pCreatePropertySheetPage(&psp
);
386 memset(&psh
, 0, sizeof(psh
));
387 psh
.dwSize
= sizeof(psh
);
388 psh
.pszCaption
= SetupW
;
390 psh
.hwndParent
= HWND_32(hwnd
);
391 psh
.u3
.phpage
= hpsp
;
393 pPropertySheet(&psh
);
397 /* If DM_UPDATE is set, should write settings to environment and initialization file */
398 if(dwMode
& DM_UPDATE
)
399 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
401 /* If DM_COPY is set, should write settings to lpdmOutput */
402 if((dwMode
& DM_COPY
) || (dwMode
& DM_UPDATE
)) {
404 memcpy(lpdmOutput
, pi
->Devmode
, pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
);
406 FIXME("lpdmOutput is NULL what should we do??\n");
410 /***************************************************************
411 * ExtDeviceMode [WINEPS16.90]
415 INT16 WINAPI
PSDRV_ExtDeviceMode16(HWND16 hwnd
, HANDLE16 hDriver
,
416 LPDEVMODEA lpdmOutput
, LPSTR lpszDevice
,
417 LPSTR lpszPort
, LPDEVMODEA lpdmInput
,
418 LPSTR lpszProfile
, WORD fwMode
)
421 return PSDRV_ExtDeviceMode(NULL
, HWND_32(hwnd
), lpdmOutput
, lpszDevice
,
422 lpszPort
, lpdmInput
, lpszProfile
, (DWORD
) fwMode
);
425 /***********************************************************************
426 * PSDRV_DeviceCapabilities
428 * Retrieves the capabilities of a printer device driver.
431 * lpszDriver -- printer driver name
432 * lpszDevice -- printer name
433 * lpszPort -- port name
434 * fwCapability -- device capability
435 * lpszOutput -- output buffer
436 * lpDevMode -- device data buffer
439 * Result depends on the setting of fwCapability. -1 indicates failure.
441 DWORD
PSDRV_DeviceCapabilities(LPSTR lpszDriver
, LPCSTR lpszDevice
, LPCSTR lpszPort
,
442 WORD fwCapability
, LPSTR lpszOutput
,
443 LPDEVMODEA lpDevMode
)
448 pi
= PSDRV_FindPrinterInfo(lpszDevice
);
450 TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability
, pi
);
454 ERR("no printerinfo for %s, return 0!\n",lpszDevice
);
459 lpdm
= lpDevMode
? lpDevMode
: (DEVMODEA
*)pi
->Devmode
;
461 switch(fwCapability
) {
466 WORD
*wp
= (WORD
*)lpszOutput
;
469 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
472 if(lpszOutput
!= NULL
)
481 POINT16
*pt
= (POINT16
*)lpszOutput
;
484 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
487 if(lpszOutput
!= NULL
) {
488 pt
->x
= ps
->PaperDimension
->x
* 254.0 / 72.0;
489 pt
->y
= ps
->PaperDimension
->y
* 254.0 / 72.0;
499 char *cp
= lpszOutput
;
502 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
505 if(lpszOutput
!= NULL
) {
506 lstrcpynA(cp
, ps
->FullName
, 64);
514 return pi
->ppd
->LandscapeOrientation
? pi
->ppd
->LandscapeOrientation
: 90;
519 WORD
*wp
= (WORD
*)lpszOutput
;
522 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
523 if(lpszOutput
!= NULL
)
524 *wp
++ = slot
->WinBin
;
531 char *cp
= lpszOutput
;
534 for(slot
= pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
, i
++)
535 if(lpszOutput
!= NULL
) {
536 lstrcpynA(cp
, slot
->FullName
, 24);
543 FIXME("DC_BINADJUST: stub.\n");
544 return DCBA_FACEUPNONE
;
546 case DC_ENUMRESOLUTIONS
:
548 LONG
*lp
= (LONG
*)lpszOutput
;
550 if(lpszOutput
!= NULL
) {
551 lp
[0] = (LONG
)pi
->ppd
->DefaultResolution
;
552 lp
[1] = (LONG
)pi
->ppd
->DefaultResolution
;
557 /* Windows returns 9999 too */
559 TRACE("DC_COPIES: returning 9999\n");
563 return lpdm
->dmDriverVersion
;
565 case DC_DATATYPE_PRODUCED
:
566 FIXME("DATA_TYPE_PRODUCED: stub.\n");
567 return -1; /* simulate that the driver supports 'RAW' */
571 if(pi
->ppd
->DefaultDuplex
&& pi
->ppd
->DefaultDuplex
->WinDuplex
!= 0)
573 TRACE("DC_DUPLEX: returning %d\n", ret
);
576 case DC_EMF_COMPLIANT
:
577 FIXME("DC_EMF_COMPLIANT: stub.\n");
578 return -1; /* simulate that the driver do not support EMF */
581 return lpdm
->dmDriverExtra
;
584 return lpdm
->dmFields
;
586 case DC_FILEDEPENDENCIES
:
587 FIXME("DC_FILEDEPENDENCIES: stub.\n");
594 ptMax
.x
= ptMax
.y
= 0;
596 if(lpszOutput
== NULL
)
599 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
601 if(ps
->PaperDimension
->x
> ptMax
.x
)
602 ptMax
.x
= ps
->PaperDimension
->x
;
603 if(ps
->PaperDimension
->y
> ptMax
.y
)
604 ptMax
.y
= ps
->PaperDimension
->y
;
606 return MAKELONG(ptMax
.x
* 254.0 / 72.0, ptMax
.y
* 254.0 / 72.0 );
613 ptMin
.x
= ptMin
.y
= -1;
615 if(lpszOutput
== NULL
)
618 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
620 if(ptMin
.x
== -1 || ps
->PaperDimension
->x
< ptMin
.x
)
621 ptMin
.x
= ps
->PaperDimension
->x
;
622 if(ptMin
.y
== -1 || ps
->PaperDimension
->y
< ptMin
.y
)
623 ptMin
.y
= ps
->PaperDimension
->y
;
625 return MAKELONG(ptMin
.x
* 254.0 / 72.0, ptMin
.y
* 254.0 / 72.0);
632 FIXME("DC_TRUETYPE: stub\n");
636 return lpdm
->dmSpecVersion
;
638 /* We'll just return false here, very few printers can collate anyway */
640 TRACE("DC_COLLATE: returning FALSE\n");
643 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
645 return (pi
->ppd
->ColorDevice
!= CD_False
) ? TRUE
: FALSE
;
647 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
648 case DC_MANUFACTURER
:
649 FIXME("DC_MANUFACTURER: stub\n");
652 /* Identification number of the printer model for use with ICM (Win9x only) */
654 FIXME("DC_MODEL: stub\n");
657 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
658 case DC_STAPLE
: /* WINVER >= 0x0500 */
659 FIXME("DC_STAPLE: stub\n");
662 /* Returns an array of 64-character string buffers containing the names of the paper forms
663 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
666 case DC_MEDIAREADY
: /* WINVER >= 0x0500 */
667 FIXME("DC_MEDIAREADY: stub\n");
670 /* Returns an array of 64-character string buffers containing the names of the supported
671 * media types, unless pOutput is NULL. The return value is the number of supported.
672 * media types (XP only)
674 case DC_MEDIATYPENAMES
: /* WINVER >= 0x0501 */
675 FIXME("DC_MEDIATYPENAMES: stub\n");
678 /* Returns an array of DWORD values which represent the supported media types, unless
679 * pOutput is NULL. The return value is the number of supported media types. (XP only)
681 case DC_MEDIATYPES
: /* WINVER >= 0x0501 */
682 FIXME("DC_MEDIATYPES: stub\n");
685 /* Returns an array of DWORD values, each representing a supported number of document
686 * pages per printed page, unless pOutput is NULL. The return value is the number of
687 * array entries. (Win2k/XP only)
690 FIXME("DC_NUP: stub\n");
693 /* Returns an array of 32-character string buffers containing a list of printer description
694 * languages supported by the printer, unless pOutput is NULL. The return value is
695 * number of array entries. (Win2k/XP only)
698 case DC_PERSONALITY
: /* WINVER >= 0x0500 */
699 FIXME("DC_PERSONALITY: stub\n");
702 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
703 case DC_PRINTERMEM
: /* WINVER >= 0x0500 */
704 FIXME("DC_PRINTERMEM: stub\n");
707 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
708 case DC_PRINTRATE
: /* WINVER >= 0x0500 */
709 FIXME("DC_PRINTRATE: stub\n");
712 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
713 case DC_PRINTRATEPPM
: /* WINVER >= 0x0500 */
714 FIXME("DC_PRINTRATEPPM: stub\n");
717 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
718 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
720 case DC_PRINTRATEUNIT
: /* WINVER >= 0x0500 */
721 FIXME("DC_PRINTRATEUNIT: stub\n");
725 FIXME("Unsupported capability %d\n", fwCapability
);
730 /**************************************************************
731 * DeviceCapabilities [WINEPS16.91]
733 DWORD WINAPI
PSDRV_DeviceCapabilities16(LPCSTR lpszDevice
,
734 LPCSTR lpszPort
, WORD fwCapability
,
735 LPSTR lpszOutput
, LPDEVMODEA lpdm
)
737 return PSDRV_DeviceCapabilities(NULL
, lpszDevice
, lpszPort
, fwCapability
,
741 /***************************************************************
742 * DeviceMode [WINEPS16.13]
745 void WINAPI
PSDRV_DeviceMode16(HWND16 hwnd
, HANDLE16 hDriver
,
746 LPSTR lpszDevice
, LPSTR lpszPort
)
748 PSDRV_ExtDeviceMode16( hwnd
, hDriver
, NULL
, lpszDevice
, lpszPort
, NULL
,
757 HPROPSHEETPAGE hPages
[10];
760 INT
PSDRV_ExtDeviceModePropSheet(HWND hwnd
, LPSTR lpszDevice
, LPSTR lpszPort
,
763 EDMPS
*ps
= pPropSheet
;
766 psp
->dwSize
= sizeof(psp
);
767 psp
->hInstance
= 0x1234;