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 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 PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
441 WORD fwCapability, LPSTR lpszOutput,
442 LPDEVMODEA lpDevMode)
447 pi = PSDRV_FindPrinterInfo(lpszDevice);
449 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver), debugstr_a(lpszDevice),
450 debugstr_a(lpszPort), fwCapability, lpszOutput, lpDevMode);
453 ERR("no printer info for %s %s, return 0!\n",
454 debugstr_a(lpszDriver), debugstr_a(lpszDevice));
458 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
460 switch(fwCapability) {
465 WORD *wp = (WORD *)lpszOutput;
468 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
470 TRACE("DC_PAPERS: %u\n", ps->WinPage);
472 if(lpszOutput != NULL)
481 POINT16 *pt = (POINT16 *)lpszOutput;
484 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
486 TRACE("DC_PAPERSIZE: %f x %f\n", ps->PaperDimension->x, ps->PaperDimension->y);
488 if(lpszOutput != NULL) {
489 pt->x = ps->PaperDimension->x * 254.0 / 72.0;
490 pt->y = ps->PaperDimension->y * 254.0 / 72.0;
500 char *cp = lpszOutput;
503 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
505 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps->FullName));
507 if(lpszOutput != NULL) {
508 lstrcpynA(cp, ps->FullName, 64);
516 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
521 WORD *wp = (WORD *)lpszOutput;
524 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
525 if(lpszOutput != NULL)
526 *wp++ = slot->WinBin;
533 char *cp = lpszOutput;
536 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
537 if(lpszOutput != NULL) {
538 lstrcpynA(cp, slot->FullName, 24);
545 FIXME("DC_BINADJUST: stub.\n");
546 return DCBA_FACEUPNONE;
548 case DC_ENUMRESOLUTIONS:
550 LONG *lp = (LONG*)lpszOutput;
552 if(lpszOutput != NULL) {
553 lp[0] = pi->ppd->DefaultResolution;
554 lp[1] = pi->ppd->DefaultResolution;
559 /* Windows returns 9999 too */
561 TRACE("DC_COPIES: returning 9999\n");
565 return lpdm->dmDriverVersion;
567 case DC_DATATYPE_PRODUCED:
568 FIXME("DATA_TYPE_PRODUCED: stub.\n");
569 return -1; /* simulate that the driver supports 'RAW' */
573 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
575 TRACE("DC_DUPLEX: returning %d\n", ret);
578 case DC_EMF_COMPLIANT:
579 FIXME("DC_EMF_COMPLIANT: stub.\n");
580 return -1; /* simulate that the driver do not support EMF */
583 return lpdm->dmDriverExtra;
586 return lpdm->dmFields;
588 case DC_FILEDEPENDENCIES:
589 FIXME("DC_FILEDEPENDENCIES: stub.\n");
596 ptMax.x = ptMax.y = 0;
598 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
600 if(ps->PaperDimension->x > ptMax.x)
601 ptMax.x = ps->PaperDimension->x;
602 if(ps->PaperDimension->y > ptMax.y)
603 ptMax.y = ps->PaperDimension->y;
605 return MAKELONG(ptMax.x * 254.0 / 72.0, ptMax.y * 254.0 / 72.0 );
612 ptMin.x = ptMin.y = -1;
614 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
616 if(ptMin.x == -1 || ps->PaperDimension->x < ptMin.x)
617 ptMin.x = ps->PaperDimension->x;
618 if(ptMin.y == -1 || ps->PaperDimension->y < ptMin.y)
619 ptMin.y = ps->PaperDimension->y;
621 return MAKELONG(ptMin.x * 254.0 / 72.0, ptMin.y * 254.0 / 72.0);
628 FIXME("DC_TRUETYPE: stub\n");
632 return lpdm->dmSpecVersion;
634 /* We'll just return false here, very few printers can collate anyway */
636 TRACE("DC_COLLATE: returning FALSE\n");
639 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
641 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
643 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
644 case DC_MANUFACTURER:
645 FIXME("DC_MANUFACTURER: stub\n");
648 /* Identification number of the printer model for use with ICM (Win9x only) */
650 FIXME("DC_MODEL: stub\n");
653 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
654 case DC_STAPLE: /* WINVER >= 0x0500 */
655 FIXME("DC_STAPLE: stub\n");
658 /* Returns an array of 64-character string buffers containing the names of the paper forms
659 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
662 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
663 FIXME("DC_MEDIAREADY: stub\n");
666 /* Returns an array of 64-character string buffers containing the names of the supported
667 * media types, unless pOutput is NULL. The return value is the number of supported.
668 * media types (XP only)
670 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
671 FIXME("DC_MEDIATYPENAMES: stub\n");
674 /* Returns an array of DWORD values which represent the supported media types, unless
675 * pOutput is NULL. The return value is the number of supported media types. (XP only)
677 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
678 FIXME("DC_MEDIATYPES: stub\n");
681 /* Returns an array of DWORD values, each representing a supported number of document
682 * pages per printed page, unless pOutput is NULL. The return value is the number of
683 * array entries. (Win2k/XP only)
686 FIXME("DC_NUP: stub\n");
689 /* Returns an array of 32-character string buffers containing a list of printer description
690 * languages supported by the printer, unless pOutput is NULL. The return value is
691 * number of array entries. (Win2k/XP only)
694 case DC_PERSONALITY: /* WINVER >= 0x0500 */
695 FIXME("DC_PERSONALITY: stub\n");
698 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
699 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
700 FIXME("DC_PRINTERMEM: stub\n");
703 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
704 case DC_PRINTRATE: /* WINVER >= 0x0500 */
705 FIXME("DC_PRINTRATE: stub\n");
708 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
709 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
710 FIXME("DC_PRINTRATEPPM: stub\n");
713 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
714 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
716 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
717 FIXME("DC_PRINTRATEUNIT: stub\n");
721 FIXME("Unsupported capability %d\n", fwCapability);
726 /**************************************************************
727 * DeviceCapabilities [WINEPS16.91]
729 DWORD WINAPI PSDRV_DeviceCapabilities16(LPCSTR lpszDevice,
730 LPCSTR lpszPort, WORD fwCapability,
731 LPSTR lpszOutput, LPDEVMODEA lpdm)
733 return PSDRV_DeviceCapabilities(NULL, lpszDevice, lpszPort, fwCapability,
737 /***************************************************************
738 * DeviceMode [WINEPS16.13]
741 void WINAPI PSDRV_DeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
742 LPSTR lpszDevice, LPSTR lpszPort)
744 PSDRV_ExtDeviceMode16( hwnd, hDriver, NULL, lpszDevice, lpszPort, NULL,
753 HPROPSHEETPAGE hPages[10];
756 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
759 EDMPS *ps = pPropSheet;
762 psp->dwSize = sizeof(psp);
763 psp->hInstance = 0x1234;