wshom.ocx: Dump VARIANT parameters, fix instance leak.
[wine/multimedia.git] / dlls / wineps.drv / driver.c
bloba62abb15f3b9eff11f85c777abaada6a26901d32
1 /*
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
28 #include "config.h"
30 #include <string.h>
32 #include "wine/debug.h"
33 #include "psdrv.h"
35 #include "winuser.h"
36 #include "wine/wingdi16.h"
37 #include "prsht.h"
38 #include "psdlg.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 /************************************************************************
50 * PSDRV_MergeDevmodes
52 * Updates dm1 with some fields from dm2
55 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
56 PRINTERINFO *pi)
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 ?
65 "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) {
72 PAGESIZE *page;
74 LIST_FOR_EACH_ENTRY(page, &pi->ppd->PageSizes, PAGESIZE, entry) {
75 if(page->WinPage == dm2->dmPublic.u1.s1.dmPaperSize)
76 break;
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 );
87 } else {
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
103 this case */
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) {
120 INPUTSLOT *slot;
122 for(slot = pi->ppd->InputSlots; slot; slot = slot->next) {
123 if(slot->WinBin == dm2->dmPublic.u1.s1.dmDefaultSource)
124 break;
126 if(slot) {
127 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
128 TRACE("Changing bin to '%s'\n", slot->FullName);
129 } else {
130 TRACE("Trying to change to unsupported bin %d\n",
131 dm2->dmPublic.u1.s1.dmDefaultSource);
135 if (dm2->dmPublic.dmFields & DM_DEFAULTSOURCE )
136 dm1->dmPublic.u1.s1.dmDefaultSource = dm2->dmPublic.u1.s1.dmDefaultSource;
137 if (dm2->dmPublic.dmFields & DM_PRINTQUALITY )
138 dm1->dmPublic.u1.s1.dmPrintQuality = dm2->dmPublic.u1.s1.dmPrintQuality;
139 if (dm2->dmPublic.dmFields & DM_COLOR )
140 dm1->dmPublic.dmColor = dm2->dmPublic.dmColor;
141 if (dm2->dmPublic.dmFields & DM_DUPLEX && pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
142 dm1->dmPublic.dmDuplex = dm2->dmPublic.dmDuplex;
143 if (dm2->dmPublic.dmFields & DM_YRESOLUTION )
144 dm1->dmPublic.dmYResolution = dm2->dmPublic.dmYResolution;
145 if (dm2->dmPublic.dmFields & DM_TTOPTION )
146 dm1->dmPublic.dmTTOption = dm2->dmPublic.dmTTOption;
147 if (dm2->dmPublic.dmFields & DM_COLLATE )
148 dm1->dmPublic.dmCollate = dm2->dmPublic.dmCollate;
149 if (dm2->dmPublic.dmFields & DM_FORMNAME )
150 lstrcpynA((LPSTR)dm1->dmPublic.dmFormName, (LPCSTR)dm2->dmPublic.dmFormName, CCHFORMNAME);
151 if (dm2->dmPublic.dmFields & DM_BITSPERPEL )
152 dm1->dmPublic.dmBitsPerPel = dm2->dmPublic.dmBitsPerPel;
153 if (dm2->dmPublic.dmFields & DM_PELSWIDTH )
154 dm1->dmPublic.dmPelsWidth = dm2->dmPublic.dmPelsWidth;
155 if (dm2->dmPublic.dmFields & DM_PELSHEIGHT )
156 dm1->dmPublic.dmPelsHeight = dm2->dmPublic.dmPelsHeight;
157 if (dm2->dmPublic.dmFields & DM_DISPLAYFLAGS )
158 dm1->dmPublic.u2.dmDisplayFlags = dm2->dmPublic.u2.dmDisplayFlags;
159 if (dm2->dmPublic.dmFields & DM_DISPLAYFREQUENCY )
160 dm1->dmPublic.dmDisplayFrequency = dm2->dmPublic.dmDisplayFrequency;
161 if (dm2->dmPublic.dmFields & DM_POSITION )
162 dm1->dmPublic.u1.s2.dmPosition = dm2->dmPublic.u1.s2.dmPosition;
163 if (dm2->dmPublic.dmFields & DM_LOGPIXELS )
164 dm1->dmPublic.dmLogPixels = dm2->dmPublic.dmLogPixels;
165 if (dm2->dmPublic.dmFields & DM_ICMMETHOD )
166 dm1->dmPublic.dmICMMethod = dm2->dmPublic.dmICMMethod;
167 if (dm2->dmPublic.dmFields & DM_ICMINTENT )
168 dm1->dmPublic.dmICMIntent = dm2->dmPublic.dmICMIntent;
169 if (dm2->dmPublic.dmFields & DM_MEDIATYPE )
170 dm1->dmPublic.dmMediaType = dm2->dmPublic.dmMediaType;
171 if (dm2->dmPublic.dmFields & DM_DITHERTYPE )
172 dm1->dmPublic.dmDitherType = dm2->dmPublic.dmDitherType;
173 if (dm2->dmPublic.dmFields & DM_PANNINGWIDTH )
174 dm1->dmPublic.dmPanningWidth = dm2->dmPublic.dmPanningWidth;
175 if (dm2->dmPublic.dmFields & DM_PANNINGHEIGHT )
176 dm1->dmPublic.dmPanningHeight = dm2->dmPublic.dmPanningHeight;
178 return;
182 /****************************************************************
183 * PSDRV_PaperDlgProc
185 * Dialog proc for 'Paper' propsheet
187 static INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg,
188 WPARAM wParam, LPARAM lParam)
190 PSDRV_DLGINFO *di;
191 int i, Cursel = 0;
192 PAGESIZE *ps;
193 DUPLEX *duplex;
195 switch(msg) {
196 case WM_INITDIALOG:
197 di = (PSDRV_DLGINFO*)((PROPSHEETPAGEA*)lParam)->lParam;
198 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)di);
200 i = 0;
201 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
202 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
203 (LPARAM)ps->FullName);
204 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
205 Cursel = i;
206 i++;
208 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
210 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
211 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
212 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
213 IDD_ORIENT_LANDSCAPE);
215 if(!di->pi->ppd->Duplexes) {
216 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
217 ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);
218 } else {
219 Cursel = 0;
220 for(duplex = di->pi->ppd->Duplexes, i = 0; duplex; duplex = duplex->next, i++) {
221 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
222 (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
223 if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
224 Cursel = i;
226 SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
228 break;
230 case WM_COMMAND:
231 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
232 switch(LOWORD(wParam)) {
233 case IDD_PAPERS:
234 if(HIWORD(wParam) == LBN_SELCHANGE) {
235 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
236 i = 0;
237 LIST_FOR_EACH_ENTRY(ps, &di->pi->ppd->PageSizes, PAGESIZE, entry) {
238 if(i >= Cursel) break;
239 i++;
241 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel, ps->WinPage);
242 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
243 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
245 break;
246 case IDD_ORIENT_PORTRAIT:
247 case IDD_ORIENT_LANDSCAPE:
248 TRACE("Setting orientation to %s\n", wParam == IDD_ORIENT_PORTRAIT ?
249 "portrait" : "landscape");
250 di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
251 DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
252 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
253 break;
254 case IDD_DUPLEX:
255 if(HIWORD(wParam) == CBN_SELCHANGE) {
256 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
257 for(i = 0, duplex = di->pi->ppd->Duplexes; i < Cursel; i++, duplex = duplex->next)
259 TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel, duplex->WinDuplex);
260 di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
261 SendMessageW(GetParent(hwnd), PSM_CHANGED, 0, 0);
263 break;
265 break;
267 case WM_NOTIFY:
269 NMHDR *nmhdr = (NMHDR *)lParam;
270 di = (PSDRV_DLGINFO *)GetWindowLongPtrW(hwnd, DWLP_USER);
271 switch(nmhdr->code) {
272 case PSN_APPLY:
273 *di->pi->Devmode = *di->dlgdm;
274 SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
275 return TRUE;
277 default:
278 return FALSE;
280 break;
283 default:
284 return FALSE;
286 return TRUE;
290 static void (WINAPI *pInitCommonControls) (void);
291 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
292 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
295 /******************************************************************
296 * PSDRV_ExtDeviceMode
298 * Retrieves or modifies device-initialization information for the PostScript
299 * driver, or displays a driver-supplied dialog box for configuring the driver.
301 * PARAMETERS
302 * lpszDriver -- Driver name
303 * hwnd -- Parent window for the dialog box
304 * lpdmOutput -- Address of a DEVMODE structure for writing initialization information
305 * lpszDevice -- Device name
306 * lpszPort -- Port name
307 * lpdmInput -- Address of a DEVMODE structure for reading initialization information
308 * lpProfile -- Name of initialization file, defaults to WIN.INI if NULL
309 * wMode -- Operation to perform. Can be a combination if > 0.
310 * (0) -- Returns number of bytes required by DEVMODE structure
311 * DM_UPDATE (1) -- Write current settings to environment and initialization file
312 * DM_COPY (2) -- Write current settings to lpdmOutput
313 * DM_PROMPT (4) -- Presents the driver's modal dialog box (USER.240)
314 * DM_MODIFY (8) -- Changes current settings according to lpdmInput before any other operation
316 * RETURNS
317 * Returns size of DEVMODE structure if wMode is 0. Otherwise, IDOK is returned for success
318 * for both dialog and non-dialog operations. IDCANCEL is returned if the dialog box was cancelled.
319 * A return value less than zero is returned if a non-dialog operation fails.
321 * BUGS
323 * Just returns default devmode at the moment. No use of initialization file.
325 INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
326 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
327 LPSTR lpszProfile, DWORD dwMode)
329 PRINTERINFO *pi = PSDRV_FindPrinterInfo(lpszDevice);
330 if(!pi) return -1;
332 TRACE("(Driver=%s, hwnd=%p, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
333 lpszDriver, hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, debugstr_a(lpszProfile), dwMode);
335 /* If dwMode == 0, return size of DEVMODE structure */
336 if(!dwMode)
337 return pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra;
339 /* If DM_MODIFY is set, change settings in accordance with lpdmInput */
340 if((dwMode & DM_MODIFY) && lpdmInput) {
341 TRACE("DM_MODIFY set. devIn->dmFields = %08x\n", lpdmInput->dmFields);
342 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
345 /* If DM_PROMPT is set, present modal dialog box */
346 if(dwMode & DM_PROMPT) {
347 HINSTANCE hinstComctl32;
348 HPROPSHEETPAGE hpsp[1];
349 PROPSHEETPAGEW psp;
350 PROPSHEETHEADERW psh;
351 PSDRV_DLGINFO *di;
352 PSDRV_DEVMODEA *dlgdm;
353 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
354 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
356 hinstComctl32 = LoadLibraryA("comctl32.dll");
357 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
358 "InitCommonControls");
359 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
360 "CreatePropertySheetPageW");
361 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
362 memset(&psp,0,sizeof(psp));
363 dlgdm = HeapAlloc( PSDRV_Heap, 0, sizeof(*dlgdm) );
364 *dlgdm = *pi->Devmode;
365 di = HeapAlloc( PSDRV_Heap, 0, sizeof(*di) );
366 di->pi = pi;
367 di->dlgdm = dlgdm;
368 psp.dwSize = sizeof(psp);
369 psp.hInstance = PSDRV_hInstance;
370 psp.u.pszTemplate = PAPERW;
371 psp.u2.pszIcon = NULL;
372 psp.pfnDlgProc = PSDRV_PaperDlgProc;
373 psp.lParam = (LPARAM)di;
374 hpsp[0] = pCreatePropertySheetPage(&psp);
376 memset(&psh, 0, sizeof(psh));
377 psh.dwSize = sizeof(psh);
378 psh.pszCaption = SetupW;
379 psh.nPages = 1;
380 psh.hwndParent = hwnd;
381 psh.u3.phpage = hpsp;
383 pPropertySheet(&psh);
387 /* If DM_UPDATE is set, should write settings to environment and initialization file */
388 if(dwMode & DM_UPDATE)
389 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
391 /* If DM_COPY is set, should write settings to lpdmOutput */
392 if((dwMode & DM_COPY) || (dwMode & DM_UPDATE)) {
393 if (lpdmOutput)
394 memcpy(lpdmOutput, pi->Devmode, pi->Devmode->dmPublic.dmSize + pi->Devmode->dmPublic.dmDriverExtra );
395 else
396 FIXME("lpdmOutput is NULL what should we do??\n");
398 return IDOK;
400 /***********************************************************************
401 * PSDRV_DeviceCapabilities
403 * Retrieves the capabilities of a printer device driver.
405 * Parameters
406 * lpszDriver -- printer driver name
407 * lpszDevice -- printer name
408 * lpszPort -- port name
409 * fwCapability -- device capability
410 * lpszOutput -- output buffer
411 * lpDevMode -- device data buffer
413 * Returns
414 * Result depends on the setting of fwCapability. -1 indicates failure.
416 DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszPort,
417 WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpDevMode)
419 PRINTERINFO *pi;
420 DEVMODEA *lpdm;
421 DWORD ret;
422 pi = PSDRV_FindPrinterInfo(lpszDevice);
424 TRACE("%s %s %s, %u, %p, %p\n", debugstr_a(lpszDriver), debugstr_a(lpszDevice),
425 debugstr_a(lpszPort), fwCapability, lpszOutput, lpDevMode);
427 if (!pi) {
428 ERR("no printer info for %s %s, return 0!\n",
429 debugstr_a(lpszDriver), debugstr_a(lpszDevice));
430 return 0;
433 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
435 switch(fwCapability) {
437 case DC_PAPERS:
439 PAGESIZE *ps;
440 WORD *wp = (WORD *)lpszOutput;
441 int i = 0;
443 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
445 TRACE("DC_PAPERS: %u\n", ps->WinPage);
446 i++;
447 if(lpszOutput != NULL)
448 *wp++ = ps->WinPage;
450 return i;
453 case DC_PAPERSIZE:
455 PAGESIZE *ps;
456 POINT16 *pt = (POINT16 *)lpszOutput;
457 int i = 0;
459 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
461 TRACE("DC_PAPERSIZE: %f x %f\n", ps->PaperDimension->x, ps->PaperDimension->y);
462 i++;
463 if(lpszOutput != NULL) {
464 pt->x = paper_size_from_points( ps->PaperDimension->x );
465 pt->y = paper_size_from_points( ps->PaperDimension->y );
466 pt++;
469 return i;
472 case DC_PAPERNAMES:
474 PAGESIZE *ps;
475 char *cp = lpszOutput;
476 int i = 0;
478 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
480 TRACE("DC_PAPERNAMES: %s\n", debugstr_a(ps->FullName));
481 i++;
482 if(lpszOutput != NULL) {
483 lstrcpynA(cp, ps->FullName, 64);
484 cp += 64;
487 return i;
490 case DC_ORIENTATION:
491 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
493 case DC_BINS:
495 INPUTSLOT *slot;
496 WORD *wp = (WORD *)lpszOutput;
497 int i = 0;
499 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
500 if(lpszOutput != NULL)
501 *wp++ = slot->WinBin;
502 return i;
505 case DC_BINNAMES:
507 INPUTSLOT *slot;
508 char *cp = lpszOutput;
509 int i = 0;
511 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
512 if(lpszOutput != NULL) {
513 lstrcpynA(cp, slot->FullName, 24);
514 cp += 24;
516 return i;
519 case DC_BINADJUST:
520 FIXME("DC_BINADJUST: stub.\n");
521 return DCBA_FACEUPNONE;
523 case DC_ENUMRESOLUTIONS:
525 LONG *lp = (LONG*)lpszOutput;
527 if(lpszOutput != NULL) {
528 lp[0] = pi->ppd->DefaultResolution;
529 lp[1] = pi->ppd->DefaultResolution;
531 return 1;
534 /* Windows returns 9999 too */
535 case DC_COPIES:
536 TRACE("DC_COPIES: returning 9999\n");
537 return 9999;
539 case DC_DRIVER:
540 return lpdm->dmDriverVersion;
542 case DC_DATATYPE_PRODUCED:
543 FIXME("DATA_TYPE_PRODUCED: stub.\n");
544 return -1; /* simulate that the driver supports 'RAW' */
546 case DC_DUPLEX:
547 ret = 0;
548 if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
549 ret = 1;
550 TRACE("DC_DUPLEX: returning %d\n", ret);
551 return ret;
553 case DC_EMF_COMPLIANT:
554 FIXME("DC_EMF_COMPLIANT: stub.\n");
555 return -1; /* simulate that the driver do not support EMF */
557 case DC_EXTRA:
558 return lpdm->dmDriverExtra;
560 case DC_FIELDS:
561 return lpdm->dmFields;
563 case DC_FILEDEPENDENCIES:
564 FIXME("DC_FILEDEPENDENCIES: stub.\n");
565 return 0;
567 case DC_MAXEXTENT:
569 PAGESIZE *ps;
570 float x = 0, y = 0;
572 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
574 if (ps->PaperDimension->x > x) x = ps->PaperDimension->x;
575 if (ps->PaperDimension->y > y) y = ps->PaperDimension->y;
577 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
580 case DC_MINEXTENT:
582 PAGESIZE *ps;
583 float x = 1e6, y = 1e6;
585 LIST_FOR_EACH_ENTRY(ps, &pi->ppd->PageSizes, PAGESIZE, entry)
587 if (ps->PaperDimension->x < x) x = ps->PaperDimension->x;
588 if (ps->PaperDimension->y < y) y = ps->PaperDimension->y;
590 return MAKELONG( paper_size_from_points(x), paper_size_from_points(y) );
593 case DC_SIZE:
594 return lpdm->dmSize;
596 case DC_TRUETYPE:
597 FIXME("DC_TRUETYPE: stub\n");
598 return DCTT_SUBDEV;
600 case DC_VERSION:
601 return lpdm->dmSpecVersion;
603 /* We'll just return false here, very few printers can collate anyway */
604 case DC_COLLATE:
605 TRACE("DC_COLLATE: returning FALSE\n");
606 return FALSE;
608 /* Printer supports colour printing - 1 if yes, 0 if no (Win2k/XP only) */
609 case DC_COLORDEVICE:
610 return (pi->ppd->ColorDevice != CD_False) ? TRUE : FALSE;
612 /* Identification number of the printer manufacturer for use with ICM (Win9x only) */
613 case DC_MANUFACTURER:
614 FIXME("DC_MANUFACTURER: stub\n");
615 return -1;
617 /* Identification number of the printer model for use with ICM (Win9x only) */
618 case DC_MODEL:
619 FIXME("DC_MODEL: stub\n");
620 return -1;
622 /* Nonzero if the printer supports stapling, zero otherwise (Win2k/XP only) */
623 case DC_STAPLE: /* WINVER >= 0x0500 */
624 FIXME("DC_STAPLE: stub\n");
625 return -1;
627 /* Returns an array of 64-character string buffers containing the names of the paper forms
628 * available for use, unless pOutput is NULL. The return value is the number of paper forms.
629 * (Win2k/XP only)
631 case DC_MEDIAREADY: /* WINVER >= 0x0500 */
632 FIXME("DC_MEDIAREADY: stub\n");
633 return -1;
635 /* Returns an array of 64-character string buffers containing the names of the supported
636 * media types, unless pOutput is NULL. The return value is the number of supported.
637 * media types (XP only)
639 case DC_MEDIATYPENAMES: /* WINVER >= 0x0501 */
640 FIXME("DC_MEDIATYPENAMES: stub\n");
641 return -1;
643 /* Returns an array of DWORD values which represent the supported media types, unless
644 * pOutput is NULL. The return value is the number of supported media types. (XP only)
646 case DC_MEDIATYPES: /* WINVER >= 0x0501 */
647 FIXME("DC_MEDIATYPES: stub\n");
648 return -1;
650 /* Returns an array of DWORD values, each representing a supported number of document
651 * pages per printed page, unless pOutput is NULL. The return value is the number of
652 * array entries. (Win2k/XP only)
654 case DC_NUP:
655 FIXME("DC_NUP: stub\n");
656 return -1;
658 /* Returns an array of 32-character string buffers containing a list of printer description
659 * languages supported by the printer, unless pOutput is NULL. The return value is
660 * number of array entries. (Win2k/XP only)
663 case DC_PERSONALITY: /* WINVER >= 0x0500 */
664 FIXME("DC_PERSONALITY: stub\n");
665 return -1;
667 /* Returns the amount of printer memory in kilobytes. (Win2k/XP only) */
668 case DC_PRINTERMEM: /* WINVER >= 0x0500 */
669 FIXME("DC_PRINTERMEM: stub\n");
670 return -1;
672 /* Returns the printer's print rate in PRINTRATEUNIT units. (Win2k/XP only) */
673 case DC_PRINTRATE: /* WINVER >= 0x0500 */
674 FIXME("DC_PRINTRATE: stub\n");
675 return -1;
677 /* Returns the printer's print rate in pages per minute. (Win2k/XP only) */
678 case DC_PRINTRATEPPM: /* WINVER >= 0x0500 */
679 FIXME("DC_PRINTRATEPPM: stub\n");
680 return -1;
682 /* Returns the printer rate unit used for DC_PRINTRATE, which is one of
683 * PRINTRATEUNIT_{CPS,IPM,LPM,PPM} (Win2k/XP only)
685 case DC_PRINTRATEUNIT: /* WINVER >= 0x0500 */
686 FIXME("DC_PRINTRATEUNIT: stub\n");
687 return -1;
689 default:
690 FIXME("Unsupported capability %d\n", fwCapability);
692 return -1;
695 #if 0
696 typedef struct {
697 DWORD nPages;
698 DWORD Unknown;
699 HPROPSHEETPAGE hPages[10];
700 } EDMPS;
702 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
703 LPVOID pPropSheet)
705 EDMPS *ps = pPropSheet;
706 PROPSHEETPAGE psp;
708 psp->dwSize = sizeof(psp);
709 psp->hInstance = 0x1234;
711 ps->nPages = 1;
715 #endif