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;
185 PSDRV_DEVMODEA *dlgdm;
188 /****************************************************************
191 * Dialog proc for 'Paper' propsheet
193 static INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg,
194 WPARAM wParam, LPARAM lParam)
203 di = (PSDRV_DLGINFO*)((PROPSHEETPAGEA*)lParam)->lParam;
204 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)di);
207 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
208 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
209 (LPARAM)ps->FullName);
210 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
214 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
216 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
217 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
218 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
219 IDD_ORIENT_LANDSCAPE);
221 if(!di->pi->ppd->Duplexes) {
222 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
223 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);
226 for(duplex = di->pi->ppd->Duplexes, i = 0; duplex; duplex = duplex->next, i++) {
227 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
228 (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
229 if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
232 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
237 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
238 switch(LOWORD(wParam)) {
240 if(HIWORD(wParam) == LBN_SELCHANGE) {
241 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
243 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
244 if(i >= Cursel) break;
247 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel, ps->WinPage);
248 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
249 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
252 case IDD_ORIENT_PORTRAIT:
253 case IDD_ORIENT_LANDSCAPE:
254 TRACE("Setting orientation to %s\n", wParam == IDD_ORIENT_PORTRAIT ?
255 "portrait" : "landscape");
256 di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
257 DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
258 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
261 if(HIWORD(wParam) == CBN_SELCHANGE) {
262 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
263 for(i = 0, duplex = di->pi->ppd->Duplexes; i < Cursel; i++, duplex = duplex->next)
265 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel, duplex->WinDuplex);
266 di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
267 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
275 NMHDR *nmhdr = (NMHDR *)lParam;
276 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
277 switch(nmhdr->code) {
279 *di->pi->Devmode = *di->dlgdm;
280 SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
296 static void (WINAPI *pInitCommonControls) (void);
297 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
298 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
300 static PRINTERINFO *PSDRV_FindPrinterInfoA(LPCSTR name)
302 int len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
303 WCHAR *nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
306 MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
307 pi = PSDRV_FindPrinterInfo( nameW );
308 HeapFree( GetProcessHeap(), 0, nameW );
313 /******************************************************************
314 * PSDRV_ExtDeviceMode
316 * Retrieves or modifies device-initialization information for the PostScript
317 * driver, or displays a driver-supplied dialog box for configuring the driver.
320 * lpszDriver -- Driver name
321 * hwnd -- Parent window for the dialog box
322 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
323 * lpszDevice -- Device name
324 * lpszPort -- Port name
325 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
326 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
327 * wMode -- Operation to perform. Can be a combination if > 0.
328 * (0) -- Returns number of bytes required by DEVMODE structure
329 * DM_UPDATE (1) -- Write current settings to environment and initialization file
330 * DM_COPY (2) -- Write current settings to lpdmOutput
331 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
332 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
335 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
336 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
337 * A return value less than zero is returned if a non-dialog operation fails.
341 * Just returns default devmode at the moment. No use of initialization file.
343 INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
344 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
345 LPSTR lpszProfile, DWORD dwMode)
347 PRINTERINFO *pi = PSDRV_FindPrinterInfoA(lpszDevice);
350 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
351 lpszDriver, hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, debugstr_a(lpszProfile), dwMode);
353 /* If dwMode == 0, return size of DEVMODE structure */
355 return pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra;
357 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
358 if((dwMode & DM_MODIFY) && lpdmInput) {
359 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput->dmFields);
360 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
363 /* If DM_PROMPT is set, present modal dialog box */
364 if(dwMode & DM_PROMPT) {
365 HINSTANCE hinstComctl32;
366 HPROPSHEETPAGE hpsp[1];
368 PROPSHEETHEADERW psh;
370 PSDRV_DEVMODEA dlgdm;
371 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
372 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
374 hinstComctl32 = LoadLibraryA("comctl32.dll");
375 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
376 "InitCommonControls");
377 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
378 "CreatePropertySheetPageW");
379 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
380 memset(&psp,0,sizeof(psp));
381 dlgdm = *pi->Devmode;
384 psp.dwSize = sizeof(psp);
385 psp.hInstance = PSDRV_hInstance;
386 psp.u.pszTemplate = PAPERW;
387 psp.u2.pszIcon = NULL;
388 psp.pfnDlgProc = PSDRV_PaperDlgProc;
389 psp.lParam = (LPARAM)&di;
390 hpsp[0] = pCreatePropertySheetPage(&psp);
392 memset(&psh, 0, sizeof(psh));
393 psh.dwSize = sizeof(psh);
394 psh.pszCaption = SetupW;
396 psh.hwndParent = hwnd;
397 psh.u3.phpage = hpsp;
399 pPropertySheet(&psh);
403 /* If DM_UPDATE is set, should write settings to environment and initialization file */
404 if(dwMode & DM_UPDATE)
405 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
407 /* If DM_COPY is set, should write settings to lpdmOutput */
408 if((dwMode & DM_COPY) || (dwMode & DM_UPDATE)) {
410 memcpy(lpdmOutput, pi->Devmode, pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra );
412 FIXME("lpdmOutput is NULL what should we do??\n");
416 /***********************************************************************
417 * PSDRV_DeviceCapabilities
419 * Retrieves the capabilities of a printer device driver.
422 * lpszDriver -- printer driver name
423 * lpszDevice -- printer name
424 * lpszPort -- port name
425 * fwCapability -- device capability
426 * lpszOutput -- output buffer
427 * lpDevMode -- device data buffer
430 * Result depends on the setting of fwCapability. -1 indicates failure.
432 DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
433 WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpDevMode)
438 pi = PSDRV_FindPrinterInfoA(lpszDevice);
440 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver), debugstr_a(lpszDevice),
441 debugstr_a(lpszPort), fwCapability, lpszOutput, lpDevMode);
444 ERR("no printer info for %s %s, return 0!\n",
445 debugstr_a(lpszDriver), debugstr_a(lpszDevice));
449 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
451 switch(fwCapability) {
456 WORD *wp = (WORD *)lpszOutput;
459 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
461 TRACE("DC_PAPERS: %u\n", ps->WinPage);
463 if(lpszOutput != NULL)
472 POINT16 *pt = (POINT16 *)lpszOutput;
475 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
477 TRACE("DC_PAPERSIZE: %f x %f\n", ps->PaperDimension->x, ps->PaperDimension->y);
479 if(lpszOutput != NULL) {
480 pt->x = paper_size_from_points( ps->PaperDimension->x );
481 pt->y = paper_size_from_points( ps->PaperDimension->y );
491 char *cp = lpszOutput;
494 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
496 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps->FullName));
498 if(lpszOutput != NULL) {
499 lstrcpynA(cp, ps->FullName, 64);
507 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
512 WORD *wp = (WORD *)lpszOutput;
515 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
516 if(lpszOutput != NULL)
517 *wp++ = slot->WinBin;
524 char *cp = lpszOutput;
527 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
528 if(lpszOutput != NULL) {
529 lstrcpynA(cp, slot->FullName, 24);
536 FIXME("DC_BINADJUST: stub.\n");
537 return DCBA_FACEUPNONE;
539 case DC_ENUMRESOLUTIONS:
541 LONG *lp = (LONG*)lpszOutput;
543 if(lpszOutput != NULL) {
544 lp[0] = pi->ppd->DefaultResolution;
545 lp[1] = pi->ppd->DefaultResolution;
550 /* Windows returns 9999 too */
552 TRACE("DC_COPIES: returning 9999\n");
556 return lpdm->dmDriverVersion;
558 case DC_DATATYPE_PRODUCED:
559 FIXME("DATA_TYPE_PRODUCED: stub.\n");
560 return -1; /* simulate that the driver supports 'RAW' */
564 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
566 TRACE("DC_DUPLEX: returning %d\n", ret);
569 case DC_EMF_COMPLIANT:
570 FIXME("DC_EMF_COMPLIANT: stub.\n");
571 return -1; /* simulate that the driver do not support EMF */
574 return lpdm->dmDriverExtra;
577 return lpdm->dmFields;
579 case DC_FILEDEPENDENCIES:
580 FIXME("DC_FILEDEPENDENCIES: stub.\n");
588 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
590 if (ps->PaperDimension->x > x) x = ps->PaperDimension->x;
591 if (ps->PaperDimension->y > y) y = ps->PaperDimension->y;
593 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
599 float x = 1e6, y = 1e6;
601 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
603 if (ps->PaperDimension->x < x) x = ps->PaperDimension->x;
604 if (ps->PaperDimension->y < y) y = ps->PaperDimension->y;
606 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
613 FIXME("DC_TRUETYPE: stub\n");
617 return lpdm->dmSpecVersion;
619 /* We'll just return false here, very few printers can collate anyway */
621 TRACE("DC_COLLATE: returning FALSE\n");
624 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
626 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
628 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
629 case DC_MANUFACTURER:
630 FIXME("DC_MANUFACTURER: stub\n");
633 /* Identification number of the printer model for use with ICM (Win9x only) */
635 FIXME("DC_MODEL: stub\n");
638 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
639 case DC_STAPLE: /* WINVER >= 0x0500 */
640 FIXME("DC_STAPLE: stub\n");
643 /* Returns an array of 64-character string buffers containing the names of the paper forms
644 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
647 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
648 FIXME("DC_MEDIAREADY: stub\n");
651 /* Returns an array of 64-character string buffers containing the names of the supported
652 * media types, unless pOutput is NULL. The return value is the number of supported.
653 * media types (XP only)
655 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
656 FIXME("DC_MEDIATYPENAMES: stub\n");
659 /* Returns an array of DWORD values which represent the supported media types, unless
660 * pOutput is NULL. The return value is the number of supported media types. (XP only)
662 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
663 FIXME("DC_MEDIATYPES: stub\n");
666 /* Returns an array of DWORD values, each representing a supported number of document
667 * pages per printed page, unless pOutput is NULL. The return value is the number of
668 * array entries. (Win2k/XP only)
671 FIXME("DC_NUP: stub\n");
674 /* Returns an array of 32-character string buffers containing a list of printer description
675 * languages supported by the printer, unless pOutput is NULL. The return value is
676 * number of array entries. (Win2k/XP only)
679 case DC_PERSONALITY: /* WINVER >= 0x0500 */
680 FIXME("DC_PERSONALITY: stub\n");
683 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
684 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
685 FIXME("DC_PRINTERMEM: stub\n");
688 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
689 case DC_PRINTRATE: /* WINVER >= 0x0500 */
690 FIXME("DC_PRINTRATE: stub\n");
693 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
694 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
695 FIXME("DC_PRINTRATEPPM: stub\n");
698 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
699 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
701 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
702 FIXME("DC_PRINTRATEUNIT: stub\n");
706 FIXME("Unsupported capability %d\n", fwCapability);
715 HPROPSHEETPAGE hPages[10];
718 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
721 EDMPS *ps = pPropSheet;
724 psp->dwSize = sizeof(psp);
725 psp->hInstance = 0x1234;