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) {
122 for(slot = pi->ppd->InputSlots; slot; slot = slot->next) {
123 if(slot->WinBin == dm2->dmPublic.u1.s1.dmDefaultSource)
127 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
128 TRACE("Changing bin to '%s'\n", slot->FullName);
130 TRACE("Trying to change to unsupported bin %d\n",
131 dm2->dmPublic.u1.s1.dmDefaultSource);
135 if (dm2->dmPublic.dmFields & DM_DEFAULTSOURCE )
136 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
137 if (dm2->dmPublic.dmFields & DM_PRINTQUALITY )
138 dm1->dmPublic.u1.s1.dmPrintQuality = dm2->dmPublic.u1.s1.dmPrintQuality;
139 if (dm2->dmPublic.dmFields & DM_COLOR )
140 dm1->dmPublic.dmColor = dm2->dmPublic.dmColor;
141 if (dm2->dmPublic.dmFields & DM_DUPLEX && pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
142 dm1->dmPublic.dmDuplex = dm2->dmPublic.dmDuplex;
143 if (dm2->dmPublic.dmFields & DM_YRESOLUTION )
144 dm1->dmPublic.dmYResolution = dm2->dmPublic.dmYResolution;
145 if (dm2->dmPublic.dmFields & DM_TTOPTION )
146 dm1->dmPublic.dmTTOption = dm2->dmPublic.dmTTOption;
147 if (dm2->dmPublic.dmFields & DM_COLLATE )
148 dm1->dmPublic.dmCollate = dm2->dmPublic.dmCollate;
149 if (dm2->dmPublic.dmFields & DM_FORMNAME )
150 lstrcpynA((LPSTR)dm1->dmPublic.dmFormName, (LPCSTR)dm2->dmPublic.dmFormName, CCHFORMNAME);
151 if (dm2->dmPublic.dmFields & DM_BITSPERPEL )
152 dm1->dmPublic.dmBitsPerPel = dm2->dmPublic.dmBitsPerPel;
153 if (dm2->dmPublic.dmFields & DM_PELSWIDTH )
154 dm1->dmPublic.dmPelsWidth = dm2->dmPublic.dmPelsWidth;
155 if (dm2->dmPublic.dmFields & DM_PELSHEIGHT )
156 dm1->dmPublic.dmPelsHeight = dm2->dmPublic.dmPelsHeight;
157 if (dm2->dmPublic.dmFields & DM_DISPLAYFLAGS )
158 dm1->dmPublic.u2.dmDisplayFlags = dm2->dmPublic.u2.dmDisplayFlags;
159 if (dm2->dmPublic.dmFields & DM_DISPLAYFREQUENCY )
160 dm1->dmPublic.dmDisplayFrequency = dm2->dmPublic.dmDisplayFrequency;
161 if (dm2->dmPublic.dmFields & DM_POSITION )
162 dm1->dmPublic.u1.s2.dmPosition = dm2->dmPublic.u1.s2.dmPosition;
163 if (dm2->dmPublic.dmFields & DM_LOGPIXELS )
164 dm1->dmPublic.dmLogPixels = dm2->dmPublic.dmLogPixels;
165 if (dm2->dmPublic.dmFields & DM_ICMMETHOD )
166 dm1->dmPublic.dmICMMethod = dm2->dmPublic.dmICMMethod;
167 if (dm2->dmPublic.dmFields & DM_ICMINTENT )
168 dm1->dmPublic.dmICMIntent = dm2->dmPublic.dmICMIntent;
169 if (dm2->dmPublic.dmFields & DM_MEDIATYPE )
170 dm1->dmPublic.dmMediaType = dm2->dmPublic.dmMediaType;
171 if (dm2->dmPublic.dmFields & DM_DITHERTYPE )
172 dm1->dmPublic.dmDitherType = dm2->dmPublic.dmDitherType;
173 if (dm2->dmPublic.dmFields & DM_PANNINGWIDTH )
174 dm1->dmPublic.dmPanningWidth = dm2->dmPublic.dmPanningWidth;
175 if (dm2->dmPublic.dmFields & DM_PANNINGHEIGHT )
176 dm1->dmPublic.dmPanningHeight = dm2->dmPublic.dmPanningHeight;
182 /****************************************************************
185 * Dialog proc for 'Paper' propsheet
187 static INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg,
188 WPARAM wParam, LPARAM lParam)
197 di = (PSDRV_DLGINFO*)((PROPSHEETPAGEA*)lParam)->lParam;
198 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)di);
201 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
202 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
203 (LPARAM)ps->FullName);
204 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
208 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
210 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
211 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
212 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
213 IDD_ORIENT_LANDSCAPE);
215 if(!di->pi->ppd->Duplexes) {
216 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
217 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);
220 for(duplex = di->pi->ppd->Duplexes, i = 0; duplex; duplex = duplex->next, i++) {
221 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
222 (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
223 if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
226 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
231 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
232 switch(LOWORD(wParam)) {
234 if(HIWORD(wParam) == LBN_SELCHANGE) {
235 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
237 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
238 if(i >= Cursel) break;
241 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel, ps->WinPage);
242 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
243 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
246 case IDD_ORIENT_PORTRAIT:
247 case IDD_ORIENT_LANDSCAPE:
248 TRACE("Setting orientation to %s\n", wParam == IDD_ORIENT_PORTRAIT ?
249 "portrait" : "landscape");
250 di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
251 DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
252 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
255 if(HIWORD(wParam) == CBN_SELCHANGE) {
256 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
257 for(i = 0, duplex = di->pi->ppd->Duplexes; i < Cursel; i++, duplex = duplex->next)
259 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel, duplex->WinDuplex);
260 di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
261 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
269 NMHDR *nmhdr = (NMHDR *)lParam;
270 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
271 switch(nmhdr->code) {
273 *di->pi->Devmode = *di->dlgdm;
274 SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
290 static void (WINAPI *pInitCommonControls) (void);
291 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
292 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
295 /******************************************************************
296 * PSDRV_ExtDeviceMode
298 * Retrieves or modifies device-initialization information for the PostScript
299 * driver, or displays a driver-supplied dialog box for configuring the driver.
302 * lpszDriver -- Driver name
303 * hwnd -- Parent window for the dialog box
304 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
305 * lpszDevice -- Device name
306 * lpszPort -- Port name
307 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
308 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
309 * wMode -- Operation to perform. Can be a combination if > 0.
310 * (0) -- Returns number of bytes required by DEVMODE structure
311 * DM_UPDATE (1) -- Write current settings to environment and initialization file
312 * DM_COPY (2) -- Write current settings to lpdmOutput
313 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
314 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
317 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
318 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
319 * A return value less than zero is returned if a non-dialog operation fails.
323 * Just returns default devmode at the moment. No use of initialization file.
325 INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
326 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
327 LPSTR lpszProfile, DWORD dwMode)
329 PRINTERINFO *pi = PSDRV_FindPrinterInfo(lpszDevice);
332 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
333 lpszDriver, hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, debugstr_a(lpszProfile), dwMode);
335 /* If dwMode == 0, return size of DEVMODE structure */
337 return pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra;
339 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
340 if((dwMode & DM_MODIFY) && lpdmInput) {
341 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput->dmFields);
342 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
345 /* If DM_PROMPT is set, present modal dialog box */
346 if(dwMode & DM_PROMPT) {
347 HINSTANCE hinstComctl32;
348 HPROPSHEETPAGE hpsp[1];
350 PROPSHEETHEADERW psh;
352 PSDRV_DEVMODEA *dlgdm;
353 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
354 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
356 hinstComctl32 = LoadLibraryA("comctl32.dll");
357 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
358 "InitCommonControls");
359 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
360 "CreatePropertySheetPageW");
361 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
362 memset(&psp,0,sizeof(psp));
363 dlgdm = HeapAlloc( PSDRV_Heap, 0, sizeof(*dlgdm) );
364 *dlgdm = *pi->Devmode;
365 di = HeapAlloc( PSDRV_Heap, 0, sizeof(*di) );
368 psp.dwSize = sizeof(psp);
369 psp.hInstance = PSDRV_hInstance;
370 psp.u.pszTemplate = PAPERW;
371 psp.u2.pszIcon = NULL;
372 psp.pfnDlgProc = PSDRV_PaperDlgProc;
373 psp.lParam = (LPARAM)di;
374 hpsp[0] = pCreatePropertySheetPage(&psp);
376 memset(&psh, 0, sizeof(psh));
377 psh.dwSize = sizeof(psh);
378 psh.pszCaption = SetupW;
380 psh.hwndParent = hwnd;
381 psh.u3.phpage = hpsp;
383 pPropertySheet(&psh);
387 /* If DM_UPDATE is set, should write settings to environment and initialization file */
388 if(dwMode & DM_UPDATE)
389 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
391 /* If DM_COPY is set, should write settings to lpdmOutput */
392 if((dwMode & DM_COPY) || (dwMode & DM_UPDATE)) {
394 memcpy(lpdmOutput, pi->Devmode, pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra );
396 FIXME("lpdmOutput is NULL what should we do??\n");
400 /***********************************************************************
401 * PSDRV_DeviceCapabilities
403 * Retrieves the capabilities of a printer device driver.
406 * lpszDriver -- printer driver name
407 * lpszDevice -- printer name
408 * lpszPort -- port name
409 * fwCapability -- device capability
410 * lpszOutput -- output buffer
411 * lpDevMode -- device data buffer
414 * Result depends on the setting of fwCapability. -1 indicates failure.
416 DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
417 WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpDevMode)
422 pi = PSDRV_FindPrinterInfo(lpszDevice);
424 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver), debugstr_a(lpszDevice),
425 debugstr_a(lpszPort), fwCapability, lpszOutput, lpDevMode);
428 ERR("no printer info for %s %s, return 0!\n",
429 debugstr_a(lpszDriver), debugstr_a(lpszDevice));
433 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
435 switch(fwCapability) {
440 WORD *wp = (WORD *)lpszOutput;
443 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
445 TRACE("DC_PAPERS: %u\n", ps->WinPage);
447 if(lpszOutput != NULL)
456 POINT16 *pt = (POINT16 *)lpszOutput;
459 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
461 TRACE("DC_PAPERSIZE: %f x %f\n", ps->PaperDimension->x, ps->PaperDimension->y);
463 if(lpszOutput != NULL) {
464 pt->x = paper_size_from_points( ps->PaperDimension->x );
465 pt->y = paper_size_from_points( ps->PaperDimension->y );
475 char *cp = lpszOutput;
478 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
480 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps->FullName));
482 if(lpszOutput != NULL) {
483 lstrcpynA(cp, ps->FullName, 64);
491 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
496 WORD *wp = (WORD *)lpszOutput;
499 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
500 if(lpszOutput != NULL)
501 *wp++ = slot->WinBin;
508 char *cp = lpszOutput;
511 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
512 if(lpszOutput != NULL) {
513 lstrcpynA(cp, slot->FullName, 24);
520 FIXME("DC_BINADJUST: stub.\n");
521 return DCBA_FACEUPNONE;
523 case DC_ENUMRESOLUTIONS:
525 LONG *lp = (LONG*)lpszOutput;
527 if(lpszOutput != NULL) {
528 lp[0] = pi->ppd->DefaultResolution;
529 lp[1] = pi->ppd->DefaultResolution;
534 /* Windows returns 9999 too */
536 TRACE("DC_COPIES: returning 9999\n");
540 return lpdm->dmDriverVersion;
542 case DC_DATATYPE_PRODUCED:
543 FIXME("DATA_TYPE_PRODUCED: stub.\n");
544 return -1; /* simulate that the driver supports 'RAW' */
548 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
550 TRACE("DC_DUPLEX: returning %d\n", ret);
553 case DC_EMF_COMPLIANT:
554 FIXME("DC_EMF_COMPLIANT: stub.\n");
555 return -1; /* simulate that the driver do not support EMF */
558 return lpdm->dmDriverExtra;
561 return lpdm->dmFields;
563 case DC_FILEDEPENDENCIES:
564 FIXME("DC_FILEDEPENDENCIES: stub.\n");
572 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
574 if (ps->PaperDimension->x > x) x = ps->PaperDimension->x;
575 if (ps->PaperDimension->y > y) y = ps->PaperDimension->y;
577 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
583 float x = 1e6, y = 1e6;
585 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
587 if (ps->PaperDimension->x < x) x = ps->PaperDimension->x;
588 if (ps->PaperDimension->y < y) y = ps->PaperDimension->y;
590 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
597 FIXME("DC_TRUETYPE: stub\n");
601 return lpdm->dmSpecVersion;
603 /* We'll just return false here, very few printers can collate anyway */
605 TRACE("DC_COLLATE: returning FALSE\n");
608 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
610 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
612 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
613 case DC_MANUFACTURER:
614 FIXME("DC_MANUFACTURER: stub\n");
617 /* Identification number of the printer model for use with ICM (Win9x only) */
619 FIXME("DC_MODEL: stub\n");
622 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
623 case DC_STAPLE: /* WINVER >= 0x0500 */
624 FIXME("DC_STAPLE: stub\n");
627 /* Returns an array of 64-character string buffers containing the names of the paper forms
628 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
631 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
632 FIXME("DC_MEDIAREADY: stub\n");
635 /* Returns an array of 64-character string buffers containing the names of the supported
636 * media types, unless pOutput is NULL. The return value is the number of supported.
637 * media types (XP only)
639 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
640 FIXME("DC_MEDIATYPENAMES: stub\n");
643 /* Returns an array of DWORD values which represent the supported media types, unless
644 * pOutput is NULL. The return value is the number of supported media types. (XP only)
646 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
647 FIXME("DC_MEDIATYPES: stub\n");
650 /* Returns an array of DWORD values, each representing a supported number of document
651 * pages per printed page, unless pOutput is NULL. The return value is the number of
652 * array entries. (Win2k/XP only)
655 FIXME("DC_NUP: stub\n");
658 /* Returns an array of 32-character string buffers containing a list of printer description
659 * languages supported by the printer, unless pOutput is NULL. The return value is
660 * number of array entries. (Win2k/XP only)
663 case DC_PERSONALITY: /* WINVER >= 0x0500 */
664 FIXME("DC_PERSONALITY: stub\n");
667 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
668 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
669 FIXME("DC_PRINTERMEM: stub\n");
672 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
673 case DC_PRINTRATE: /* WINVER >= 0x0500 */
674 FIXME("DC_PRINTRATE: stub\n");
677 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
678 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
679 FIXME("DC_PRINTRATEPPM: stub\n");
682 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
683 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
685 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
686 FIXME("DC_PRINTRATEUNIT: stub\n");
690 FIXME("Unsupported capability %d\n", fwCapability);
699 HPROPSHEETPAGE hPages[10];
702 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
705 EDMPS *ps = pPropSheet;
708 psp->dwSize = sizeof(psp);
709 psp->hInstance = 0x1234;