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);
43 /************************************************************************
47 * Updates dm1 with some fields from dm2
50 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
53 /* some sanity checks here on dm2 */
55 if(dm2->dmPublic.dmFields & DM_ORIENTATION) {
56 dm1->dmPublic.u1.s1.dmOrientation = dm2->dmPublic.u1.s1.dmOrientation;
57 TRACE("Changing orientation to %d (%s)\n",
58 dm1->dmPublic.u1.s1.dmOrientation,
59 dm1->dmPublic.u1.s1.dmOrientation == DMORIENT_PORTRAIT ?
61 (dm1->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE ?
62 "Landscape" : "unknown"));
65 /* NB PaperWidth is always < PaperLength */
66 if(dm2->dmPublic.dmFields & DM_PAPERSIZE) {
69 LIST_FOR_EACH_ENTRY(page, &pi->ppd->PageSizes, PAGESIZE, entry) {
70 if(page->WinPage == dm2->dmPublic.u1.s1.dmPaperSize)
73 if(&page->entry != &pi->ppd->PageSizes ) {
74 dm1->dmPublic.u1.s1.dmPaperSize = dm2->dmPublic.u1.s1.dmPaperSize;
75 dm1->dmPublic.u1.s1.dmPaperWidth = page->PaperDimension->x *
77 dm1->dmPublic.u1.s1.dmPaperLength = page->PaperDimension->y *
79 dm1->dmPublic.dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH);
80 dm1->dmPublic.dmFields |= DM_PAPERSIZE;
81 TRACE("Changing page to %s %d x %d\n", page->FullName,
82 dm1->dmPublic.u1.s1.dmPaperWidth,
83 dm1->dmPublic.u1.s1.dmPaperLength );
85 TRACE("Trying to change to unsupported pagesize %d\n",
86 dm2->dmPublic.u1.s1.dmPaperSize);
88 } else if((dm2->dmPublic.dmFields & DM_PAPERLENGTH) &&
89 (dm2->dmPublic.dmFields & DM_PAPERWIDTH)) {
90 dm1->dmPublic.u1.s1.dmPaperLength = dm2->dmPublic.u1.s1.dmPaperLength;
91 dm1->dmPublic.u1.s1.dmPaperWidth = dm2->dmPublic.u1.s1.dmPaperWidth;
92 TRACE("Changing PaperLength|Width to %dx%d\n",
93 dm2->dmPublic.u1.s1.dmPaperLength,
94 dm2->dmPublic.u1.s1.dmPaperWidth);
95 dm1->dmPublic.dmFields &= ~DM_PAPERSIZE;
96 dm1->dmPublic.dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
97 } else if(dm2->dmPublic.dmFields & (DM_PAPERLENGTH | DM_PAPERWIDTH)) {
98 /* You might think that this would be allowed if dm1 is in custom size
99 mode, but apparently Windows reverts to standard paper mode even in
101 FIXME("Trying to change only paperlength or paperwidth\n");
102 dm1->dmPublic.dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH);
103 dm1->dmPublic.dmFields |= DM_PAPERSIZE;
106 if(dm2->dmPublic.dmFields & DM_SCALE) {
107 dm1->dmPublic.u1.s1.dmScale = dm2->dmPublic.u1.s1.dmScale;
108 TRACE("Changing Scale to %d\n", dm2->dmPublic.u1.s1.dmScale);
111 if(dm2->dmPublic.dmFields & DM_COPIES) {
112 dm1->dmPublic.u1.s1.dmCopies = dm2->dmPublic.u1.s1.dmCopies;
113 TRACE("Changing Copies to %d\n", dm2->dmPublic.u1.s1.dmCopies);
116 if(dm2->dmPublic.dmFields & DM_DEFAULTSOURCE) {
119 for(slot = pi->ppd->InputSlots; slot; slot = slot->next) {
120 if(slot->WinBin == dm2->dmPublic.u1.s1.dmDefaultSource)
124 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
125 TRACE("Changing bin to '%s'\n", slot->FullName);
127 TRACE("Trying to change to unsupported bin %d\n",
128 dm2->dmPublic.u1.s1.dmDefaultSource);
132 if (dm2->dmPublic.dmFields & DM_DEFAULTSOURCE )
133 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
134 if (dm2->dmPublic.dmFields & DM_PRINTQUALITY )
135 dm1->dmPublic.u1.s1.dmPrintQuality = dm2->dmPublic.u1.s1.dmPrintQuality;
136 if (dm2->dmPublic.dmFields & DM_COLOR )
137 dm1->dmPublic.dmColor = dm2->dmPublic.dmColor;
138 if (dm2->dmPublic.dmFields & DM_DUPLEX && pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
139 dm1->dmPublic.dmDuplex = dm2->dmPublic.dmDuplex;
140 if (dm2->dmPublic.dmFields & DM_YRESOLUTION )
141 dm1->dmPublic.dmYResolution = dm2->dmPublic.dmYResolution;
142 if (dm2->dmPublic.dmFields & DM_TTOPTION )
143 dm1->dmPublic.dmTTOption = dm2->dmPublic.dmTTOption;
144 if (dm2->dmPublic.dmFields & DM_COLLATE )
145 dm1->dmPublic.dmCollate = dm2->dmPublic.dmCollate;
146 if (dm2->dmPublic.dmFields & DM_FORMNAME )
147 lstrcpynA((LPSTR)dm1->dmPublic.dmFormName, (LPCSTR)dm2->dmPublic.dmFormName, CCHFORMNAME);
148 if (dm2->dmPublic.dmFields & DM_BITSPERPEL )
149 dm1->dmPublic.dmBitsPerPel = dm2->dmPublic.dmBitsPerPel;
150 if (dm2->dmPublic.dmFields & DM_PELSWIDTH )
151 dm1->dmPublic.dmPelsWidth = dm2->dmPublic.dmPelsWidth;
152 if (dm2->dmPublic.dmFields & DM_PELSHEIGHT )
153 dm1->dmPublic.dmPelsHeight = dm2->dmPublic.dmPelsHeight;
154 if (dm2->dmPublic.dmFields & DM_DISPLAYFLAGS )
155 dm1->dmPublic.u2.dmDisplayFlags = dm2->dmPublic.u2.dmDisplayFlags;
156 if (dm2->dmPublic.dmFields & DM_DISPLAYFREQUENCY )
157 dm1->dmPublic.dmDisplayFrequency = dm2->dmPublic.dmDisplayFrequency;
158 if (dm2->dmPublic.dmFields & DM_POSITION )
159 dm1->dmPublic.u1.s2.dmPosition = dm2->dmPublic.u1.s2.dmPosition;
160 if (dm2->dmPublic.dmFields & DM_LOGPIXELS )
161 dm1->dmPublic.dmLogPixels = dm2->dmPublic.dmLogPixels;
162 if (dm2->dmPublic.dmFields & DM_ICMMETHOD )
163 dm1->dmPublic.dmICMMethod = dm2->dmPublic.dmICMMethod;
164 if (dm2->dmPublic.dmFields & DM_ICMINTENT )
165 dm1->dmPublic.dmICMIntent = dm2->dmPublic.dmICMIntent;
166 if (dm2->dmPublic.dmFields & DM_MEDIATYPE )
167 dm1->dmPublic.dmMediaType = dm2->dmPublic.dmMediaType;
168 if (dm2->dmPublic.dmFields & DM_DITHERTYPE )
169 dm1->dmPublic.dmDitherType = dm2->dmPublic.dmDitherType;
170 if (dm2->dmPublic.dmFields & DM_PANNINGWIDTH )
171 dm1->dmPublic.dmPanningWidth = dm2->dmPublic.dmPanningWidth;
172 if (dm2->dmPublic.dmFields & DM_PANNINGHEIGHT )
173 dm1->dmPublic.dmPanningHeight = dm2->dmPublic.dmPanningHeight;
179 /****************************************************************
182 * Dialog proc for 'Paper' propsheet
184 static INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg,
185 WPARAM wParam, LPARAM lParam)
194 di = (PSDRV_DLGINFO*)((PROPSHEETPAGEA*)lParam)->lParam;
195 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)di);
198 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
199 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
200 (LPARAM)ps->FullName);
201 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
205 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
207 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
208 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
209 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
210 IDD_ORIENT_LANDSCAPE);
212 if(!di->pi->ppd->Duplexes) {
213 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
214 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);
217 for(duplex = di->pi->ppd->Duplexes, i = 0; duplex; duplex = duplex->next, i++) {
218 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
219 (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
220 if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
223 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
228 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
229 switch(LOWORD(wParam)) {
231 if(HIWORD(wParam) == LBN_SELCHANGE) {
232 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
234 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
235 if(i >= Cursel) break;
238 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel, ps->WinPage);
239 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
240 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
243 case IDD_ORIENT_PORTRAIT:
244 case IDD_ORIENT_LANDSCAPE:
245 TRACE("Setting orientation to %s\n", wParam == IDD_ORIENT_PORTRAIT ?
246 "portrait" : "landscape");
247 di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
248 DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
249 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
252 if(HIWORD(wParam) == CBN_SELCHANGE) {
253 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
254 for(i = 0, duplex = di->pi->ppd->Duplexes; i < Cursel; i++, duplex = duplex->next)
256 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel, duplex->WinDuplex);
257 di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
258 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
266 NMHDR *nmhdr = (NMHDR *)lParam;
267 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
268 switch(nmhdr->code) {
270 *di->pi->Devmode = *di->dlgdm;
271 SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
287 static void (WINAPI *pInitCommonControls) (void);
288 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
289 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
292 /******************************************************************
293 * PSDRV_ExtDeviceMode
295 * Retrieves or modifies device-initialization information for the PostScript
296 * driver, or displays a driver-supplied dialog box for configuring the driver.
299 * lpszDriver -- Driver name
300 * hwnd -- Parent window for the dialog box
301 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
302 * lpszDevice -- Device name
303 * lpszPort -- Port name
304 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
305 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
306 * wMode -- Operation to perform. Can be a combination if > 0.
307 * (0) -- Returns number of bytes required by DEVMODE structure
308 * DM_UPDATE (1) -- Write current settings to environment and initialization file
309 * DM_COPY (2) -- Write current settings to lpdmOutput
310 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
311 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
314 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
315 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
316 * A return value less than zero is returned if a non-dialog operation fails.
320 * Just returns default devmode at the moment. No use of initialization file.
322 INT CDECL PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
323 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
324 LPSTR lpszProfile, DWORD dwMode)
326 PRINTERINFO *pi = PSDRV_FindPrinterInfo(lpszDevice);
329 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
330 lpszDriver, hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, debugstr_a(lpszProfile), dwMode);
332 /* If dwMode == 0, return size of DEVMODE structure */
334 return pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra;
336 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
337 if((dwMode & DM_MODIFY) && lpdmInput) {
338 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput->dmFields);
339 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
342 /* If DM_PROMPT is set, present modal dialog box */
343 if(dwMode & DM_PROMPT) {
344 HINSTANCE hinstComctl32;
345 HPROPSHEETPAGE hpsp[1];
347 PROPSHEETHEADERW psh;
349 PSDRV_DEVMODEA *dlgdm;
350 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
351 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
353 hinstComctl32 = LoadLibraryA("comctl32.dll");
354 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
355 "InitCommonControls");
356 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
357 "CreatePropertySheetPageW");
358 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
359 memset(&psp,0,sizeof(psp));
360 dlgdm = HeapAlloc( PSDRV_Heap, 0, sizeof(*dlgdm) );
361 *dlgdm = *pi->Devmode;
362 di = HeapAlloc( PSDRV_Heap, 0, sizeof(*di) );
365 psp.dwSize = sizeof(psp);
366 psp.hInstance = PSDRV_hInstance;
367 psp.u.pszTemplate = PAPERW;
368 psp.u2.pszIcon = NULL;
369 psp.pfnDlgProc = PSDRV_PaperDlgProc;
370 psp.lParam = (LPARAM)di;
371 hpsp[0] = pCreatePropertySheetPage(&psp);
373 memset(&psh, 0, sizeof(psh));
374 psh.dwSize = sizeof(psh);
375 psh.pszCaption = SetupW;
377 psh.hwndParent = hwnd;
378 psh.u3.phpage = hpsp;
380 pPropertySheet(&psh);
384 /* If DM_UPDATE is set, should write settings to environment and initialization file */
385 if(dwMode & DM_UPDATE)
386 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
388 /* If DM_COPY is set, should write settings to lpdmOutput */
389 if((dwMode & DM_COPY) || (dwMode & DM_UPDATE)) {
391 memcpy(lpdmOutput, pi->Devmode, pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra );
393 FIXME("lpdmOutput is NULL what should we do??\n");
397 /***********************************************************************
398 * PSDRV_DeviceCapabilities
400 * Retrieves the capabilities of a printer device driver.
403 * lpszDriver -- printer driver name
404 * lpszDevice -- printer name
405 * lpszPort -- port name
406 * fwCapability -- device capability
407 * lpszOutput -- output buffer
408 * lpDevMode -- device data buffer
411 * Result depends on the setting of fwCapability. -1 indicates failure.
413 DWORD CDECL PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
414 WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpDevMode)
419 pi = PSDRV_FindPrinterInfo(lpszDevice);
421 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver), debugstr_a(lpszDevice),
422 debugstr_a(lpszPort), fwCapability, lpszOutput, lpDevMode);
425 ERR("no printer info for %s %s, return 0!\n",
426 debugstr_a(lpszDriver), debugstr_a(lpszDevice));
430 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
432 switch(fwCapability) {
437 WORD *wp = (WORD *)lpszOutput;
440 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
442 TRACE("DC_PAPERS: %u\n", ps->WinPage);
444 if(lpszOutput != NULL)
453 POINT16 *pt = (POINT16 *)lpszOutput;
456 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
458 TRACE("DC_PAPERSIZE: %f x %f\n", ps->PaperDimension->x, ps->PaperDimension->y);
460 if(lpszOutput != NULL) {
461 pt->x = ps->PaperDimension->x * 254.0 / 72.0;
462 pt->y = ps->PaperDimension->y * 254.0 / 72.0;
472 char *cp = lpszOutput;
475 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
477 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps->FullName));
479 if(lpszOutput != NULL) {
480 lstrcpynA(cp, ps->FullName, 64);
488 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
493 WORD *wp = (WORD *)lpszOutput;
496 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
497 if(lpszOutput != NULL)
498 *wp++ = slot->WinBin;
505 char *cp = lpszOutput;
508 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
509 if(lpszOutput != NULL) {
510 lstrcpynA(cp, slot->FullName, 24);
517 FIXME("DC_BINADJUST: stub.\n");
518 return DCBA_FACEUPNONE;
520 case DC_ENUMRESOLUTIONS:
522 LONG *lp = (LONG*)lpszOutput;
524 if(lpszOutput != NULL) {
525 lp[0] = pi->ppd->DefaultResolution;
526 lp[1] = pi->ppd->DefaultResolution;
531 /* Windows returns 9999 too */
533 TRACE("DC_COPIES: returning 9999\n");
537 return lpdm->dmDriverVersion;
539 case DC_DATATYPE_PRODUCED:
540 FIXME("DATA_TYPE_PRODUCED: stub.\n");
541 return -1; /* simulate that the driver supports 'RAW' */
545 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
547 TRACE("DC_DUPLEX: returning %d\n", ret);
550 case DC_EMF_COMPLIANT:
551 FIXME("DC_EMF_COMPLIANT: stub.\n");
552 return -1; /* simulate that the driver do not support EMF */
555 return lpdm->dmDriverExtra;
558 return lpdm->dmFields;
560 case DC_FILEDEPENDENCIES:
561 FIXME("DC_FILEDEPENDENCIES: stub.\n");
568 ptMax.x = ptMax.y = 0;
570 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
572 if(ps->PaperDimension->x > ptMax.x)
573 ptMax.x = ps->PaperDimension->x;
574 if(ps->PaperDimension->y > ptMax.y)
575 ptMax.y = ps->PaperDimension->y;
577 return MAKELONG(ptMax.x * 254.0 / 72.0, ptMax.y * 254.0 / 72.0 );
584 ptMin.x = ptMin.y = -1;
586 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
588 if(ptMin.x == -1 || ps->PaperDimension->x < ptMin.x)
589 ptMin.x = ps->PaperDimension->x;
590 if(ptMin.y == -1 || ps->PaperDimension->y < ptMin.y)
591 ptMin.y = ps->PaperDimension->y;
593 return MAKELONG(ptMin.x * 254.0 / 72.0, ptMin.y * 254.0 / 72.0);
600 FIXME("DC_TRUETYPE: stub\n");
604 return lpdm->dmSpecVersion;
606 /* We'll just return false here, very few printers can collate anyway */
608 TRACE("DC_COLLATE: returning FALSE\n");
611 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
613 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
615 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
616 case DC_MANUFACTURER:
617 FIXME("DC_MANUFACTURER: stub\n");
620 /* Identification number of the printer model for use with ICM (Win9x only) */
622 FIXME("DC_MODEL: stub\n");
625 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
626 case DC_STAPLE: /* WINVER >= 0x0500 */
627 FIXME("DC_STAPLE: stub\n");
630 /* Returns an array of 64-character string buffers containing the names of the paper forms
631 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
634 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
635 FIXME("DC_MEDIAREADY: stub\n");
638 /* Returns an array of 64-character string buffers containing the names of the supported
639 * media types, unless pOutput is NULL. The return value is the number of supported.
640 * media types (XP only)
642 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
643 FIXME("DC_MEDIATYPENAMES: stub\n");
646 /* Returns an array of DWORD values which represent the supported media types, unless
647 * pOutput is NULL. The return value is the number of supported media types. (XP only)
649 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
650 FIXME("DC_MEDIATYPES: stub\n");
653 /* Returns an array of DWORD values, each representing a supported number of document
654 * pages per printed page, unless pOutput is NULL. The return value is the number of
655 * array entries. (Win2k/XP only)
658 FIXME("DC_NUP: stub\n");
661 /* Returns an array of 32-character string buffers containing a list of printer description
662 * languages supported by the printer, unless pOutput is NULL. The return value is
663 * number of array entries. (Win2k/XP only)
666 case DC_PERSONALITY: /* WINVER >= 0x0500 */
667 FIXME("DC_PERSONALITY: stub\n");
670 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
671 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
672 FIXME("DC_PRINTERMEM: stub\n");
675 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
676 case DC_PRINTRATE: /* WINVER >= 0x0500 */
677 FIXME("DC_PRINTRATE: stub\n");
680 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
681 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
682 FIXME("DC_PRINTRATEPPM: stub\n");
685 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
686 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
688 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
689 FIXME("DC_PRINTRATEUNIT: stub\n");
693 FIXME("Unsupported capability %d\n", fwCapability);
702 HPROPSHEETPAGE hPages[10];
705 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
708 EDMPS *ps = pPropSheet;
711 psp->dwSize = sizeof(psp);
712 psp->hInstance = 0x1234;