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
33 #include "ddk/winddiui.h"
35 #include "wine/debug.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 INPUTSLOT
*find_slot( PPD
*ppd
, const PSDRV_DEVMODE
*dm
)
52 LIST_FOR_EACH_ENTRY( slot
, &ppd
->InputSlots
, INPUTSLOT
, entry
)
53 if (slot
->WinBin
== dm
->dmPublic
.dmDefaultSource
)
59 PAGESIZE
*find_pagesize( PPD
*ppd
, const PSDRV_DEVMODE
*dm
)
63 LIST_FOR_EACH_ENTRY( page
, &ppd
->PageSizes
, PAGESIZE
, entry
)
64 if (page
->WinPage
== dm
->dmPublic
.dmPaperSize
)
70 DUPLEX
*find_duplex( PPD
*ppd
, const PSDRV_DEVMODE
*dm
)
73 WORD win_duplex
= dm
->dmPublic
.dmFields
& DM_DUPLEX
? dm
->dmPublic
.dmDuplex
: 0;
75 if (win_duplex
== 0) return NULL
; /* Not capable */
77 LIST_FOR_EACH_ENTRY( duplex
, &ppd
->Duplexes
, DUPLEX
, entry
)
78 if (duplex
->WinDuplex
== win_duplex
)
84 /************************************************************************
88 * Updates dm1 with some fields from dm2
91 void PSDRV_MergeDevmodes( PSDRV_DEVMODE
*dm1
, const PSDRV_DEVMODE
*dm2
, PRINTERINFO
*pi
)
93 /* some sanity checks here on dm2 */
95 if(dm2
->dmPublic
.dmFields
& DM_ORIENTATION
) {
96 dm1
->dmPublic
.dmOrientation
= dm2
->dmPublic
.dmOrientation
;
97 TRACE("Changing orientation to %d (%s)\n",
98 dm1
->dmPublic
.dmOrientation
,
99 dm1
->dmPublic
.dmOrientation
== DMORIENT_PORTRAIT
?
101 (dm1
->dmPublic
.dmOrientation
== DMORIENT_LANDSCAPE
?
102 "Landscape" : "unknown"));
105 /* NB PaperWidth is always < PaperLength */
106 if (dm2
->dmPublic
.dmFields
& DM_PAPERSIZE
)
108 PAGESIZE
*page
= find_pagesize( pi
->ppd
, dm2
);
112 dm1
->dmPublic
.dmPaperSize
= dm2
->dmPublic
.dmPaperSize
;
113 dm1
->dmPublic
.dmPaperWidth
= paper_size_from_points( page
->PaperDimension
->x
);
114 dm1
->dmPublic
.dmPaperLength
= paper_size_from_points( page
->PaperDimension
->y
);
115 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
| DM_PAPERWIDTH
| DM_PAPERLENGTH
;
116 TRACE("Changing page to %s %d x %d\n", page
->FullName
,
117 dm1
->dmPublic
.dmPaperWidth
,
118 dm1
->dmPublic
.dmPaperLength
);
120 if (dm1
->dmPublic
.dmSize
>= FIELD_OFFSET(DEVMODEW
, dmFormName
) + CCHFORMNAME
* sizeof(WCHAR
))
122 MultiByteToWideChar(CP_ACP
, 0, page
->FullName
, -1, dm1
->dmPublic
.dmFormName
, CCHFORMNAME
);
123 dm1
->dmPublic
.dmFields
|= DM_FORMNAME
;
127 TRACE("Trying to change to unsupported pagesize %d\n", dm2
->dmPublic
.dmPaperSize
);
130 else if((dm2
->dmPublic
.dmFields
& DM_PAPERLENGTH
) &&
131 (dm2
->dmPublic
.dmFields
& DM_PAPERWIDTH
)) {
132 dm1
->dmPublic
.dmPaperLength
= dm2
->dmPublic
.dmPaperLength
;
133 dm1
->dmPublic
.dmPaperWidth
= dm2
->dmPublic
.dmPaperWidth
;
134 TRACE("Changing PaperLength|Width to %dx%d\n",
135 dm2
->dmPublic
.dmPaperLength
,
136 dm2
->dmPublic
.dmPaperWidth
);
137 dm1
->dmPublic
.dmFields
&= ~DM_PAPERSIZE
;
138 dm1
->dmPublic
.dmFields
|= (DM_PAPERLENGTH
| DM_PAPERWIDTH
);
139 } else if(dm2
->dmPublic
.dmFields
& (DM_PAPERLENGTH
| DM_PAPERWIDTH
)) {
140 /* You might think that this would be allowed if dm1 is in custom size
141 mode, but apparently Windows reverts to standard paper mode even in
143 FIXME("Trying to change only paperlength or paperwidth\n");
144 dm1
->dmPublic
.dmFields
&= ~(DM_PAPERLENGTH
| DM_PAPERWIDTH
);
145 dm1
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
148 if(dm2
->dmPublic
.dmFields
& DM_SCALE
) {
149 dm1
->dmPublic
.dmScale
= dm2
->dmPublic
.dmScale
;
150 TRACE("Changing Scale to %d\n", dm2
->dmPublic
.dmScale
);
153 if(dm2
->dmPublic
.dmFields
& DM_COPIES
) {
154 dm1
->dmPublic
.dmCopies
= dm2
->dmPublic
.dmCopies
;
155 TRACE("Changing Copies to %d\n", dm2
->dmPublic
.dmCopies
);
158 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
160 INPUTSLOT
*slot
= find_slot( pi
->ppd
, dm2
);
164 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
165 TRACE("Changing bin to '%s'\n", slot
->FullName
);
168 TRACE("Trying to change to unsupported bin %d\n", dm2
->dmPublic
.dmDefaultSource
);
171 if (dm2
->dmPublic
.dmFields
& DM_DEFAULTSOURCE
)
172 dm1
->dmPublic
.dmDefaultSource
= dm2
->dmPublic
.dmDefaultSource
;
173 if (dm2
->dmPublic
.dmFields
& DM_PRINTQUALITY
)
174 dm1
->dmPublic
.dmPrintQuality
= dm2
->dmPublic
.dmPrintQuality
;
175 if (dm2
->dmPublic
.dmFields
& DM_COLOR
)
176 dm1
->dmPublic
.dmColor
= dm2
->dmPublic
.dmColor
;
177 if (dm2
->dmPublic
.dmFields
& DM_DUPLEX
&& pi
->ppd
->DefaultDuplex
&& pi
->ppd
->DefaultDuplex
->WinDuplex
!= 0)
178 dm1
->dmPublic
.dmDuplex
= dm2
->dmPublic
.dmDuplex
;
179 if (dm2
->dmPublic
.dmFields
& DM_YRESOLUTION
)
180 dm1
->dmPublic
.dmYResolution
= dm2
->dmPublic
.dmYResolution
;
181 if (dm2
->dmPublic
.dmFields
& DM_TTOPTION
)
182 dm1
->dmPublic
.dmTTOption
= dm2
->dmPublic
.dmTTOption
;
183 if (dm2
->dmPublic
.dmFields
& DM_COLLATE
)
184 dm1
->dmPublic
.dmCollate
= dm2
->dmPublic
.dmCollate
;
185 if (dm2
->dmPublic
.dmFields
& DM_FORMNAME
)
186 lstrcpynW(dm1
->dmPublic
.dmFormName
, dm2
->dmPublic
.dmFormName
, CCHFORMNAME
);
187 if (dm2
->dmPublic
.dmFields
& DM_BITSPERPEL
)
188 dm1
->dmPublic
.dmBitsPerPel
= dm2
->dmPublic
.dmBitsPerPel
;
189 if (dm2
->dmPublic
.dmFields
& DM_PELSWIDTH
)
190 dm1
->dmPublic
.dmPelsWidth
= dm2
->dmPublic
.dmPelsWidth
;
191 if (dm2
->dmPublic
.dmFields
& DM_PELSHEIGHT
)
192 dm1
->dmPublic
.dmPelsHeight
= dm2
->dmPublic
.dmPelsHeight
;
193 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFLAGS
)
194 dm1
->dmPublic
.dmDisplayFlags
= dm2
->dmPublic
.dmDisplayFlags
;
195 if (dm2
->dmPublic
.dmFields
& DM_DISPLAYFREQUENCY
)
196 dm1
->dmPublic
.dmDisplayFrequency
= dm2
->dmPublic
.dmDisplayFrequency
;
197 if (dm2
->dmPublic
.dmFields
& DM_POSITION
)
198 dm1
->dmPublic
.dmPosition
= dm2
->dmPublic
.dmPosition
;
199 if (dm2
->dmPublic
.dmFields
& DM_LOGPIXELS
)
200 dm1
->dmPublic
.dmLogPixels
= dm2
->dmPublic
.dmLogPixels
;
201 if (dm2
->dmPublic
.dmFields
& DM_ICMMETHOD
)
202 dm1
->dmPublic
.dmICMMethod
= dm2
->dmPublic
.dmICMMethod
;
203 if (dm2
->dmPublic
.dmFields
& DM_ICMINTENT
)
204 dm1
->dmPublic
.dmICMIntent
= dm2
->dmPublic
.dmICMIntent
;
205 if (dm2
->dmPublic
.dmFields
& DM_MEDIATYPE
)
206 dm1
->dmPublic
.dmMediaType
= dm2
->dmPublic
.dmMediaType
;
207 if (dm2
->dmPublic
.dmFields
& DM_DITHERTYPE
)
208 dm1
->dmPublic
.dmDitherType
= dm2
->dmPublic
.dmDitherType
;
209 if (dm2
->dmPublic
.dmFields
& DM_PANNINGWIDTH
)
210 dm1
->dmPublic
.dmPanningWidth
= dm2
->dmPublic
.dmPanningWidth
;
211 if (dm2
->dmPublic
.dmFields
& DM_PANNINGHEIGHT
)
212 dm1
->dmPublic
.dmPanningHeight
= dm2
->dmPublic
.dmPanningHeight
;
221 PSDRV_DEVMODE
*dlgdm
;
224 /****************************************************************
227 * Dialog proc for 'Paper' propsheet
229 static INT_PTR CALLBACK
PSDRV_PaperDlgProc(HWND hwnd
, UINT msg
,
230 WPARAM wParam
, LPARAM lParam
)
240 di
= (PSDRV_DLGINFO
*)((PROPSHEETPAGEA
*)lParam
)->lParam
;
241 SetWindowLongPtrW(hwnd
, DWLP_USER
, (LONG_PTR
)di
);
244 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
245 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_INSERTSTRING
, i
,
246 (LPARAM
)ps
->FullName
);
247 if(di
->pi
->Devmode
->dmPublic
.dmPaperSize
== ps
->WinPage
)
251 SendDlgItemMessageA(hwnd
, IDD_PAPERS
, LB_SETCURSEL
, Cursel
, 0);
253 CheckRadioButton(hwnd
, IDD_ORIENT_PORTRAIT
, IDD_ORIENT_LANDSCAPE
,
254 di
->pi
->Devmode
->dmPublic
.dmOrientation
==
255 DMORIENT_PORTRAIT
? IDD_ORIENT_PORTRAIT
:
256 IDD_ORIENT_LANDSCAPE
);
258 if (list_empty( &di
->pi
->ppd
->Duplexes
))
260 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX
), SW_HIDE
);
261 ShowWindow(GetDlgItem(hwnd
, IDD_DUPLEX_NAME
), SW_HIDE
);
266 LIST_FOR_EACH_ENTRY( duplex
, &di
->pi
->ppd
->Duplexes
, DUPLEX
, entry
)
268 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_INSERTSTRING
, i
,
269 (LPARAM
)(duplex
->FullName
? duplex
->FullName
: duplex
->Name
));
270 if(di
->pi
->Devmode
->dmPublic
.dmDuplex
== duplex
->WinDuplex
)
274 SendDlgItemMessageA(hwnd
, IDD_DUPLEX
, CB_SETCURSEL
, Cursel
, 0);
277 if (list_empty( &di
->pi
->ppd
->Resolutions
))
282 res
= di
->pi
->ppd
->DefaultResolution
;
283 len
= swprintf(buf
, ARRAY_SIZE(buf
), L
"%d", res
);
285 LoadStringW(PSDRV_hInstance
, IDS_DPI
, buf
+ len
, ARRAY_SIZE(buf
) - len
);
286 SendDlgItemMessageW(hwnd
, IDD_QUALITY
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
287 SendDlgItemMessageW(hwnd
, IDD_QUALITY
, CB_SETITEMDATA
, 0, MAKELONG(res
, res
));
295 resx
= resy
= di
->pi
->ppd
->DefaultResolution
;
297 if (di
->pi
->Devmode
->dmPublic
.dmFields
& DM_PRINTQUALITY
)
298 resx
= resy
= di
->pi
->Devmode
->dmPublic
.dmPrintQuality
;
300 if (di
->pi
->Devmode
->dmPublic
.dmFields
& DM_YRESOLUTION
)
301 resy
= di
->pi
->Devmode
->dmPublic
.dmYResolution
;
303 if (di
->pi
->Devmode
->dmPublic
.dmFields
& DM_LOGPIXELS
)
304 resx
= resy
= di
->pi
->Devmode
->dmPublic
.dmLogPixels
;
306 LIST_FOR_EACH_ENTRY(res
, &di
->pi
->ppd
->Resolutions
, RESOLUTION
, entry
)
312 if (res
->resx
== res
->resy
)
313 len
= swprintf(buf
, ARRAY_SIZE(buf
), L
"%d", res
->resx
);
315 len
= swprintf(buf
, ARRAY_SIZE(buf
), L
"%dx%d", res
->resx
, res
->resy
);
317 LoadStringW(PSDRV_hInstance
, IDS_DPI
, buf
+ len
, ARRAY_SIZE(buf
) - len
);
318 idx
= SendDlgItemMessageW(hwnd
, IDD_QUALITY
, CB_ADDSTRING
, 0, (LPARAM
)buf
);
319 SendDlgItemMessageW(hwnd
, IDD_QUALITY
, CB_SETITEMDATA
, idx
, MAKELONG(res
->resx
, res
->resy
));
321 if (res
->resx
== resx
&& res
->resy
== resy
)
325 SendDlgItemMessageW(hwnd
, IDD_QUALITY
, CB_SETCURSEL
, Cursel
, 0);
330 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
331 switch(LOWORD(wParam
)) {
333 if(HIWORD(wParam
) == LBN_SELCHANGE
) {
334 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), LB_GETCURSEL
, 0, 0);
336 LIST_FOR_EACH_ENTRY(ps
, &di
->pi
->ppd
->PageSizes
, PAGESIZE
, entry
) {
337 if(i
>= Cursel
) break;
340 TRACE("Setting pagesize to item %d, WinPage %d (%s), PaperSize %.2fx%.2f\n", Cursel
,
341 ps
->WinPage
, ps
->FullName
, ps
->PaperDimension
->x
, ps
->PaperDimension
->y
);
342 di
->dlgdm
->dmPublic
.dmPaperSize
= ps
->WinPage
;
343 di
->dlgdm
->dmPublic
.dmFields
|= DM_PAPERSIZE
;
345 di
->dlgdm
->dmPublic
.dmPaperWidth
= paper_size_from_points(ps
->PaperDimension
->x
);
346 di
->dlgdm
->dmPublic
.dmPaperLength
= paper_size_from_points(ps
->PaperDimension
->y
);
347 di
->dlgdm
->dmPublic
.dmFields
|= DM_PAPERLENGTH
| DM_PAPERWIDTH
;
349 if (di
->dlgdm
->dmPublic
.dmSize
>= FIELD_OFFSET(DEVMODEW
, dmFormName
) + CCHFORMNAME
* sizeof(WCHAR
))
351 MultiByteToWideChar(CP_ACP
, 0, ps
->FullName
, -1, di
->dlgdm
->dmPublic
.dmFormName
, CCHFORMNAME
);
352 di
->dlgdm
->dmPublic
.dmFields
|= DM_FORMNAME
;
354 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
357 case IDD_ORIENT_PORTRAIT
:
358 case IDD_ORIENT_LANDSCAPE
:
359 TRACE("Setting orientation to %s\n", wParam
== IDD_ORIENT_PORTRAIT
?
360 "portrait" : "landscape");
361 di
->dlgdm
->dmPublic
.dmOrientation
= wParam
== IDD_ORIENT_PORTRAIT
?
362 DMORIENT_PORTRAIT
: DMORIENT_LANDSCAPE
;
363 di
->dlgdm
->dmPublic
.dmFields
|= DM_ORIENTATION
;
364 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
367 if(HIWORD(wParam
) == CBN_SELCHANGE
) {
368 Cursel
= SendDlgItemMessageA(hwnd
, LOWORD(wParam
), CB_GETCURSEL
, 0, 0);
370 LIST_FOR_EACH_ENTRY( duplex
, &di
->pi
->ppd
->Duplexes
, DUPLEX
, entry
)
372 if (i
>= Cursel
) break;
375 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel
, duplex
->WinDuplex
);
376 di
->dlgdm
->dmPublic
.dmDuplex
= duplex
->WinDuplex
;
377 di
->dlgdm
->dmPublic
.dmFields
|= DM_DUPLEX
;
378 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
383 if (HIWORD(wParam
) == CBN_SELCHANGE
)
388 Cursel
= SendDlgItemMessageW(hwnd
, LOWORD(wParam
), CB_GETCURSEL
, 0, 0);
389 data
= SendDlgItemMessageW(hwnd
, IDD_QUALITY
, CB_GETITEMDATA
, Cursel
, 0);
393 TRACE("Setting resolution to %dx%d\n", resx
, resy
);
395 di
->dlgdm
->dmPublic
.dmPrintQuality
= resx
;
396 di
->dlgdm
->dmPublic
.dmFields
|= DM_PRINTQUALITY
;
398 di
->dlgdm
->dmPublic
.dmYResolution
= resy
;
399 di
->dlgdm
->dmPublic
.dmFields
|= DM_YRESOLUTION
;
401 if (di
->pi
->Devmode
->dmPublic
.dmFields
& DM_LOGPIXELS
)
403 di
->dlgdm
->dmPublic
.dmLogPixels
= resx
;
404 di
->dlgdm
->dmPublic
.dmFields
|= DM_LOGPIXELS
;
407 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, 0, 0);
415 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
416 di
= (PSDRV_DLGINFO
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
417 switch(nmhdr
->code
) {
419 *di
->pi
->Devmode
= *di
->dlgdm
;
420 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, PSNRET_NOERROR
);
436 static HPROPSHEETPAGE (WINAPI
*pCreatePropertySheetPage
) (LPCPROPSHEETPAGEW
);
437 static int (WINAPI
*pPropertySheet
) (LPCPROPSHEETHEADERW
);
439 /******************************************************************************
440 * DrvDocumentProperties (wineps.drv.@)
442 * Retrieves or modifies device-initialization information for the PostScript
443 * driver, or displays a driver-supplied dialog box for configuring the driver.
446 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
447 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
448 * A return value less than zero is returned if a non-dialog operation fails.
452 * Just returns default devmode at the moment. No use of initialization file.
454 INT WINAPI
DrvDocumentProperties(HWND hwnd
, const WCHAR
*device
, DEVMODEW
*output
,
455 DEVMODEW
*input
, DWORD mode
)
459 TRACE("(hwnd=%p, Device='%s', devOut=%p, devIn=%p, Mode=%04lx)\n",
460 hwnd
, debugstr_w(device
), output
, input
, mode
);
462 if (!(pi
= PSDRV_FindPrinterInfo(device
))) return -1;
464 /* If mode == 0, return size of DEVMODE structure */
466 return pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
;
468 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
469 if ((mode
& DM_MODIFY
) && input
)
471 TRACE("DM_MODIFY set. devIn->dmFields = %08lx\n", input
->dmFields
);
472 PSDRV_MergeDevmodes(pi
->Devmode
, (PSDRV_DEVMODE
*)input
, pi
);
475 /* If DM_PROMPT is set, present modal dialog box */
476 if (mode
& DM_PROMPT
) {
477 HINSTANCE hinstComctl32
;
478 HPROPSHEETPAGE hpsp
[1];
480 PROPSHEETHEADERW psh
;
485 LoadStringW(PSDRV_hInstance
, IDS_SETUP
, SetupW
, ARRAY_SIZE(SetupW
));
486 hinstComctl32
= LoadLibraryA("comctl32.dll");
487 pCreatePropertySheetPage
= (void*)GetProcAddress(hinstComctl32
,
488 "CreatePropertySheetPageW");
489 pPropertySheet
= (void*)GetProcAddress(hinstComctl32
, "PropertySheetW");
490 memset(&psp
,0,sizeof(psp
));
491 dlgdm
= *pi
->Devmode
;
494 psp
.dwSize
= sizeof(psp
);
495 psp
.hInstance
= PSDRV_hInstance
;
496 psp
.pszTemplate
= L
"PAPER";
498 psp
.pfnDlgProc
= PSDRV_PaperDlgProc
;
499 psp
.lParam
= (LPARAM
)&di
;
500 hpsp
[0] = pCreatePropertySheetPage(&psp
);
502 memset(&psh
, 0, sizeof(psh
));
503 psh
.dwSize
= sizeof(psh
);
504 psh
.pszCaption
= SetupW
;
506 psh
.hwndParent
= hwnd
;
509 pPropertySheet(&psh
);
513 /* If DM_UPDATE is set, should write settings to environment and initialization file */
514 if (mode
& DM_UPDATE
)
515 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
517 /* If DM_COPY is set, should write settings to lpdmOutput */
518 if (output
&& (mode
& (DM_COPY
| DM_UPDATE
)))
519 memcpy( output
, &pi
->Devmode
->dmPublic
,
520 pi
->Devmode
->dmPublic
.dmSize
+ pi
->Devmode
->dmPublic
.dmDriverExtra
);
524 /******************************************************************************
525 * DrvDeviceCapabilities (wineps.drv.@)
527 DWORD WINAPI
DrvDeviceCapabilities(HANDLE printer
, WCHAR
*device_name
, WORD capability
,
528 void *output
, DEVMODEW
*devmode
)
534 TRACE("%s %u, %p, %p\n", debugstr_w(device_name
), capability
, output
, devmode
);
536 if (!(pi
= PSDRV_FindPrinterInfo(device_name
))) {
537 ERR("no printer info for %s, return 0!\n", debugstr_w(device_name
));
541 lpdm
= &pi
->Devmode
->dmPublic
;
542 if (devmode
) lpdm
= devmode
;
552 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
554 TRACE("DC_PAPERS: %u\n", ps
->WinPage
);
556 if (output
!= NULL
) *wp
++ = ps
->WinPage
;
568 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
570 TRACE("DC_PAPERSIZE: %f x %f\n", ps
->PaperDimension
->x
, ps
->PaperDimension
->y
);
572 if (output
!= NULL
) {
573 pt
->x
= paper_size_from_points( ps
->PaperDimension
->x
);
574 pt
->y
= paper_size_from_points( ps
->PaperDimension
->y
);
588 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
590 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps
->FullName
));
592 if (output
!= NULL
) {
593 MultiByteToWideChar(CP_ACP
, 0, ps
->FullName
, -1, cp
, 64);
602 ret
= pi
->ppd
->LandscapeOrientation
? pi
->ppd
->LandscapeOrientation
: 90;
611 LIST_FOR_EACH_ENTRY( slot
, &pi
->ppd
->InputSlots
, INPUTSLOT
, entry
)
615 *wp
++ = slot
->WinBin
;
627 LIST_FOR_EACH_ENTRY( slot
, &pi
->ppd
->InputSlots
, INPUTSLOT
, entry
)
632 MultiByteToWideChar(CP_ACP
, 0, slot
->FullName
, -1, cp
, 24);
641 FIXME("DC_BINADJUST: stub.\n");
642 ret
= DCBA_FACEUPNONE
;
645 case DC_ENUMRESOLUTIONS
:
651 LIST_FOR_EACH_ENTRY(res
, &pi
->ppd
->Resolutions
, RESOLUTION
, entry
)
665 /* Windows returns 9999 too */
667 TRACE("DC_COPIES: returning 9999\n");
672 ret
= lpdm
->dmDriverVersion
;
675 case DC_DATATYPE_PRODUCED
:
676 FIXME("DATA_TYPE_PRODUCED: stub.\n");
677 ret
= -1; /* simulate that the driver supports 'RAW' */
682 if(pi
->ppd
->DefaultDuplex
&& pi
->ppd
->DefaultDuplex
->WinDuplex
!= 0)
684 TRACE("DC_DUPLEX: returning %ld\n", ret
);
687 case DC_EMF_COMPLIANT
:
688 FIXME("DC_EMF_COMPLIANT: stub.\n");
689 ret
= -1; /* simulate that the driver do not support EMF */
693 ret
= lpdm
->dmDriverExtra
;
697 ret
= lpdm
->dmFields
;
700 case DC_FILEDEPENDENCIES
:
701 FIXME("DC_FILEDEPENDENCIES: stub.\n");
710 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
712 if (ps
->PaperDimension
->x
> x
) x
= ps
->PaperDimension
->x
;
713 if (ps
->PaperDimension
->y
> y
) y
= ps
->PaperDimension
->y
;
715 ret
= MAKELONG( paper_size_from_points(x
), paper_size_from_points(y
) );
722 float x
= 1e6
, y
= 1e6
;
724 LIST_FOR_EACH_ENTRY(ps
, &pi
->ppd
->PageSizes
, PAGESIZE
, entry
)
726 if (ps
->PaperDimension
->x
< x
) x
= ps
->PaperDimension
->x
;
727 if (ps
->PaperDimension
->y
< y
) y
= ps
->PaperDimension
->y
;
729 ret
= MAKELONG( paper_size_from_points(x
), paper_size_from_points(y
) );
738 FIXME("DC_TRUETYPE: stub\n");
743 ret
= lpdm
->dmSpecVersion
;
746 /* We'll just return false here, very few printers can collate anyway */
748 TRACE("DC_COLLATE: returning FALSE\n");
752 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
754 ret
= pi
->ppd
->ColorDevice
!= CD_False
;
757 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
758 case DC_MANUFACTURER
:
759 FIXME("DC_MANUFACTURER: stub\n");
763 /* Identification number of the printer model for use with ICM (Win9x only) */
765 FIXME("DC_MODEL: stub\n");
769 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
770 case DC_STAPLE
: /* WINVER >= 0x0500 */
771 FIXME("DC_STAPLE: stub\n");
775 /* Returns an array of 64-character string buffers containing the names of the paper forms
776 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
779 case DC_MEDIAREADY
: /* WINVER >= 0x0500 */
780 FIXME("DC_MEDIAREADY: stub\n");
784 /* Returns an array of 64-character string buffers containing the names of the supported
785 * media types, unless pOutput is NULL. The return value is the number of supported.
786 * media types (XP only)
788 case DC_MEDIATYPENAMES
: /* WINVER >= 0x0501 */
789 FIXME("DC_MEDIATYPENAMES: stub\n");
793 /* Returns an array of DWORD values which represent the supported media types, unless
794 * pOutput is NULL. The return value is the number of supported media types. (XP only)
796 case DC_MEDIATYPES
: /* WINVER >= 0x0501 */
797 FIXME("DC_MEDIATYPES: stub\n");
801 /* Returns an array of DWORD values, each representing a supported number of document
802 * pages per printed page, unless pOutput is NULL. The return value is the number of
803 * array entries. (Win2k/XP only)
806 FIXME("DC_NUP: stub\n");
810 /* Returns an array of 32-character string buffers containing a list of printer description
811 * languages supported by the printer, unless pOutput is NULL. The return value is
812 * number of array entries. (Win2k/XP only)
814 case DC_PERSONALITY
: /* WINVER >= 0x0500 */
815 FIXME("DC_PERSONALITY: stub\n");
819 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
820 case DC_PRINTERMEM
: /* WINVER >= 0x0500 */
821 FIXME("DC_PRINTERMEM: stub\n");
825 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
826 case DC_PRINTRATE
: /* WINVER >= 0x0500 */
827 FIXME("DC_PRINTRATE: stub\n");
831 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
832 case DC_PRINTRATEPPM
: /* WINVER >= 0x0500 */
833 FIXME("DC_PRINTRATEPPM: stub\n");
837 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
838 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
840 case DC_PRINTRATEUNIT
: /* WINVER >= 0x0500 */
841 FIXME("DC_PRINTRATEUNIT: stub\n");
846 FIXME("Unsupported capability %d\n", capability
);
857 HPROPSHEETPAGE hPages
[10];
860 INT
PSDRV_ExtDeviceModePropSheet(HWND hwnd
, LPSTR lpszDevice
, LPSTR lpszPort
,
863 EDMPS
*ps
= pPropSheet
;
866 psp
->dwSize
= sizeof(psp
);
867 psp
->hInstance
= 0x1234;