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 for(page = pi->ppd->PageSizes; page; page = page->next) {
71 if(page->WinPage == dm2->dmPublic.u1.s1.dmPaperSize)
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);
211 for(ps = di->pi->ppd->PageSizes, i = 0; ps; ps = ps->next, i++) {
212 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
213 (LPARAM)ps->FullName);
214 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
217 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
219 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
220 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
221 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
222 IDD_ORIENT_LANDSCAPE);
224 if(!di->pi->ppd->Duplexes) {
225 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
226 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);
229 for(duplex = di->pi->ppd->Duplexes, i = 0; duplex; duplex = duplex->next, i++) {
230 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
231 (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
232 if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
235 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
240 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
241 switch(LOWORD(wParam)) {
243 if(HIWORD(wParam) == LBN_SELCHANGE) {
244 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
245 for(i = 0, ps = di->pi->ppd->PageSizes; i < Cursel; i++, ps = ps->next)
247 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel,
249 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
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;
260 if(HIWORD(wParam) == CBN_SELCHANGE) {
261 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
262 for(i = 0, duplex = di->pi->ppd->Duplexes; i < Cursel; i++, duplex = duplex->next)
264 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel,
266 di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
274 NMHDR *nmhdr = (NMHDR *)lParam;
275 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
276 switch(nmhdr->code) {
278 memcpy(di->pi->Devmode, di->dlgdm, sizeof(PSDRV_DEVMODEA));
279 SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
295 static void (WINAPI *pInitCommonControls) (void);
296 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
297 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
300 /******************************************************************
301 * PSDRV_ExtDeviceMode
303 * Retrieves or modifies device-initialization information for the PostScript
304 * driver, or displays a driver-supplied dialog box for configuring the driver.
307 * lpszDriver -- Driver name
308 * hwnd -- Parent window for the dialog box
309 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
310 * lpszDevice -- Device name
311 * lpszPort -- Port name
312 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
313 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
314 * wMode -- Operation to perform. Can be a combination if > 0.
315 * (0) -- Returns number of bytes required by DEVMODE structure
316 * DM_UPDATE (1) -- Write current settings to environment and initialization file
317 * DM_COPY (2) -- Write current settings to lpdmOutput
318 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
319 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
322 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
323 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
324 * A return value less than zero is returned if a non-dialog operation fails.
328 * Just returns default devmode at the moment. No use of initialization file.
330 INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
331 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
332 LPSTR lpszProfile, DWORD dwMode)
334 PRINTERINFO *pi = PSDRV_FindPrinterInfo(lpszDevice);
337 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
338 lpszDriver, hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, lpszProfile, dwMode);
340 /* If dwMode == 0, return size of DEVMODE structure */
342 return pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra;
344 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
345 if((dwMode & DM_MODIFY) && lpdmInput) {
346 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput->dmFields);
347 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
350 /* If DM_PROMPT is set, present modal dialog box */
351 if(dwMode & DM_PROMPT) {
352 HINSTANCE hinstComctl32;
353 HPROPSHEETPAGE hpsp[1];
355 PROPSHEETHEADERW psh;
357 PSDRV_DEVMODEA *dlgdm;
358 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
359 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
361 hinstComctl32 = LoadLibraryA("comctl32.dll");
362 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
363 "InitCommonControls");
364 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
365 "CreatePropertySheetPageW");
366 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
367 memset(&psp,0,sizeof(psp));
368 dlgdm = HeapAlloc( PSDRV_Heap, 0, sizeof(*dlgdm) );
369 memcpy(dlgdm, pi->Devmode, sizeof(*dlgdm));
370 di = HeapAlloc( PSDRV_Heap, 0, sizeof(*di) );
373 psp.dwSize = sizeof(psp);
374 psp.hInstance = PSDRV_hInstance;
375 psp.u.pszTemplate = PAPERW;
376 psp.u2.pszIcon = NULL;
377 psp.pfnDlgProc = PSDRV_PaperDlgProc;
378 psp.lParam = (LPARAM)di;
379 hpsp[0] = pCreatePropertySheetPage(&psp);
381 memset(&psh, 0, sizeof(psh));
382 psh.dwSize = sizeof(psh);
383 psh.pszCaption = SetupW;
385 psh.hwndParent = HWND_32(hwnd);
386 psh.u3.phpage = hpsp;
388 pPropertySheet(&psh);
392 /* If DM_UPDATE is set, should write settings to environment and initialization file */
393 if(dwMode & DM_UPDATE)
394 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
396 /* If DM_COPY is set, should write settings to lpdmOutput */
397 if((dwMode & DM_COPY) || (dwMode & DM_UPDATE)) {
399 memcpy(lpdmOutput, pi->Devmode, pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra );
401 FIXME("lpdmOutput is NULL what should we do??\n");
405 /***************************************************************
406 * ExtDeviceMode [WINEPS16.90]
410 INT16 WINAPI PSDRV_ExtDeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
411 LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
412 LPSTR lpszPort, LPDEVMODEA lpdmInput,
413 LPSTR lpszProfile, WORD fwMode)
416 return PSDRV_ExtDeviceMode(NULL, HWND_32(hwnd), lpdmOutput, lpszDevice,
417 lpszPort, lpdmInput, lpszProfile, (DWORD) fwMode);
420 /***********************************************************************
421 * PSDRV_DeviceCapabilities
423 * Retrieves the capabilities of a printer device driver.
426 * lpszDriver -- printer driver name
427 * lpszDevice -- printer name
428 * lpszPort -- port name
429 * fwCapability -- device capability
430 * lpszOutput -- output buffer
431 * lpDevMode -- device data buffer
434 * Result depends on the setting of fwCapability. -1 indicates failure.
436 DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
437 WORD fwCapability, LPSTR lpszOutput,
438 LPDEVMODEA lpDevMode)
443 pi = PSDRV_FindPrinterInfo(lpszDevice);
445 TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability, pi);
449 ERR("no printerinfo for %s, return 0!\n",lpszDevice);
454 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
456 switch(fwCapability) {
461 WORD *wp = (WORD *)lpszOutput;
464 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
465 if(lpszOutput != NULL)
473 POINT16 *pt = (POINT16 *)lpszOutput;
476 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
477 if(lpszOutput != NULL) {
478 pt->x = ps->PaperDimension->x * 254.0 / 72.0;
479 pt->y = ps->PaperDimension->y * 254.0 / 72.0;
488 char *cp = lpszOutput;
491 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
492 if(lpszOutput != NULL) {
493 lstrcpynA(cp, ps->FullName, 64);
500 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
505 WORD *wp = (WORD *)lpszOutput;
508 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
509 if(lpszOutput != NULL)
510 *wp++ = slot->WinBin;
517 char *cp = lpszOutput;
520 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
521 if(lpszOutput != NULL) {
522 lstrcpynA(cp, slot->FullName, 24);
529 FIXME("DC_BINADJUST: stub.\n");
530 return DCBA_FACEUPNONE;
532 case DC_ENUMRESOLUTIONS:
534 LONG *lp = (LONG*)lpszOutput;
536 if(lpszOutput != NULL) {
537 lp[0] = (LONG)pi->ppd->DefaultResolution;
538 lp[1] = (LONG)pi->ppd->DefaultResolution;
543 /* Windows returns 9999 too */
545 TRACE("DC_COPIES: returning 9999\n");
549 return lpdm->dmDriverVersion;
551 case DC_DATATYPE_PRODUCED:
552 FIXME("DATA_TYPE_PRODUCED: stub.\n");
553 return -1; /* simulate that the driver supports 'RAW' */
557 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
559 TRACE("DC_DUPLEX: returning %d\n", ret);
562 case DC_EMF_COMPLIANT:
563 FIXME("DC_EMF_COMPLIANT: stub.\n");
564 return -1; /* simulate that the driver do not support EMF */
567 return lpdm->dmDriverExtra;
570 return lpdm->dmFields;
572 case DC_FILEDEPENDENCIES:
573 FIXME("DC_FILEDEPENDENCIES: stub.\n");
581 ptMax.x = ptMax.y = 0;
583 if(lpszOutput == NULL)
587 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
588 if(ps->PaperDimension->x > ptMax.x)
589 ptMax.x = ps->PaperDimension->x;
590 if(ps->PaperDimension->y > ptMax.y)
591 ptMax.y = ps->PaperDimension->y;
593 *((POINT*)lpszOutput) = ptMax;
602 ptMax.x = ptMax.y = 0;
604 if(lpszOutput == NULL)
608 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
609 if(ps->PaperDimension->x > ptMax.x)
610 ptMax.x = ps->PaperDimension->x;
611 if(ps->PaperDimension->y > ptMax.y)
612 ptMax.y = ps->PaperDimension->y;
614 *((POINT*)lpszOutput) = ptMax;
622 FIXME("DC_TRUETYPE: stub\n");
626 return lpdm->dmSpecVersion;
628 /* We'll just return false here, very few printers can collate anyway */
630 TRACE("DC_COLLATE: returning FALSE\n");
633 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
635 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
637 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
638 case DC_MANUFACTURER:
639 FIXME("DC_MANUFACTURER: stub\n");
642 /* Identification number of the printer model for use with ICM (Win9x only) */
644 FIXME("DC_MODEL: stub\n");
647 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
648 case DC_STAPLE: /* WINVER >= 0x0500 */
649 FIXME("DC_STAPLE: stub\n");
652 /* Returns an array of 64-character string buffers containing the names of the paper forms
653 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
656 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
657 FIXME("DC_MEDIAREADY: stub\n");
660 /* Returns an array of 64-character string buffers containing the names of the supported
661 * media types, unless pOutput is NULL. The return value is the number of supported.
662 * media types (XP only)
664 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
665 FIXME("DC_MEDIATYPENAMES: stub\n");
668 /* Returns an array of DWORD values which represent the supported media types, unless
669 * pOutput is NULL. The return value is the number of supported media types. (XP only)
671 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
672 FIXME("DC_MEDIATYPES: stub\n");
675 /* Returns an array of DWORD values, each representing a supported number of document
676 * pages per printed page, unless pOutput is NULL. The return value is the number of
677 * array entries. (Win2k/XP only)
680 FIXME("DC_NUP: stub\n");
683 /* Returns an array of 32-character string buffers containing a list of printer description
684 * languages supported by the printer, unless pOutput is NULL. The return value is
685 * number of array entries. (Win2k/XP only)
688 case DC_PERSONALITY: /* WINVER >= 0x0500 */
689 FIXME("DC_PERSONALITY: stub\n");
692 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
693 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
694 FIXME("DC_PRINTERMEM: stub\n");
697 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
698 case DC_PRINTRATE: /* WINVER >= 0x0500 */
699 FIXME("DC_PRINTRATE: stub\n");
702 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
703 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
704 FIXME("DC_PRINTRATEPPM: stub\n");
707 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
708 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
710 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
711 FIXME("DC_PRINTRATEUNIT: stub\n");
715 FIXME("Unsupported capability %d\n", fwCapability);
720 /**************************************************************
721 * DeviceCapabilities [WINEPS16.91]
723 DWORD WINAPI PSDRV_DeviceCapabilities16(LPCSTR lpszDevice,
724 LPCSTR lpszPort, WORD fwCapability,
725 LPSTR lpszOutput, LPDEVMODEA lpdm)
727 return PSDRV_DeviceCapabilities(NULL, lpszDevice, lpszPort, fwCapability,
731 /***************************************************************
732 * DeviceMode [WINEPS16.13]
735 void WINAPI PSDRV_DeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
736 LPSTR lpszDevice, LPSTR lpszPort)
738 PSDRV_ExtDeviceMode16( hwnd, hDriver, NULL, lpszDevice, lpszPort, NULL,
747 HPROPSHEETPAGE hPages[10];
750 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
753 EDMPS *ps = pPropSheet;
756 psp->dwSize = sizeof(psp);
757 psp->hInstance = 0x1234;