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)) {
338 memcpy(lpdmOutput, pi->Devmode, sizeof(DEVMODEA));
343 /**************************************************************
345 * PSDRV_ExtDeviceMode
347 INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
348 LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
349 LPSTR lpszProfile, DWORD dwMode)
351 return PSDRV_ExtDeviceMode16(hwnd, 0, lpdmOutput, lpszDevice, lpszPort,
352 lpdmInput, lpszProfile, dwMode);
355 /***********************************************************************
356 * DeviceCapabilities [WINEPS16.91]
359 DWORD WINAPI PSDRV_DeviceCapabilities16(LPCSTR lpszDevice, LPCSTR lpszPort,
360 WORD fwCapability, LPSTR lpszOutput,
361 LPDEVMODEA lpDevMode)
365 pi = PSDRV_FindPrinterInfo(lpszDevice);
367 TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability, pi);
371 ERR("no printerinfo for %s, return 0!\n",lpszDevice);
376 lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
378 switch(fwCapability) {
383 WORD *wp = (WORD *)lpszOutput;
386 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
387 if(lpszOutput != NULL)
395 POINT16 *pt = (POINT16 *)lpszOutput;
398 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
399 if(lpszOutput != NULL) {
400 pt->x = ps->PaperDimension->x * 254.0 / 72.0;
401 pt->y = ps->PaperDimension->y * 254.0 / 72.0;
410 char *cp = lpszOutput;
413 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
414 if(lpszOutput != NULL) {
415 lstrcpynA(cp, ps->FullName, 64);
422 return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
427 WORD *wp = (WORD *)lpszOutput;
430 /* We explicitly list DMBIN_AUTO first; actually while win9x does this
431 win2000 lists DMBIN_FORMSOURCE instead. */
433 if(lpszOutput != NULL)
436 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
437 if(lpszOutput != NULL)
438 *wp++ = slot->WinBin;
445 char *cp = lpszOutput;
448 /* Add an entry corresponding to DMBIN_AUTO, see DC_BINS */
450 if(lpszOutput != NULL) {
451 strcpy(cp, "Automatically Select");
455 for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
456 if(lpszOutput != NULL) {
457 lstrcpynA(cp, slot->FullName, 24);
464 FIXME("DC_BINADJUST: stub.\n");
465 return DCBA_FACEUPNONE;
467 case DC_ENUMRESOLUTIONS:
469 LONG *lp = (LONG*)lpszOutput;
471 if(lpszOutput != NULL) {
472 lp[0] = (LONG)pi->ppd->DefaultResolution;
473 lp[1] = (LONG)pi->ppd->DefaultResolution;
479 FIXME("DC_COPIES: returning %d. Is this correct?\n", lpdm->dmCopies);
480 return lpdm->dmCopies;
483 return lpdm->dmDriverVersion;
485 case DC_DATATYPE_PRODUCED:
486 FIXME("DATA_TYPE_PRODUCED: stub.\n");
487 return -1; /* simulate that the driver supports 'RAW' */
490 FIXME("DC_DUPLEX: returning %d. Is this correct?\n", lpdm->dmDuplex);
491 return lpdm->dmDuplex;
493 case DC_EMF_COMPLIANT:
494 FIXME("DC_EMF_COMPLIANT: stub.\n");
495 return -1; /* simulate that the driver do not support EMF */
498 return lpdm->dmDriverExtra;
501 return lpdm->dmFields;
503 case DC_FILEDEPENDENCIES:
504 FIXME("DC_FILEDEPENDENCIES: stub.\n");
512 ptMax.x = ptMax.y = 0;
514 if(lpszOutput == NULL)
518 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
519 if(ps->PaperDimension->x > ptMax.x)
520 ptMax.x = ps->PaperDimension->x;
521 if(ps->PaperDimension->y > ptMax.y)
522 ptMax.y = ps->PaperDimension->y;
524 *((POINT*)lpszOutput) = ptMax;
533 ptMax.x = ptMax.y = 0;
535 if(lpszOutput == NULL)
539 for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
540 if(ps->PaperDimension->x > ptMax.x)
541 ptMax.x = ps->PaperDimension->x;
542 if(ps->PaperDimension->y > ptMax.y)
543 ptMax.y = ps->PaperDimension->y;
545 *((POINT*)lpszOutput) = ptMax;
553 FIXME("DC_TRUETYPE: stub\n");
557 return lpdm->dmSpecVersion;
560 FIXME("Unsupported capability %d\n", fwCapability);
565 /**************************************************************
567 * PSDRV_DeviceCapabilities
569 DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
570 LPCSTR lpszPort, WORD fwCapability,
571 LPSTR lpszOutput, LPDEVMODEA lpdm)
573 return PSDRV_DeviceCapabilities16(lpszDevice, lpszPort, fwCapability,
577 /***************************************************************
578 * DeviceMode [WINEPS16.13]
581 void WINAPI PSDRV_DeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
582 LPSTR lpszDevice, LPSTR lpszPort)
584 PSDRV_ExtDeviceMode16( hwnd, hDriver, NULL, lpszDevice, lpszPort, NULL,
593 HPROPSHEETPAGE hPages[10];
596 INT PSDRV_ExtDeviceModePropSheet(HWND hwnd, LPSTR lpszDevice, LPSTR lpszPort,
599 EDMPS *ps = pPropSheet;
602 psp->dwSize = sizeof(psp);
603 psp->hInstance = 0x1234;