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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
36 /************************************************************************
40 * Updates dm1 with some fields from dm2
43 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
46 /* some sanity checks here on dm2 */
48 if(dm2->dmPublic.dmFields & DM_ORIENTATION) {
49 dm1->dmPublic.u1.s1.dmOrientation = dm2->dmPublic.u1.s1.dmOrientation;
50 TRACE("Changing orientation to %d (%s)\n",
51 dm1->dmPublic.u1.s1.dmOrientation,
52 dm1->dmPublic.u1.s1.dmOrientation == DMORIENT_PORTRAIT ?
54 (dm1->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE ?
55 "Landscape" : "unknown"));
58 /* NB PaperWidth is always < PaperLength */
59 if(dm2->dmPublic.dmFields & DM_PAPERSIZE) {
62 for(page = pi->ppd->PageSizes; page; page = page->next) {
63 if(page->WinPage == dm2->dmPublic.u1.s1.dmPaperSize)
67 dm1->dmPublic.u1.s1.dmPaperSize = dm2->dmPublic.u1.s1.dmPaperSize;
68 dm1->dmPublic.u1.s1.dmPaperWidth = page->PaperDimension->x *
70 dm1->dmPublic.u1.s1.dmPaperLength = page->PaperDimension->y *
72 dm1->dmPublic.dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH);
73 dm1->dmPublic.dmFields |= DM_PAPERSIZE;
74 TRACE("Changing page to %s %d x %d\n", page->FullName,
75 dm1->dmPublic.u1.s1.dmPaperWidth,
76 dm1->dmPublic.u1.s1.dmPaperLength );
78 TRACE("Trying to change to unsupported pagesize %d\n",
79 dm2->dmPublic.u1.s1.dmPaperSize);
81 } else if((dm2->dmPublic.dmFields & DM_PAPERLENGTH) &&
82 (dm2->dmPublic.dmFields & DM_PAPERWIDTH)) {
83 dm1->dmPublic.u1.s1.dmPaperLength = dm2->dmPublic.u1.s1.dmPaperLength;
84 dm1->dmPublic.u1.s1.dmPaperWidth = dm2->dmPublic.u1.s1.dmPaperWidth;
85 TRACE("Changing PaperLength|Width to %dx%d\n",
86 dm2->dmPublic.u1.s1.dmPaperLength,
87 dm2->dmPublic.u1.s1.dmPaperWidth);
88 dm1->dmPublic.dmFields &= ~DM_PAPERSIZE;
89 dm1->dmPublic.dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
90 } else if(dm2->dmPublic.dmFields & (DM_PAPERLENGTH | DM_PAPERWIDTH)) {
91 /* You might think that this would be allowed if dm1 is in custom size
92 mode, but apparently Windows reverts to standard paper mode even in
94 FIXME("Trying to change only paperlength or paperwidth\n");
95 dm1->dmPublic.dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH);
96 dm1->dmPublic.dmFields |= DM_PAPERSIZE;
99 if(dm2->dmPublic.dmFields & DM_SCALE) {
100 dm1->dmPublic.dmScale = dm2->dmPublic.dmScale;
101 TRACE("Changing Scale to %d\n", dm2->dmPublic.dmScale);
104 if(dm2->dmPublic.dmFields & DM_COPIES) {
105 dm1->dmPublic.dmCopies = dm2->dmPublic.dmCopies;
106 TRACE("Changing Copies to %d\n", dm2->dmPublic.dmCopies);
109 if(dm2->dmPublic.dmFields & DM_DEFAULTSOURCE) {
112 for(slot = pi->ppd->InputSlots; slot; slot = slot->next) {
113 if(slot->WinBin == dm2->dmPublic.dmDefaultSource)
117 dm1->dmPublic.dmDefaultSource = dm2->dmPublic.dmDefaultSource;
118 TRACE("Changing bin to '%s'\n", slot->FullName);
120 TRACE("Trying to change to unsupported bin %d\n",
121 dm2->dmPublic.dmDefaultSource);
125 if (dm2->dmPublic.dmFields & DM_DEFAULTSOURCE )
126 dm1->dmPublic.dmDefaultSource = dm2->dmPublic.dmDefaultSource;
127 if (dm2->dmPublic.dmFields & DM_PRINTQUALITY )
128 dm1->dmPublic.dmPrintQuality = dm2->dmPublic.dmPrintQuality;
129 if (dm2->dmPublic.dmFields & DM_COLOR )
130 dm1->dmPublic.dmColor = dm2->dmPublic.dmColor;
131 if (dm2->dmPublic.dmFields & DM_DUPLEX )
132 dm1->dmPublic.dmDuplex = dm2->dmPublic.dmDuplex;
133 if (dm2->dmPublic.dmFields & DM_YRESOLUTION )
134 dm1->dmPublic.dmYResolution = dm2->dmPublic.dmYResolution;
135 if (dm2->dmPublic.dmFields & DM_TTOPTION )
136 dm1->dmPublic.dmTTOption = dm2->dmPublic.dmTTOption;
137 if (dm2->dmPublic.dmFields & DM_COLLATE )
138 dm1->dmPublic.dmCollate = dm2->dmPublic.dmCollate;
139 if (dm2->dmPublic.dmFields & DM_FORMNAME )
140 lstrcpynA(dm1->dmPublic.dmFormName, dm2->dmPublic.dmFormName, CCHFORMNAME);
141 if (dm2->dmPublic.dmFields & DM_BITSPERPEL )
142 dm1->dmPublic.dmBitsPerPel = dm2->dmPublic.dmBitsPerPel;
143 if (dm2->dmPublic.dmFields & DM_PELSWIDTH )
144 dm1->dmPublic.dmPelsWidth = dm2->dmPublic.dmPelsWidth;
145 if (dm2->dmPublic.dmFields & DM_PELSHEIGHT )
146 dm1->dmPublic.dmPelsHeight = dm2->dmPublic.dmPelsHeight;
147 if (dm2->dmPublic.dmFields & DM_DISPLAYFLAGS )
148 dm1->dmPublic.dmDisplayFlags = dm2->dmPublic.dmDisplayFlags;
149 if (dm2->dmPublic.dmFields & DM_DISPLAYFREQUENCY )
150 dm1->dmPublic.dmDisplayFrequency = dm2->dmPublic.dmDisplayFrequency;
151 if (dm2->dmPublic.dmFields & DM_POSITION )
152 dm1->dmPublic.u1.dmPosition = dm2->dmPublic.u1.dmPosition;
153 if (dm2->dmPublic.dmFields & DM_LOGPIXELS )
154 dm1->dmPublic.dmLogPixels = dm2->dmPublic.dmLogPixels;
155 if (dm2->dmPublic.dmFields & DM_ICMMETHOD )
156 dm1->dmPublic.dmICMMethod = dm2->dmPublic.dmICMMethod;
157 if (dm2->dmPublic.dmFields & DM_ICMINTENT )
158 dm1->dmPublic.dmICMIntent = dm2->dmPublic.dmICMIntent;
159 if (dm2->dmPublic.dmFields & DM_MEDIATYPE )
160 dm1->dmPublic.dmMediaType = dm2->dmPublic.dmMediaType;
161 if (dm2->dmPublic.dmFields & DM_DITHERTYPE )
162 dm1->dmPublic.dmDitherType = dm2->dmPublic.dmDitherType;
163 if (dm2->dmPublic.dmFields & DM_PANNINGWIDTH )
164 dm1->dmPublic.dmPanningWidth = dm2->dmPublic.dmPanningWidth;
165 if (dm2->dmPublic.dmFields & DM_PANNINGHEIGHT )
166 dm1->dmPublic.dmPanningHeight = dm2->dmPublic.dmPanningHeight;
172 /**************************************************************
173 * AdvancedSetupDialog [WINEPS16.93]
176 WORD WINAPI PSDRV_AdvancedSetupDialog16(HWND16 hwnd, HANDLE16 hDriver,
177 LPDEVMODEA devin, LPDEVMODEA devout)
180 TRACE("hwnd = %04x, hDriver = %04x devin=%p devout=%p\n", hwnd,
181 hDriver, devin, devout);
185 /****************************************************************
188 * Dialog proc for 'Paper' propsheet
190 BOOL WINAPI PSDRV_PaperDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
200 di = (PSDRV_DLGINFO*)((PROPSHEETPAGEA*)lParam)->lParam;
201 SetWindowLongA(hwnd, DWL_USER, (LONG)di);
203 for(ps = di->pi->ppd->PageSizes, i = 0; ps; ps = ps->next, i++) {
204 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_INSERTSTRING, i,
205 (LPARAM)ps->FullName);
206 if(di->pi->Devmode->dmPublic.u1.s1.dmPaperSize == ps->WinPage)
209 SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
211 CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
212 di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
213 DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
214 IDD_ORIENT_LANDSCAPE);
218 di = (PSDRV_DLGINFO *)GetWindowLongA(hwnd, DWL_USER);
219 switch(LOWORD(wParam)) {
221 if(HIWORD(wParam) == LBN_SELCHANGE) {
222 Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), LB_GETCURSEL, 0, 0);
223 for(i = 0, ps = di->pi->ppd->PageSizes; i < Cursel; i++, ps = ps->next)
225 TRACE("Setting pagesize to item %d Winpage = %d\n", Cursel,
227 di->dlgdm->dmPublic.u1.s1.dmPaperSize = ps->WinPage;
230 case IDD_ORIENT_PORTRAIT:
231 case IDD_ORIENT_LANDSCAPE:
232 TRACE("Setting orientation to %s\n", wParam == IDD_ORIENT_PORTRAIT ?
233 "portrait" : "landscape");
234 di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
235 DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
242 NMHDR *nmhdr = (NMHDR *)lParam;
243 di = (PSDRV_DLGINFO *)GetWindowLongA(hwnd, DWL_USER);
244 switch(nmhdr->code) {
246 memcpy(di->pi->Devmode, di->dlgdm, sizeof(PSDRV_DEVMODEA));
247 SetWindowLongA(hwnd, DWL_MSGRESULT, PSNRET_NOERROR);
265 static void (WINAPI *pInitCommonControls) (void);
266 static HPROPSHEETPAGE (WINAPI *pCreatePropertySheetPage) (LPCPROPSHEETPAGEW);
267 static int (WINAPI *pPropertySheet) (LPCPROPSHEETHEADERW);
269 /***************************************************************
270 * ExtDeviceMode [WINEPS16.90]
272 * Just returns default devmode at the moment
274 INT16 WINAPI PSDRV_ExtDeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
275 LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
276 LPSTR lpszPort, LPDEVMODEA lpdmInput,
277 LPSTR lpszProfile, WORD fwMode)
279 PRINTERINFO *pi = PSDRV_FindPrinterInfo(lpszDevice);
282 TRACE("(hwnd=%04x, hDriver=%04x, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
283 hwnd, hDriver, lpdmOutput, lpszDevice, lpszPort, lpdmInput, lpszProfile,
287 return sizeof(DEVMODEA); /* Just copy dmPublic bit of PSDRV_DEVMODE */
289 if((fwMode & DM_MODIFY) && lpdmInput) {
290 TRACE("DM_MODIFY set. devIn->dmFields = %08lx\n", lpdmInput->dmFields);
291 PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
294 if(fwMode & DM_PROMPT) {
295 HINSTANCE hinstComctl32, hinstWineps32 = LoadLibraryA("WINEPS");
296 HPROPSHEETPAGE hpsp[1];
298 PROPSHEETHEADERW psh;
300 PSDRV_DEVMODEA *dlgdm;
301 static const WCHAR PAPERW[] = {'P','A','P','E','R','\0'};
302 static const WCHAR SetupW[] = {'S','e','t','u','p','\0'};
304 hinstComctl32 = LoadLibraryA("comctl32.dll");
305 pInitCommonControls = (void*)GetProcAddress(hinstComctl32,
306 "InitCommonControls");
307 pCreatePropertySheetPage = (void*)GetProcAddress(hinstComctl32,
308 "CreatePropertySheetPageW");
309 pPropertySheet = (void*)GetProcAddress(hinstComctl32, "PropertySheetW");
310 memset(&psp,0,sizeof(psp));
311 dlgdm = HeapAlloc( PSDRV_Heap, 0, sizeof(*dlgdm) );
312 memcpy(dlgdm, pi->Devmode, sizeof(*dlgdm));
313 di = HeapAlloc( PSDRV_Heap, 0, sizeof(*di) );
316 psp.dwSize = sizeof(psp);
317 psp.hInstance = hinstWineps32;
318 psp.u.pszTemplate = PAPERW;
319 psp.u2.pszIcon = NULL;
320 psp.pfnDlgProc = PSDRV_PaperDlgProc;
321 psp.lParam = (LPARAM)di;
322 hpsp[0] = pCreatePropertySheetPage(&psp);
324 memset(&psh, 0, sizeof(psh));
325 psh.dwSize = sizeof(psh);
326 psh.pszCaption = SetupW;
328 psh.hwndParent = hwnd;
329 psh.u3.phpage = hpsp;
331 pPropertySheet(&psh);
334 if(fwMode & DM_UPDATE)
335 FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
337 if((fwMode & DM_COPY) || (fwMode & DM_UPDATE)) {
339 memcpy(lpdmOutput, pi->Devmode, sizeof(DEVMODEA));
341 FIXME("lpdmOutput is NULL what should we do??\n");
346 /**************************************************************
348 * PSDRV_ExtDeviceMode
350 INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
351 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
352 LPSTR lpszProfile, DWORD dwMode)
354 return PSDRV_ExtDeviceMode16(hwnd, 0, lpdmOutput, lpszDevice, lpszPort,
355 lpdmInput, lpszProfile, dwMode);
358 /***********************************************************************
359 * DeviceCapabilities [WINEPS16.91]
362 DWORD WINAPI PSDRV_DeviceCapabilities16(LPCSTR lpszDevice, LPCSTR lpszPort,
363 WORD fwCapability, LPSTR lpszOutput,
364 LPDEVMODEA lpDevMode)
368 pi = PSDRV_FindPrinterInfo(lpszDevice);
370 TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability, pi);
374 ERR("no printerinfo for %s, return 0!\n",lpszDevice);
379 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
381 switch(fwCapability) {
386 WORD *wp = (WORD *)lpszOutput;
389 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
390 if(lpszOutput != NULL)
398 POINT16 *pt = (POINT16 *)lpszOutput;
401 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
402 if(lpszOutput != NULL) {
403 pt->x = ps->PaperDimension->x * 254.0 / 72.0;
404 pt->y = ps->PaperDimension->y * 254.0 / 72.0;
413 char *cp = lpszOutput;
416 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
417 if(lpszOutput != NULL) {
418 lstrcpynA(cp, ps->FullName, 64);
425 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
430 WORD *wp = (WORD *)lpszOutput;
433 /* We explicitly list DMBIN_AUTO first; actually while win9x does this
434 win2000 lists DMBIN_FORMSOURCE instead. */
436 if(lpszOutput != NULL)
439 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
440 if(lpszOutput != NULL)
441 *wp++ = slot->WinBin;
448 char *cp = lpszOutput;
451 /* Add an entry corresponding to DMBIN_AUTO, see DC_BINS */
453 if(lpszOutput != NULL) {
454 strcpy(cp, "Automatically Select");
458 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
459 if(lpszOutput != NULL) {
460 lstrcpynA(cp, slot->FullName, 24);
467 FIXME("DC_BINADJUST: stub.\n");
468 return DCBA_FACEUPNONE;
470 case DC_ENUMRESOLUTIONS:
472 LONG *lp = (LONG*)lpszOutput;
474 if(lpszOutput != NULL) {
475 lp[0] = (LONG)pi->ppd->DefaultResolution;
476 lp[1] = (LONG)pi->ppd->DefaultResolution;
482 FIXME("DC_COPIES: returning %d. Is this correct?\n", lpdm->dmCopies);
483 return lpdm->dmCopies;
486 return lpdm->dmDriverVersion;
488 case DC_DATATYPE_PRODUCED:
489 FIXME("DATA_TYPE_PRODUCED: stub.\n");
490 return -1; /* simulate that the driver supports 'RAW' */
493 FIXME("DC_DUPLEX: returning %d. Is this correct?\n", lpdm->dmDuplex);
494 return lpdm->dmDuplex;
496 case DC_EMF_COMPLIANT:
497 FIXME("DC_EMF_COMPLIANT: stub.\n");
498 return -1; /* simulate that the driver do not support EMF */
501 return lpdm->dmDriverExtra;
504 return lpdm->dmFields;
506 case DC_FILEDEPENDENCIES:
507 FIXME("DC_FILEDEPENDENCIES: stub.\n");
515 ptMax.x = ptMax.y = 0;
517 if(lpszOutput == NULL)
521 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
522 if(ps->PaperDimension->x > ptMax.x)
523 ptMax.x = ps->PaperDimension->x;
524 if(ps->PaperDimension->y > ptMax.y)
525 ptMax.y = ps->PaperDimension->y;
527 *((POINT*)lpszOutput) = ptMax;
536 ptMax.x = ptMax.y = 0;
538 if(lpszOutput == NULL)
542 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
543 if(ps->PaperDimension->x > ptMax.x)
544 ptMax.x = ps->PaperDimension->x;
545 if(ps->PaperDimension->y > ptMax.y)
546 ptMax.y = ps->PaperDimension->y;
548 *((POINT*)lpszOutput) = ptMax;
556 FIXME("DC_TRUETYPE: stub\n");
560 return lpdm->dmSpecVersion;
563 FIXME("Unsupported capability %d\n", fwCapability);
568 /**************************************************************
570 * PSDRV_DeviceCapabilities
572 DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
573 LPCSTR lpszPort, WORD fwCapability,
574 LPSTR lpszOutput, LPDEVMODEA lpdm)
576 return PSDRV_DeviceCapabilities16(lpszDevice, lpszPort, fwCapability,
580 /***************************************************************
581 * DeviceMode [WINEPS16.13]
584 void WINAPI PSDRV_DeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
585 LPSTR lpszDevice, LPSTR lpszPort)
587 PSDRV_ExtDeviceMode16( hwnd, hDriver, NULL, lpszDevice, lpszPort, NULL,
596 HPROPSHEETPAGE hPages[10];
599 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
602 EDMPS *ps = pPropSheet;
605 psp->dwSize = sizeof(psp);
606 psp->hInstance = 0x1234;