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"
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 /**************************************************************
180 * AdvancedSetupDialog [WINEPS16.93]
183 WORD WINAPI PSDRV_AdvancedSetupDialog16(HWND16 hwnd, HANDLE16 hDriver,
184 LPDEVMODEA devin, LPDEVMODEA devout)
187 TRACE("hwnd = %04x, hDriver = %04x devin=%p devout=%p\n", hwnd,
188 hDriver, devin, devout);
192 /****************************************************************
195 * Dialog proc for 'Paper' propsheet
197 static INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg,
198 WPARAM wParam, LPARAM lParam)
207 di = (PSDRV_DLGINFO*)((PROPSHEETPAGEA*)lParam)->lParam;
208 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)di);
211 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
212 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
213 (LPARAM)ps->FullName);
214 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
218 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
220 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
221 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
222 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
223 IDD_ORIENT_LANDSCAPE);
225 if(!di->pi->ppd->Duplexes) {
226 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
227 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);
230 for(duplex = di->pi->ppd->Duplexes, i = 0; duplex; duplex = duplex->next, i++) {
231 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
232 (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
233 if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
236 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
241 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
242 switch(LOWORD(wParam)) {
244 if(HIWORD(wParam) == LBN_SELCHANGE) {
245 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
247 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
248 if(i >= Cursel) break;
251 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel,
253 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
256 case IDD_ORIENT_PORTRAIT:
257 case IDD_ORIENT_LANDSCAPE:
258 TRACE("Setting orientation to %s\n", wParam == IDD_ORIENT_PORTRAIT ?
259 "portrait" : "landscape");
260 di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
261 DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
264 if(HIWORD(wParam) == CBN_SELCHANGE) {
265 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
266 for(i = 0, duplex = di->pi->ppd->Duplexes; i < Cursel; i++, duplex = duplex->next)
268 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel,
270 di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
278 NMHDR *nmhdr = (NMHDR *)lParam;
279 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
280 switch(nmhdr->code) {
282 *di->pi->Devmode = *di->dlgdm;
283 SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
299 static void (WINAPI *pInitCommonControls) (void);
300 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
301 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
304 /******************************************************************
305 * PSDRV_ExtDeviceMode
307 * Retrieves or modifies device-initialization information for the PostScript
308 * driver, or displays a driver-supplied dialog box for configuring the driver.
311 * lpszDriver -- Driver name
312 * hwnd -- Parent window for the dialog box
313 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
314 * lpszDevice -- Device name
315 * lpszPort -- Port name
316 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
317 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
318 * wMode -- Operation to perform. Can be a combination if > 0.
319 * (0) -- Returns number of bytes required by DEVMODE structure
320 * DM_UPDATE (1) -- Write current settings to environment and initialization file
321 * DM_COPY (2) -- Write current settings to lpdmOutput
322 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
323 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
326 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
327 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
328 * A return value less than zero is returned if a non-dialog operation fails.
332 * Just returns default devmode at the moment. No use of initialization file.
334 INT CDECL PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
335 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
336 LPSTR lpszProfile, DWORD dwMode)
338 PRINTERINFO *pi = PSDRV_FindPrinterInfo(lpszDevice);
341 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
342 lpszDriver, hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, lpszProfile, dwMode);
344 /* If dwMode == 0, return size of DEVMODE structure */
346 return pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra;
348 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
349 if((dwMode & DM_MODIFY) && lpdmInput) {
350 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput->dmFields);
351 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
354 /* If DM_PROMPT is set, present modal dialog box */
355 if(dwMode & DM_PROMPT) {
356 HINSTANCE hinstComctl32;
357 HPROPSHEETPAGE hpsp[1];
359 PROPSHEETHEADERW psh;
361 PSDRV_DEVMODEA *dlgdm;
362 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
363 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
365 hinstComctl32 = LoadLibraryA("comctl32.dll");
366 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
367 "InitCommonControls");
368 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
369 "CreatePropertySheetPageW");
370 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
371 memset(&psp,0,sizeof(psp));
372 dlgdm = HeapAlloc( PSDRV_Heap, 0, sizeof(*dlgdm) );
373 *dlgdm = *pi->Devmode;
374 di = HeapAlloc( PSDRV_Heap, 0, sizeof(*di) );
377 psp.dwSize = sizeof(psp);
378 psp.hInstance = PSDRV_hInstance;
379 psp.u.pszTemplate = PAPERW;
380 psp.u2.pszIcon = NULL;
381 psp.pfnDlgProc = PSDRV_PaperDlgProc;
382 psp.lParam = (LPARAM)di;
383 hpsp[0] = pCreatePropertySheetPage(&psp);
385 memset(&psh, 0, sizeof(psh));
386 psh.dwSize = sizeof(psh);
387 psh.pszCaption = SetupW;
389 psh.hwndParent = HWND_32(hwnd);
390 psh.u3.phpage = hpsp;
392 pPropertySheet(&psh);
396 /* If DM_UPDATE is set, should write settings to environment and initialization file */
397 if(dwMode & DM_UPDATE)
398 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
400 /* If DM_COPY is set, should write settings to lpdmOutput */
401 if((dwMode & DM_COPY) || (dwMode & DM_UPDATE)) {
403 memcpy(lpdmOutput, pi->Devmode, pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra );
405 FIXME("lpdmOutput is NULL what should we do??\n");
409 /***************************************************************
410 * ExtDeviceMode [WINEPS16.90]
414 INT16 WINAPI PSDRV_ExtDeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
415 LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
416 LPSTR lpszPort, LPDEVMODEA lpdmInput,
417 LPSTR lpszProfile, WORD fwMode)
420 return PSDRV_ExtDeviceMode(NULL, HWND_32(hwnd), lpdmOutput, lpszDevice,
421 lpszPort, lpdmInput, lpszProfile, (DWORD) fwMode);
424 /***********************************************************************
425 * PSDRV_DeviceCapabilities
427 * Retrieves the capabilities of a printer device driver.
430 * lpszDriver -- printer driver name
431 * lpszDevice -- printer name
432 * lpszPort -- port name
433 * fwCapability -- device capability
434 * lpszOutput -- output buffer
435 * lpDevMode -- device data buffer
438 * Result depends on the setting of fwCapability. -1 indicates failure.
440 DWORD CDECL PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
441 WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpDevMode)
446 pi = PSDRV_FindPrinterInfo(lpszDevice);
448 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver), debugstr_a(lpszDevice),
449 debugstr_a(lpszPort), fwCapability, lpszOutput, lpDevMode);
452 ERR("no printer info for %s %s, return 0!\n",
453 debugstr_a(lpszDriver), debugstr_a(lpszDevice));
457 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
459 switch(fwCapability) {
464 WORD *wp = (WORD *)lpszOutput;
467 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
469 TRACE("DC_PAPERS: %u\n", ps->WinPage);
471 if(lpszOutput != NULL)
480 POINT16 *pt = (POINT16 *)lpszOutput;
483 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
485 TRACE("DC_PAPERSIZE: %f x %f\n", ps->PaperDimension->x, ps->PaperDimension->y);
487 if(lpszOutput != NULL) {
488 pt->x = ps->PaperDimension->x * 254.0 / 72.0;
489 pt->y = ps->PaperDimension->y * 254.0 / 72.0;
499 char *cp = lpszOutput;
502 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
504 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps->FullName));
506 if(lpszOutput != NULL) {
507 lstrcpynA(cp, ps->FullName, 64);
515 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
520 WORD *wp = (WORD *)lpszOutput;
523 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
524 if(lpszOutput != NULL)
525 *wp++ = slot->WinBin;
532 char *cp = lpszOutput;
535 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
536 if(lpszOutput != NULL) {
537 lstrcpynA(cp, slot->FullName, 24);
544 FIXME("DC_BINADJUST: stub.\n");
545 return DCBA_FACEUPNONE;
547 case DC_ENUMRESOLUTIONS:
549 LONG *lp = (LONG*)lpszOutput;
551 if(lpszOutput != NULL) {
552 lp[0] = pi->ppd->DefaultResolution;
553 lp[1] = pi->ppd->DefaultResolution;
558 /* Windows returns 9999 too */
560 TRACE("DC_COPIES: returning 9999\n");
564 return lpdm->dmDriverVersion;
566 case DC_DATATYPE_PRODUCED:
567 FIXME("DATA_TYPE_PRODUCED: stub.\n");
568 return -1; /* simulate that the driver supports 'RAW' */
572 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
574 TRACE("DC_DUPLEX: returning %d\n", ret);
577 case DC_EMF_COMPLIANT:
578 FIXME("DC_EMF_COMPLIANT: stub.\n");
579 return -1; /* simulate that the driver do not support EMF */
582 return lpdm->dmDriverExtra;
585 return lpdm->dmFields;
587 case DC_FILEDEPENDENCIES:
588 FIXME("DC_FILEDEPENDENCIES: stub.\n");
595 ptMax.x = ptMax.y = 0;
597 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
599 if(ps->PaperDimension->x > ptMax.x)
600 ptMax.x = ps->PaperDimension->x;
601 if(ps->PaperDimension->y > ptMax.y)
602 ptMax.y = ps->PaperDimension->y;
604 return MAKELONG(ptMax.x * 254.0 / 72.0, ptMax.y * 254.0 / 72.0 );
611 ptMin.x = ptMin.y = -1;
613 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
615 if(ptMin.x == -1 || ps->PaperDimension->x < ptMin.x)
616 ptMin.x = ps->PaperDimension->x;
617 if(ptMin.y == -1 || ps->PaperDimension->y < ptMin.y)
618 ptMin.y = ps->PaperDimension->y;
620 return MAKELONG(ptMin.x * 254.0 / 72.0, ptMin.y * 254.0 / 72.0);
627 FIXME("DC_TRUETYPE: stub\n");
631 return lpdm->dmSpecVersion;
633 /* We'll just return false here, very few printers can collate anyway */
635 TRACE("DC_COLLATE: returning FALSE\n");
638 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
640 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
642 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
643 case DC_MANUFACTURER:
644 FIXME("DC_MANUFACTURER: stub\n");
647 /* Identification number of the printer model for use with ICM (Win9x only) */
649 FIXME("DC_MODEL: stub\n");
652 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
653 case DC_STAPLE: /* WINVER >= 0x0500 */
654 FIXME("DC_STAPLE: stub\n");
657 /* Returns an array of 64-character string buffers containing the names of the paper forms
658 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
661 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
662 FIXME("DC_MEDIAREADY: stub\n");
665 /* Returns an array of 64-character string buffers containing the names of the supported
666 * media types, unless pOutput is NULL. The return value is the number of supported.
667 * media types (XP only)
669 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
670 FIXME("DC_MEDIATYPENAMES: stub\n");
673 /* Returns an array of DWORD values which represent the supported media types, unless
674 * pOutput is NULL. The return value is the number of supported media types. (XP only)
676 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
677 FIXME("DC_MEDIATYPES: stub\n");
680 /* Returns an array of DWORD values, each representing a supported number of document
681 * pages per printed page, unless pOutput is NULL. The return value is the number of
682 * array entries. (Win2k/XP only)
685 FIXME("DC_NUP: stub\n");
688 /* Returns an array of 32-character string buffers containing a list of printer description
689 * languages supported by the printer, unless pOutput is NULL. The return value is
690 * number of array entries. (Win2k/XP only)
693 case DC_PERSONALITY: /* WINVER >= 0x0500 */
694 FIXME("DC_PERSONALITY: stub\n");
697 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
698 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
699 FIXME("DC_PRINTERMEM: stub\n");
702 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
703 case DC_PRINTRATE: /* WINVER >= 0x0500 */
704 FIXME("DC_PRINTRATE: stub\n");
707 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
708 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
709 FIXME("DC_PRINTRATEPPM: stub\n");
712 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
713 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
715 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
716 FIXME("DC_PRINTRATEUNIT: stub\n");
720 FIXME("Unsupported capability %d\n", fwCapability);
725 /**************************************************************
726 * DeviceCapabilities [WINEPS16.91]
728 DWORD WINAPI PSDRV_DeviceCapabilities16(LPCSTR lpszDevice,
729 LPCSTR lpszPort, WORD fwCapability,
730 LPSTR lpszOutput, LPDEVMODEA lpdm)
732 return PSDRV_DeviceCapabilities(NULL, lpszDevice, lpszPort, fwCapability,
736 /***************************************************************
737 * DeviceMode [WINEPS16.13]
740 void WINAPI PSDRV_DeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
741 LPSTR lpszDevice, LPSTR lpszPort)
743 PSDRV_ExtDeviceMode16( hwnd, hDriver, NULL, lpszDevice, lpszPort, NULL,
752 HPROPSHEETPAGE hPages[10];
755 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
758 EDMPS *ps = pPropSheet;
761 psp->dwSize = sizeof(psp);
762 psp->hInstance = 0x1234;