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)
123 LIST_FOR_EACH_ENTRY( slot, &pi->ppd->InputSlots, INPUTSLOT, entry )
124 if(slot->WinBin == dm2->dmPublic.u1.s1.dmDefaultSource)
127 if (&slot->entry != &pi->ppd->InputSlots)
129 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
130 TRACE("Changing bin to '%s'\n", slot->FullName);
133 TRACE("Trying to change to unsupported bin %d\n", dm2->dmPublic.u1.s1.dmDefaultSource);
136 if (dm2->dmPublic.dmFields & DM_DEFAULTSOURCE )
137 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
138 if (dm2->dmPublic.dmFields & DM_PRINTQUALITY )
139 dm1->dmPublic.u1.s1.dmPrintQuality = dm2->dmPublic.u1.s1.dmPrintQuality;
140 if (dm2->dmPublic.dmFields & DM_COLOR )
141 dm1->dmPublic.dmColor = dm2->dmPublic.dmColor;
142 if (dm2->dmPublic.dmFields & DM_DUPLEX && pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
143 dm1->dmPublic.dmDuplex = dm2->dmPublic.dmDuplex;
144 if (dm2->dmPublic.dmFields & DM_YRESOLUTION )
145 dm1->dmPublic.dmYResolution = dm2->dmPublic.dmYResolution;
146 if (dm2->dmPublic.dmFields & DM_TTOPTION )
147 dm1->dmPublic.dmTTOption = dm2->dmPublic.dmTTOption;
148 if (dm2->dmPublic.dmFields & DM_COLLATE )
149 dm1->dmPublic.dmCollate = dm2->dmPublic.dmCollate;
150 if (dm2->dmPublic.dmFields & DM_FORMNAME )
151 lstrcpynA((LPSTR)dm1->dmPublic.dmFormName, (LPCSTR)dm2->dmPublic.dmFormName, CCHFORMNAME);
152 if (dm2->dmPublic.dmFields & DM_BITSPERPEL )
153 dm1->dmPublic.dmBitsPerPel = dm2->dmPublic.dmBitsPerPel;
154 if (dm2->dmPublic.dmFields & DM_PELSWIDTH )
155 dm1->dmPublic.dmPelsWidth = dm2->dmPublic.dmPelsWidth;
156 if (dm2->dmPublic.dmFields & DM_PELSHEIGHT )
157 dm1->dmPublic.dmPelsHeight = dm2->dmPublic.dmPelsHeight;
158 if (dm2->dmPublic.dmFields & DM_DISPLAYFLAGS )
159 dm1->dmPublic.u2.dmDisplayFlags = dm2->dmPublic.u2.dmDisplayFlags;
160 if (dm2->dmPublic.dmFields & DM_DISPLAYFREQUENCY )
161 dm1->dmPublic.dmDisplayFrequency = dm2->dmPublic.dmDisplayFrequency;
162 if (dm2->dmPublic.dmFields & DM_POSITION )
163 dm1->dmPublic.u1.s2.dmPosition = dm2->dmPublic.u1.s2.dmPosition;
164 if (dm2->dmPublic.dmFields & DM_LOGPIXELS )
165 dm1->dmPublic.dmLogPixels = dm2->dmPublic.dmLogPixels;
166 if (dm2->dmPublic.dmFields & DM_ICMMETHOD )
167 dm1->dmPublic.dmICMMethod = dm2->dmPublic.dmICMMethod;
168 if (dm2->dmPublic.dmFields & DM_ICMINTENT )
169 dm1->dmPublic.dmICMIntent = dm2->dmPublic.dmICMIntent;
170 if (dm2->dmPublic.dmFields & DM_MEDIATYPE )
171 dm1->dmPublic.dmMediaType = dm2->dmPublic.dmMediaType;
172 if (dm2->dmPublic.dmFields & DM_DITHERTYPE )
173 dm1->dmPublic.dmDitherType = dm2->dmPublic.dmDitherType;
174 if (dm2->dmPublic.dmFields & DM_PANNINGWIDTH )
175 dm1->dmPublic.dmPanningWidth = dm2->dmPublic.dmPanningWidth;
176 if (dm2->dmPublic.dmFields & DM_PANNINGHEIGHT )
177 dm1->dmPublic.dmPanningHeight = dm2->dmPublic.dmPanningHeight;
186 PSDRV_DEVMODEA *dlgdm;
189 /****************************************************************
192 * Dialog proc for 'Paper' propsheet
194 static INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg,
195 WPARAM wParam, LPARAM lParam)
204 di = (PSDRV_DLGINFO*)((PROPSHEETPAGEA*)lParam)->lParam;
205 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)di);
208 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
209 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
210 (LPARAM)ps->FullName);
211 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
215 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
217 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
218 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
219 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
220 IDD_ORIENT_LANDSCAPE);
222 if (list_empty( &di->pi->ppd->Duplexes ))
224 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
225 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);
230 LIST_FOR_EACH_ENTRY( duplex, &di->pi->ppd->Duplexes, DUPLEX, entry )
232 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
233 (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
234 if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
238 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
243 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
244 switch(LOWORD(wParam)) {
246 if(HIWORD(wParam) == LBN_SELCHANGE) {
247 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
249 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
250 if(i >= Cursel) break;
253 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel, ps->WinPage);
254 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
255 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
258 case IDD_ORIENT_PORTRAIT:
259 case IDD_ORIENT_LANDSCAPE:
260 TRACE("Setting orientation to %s\n", wParam == IDD_ORIENT_PORTRAIT ?
261 "portrait" : "landscape");
262 di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
263 DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
264 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
267 if(HIWORD(wParam) == CBN_SELCHANGE) {
268 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
270 LIST_FOR_EACH_ENTRY( duplex, &di->pi->ppd->Duplexes, DUPLEX, entry )
272 if (i >= Cursel) break;
275 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel, duplex->WinDuplex);
276 di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
277 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
285 NMHDR *nmhdr = (NMHDR *)lParam;
286 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
287 switch(nmhdr->code) {
289 *di->pi->Devmode = *di->dlgdm;
290 SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
306 static void (WINAPI *pInitCommonControls) (void);
307 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
308 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
310 static PRINTERINFO *PSDRV_FindPrinterInfoA(LPCSTR name)
312 int len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
313 WCHAR *nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
316 MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
317 pi = PSDRV_FindPrinterInfo( nameW );
318 HeapFree( GetProcessHeap(), 0, nameW );
323 /******************************************************************
324 * PSDRV_ExtDeviceMode
326 * Retrieves or modifies device-initialization information for the PostScript
327 * driver, or displays a driver-supplied dialog box for configuring the driver.
330 * lpszDriver -- Driver name
331 * hwnd -- Parent window for the dialog box
332 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
333 * lpszDevice -- Device name
334 * lpszPort -- Port name
335 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
336 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
337 * wMode -- Operation to perform. Can be a combination if > 0.
338 * (0) -- Returns number of bytes required by DEVMODE structure
339 * DM_UPDATE (1) -- Write current settings to environment and initialization file
340 * DM_COPY (2) -- Write current settings to lpdmOutput
341 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
342 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
345 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
346 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
347 * A return value less than zero is returned if a non-dialog operation fails.
351 * Just returns default devmode at the moment. No use of initialization file.
353 INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
354 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
355 LPSTR lpszProfile, DWORD dwMode)
357 PRINTERINFO *pi = PSDRV_FindPrinterInfoA(lpszDevice);
360 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
361 lpszDriver, hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, debugstr_a(lpszProfile), dwMode);
363 /* If dwMode == 0, return size of DEVMODE structure */
365 return pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra;
367 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
368 if((dwMode & DM_MODIFY) && lpdmInput) {
369 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput->dmFields);
370 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
373 /* If DM_PROMPT is set, present modal dialog box */
374 if(dwMode & DM_PROMPT) {
375 HINSTANCE hinstComctl32;
376 HPROPSHEETPAGE hpsp[1];
378 PROPSHEETHEADERW psh;
380 PSDRV_DEVMODEA dlgdm;
381 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
382 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
384 hinstComctl32 = LoadLibraryA("comctl32.dll");
385 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
386 "InitCommonControls");
387 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
388 "CreatePropertySheetPageW");
389 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
390 memset(&psp,0,sizeof(psp));
391 dlgdm = *pi->Devmode;
394 psp.dwSize = sizeof(psp);
395 psp.hInstance = PSDRV_hInstance;
396 psp.u.pszTemplate = PAPERW;
397 psp.u2.pszIcon = NULL;
398 psp.pfnDlgProc = PSDRV_PaperDlgProc;
399 psp.lParam = (LPARAM)&di;
400 hpsp[0] = pCreatePropertySheetPage(&psp);
402 memset(&psh, 0, sizeof(psh));
403 psh.dwSize = sizeof(psh);
404 psh.pszCaption = SetupW;
406 psh.hwndParent = hwnd;
407 psh.u3.phpage = hpsp;
409 pPropertySheet(&psh);
413 /* If DM_UPDATE is set, should write settings to environment and initialization file */
414 if(dwMode & DM_UPDATE)
415 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
417 /* If DM_COPY is set, should write settings to lpdmOutput */
418 if((dwMode & DM_COPY) || (dwMode & DM_UPDATE)) {
420 memcpy(lpdmOutput, pi->Devmode, pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra );
422 FIXME("lpdmOutput is NULL what should we do??\n");
426 /***********************************************************************
427 * PSDRV_DeviceCapabilities
429 * Retrieves the capabilities of a printer device driver.
432 * lpszDriver -- printer driver name
433 * lpszDevice -- printer name
434 * lpszPort -- port name
435 * fwCapability -- device capability
436 * lpszOutput -- output buffer
437 * lpDevMode -- device data buffer
440 * Result depends on the setting of fwCapability. -1 indicates failure.
442 DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
443 WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpDevMode)
448 pi = PSDRV_FindPrinterInfoA(lpszDevice);
450 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver), debugstr_a(lpszDevice),
451 debugstr_a(lpszPort), fwCapability, lpszOutput, lpDevMode);
454 ERR("no printer info for %s %s, return 0!\n",
455 debugstr_a(lpszDriver), debugstr_a(lpszDevice));
459 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
461 switch(fwCapability) {
466 WORD *wp = (WORD *)lpszOutput;
469 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
471 TRACE("DC_PAPERS: %u\n", ps->WinPage);
473 if(lpszOutput != NULL)
482 POINT16 *pt = (POINT16 *)lpszOutput;
485 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
487 TRACE("DC_PAPERSIZE: %f x %f\n", ps->PaperDimension->x, ps->PaperDimension->y);
489 if(lpszOutput != NULL) {
490 pt->x = paper_size_from_points( ps->PaperDimension->x );
491 pt->y = paper_size_from_points( ps->PaperDimension->y );
501 char *cp = lpszOutput;
504 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
506 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps->FullName));
508 if(lpszOutput != NULL) {
509 lstrcpynA(cp, ps->FullName, 64);
517 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
522 WORD *wp = (WORD *)lpszOutput;
525 LIST_FOR_EACH_ENTRY( slot, &pi->ppd->InputSlots, INPUTSLOT, entry )
528 if (lpszOutput != NULL)
529 *wp++ = slot->WinBin;
537 char *cp = lpszOutput;
540 LIST_FOR_EACH_ENTRY( slot, &pi->ppd->InputSlots, INPUTSLOT, entry )
543 if (lpszOutput != NULL)
545 lstrcpynA( cp, slot->FullName, 24 );
553 FIXME("DC_BINADJUST: stub.\n");
554 return DCBA_FACEUPNONE;
556 case DC_ENUMRESOLUTIONS:
558 LONG *lp = (LONG*)lpszOutput;
560 if(lpszOutput != NULL) {
561 lp[0] = pi->ppd->DefaultResolution;
562 lp[1] = pi->ppd->DefaultResolution;
567 /* Windows returns 9999 too */
569 TRACE("DC_COPIES: returning 9999\n");
573 return lpdm->dmDriverVersion;
575 case DC_DATATYPE_PRODUCED:
576 FIXME("DATA_TYPE_PRODUCED: stub.\n");
577 return -1; /* simulate that the driver supports 'RAW' */
581 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
583 TRACE("DC_DUPLEX: returning %d\n", ret);
586 case DC_EMF_COMPLIANT:
587 FIXME("DC_EMF_COMPLIANT: stub.\n");
588 return -1; /* simulate that the driver do not support EMF */
591 return lpdm->dmDriverExtra;
594 return lpdm->dmFields;
596 case DC_FILEDEPENDENCIES:
597 FIXME("DC_FILEDEPENDENCIES: stub.\n");
605 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
607 if (ps->PaperDimension->x > x) x = ps->PaperDimension->x;
608 if (ps->PaperDimension->y > y) y = ps->PaperDimension->y;
610 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
616 float x = 1e6, y = 1e6;
618 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
620 if (ps->PaperDimension->x < x) x = ps->PaperDimension->x;
621 if (ps->PaperDimension->y < y) y = ps->PaperDimension->y;
623 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
630 FIXME("DC_TRUETYPE: stub\n");
634 return lpdm->dmSpecVersion;
636 /* We'll just return false here, very few printers can collate anyway */
638 TRACE("DC_COLLATE: returning FALSE\n");
641 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
643 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
645 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
646 case DC_MANUFACTURER:
647 FIXME("DC_MANUFACTURER: stub\n");
650 /* Identification number of the printer model for use with ICM (Win9x only) */
652 FIXME("DC_MODEL: stub\n");
655 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
656 case DC_STAPLE: /* WINVER >= 0x0500 */
657 FIXME("DC_STAPLE: stub\n");
660 /* Returns an array of 64-character string buffers containing the names of the paper forms
661 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
664 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
665 FIXME("DC_MEDIAREADY: stub\n");
668 /* Returns an array of 64-character string buffers containing the names of the supported
669 * media types, unless pOutput is NULL. The return value is the number of supported.
670 * media types (XP only)
672 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
673 FIXME("DC_MEDIATYPENAMES: stub\n");
676 /* Returns an array of DWORD values which represent the supported media types, unless
677 * pOutput is NULL. The return value is the number of supported media types. (XP only)
679 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
680 FIXME("DC_MEDIATYPES: stub\n");
683 /* Returns an array of DWORD values, each representing a supported number of document
684 * pages per printed page, unless pOutput is NULL. The return value is the number of
685 * array entries. (Win2k/XP only)
688 FIXME("DC_NUP: stub\n");
691 /* Returns an array of 32-character string buffers containing a list of printer description
692 * languages supported by the printer, unless pOutput is NULL. The return value is
693 * number of array entries. (Win2k/XP only)
696 case DC_PERSONALITY: /* WINVER >= 0x0500 */
697 FIXME("DC_PERSONALITY: stub\n");
700 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
701 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
702 FIXME("DC_PRINTERMEM: stub\n");
705 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
706 case DC_PRINTRATE: /* WINVER >= 0x0500 */
707 FIXME("DC_PRINTRATE: stub\n");
710 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
711 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
712 FIXME("DC_PRINTRATEPPM: stub\n");
715 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
716 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
718 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
719 FIXME("DC_PRINTRATEUNIT: stub\n");
723 FIXME("Unsupported capability %d\n", fwCapability);
732 HPROPSHEETPAGE hPages[10];
735 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
738 EDMPS *ps = pPropSheet;
741 psp->dwSize = sizeof(psp);
742 psp->hInstance = 0x1234;