xref: /aoo42x/main/vcl/win/source/gdi/salprn.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <string.h>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <osl/module.h>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <tools/urlobj.hxx>
36*cdf0e10cSrcweir #include <tools/svwin.h>
37*cdf0e10cSrcweir #ifdef __MINGW32__
38*cdf0e10cSrcweir #include <excpt.h>
39*cdf0e10cSrcweir #endif
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include <win/wincomp.hxx>
42*cdf0e10cSrcweir #include <win/saldata.hxx>
43*cdf0e10cSrcweir #include <win/salinst.h>
44*cdf0e10cSrcweir #include <win/salgdi.h>
45*cdf0e10cSrcweir #include <win/salframe.h>
46*cdf0e10cSrcweir #include <win/salprn.h>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include <salptype.hxx>
49*cdf0e10cSrcweir #include <print.h>
50*cdf0e10cSrcweir #include <jobset.h>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
57*cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
58*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir #include <malloc.h>
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir #ifdef __MINGW32__
63*cdf0e10cSrcweir #define CATCH_DRIVER_EX_BEGIN                                               \
64*cdf0e10cSrcweir     jmp_buf jmpbuf;                                                         \
65*cdf0e10cSrcweir     __SEHandler han;                                                        \
66*cdf0e10cSrcweir     if (__builtin_setjmp(jmpbuf) == 0)                                      \
67*cdf0e10cSrcweir     {                                                                       \
68*cdf0e10cSrcweir         han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER)
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir #define CATCH_DRIVER_EX_END(mes, p)                                         \
71*cdf0e10cSrcweir     }                                                                       \
72*cdf0e10cSrcweir     han.Reset()
73*cdf0e10cSrcweir #define CATCH_DRIVER_EX_END_2(mes)                                            \
74*cdf0e10cSrcweir     }                                                                       \
75*cdf0e10cSrcweir     han.Reset()
76*cdf0e10cSrcweir #else
77*cdf0e10cSrcweir #define CATCH_DRIVER_EX_BEGIN                                               \
78*cdf0e10cSrcweir     __try                                                                   \
79*cdf0e10cSrcweir     {
80*cdf0e10cSrcweir #define CATCH_DRIVER_EX_END(mes, p)                                         \
81*cdf0e10cSrcweir     }                                                                       \
82*cdf0e10cSrcweir     __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))\
83*cdf0e10cSrcweir     {                                                                       \
84*cdf0e10cSrcweir         DBG_ERROR( mes );                                                   \
85*cdf0e10cSrcweir         p->markInvalid();                                                   \
86*cdf0e10cSrcweir     }
87*cdf0e10cSrcweir #define CATCH_DRIVER_EX_END_2(mes)                                         \
88*cdf0e10cSrcweir     }                                                                       \
89*cdf0e10cSrcweir     __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))\
90*cdf0e10cSrcweir     {                                                                       \
91*cdf0e10cSrcweir         DBG_ERROR( mes );                                                   \
92*cdf0e10cSrcweir     }
93*cdf0e10cSrcweir #endif
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir using namespace com::sun::star;
97*cdf0e10cSrcweir using namespace com::sun::star::uno;
98*cdf0e10cSrcweir using namespace com::sun::star::lang;
99*cdf0e10cSrcweir using namespace com::sun::star::ui::dialogs;
100*cdf0e10cSrcweir using namespace rtl;
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir // =======================================================================
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir static char aImplWindows[] = "windows";
105*cdf0e10cSrcweir static char aImplDevices[] = "devices";
106*cdf0e10cSrcweir static char aImplDevice[]  = "device";
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir static LPDEVMODEA SAL_DEVMODE_A( const ImplJobSetup* pSetupData )
109*cdf0e10cSrcweir {
110*cdf0e10cSrcweir     LPDEVMODEA pRet = NULL;
111*cdf0e10cSrcweir     SalDriverData* pDrv = (SalDriverData*)pSetupData->mpDriverData;
112*cdf0e10cSrcweir     if( pDrv->mnVersion == SAL_DRIVERDATA_VERSION_A &&
113*cdf0e10cSrcweir         pSetupData->mnDriverDataLen >= sizeof(DEVMODEA)+sizeof(SalDriverData)-1
114*cdf0e10cSrcweir         )
115*cdf0e10cSrcweir         pRet = ((LPDEVMODEA)((pSetupData->mpDriverData) + (pDrv->mnDriverOffset)));
116*cdf0e10cSrcweir     return pRet;
117*cdf0e10cSrcweir }
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir static LPDEVMODEW SAL_DEVMODE_W( const ImplJobSetup* pSetupData )
120*cdf0e10cSrcweir {
121*cdf0e10cSrcweir     LPDEVMODEW pRet = NULL;
122*cdf0e10cSrcweir     SalDriverData* pDrv = (SalDriverData*)pSetupData->mpDriverData;
123*cdf0e10cSrcweir     if( pDrv->mnVersion == SAL_DRIVERDATA_VERSION_W &&
124*cdf0e10cSrcweir         pSetupData->mnDriverDataLen >= sizeof(DEVMODEW)+sizeof(SalDriverData)-1
125*cdf0e10cSrcweir         )
126*cdf0e10cSrcweir         pRet = ((LPDEVMODEW)((pSetupData->mpDriverData) + (pDrv->mnDriverOffset)));
127*cdf0e10cSrcweir     return pRet;
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir // =======================================================================
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir static sal_uLong ImplWinQueueStatusToSal( DWORD nWinStatus )
133*cdf0e10cSrcweir {
134*cdf0e10cSrcweir 	sal_uLong nStatus = 0;
135*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PAUSED )
136*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PAUSED;
137*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_ERROR )
138*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_ERROR;
139*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PENDING_DELETION )
140*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PENDING_DELETION;
141*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PAPER_JAM )
142*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PAPER_JAM;
143*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PAPER_OUT )
144*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PAPER_OUT;
145*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_MANUAL_FEED )
146*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_MANUAL_FEED;
147*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PAPER_PROBLEM )
148*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PAPER_PROBLEM;
149*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_OFFLINE )
150*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_OFFLINE;
151*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_IO_ACTIVE )
152*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_IO_ACTIVE;
153*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_BUSY )
154*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_BUSY;
155*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PRINTING )
156*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PRINTING;
157*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_OUTPUT_BIN_FULL )
158*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_OUTPUT_BIN_FULL;
159*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_WAITING )
160*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_WAITING;
161*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PROCESSING )
162*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PROCESSING;
163*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_INITIALIZING )
164*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_INITIALIZING;
165*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_WARMING_UP )
166*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_WARMING_UP;
167*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_TONER_LOW )
168*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_TONER_LOW;
169*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_NO_TONER )
170*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_NO_TONER;
171*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_PAGE_PUNT )
172*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_PAGE_PUNT;
173*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_USER_INTERVENTION )
174*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_USER_INTERVENTION;
175*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_OUT_OF_MEMORY )
176*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_OUT_OF_MEMORY;
177*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_DOOR_OPEN )
178*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_DOOR_OPEN;
179*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_SERVER_UNKNOWN )
180*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_SERVER_UNKNOWN;
181*cdf0e10cSrcweir 	if ( nWinStatus & PRINTER_STATUS_POWER_SAVE )
182*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_POWER_SAVE;
183*cdf0e10cSrcweir 	if ( !nStatus && !(nWinStatus & PRINTER_STATUS_NOT_AVAILABLE) )
184*cdf0e10cSrcweir 		nStatus |= QUEUE_STATUS_READY;
185*cdf0e10cSrcweir 	return nStatus;
186*cdf0e10cSrcweir }
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir // -----------------------------------------------------------------------
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir static void getPrinterQueueInfoOldStyle( ImplPrnQueueList* pList )
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir 	DWORD			i;
193*cdf0e10cSrcweir 	DWORD			n;
194*cdf0e10cSrcweir 	DWORD			nBytes = 0;
195*cdf0e10cSrcweir 	DWORD			nInfoPrn2;
196*cdf0e10cSrcweir 	sal_Bool			bFound = FALSE;
197*cdf0e10cSrcweir 	PRINTER_INFO_2* pWinInfo2 = NULL;
198*cdf0e10cSrcweir 	PRINTER_INFO_2* pGetInfo2;
199*cdf0e10cSrcweir 	EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoPrn2 );
200*cdf0e10cSrcweir 	if ( nBytes )
201*cdf0e10cSrcweir 	{
202*cdf0e10cSrcweir 		pWinInfo2 = (PRINTER_INFO_2*) rtl_allocateMemory( nBytes );
203*cdf0e10cSrcweir 		if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoPrn2 ) )
204*cdf0e10cSrcweir 		{
205*cdf0e10cSrcweir 			pGetInfo2 = pWinInfo2;
206*cdf0e10cSrcweir 			for ( i = 0; i < nInfoPrn2; i++ )
207*cdf0e10cSrcweir 			{
208*cdf0e10cSrcweir 				SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
209*cdf0e10cSrcweir 				pInfo->maPrinterName = ImplSalGetUniString( pGetInfo2->pPrinterName );
210*cdf0e10cSrcweir 				pInfo->maDriver 	 = ImplSalGetUniString( pGetInfo2->pDriverName );
211*cdf0e10cSrcweir 				XubString aPortName;
212*cdf0e10cSrcweir 				if ( pGetInfo2->pPortName )
213*cdf0e10cSrcweir 					aPortName = ImplSalGetUniString( pGetInfo2->pPortName );
214*cdf0e10cSrcweir 				// pLocation can be 0 (the Windows docu doesn't describe this)
215*cdf0e10cSrcweir 				if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
216*cdf0e10cSrcweir 					pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
217*cdf0e10cSrcweir 				else
218*cdf0e10cSrcweir 					pInfo->maLocation = aPortName;
219*cdf0e10cSrcweir 				// pComment can be 0 (the Windows docu doesn't describe this)
220*cdf0e10cSrcweir 				if ( pGetInfo2->pComment )
221*cdf0e10cSrcweir 					pInfo->maComment = ImplSalGetUniString( pGetInfo2->pComment );
222*cdf0e10cSrcweir 				pInfo->mnStatus 	 = ImplWinQueueStatusToSal( pGetInfo2->Status );
223*cdf0e10cSrcweir 				pInfo->mnJobs		 = pGetInfo2->cJobs;
224*cdf0e10cSrcweir 				pInfo->mpSysData	 = new XubString( aPortName );
225*cdf0e10cSrcweir 				pList->Add( pInfo );
226*cdf0e10cSrcweir 				pGetInfo2++;
227*cdf0e10cSrcweir 			}
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 			bFound = TRUE;
230*cdf0e10cSrcweir 		}
231*cdf0e10cSrcweir 	}
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 	// read printers from win.ini
234*cdf0e10cSrcweir 	// TODO: MSDN: GetProfileString() should not be called from server
235*cdf0e10cSrcweir 	// code because it is just there for WIN16 compatibility
236*cdf0e10cSrcweir 	UINT	nSize = 4096;
237*cdf0e10cSrcweir 	char*	pBuf = new char[nSize];
238*cdf0e10cSrcweir 	UINT	nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
239*cdf0e10cSrcweir 	while ( nRead >= nSize-2 )
240*cdf0e10cSrcweir 	{
241*cdf0e10cSrcweir 		nSize += 2048;
242*cdf0e10cSrcweir 		delete []pBuf;
243*cdf0e10cSrcweir 		pBuf = new char[nSize];
244*cdf0e10cSrcweir 		nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
245*cdf0e10cSrcweir 	}
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir 	// extract printer names from buffer and fill list
248*cdf0e10cSrcweir 	char* pName = pBuf;
249*cdf0e10cSrcweir 	while ( *pName )
250*cdf0e10cSrcweir 	{
251*cdf0e10cSrcweir 		char*	pPortName;
252*cdf0e10cSrcweir 		char*	pTmp;
253*cdf0e10cSrcweir 		char	aPortBuf[256];
254*cdf0e10cSrcweir 		GetProfileStringA( aImplDevices, pName, "", aPortBuf, sizeof( aPortBuf ) );
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 		pPortName = aPortBuf;
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir 		// create name
259*cdf0e10cSrcweir 		xub_StrLen nNameLen = sal::static_int_cast<xub_StrLen>(strlen( pName ));
260*cdf0e10cSrcweir 		XubString aName( ImplSalGetUniString( pName, nNameLen ) );
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 		// get driver name
263*cdf0e10cSrcweir 		pTmp = pPortName;
264*cdf0e10cSrcweir 		while ( *pTmp != ',' )
265*cdf0e10cSrcweir 			pTmp++;
266*cdf0e10cSrcweir 		XubString aDriver( ImplSalGetUniString( pPortName, (sal_uInt16)(pTmp-pPortName) ) );
267*cdf0e10cSrcweir 		pPortName = pTmp;
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 		// get port names
270*cdf0e10cSrcweir 		do
271*cdf0e10cSrcweir 		{
272*cdf0e10cSrcweir 			pPortName++;
273*cdf0e10cSrcweir 			pTmp = pPortName;
274*cdf0e10cSrcweir 			while ( *pTmp && (*pTmp != ',') )
275*cdf0e10cSrcweir 				pTmp++;
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 			String aPortName( ImplSalGetUniString( pPortName, (sal_uInt16)(pTmp-pPortName) ) );
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir 			// create new entry
280*cdf0e10cSrcweir             // look up if printer was already found in first loop
281*cdf0e10cSrcweir 			sal_Bool bAdd = TRUE;
282*cdf0e10cSrcweir 			if ( pWinInfo2 )
283*cdf0e10cSrcweir 			{
284*cdf0e10cSrcweir 				pGetInfo2 = pWinInfo2;
285*cdf0e10cSrcweir 				for ( n = 0; n < nInfoPrn2; n++ )
286*cdf0e10cSrcweir 				{
287*cdf0e10cSrcweir 					if ( aName.EqualsIgnoreCaseAscii( pGetInfo2->pPrinterName ) )
288*cdf0e10cSrcweir 					{
289*cdf0e10cSrcweir 						bAdd = FALSE;
290*cdf0e10cSrcweir 						break;
291*cdf0e10cSrcweir 					}
292*cdf0e10cSrcweir 					pGetInfo2++;
293*cdf0e10cSrcweir 				}
294*cdf0e10cSrcweir 			}
295*cdf0e10cSrcweir 			// if it's a new printer, add it
296*cdf0e10cSrcweir 			if ( bAdd )
297*cdf0e10cSrcweir 			{
298*cdf0e10cSrcweir 				SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
299*cdf0e10cSrcweir 				pInfo->maPrinterName = aName;
300*cdf0e10cSrcweir 				pInfo->maDriver 	 = aDriver;
301*cdf0e10cSrcweir 				pInfo->maLocation	 = aPortName;
302*cdf0e10cSrcweir 				pInfo->mnStatus 	 = 0;
303*cdf0e10cSrcweir 				pInfo->mnJobs		 = QUEUE_JOBS_DONTKNOW;
304*cdf0e10cSrcweir 				pInfo->mpSysData	 = new XubString( aPortName );
305*cdf0e10cSrcweir 				pList->Add( pInfo );
306*cdf0e10cSrcweir 			}
307*cdf0e10cSrcweir 		}
308*cdf0e10cSrcweir 		while ( *pTmp == ',' );
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir 		pName += nNameLen + 1;
311*cdf0e10cSrcweir 	}
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 	delete []pBuf;
314*cdf0e10cSrcweir 	rtl_freeMemory( pWinInfo2 );
315*cdf0e10cSrcweir }
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir void WinSalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
318*cdf0e10cSrcweir {
319*cdf0e10cSrcweir     if( ! aSalShlData.mbWPrinter )
320*cdf0e10cSrcweir     {
321*cdf0e10cSrcweir         getPrinterQueueInfoOldStyle( pList );
322*cdf0e10cSrcweir         return;
323*cdf0e10cSrcweir     }
324*cdf0e10cSrcweir 	DWORD			i;
325*cdf0e10cSrcweir 	DWORD			nBytes = 0;
326*cdf0e10cSrcweir 	DWORD			nInfoPrn4 = 0;
327*cdf0e10cSrcweir 	PRINTER_INFO_4W* pWinInfo4 = NULL;
328*cdf0e10cSrcweir 	EnumPrintersW( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, NULL, 0, &nBytes, &nInfoPrn4 );
329*cdf0e10cSrcweir 	if ( nBytes )
330*cdf0e10cSrcweir 	{
331*cdf0e10cSrcweir 		pWinInfo4 = (PRINTER_INFO_4W*) rtl_allocateMemory( nBytes );
332*cdf0e10cSrcweir 		if ( EnumPrintersW( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, (LPBYTE)pWinInfo4, nBytes, &nBytes, &nInfoPrn4 ) )
333*cdf0e10cSrcweir 		{
334*cdf0e10cSrcweir 			for ( i = 0; i < nInfoPrn4; i++ )
335*cdf0e10cSrcweir 			{
336*cdf0e10cSrcweir 				SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
337*cdf0e10cSrcweir 				pInfo->maPrinterName = UniString( reinterpret_cast< const sal_Unicode* >(pWinInfo4[i].pPrinterName) );
338*cdf0e10cSrcweir 				pInfo->mnStatus 	 = 0;
339*cdf0e10cSrcweir 				pInfo->mnJobs		 = 0;
340*cdf0e10cSrcweir 				pInfo->mpSysData	 = NULL;
341*cdf0e10cSrcweir 				pList->Add( pInfo );
342*cdf0e10cSrcweir 			}
343*cdf0e10cSrcweir 		}
344*cdf0e10cSrcweir         rtl_freeMemory( pWinInfo4 );
345*cdf0e10cSrcweir 	}
346*cdf0e10cSrcweir }
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir // -----------------------------------------------------------------------
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir static void getPrinterQueueStateOldStyle( SalPrinterQueueInfo* pInfo )
351*cdf0e10cSrcweir {
352*cdf0e10cSrcweir 	DWORD				nBytes = 0;
353*cdf0e10cSrcweir 	DWORD				nInfoRet;
354*cdf0e10cSrcweir 	PRINTER_INFO_2* 	pWinInfo2;
355*cdf0e10cSrcweir 	EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoRet );
356*cdf0e10cSrcweir 	if ( nBytes )
357*cdf0e10cSrcweir 	{
358*cdf0e10cSrcweir 		pWinInfo2 = (PRINTER_INFO_2*) rtl_allocateMemory( nBytes );
359*cdf0e10cSrcweir 		if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoRet ) )
360*cdf0e10cSrcweir 		{
361*cdf0e10cSrcweir 			PRINTER_INFO_2* pGetInfo2 = pWinInfo2;
362*cdf0e10cSrcweir 			for ( DWORD i = 0; i < nInfoRet; i++ )
363*cdf0e10cSrcweir 			{
364*cdf0e10cSrcweir 				if ( pInfo->maPrinterName.EqualsAscii( pGetInfo2->pPrinterName ) &&
365*cdf0e10cSrcweir 					 ( pInfo->maDriver.Len() == 0 ||
366*cdf0e10cSrcweir                        pInfo->maDriver.EqualsAscii( pGetInfo2->pDriverName ) )
367*cdf0e10cSrcweir                        )
368*cdf0e10cSrcweir 				{
369*cdf0e10cSrcweir                     XubString aPortName;
370*cdf0e10cSrcweir                     if ( pGetInfo2->pPortName )
371*cdf0e10cSrcweir                         aPortName = ImplSalGetUniString( pGetInfo2->pPortName );
372*cdf0e10cSrcweir                     // pLocation can be 0 (the Windows docu doesn't describe this)
373*cdf0e10cSrcweir                     if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
374*cdf0e10cSrcweir                         pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
375*cdf0e10cSrcweir                     else
376*cdf0e10cSrcweir                         pInfo->maLocation = aPortName;
377*cdf0e10cSrcweir                     // pComment can be 0 (the Windows docu doesn't describe this)
378*cdf0e10cSrcweir                     if ( pGetInfo2->pComment )
379*cdf0e10cSrcweir                         pInfo->maComment = ImplSalGetUniString( pGetInfo2->pComment );
380*cdf0e10cSrcweir                     pInfo->mnStatus 	 = ImplWinQueueStatusToSal( pGetInfo2->Status );
381*cdf0e10cSrcweir                     pInfo->mnJobs		 = pGetInfo2->cJobs;
382*cdf0e10cSrcweir                     if( ! pInfo->mpSysData )
383*cdf0e10cSrcweir                         pInfo->mpSysData	 = new XubString( aPortName );
384*cdf0e10cSrcweir 					break;
385*cdf0e10cSrcweir 				}
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir 				pGetInfo2++;
388*cdf0e10cSrcweir 			}
389*cdf0e10cSrcweir 		}
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir 		rtl_freeMemory( pWinInfo2 );
392*cdf0e10cSrcweir 	}
393*cdf0e10cSrcweir }
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir void WinSalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
396*cdf0e10cSrcweir {
397*cdf0e10cSrcweir     if( ! aSalShlData.mbWPrinter )
398*cdf0e10cSrcweir     {
399*cdf0e10cSrcweir         getPrinterQueueStateOldStyle( pInfo );
400*cdf0e10cSrcweir         return;
401*cdf0e10cSrcweir     }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir     HANDLE hPrinter = 0;
404*cdf0e10cSrcweir     LPWSTR pPrnName = reinterpret_cast<LPWSTR>(const_cast<sal_Unicode*>(pInfo->maPrinterName.GetBuffer()));
405*cdf0e10cSrcweir     if( OpenPrinterW( pPrnName, &hPrinter, NULL ) )
406*cdf0e10cSrcweir     {
407*cdf0e10cSrcweir         DWORD				nBytes = 0;
408*cdf0e10cSrcweir         GetPrinterW( hPrinter, 2, NULL, 0, &nBytes );
409*cdf0e10cSrcweir         if( nBytes )
410*cdf0e10cSrcweir         {
411*cdf0e10cSrcweir             PRINTER_INFO_2W* pWinInfo2 = (PRINTER_INFO_2W*)rtl_allocateMemory(nBytes);
412*cdf0e10cSrcweir             if( GetPrinterW( hPrinter, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes ) )
413*cdf0e10cSrcweir             {
414*cdf0e10cSrcweir                 if( pWinInfo2->pDriverName )
415*cdf0e10cSrcweir                     pInfo->maDriver = String( reinterpret_cast< const sal_Unicode* >(pWinInfo2->pDriverName) );
416*cdf0e10cSrcweir                 XubString aPortName;
417*cdf0e10cSrcweir                 if ( pWinInfo2->pPortName )
418*cdf0e10cSrcweir                     aPortName = String( reinterpret_cast< const sal_Unicode* >(pWinInfo2->pPortName) );
419*cdf0e10cSrcweir                 // pLocation can be 0 (the Windows docu doesn't describe this)
420*cdf0e10cSrcweir                 if ( pWinInfo2->pLocation && *pWinInfo2->pLocation )
421*cdf0e10cSrcweir                     pInfo->maLocation = String( reinterpret_cast< const sal_Unicode* >(pWinInfo2->pLocation) );
422*cdf0e10cSrcweir                 else
423*cdf0e10cSrcweir                     pInfo->maLocation = aPortName;
424*cdf0e10cSrcweir                 // pComment can be 0 (the Windows docu doesn't describe this)
425*cdf0e10cSrcweir                 if ( pWinInfo2->pComment )
426*cdf0e10cSrcweir                     pInfo->maComment = String( reinterpret_cast< const sal_Unicode* >(pWinInfo2->pComment) );
427*cdf0e10cSrcweir                 pInfo->mnStatus 	 = ImplWinQueueStatusToSal( pWinInfo2->Status );
428*cdf0e10cSrcweir                 pInfo->mnJobs		 = pWinInfo2->cJobs;
429*cdf0e10cSrcweir                 if( ! pInfo->mpSysData )
430*cdf0e10cSrcweir                     pInfo->mpSysData	 = new XubString( aPortName );
431*cdf0e10cSrcweir             }
432*cdf0e10cSrcweir             rtl_freeMemory(pWinInfo2);
433*cdf0e10cSrcweir         }
434*cdf0e10cSrcweir         ClosePrinter( hPrinter );
435*cdf0e10cSrcweir     }
436*cdf0e10cSrcweir }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir // -----------------------------------------------------------------------
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir void WinSalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
441*cdf0e10cSrcweir {
442*cdf0e10cSrcweir 	delete (String*)(pInfo->mpSysData);
443*cdf0e10cSrcweir 	delete pInfo;
444*cdf0e10cSrcweir }
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir // -----------------------------------------------------------------------
447*cdf0e10cSrcweir XubString WinSalInstance::GetDefaultPrinter()
448*cdf0e10cSrcweir {
449*cdf0e10cSrcweir     static bool bGetDefPrtAPI = true;
450*cdf0e10cSrcweir     static sal_Bool(WINAPI*pGetDefaultPrinter)(LPWSTR,LPDWORD) = NULL;
451*cdf0e10cSrcweir     // try to use GetDefaultPrinter API (not available prior to W2000)
452*cdf0e10cSrcweir     if( bGetDefPrtAPI )
453*cdf0e10cSrcweir     {
454*cdf0e10cSrcweir         bGetDefPrtAPI = false;
455*cdf0e10cSrcweir         // check for W2k and XP
456*cdf0e10cSrcweir         if( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && aSalShlData.maVersionInfo.dwMajorVersion >= 5 )
457*cdf0e10cSrcweir         {
458*cdf0e10cSrcweir             OUString aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "winspool.drv" ) );
459*cdf0e10cSrcweir             oslModule pLib = osl_loadModule( aLibraryName.pData, SAL_LOADMODULE_DEFAULT );
460*cdf0e10cSrcweir             oslGenericFunction pFunc = NULL;
461*cdf0e10cSrcweir             if( pLib )
462*cdf0e10cSrcweir             {
463*cdf0e10cSrcweir                 OUString queryFuncName( RTL_CONSTASCII_USTRINGPARAM( "GetDefaultPrinterW" ) );
464*cdf0e10cSrcweir                 pFunc = osl_getFunctionSymbol( pLib, queryFuncName.pData );
465*cdf0e10cSrcweir             }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir             pGetDefaultPrinter = (sal_Bool(WINAPI*)(LPWSTR,LPDWORD)) pFunc;
468*cdf0e10cSrcweir         }
469*cdf0e10cSrcweir     }
470*cdf0e10cSrcweir     if( pGetDefaultPrinter )
471*cdf0e10cSrcweir     {
472*cdf0e10cSrcweir         DWORD   nChars = 0;
473*cdf0e10cSrcweir         pGetDefaultPrinter( NULL, &nChars );
474*cdf0e10cSrcweir         if( nChars )
475*cdf0e10cSrcweir         {
476*cdf0e10cSrcweir             LPWSTR  pStr = (LPWSTR)rtl_allocateMemory(nChars*sizeof(WCHAR));
477*cdf0e10cSrcweir             XubString aDefPrt;
478*cdf0e10cSrcweir             if( pGetDefaultPrinter( pStr, &nChars ) )
479*cdf0e10cSrcweir             {
480*cdf0e10cSrcweir                 aDefPrt = reinterpret_cast<sal_Unicode* >(pStr);
481*cdf0e10cSrcweir             }
482*cdf0e10cSrcweir             rtl_freeMemory( pStr );
483*cdf0e10cSrcweir             if( aDefPrt.Len() )
484*cdf0e10cSrcweir                 return aDefPrt;
485*cdf0e10cSrcweir         }
486*cdf0e10cSrcweir     }
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir 	// get default printer from win.ini
489*cdf0e10cSrcweir 	char szBuffer[256];
490*cdf0e10cSrcweir 	GetProfileStringA( aImplWindows, aImplDevice, "", szBuffer, sizeof( szBuffer ) );
491*cdf0e10cSrcweir 	if ( szBuffer[0] )
492*cdf0e10cSrcweir 	{
493*cdf0e10cSrcweir 		// Printername suchen
494*cdf0e10cSrcweir 		char* pBuf = szBuffer;
495*cdf0e10cSrcweir 		char* pTmp = pBuf;
496*cdf0e10cSrcweir 		while ( *pTmp && (*pTmp != ',') )
497*cdf0e10cSrcweir 			pTmp++;
498*cdf0e10cSrcweir 		return ImplSalGetUniString( pBuf, (xub_StrLen)(pTmp-pBuf) );
499*cdf0e10cSrcweir 	}
500*cdf0e10cSrcweir 	else
501*cdf0e10cSrcweir 		return XubString();
502*cdf0e10cSrcweir }
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir // =======================================================================
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir static DWORD ImplDeviceCaps( WinSalInfoPrinter* pPrinter, WORD nCaps,
507*cdf0e10cSrcweir 							 BYTE* pOutput, const ImplJobSetup* pSetupData )
508*cdf0e10cSrcweir {
509*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
510*cdf0e10cSrcweir     {
511*cdf0e10cSrcweir         DEVMODEW* pDevMode;
512*cdf0e10cSrcweir         if ( !pSetupData || !pSetupData->mpDriverData )
513*cdf0e10cSrcweir             pDevMode = NULL;
514*cdf0e10cSrcweir         else
515*cdf0e10cSrcweir             pDevMode = SAL_DEVMODE_W( pSetupData );
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir         return DeviceCapabilitiesW( reinterpret_cast<LPCWSTR>(pPrinter->maDeviceName.GetBuffer()),
518*cdf0e10cSrcweir                                     reinterpret_cast<LPCWSTR>(pPrinter->maPortName.GetBuffer()),
519*cdf0e10cSrcweir                                     nCaps, (LPWSTR)pOutput, pDevMode );
520*cdf0e10cSrcweir     }
521*cdf0e10cSrcweir     else
522*cdf0e10cSrcweir     {
523*cdf0e10cSrcweir         DEVMODEA* pDevMode;
524*cdf0e10cSrcweir         if ( !pSetupData || !pSetupData->mpDriverData )
525*cdf0e10cSrcweir             pDevMode = NULL;
526*cdf0e10cSrcweir         else
527*cdf0e10cSrcweir             pDevMode = SAL_DEVMODE_A( pSetupData );
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir         return DeviceCapabilitiesA( ImplSalGetWinAnsiString( pPrinter->maDeviceName, TRUE ).GetBuffer(),
530*cdf0e10cSrcweir                                 ImplSalGetWinAnsiString( pPrinter->maPortName, TRUE ).GetBuffer(),
531*cdf0e10cSrcweir                                 nCaps, (LPSTR)pOutput, pDevMode );
532*cdf0e10cSrcweir     }
533*cdf0e10cSrcweir }
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir // -----------------------------------------------------------------------
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir static sal_Bool ImplTestSalJobSetup( WinSalInfoPrinter* pPrinter,
538*cdf0e10cSrcweir 								 ImplJobSetup* pSetupData, sal_Bool bDelete )
539*cdf0e10cSrcweir {
540*cdf0e10cSrcweir 	if ( pSetupData && pSetupData->mpDriverData )
541*cdf0e10cSrcweir 	{
542*cdf0e10cSrcweir         // signature and size must fit to avoid using
543*cdf0e10cSrcweir         // JobSetups from a wrong system
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir         // initialize versions from jobsetup
546*cdf0e10cSrcweir         // those will be overwritten with driver's version
547*cdf0e10cSrcweir         DEVMODEA* pDevModeA = NULL;
548*cdf0e10cSrcweir         DEVMODEW* pDevModeW = NULL;
549*cdf0e10cSrcweir         LONG dmSpecVersion = -1;
550*cdf0e10cSrcweir         LONG dmDriverVersion = -1;
551*cdf0e10cSrcweir         SalDriverData* pSalDriverData = (SalDriverData*)pSetupData->mpDriverData;
552*cdf0e10cSrcweir         BYTE* pDriverData = ((BYTE*)pSalDriverData) + pSalDriverData->mnDriverOffset;
553*cdf0e10cSrcweir         if( pSalDriverData->mnVersion == SAL_DRIVERDATA_VERSION_W )
554*cdf0e10cSrcweir         {
555*cdf0e10cSrcweir             if( aSalShlData.mbWPrinter )
556*cdf0e10cSrcweir                 pDevModeW = (DEVMODEW*)pDriverData;
557*cdf0e10cSrcweir         }
558*cdf0e10cSrcweir         else if( pSalDriverData->mnVersion == SAL_DRIVERDATA_VERSION_A )
559*cdf0e10cSrcweir         {
560*cdf0e10cSrcweir             if( ! aSalShlData.mbWPrinter )
561*cdf0e10cSrcweir                 pDevModeA = (DEVMODEA*)pDriverData;
562*cdf0e10cSrcweir         }
563*cdf0e10cSrcweir 
564*cdf0e10cSrcweir         long nSysJobSize = -1;
565*cdf0e10cSrcweir         if( pPrinter && ( pDevModeA || pDevModeW ) )
566*cdf0e10cSrcweir         {
567*cdf0e10cSrcweir             // just too many driver crashes in that area -> check the dmSpecVersion and dmDriverVersion fields always !!!
568*cdf0e10cSrcweir             // this prevents using the jobsetup between different Windows versions (eg from XP to 9x) but we
569*cdf0e10cSrcweir             // can avoid potential driver crashes as their jobsetups are often not compatible
570*cdf0e10cSrcweir             // #110800#, #111151#, #112381#, #i16580#, #i14173# and perhaps #112375#
571*cdf0e10cSrcweir             ByteString aPrinterNameA= ImplSalGetWinAnsiString( pPrinter->maDeviceName, TRUE );
572*cdf0e10cSrcweir             HANDLE hPrn;
573*cdf0e10cSrcweir             LPWSTR pPrinterNameW = reinterpret_cast<LPWSTR>(const_cast<sal_Unicode*>(pPrinter->maDeviceName.GetBuffer()));
574*cdf0e10cSrcweir             if ( ! aSalShlData.mbWPrinter )
575*cdf0e10cSrcweir             {
576*cdf0e10cSrcweir                 if ( !OpenPrinterA( (LPSTR)aPrinterNameA.GetBuffer(), &hPrn, NULL ) )
577*cdf0e10cSrcweir                     return FALSE;
578*cdf0e10cSrcweir             }
579*cdf0e10cSrcweir             else
580*cdf0e10cSrcweir                 if ( !OpenPrinterW( pPrinterNameW, &hPrn, NULL ) )
581*cdf0e10cSrcweir                     return FALSE;
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir             // #131642# hPrn==HGDI_ERROR even though OpenPrinter() succeeded!
584*cdf0e10cSrcweir             if( hPrn == HGDI_ERROR )
585*cdf0e10cSrcweir                 return FALSE;
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir             if( aSalShlData.mbWPrinter )
588*cdf0e10cSrcweir             {
589*cdf0e10cSrcweir                 nSysJobSize = DocumentPropertiesW( 0, hPrn,
590*cdf0e10cSrcweir                                                    pPrinterNameW,
591*cdf0e10cSrcweir                                                    NULL, NULL, 0 );
592*cdf0e10cSrcweir             }
593*cdf0e10cSrcweir             else
594*cdf0e10cSrcweir             {
595*cdf0e10cSrcweir                 nSysJobSize = DocumentPropertiesA( 0, hPrn,
596*cdf0e10cSrcweir                                                    (LPSTR)aPrinterNameA.GetBuffer(),
597*cdf0e10cSrcweir                                                    NULL, NULL, 0 );
598*cdf0e10cSrcweir             }
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir             if( nSysJobSize < 0 )
601*cdf0e10cSrcweir             {
602*cdf0e10cSrcweir                 ClosePrinter( hPrn );
603*cdf0e10cSrcweir                 return FALSE;
604*cdf0e10cSrcweir             }
605*cdf0e10cSrcweir             BYTE *pBuffer = (BYTE*)_alloca( nSysJobSize );
606*cdf0e10cSrcweir             LONG nRet = -1;
607*cdf0e10cSrcweir             if( aSalShlData.mbWPrinter )
608*cdf0e10cSrcweir             {
609*cdf0e10cSrcweir                 nRet = DocumentPropertiesW( 0, hPrn,
610*cdf0e10cSrcweir                                             pPrinterNameW,
611*cdf0e10cSrcweir                                             (LPDEVMODEW)pBuffer, NULL, DM_OUT_BUFFER );
612*cdf0e10cSrcweir             }
613*cdf0e10cSrcweir             else
614*cdf0e10cSrcweir             {
615*cdf0e10cSrcweir                 nRet = DocumentPropertiesA( 0, hPrn,
616*cdf0e10cSrcweir                                             (LPSTR)aPrinterNameA.GetBuffer(),
617*cdf0e10cSrcweir                                             (LPDEVMODEA)pBuffer, NULL, DM_OUT_BUFFER );
618*cdf0e10cSrcweir             }
619*cdf0e10cSrcweir             if( nRet < 0 )
620*cdf0e10cSrcweir             {
621*cdf0e10cSrcweir                 ClosePrinter( hPrn );
622*cdf0e10cSrcweir                 return FALSE;
623*cdf0e10cSrcweir             }
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir             // the spec version differs between the windows platforms, ie 98,NT,2000/XP
626*cdf0e10cSrcweir             // this allows us to throw away printer settings from other platforms that might crash a buggy driver
627*cdf0e10cSrcweir             // we check the driver version as well
628*cdf0e10cSrcweir             dmSpecVersion = aSalShlData.mbWPrinter ? ((DEVMODEW*)pBuffer)->dmSpecVersion : ((DEVMODEA*)pBuffer)->dmSpecVersion;
629*cdf0e10cSrcweir             dmDriverVersion = aSalShlData.mbWPrinter ? ((DEVMODEW*)pBuffer)->dmDriverVersion : ((DEVMODEA*)pBuffer)->dmDriverVersion;
630*cdf0e10cSrcweir 
631*cdf0e10cSrcweir             ClosePrinter( hPrn );
632*cdf0e10cSrcweir         }
633*cdf0e10cSrcweir         SalDriverData* pSetupDriverData = (SalDriverData*)(pSetupData->mpDriverData);
634*cdf0e10cSrcweir 		if ( (pSetupData->mnSystem == JOBSETUP_SYSTEM_WINDOWS) &&
635*cdf0e10cSrcweir              (pPrinter->maDriverName == pSetupData->maDriver) &&
636*cdf0e10cSrcweir 			 (pSetupData->mnDriverDataLen > sizeof( SalDriverData )) &&
637*cdf0e10cSrcweir              (long)(pSetupData->mnDriverDataLen - pSetupDriverData->mnDriverOffset) == nSysJobSize &&
638*cdf0e10cSrcweir 			 pSetupDriverData->mnSysSignature == SAL_DRIVERDATA_SYSSIGN )
639*cdf0e10cSrcweir         {
640*cdf0e10cSrcweir             if( pDevModeA &&
641*cdf0e10cSrcweir                 (dmSpecVersion == pDevModeA->dmSpecVersion) &&
642*cdf0e10cSrcweir                 (dmDriverVersion == pDevModeA->dmDriverVersion) )
643*cdf0e10cSrcweir                 return TRUE;
644*cdf0e10cSrcweir             if( pDevModeW &&
645*cdf0e10cSrcweir                 (dmSpecVersion == pDevModeW->dmSpecVersion) &&
646*cdf0e10cSrcweir                 (dmDriverVersion == pDevModeW->dmDriverVersion) )
647*cdf0e10cSrcweir                 return TRUE;
648*cdf0e10cSrcweir         }
649*cdf0e10cSrcweir 		if ( bDelete )
650*cdf0e10cSrcweir 		{
651*cdf0e10cSrcweir 			rtl_freeMemory( pSetupData->mpDriverData );
652*cdf0e10cSrcweir 			pSetupData->mpDriverData = NULL;
653*cdf0e10cSrcweir 			pSetupData->mnDriverDataLen = 0;
654*cdf0e10cSrcweir 		}
655*cdf0e10cSrcweir 	}
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir 	return FALSE;
658*cdf0e10cSrcweir }
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir // -----------------------------------------------------------------------
661*cdf0e10cSrcweir 
662*cdf0e10cSrcweir static sal_Bool ImplUpdateSalJobSetup( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetupData,
663*cdf0e10cSrcweir 								   sal_Bool bIn, WinSalFrame* pVisibleDlgParent )
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir     ByteString aPrinterNameA = ImplSalGetWinAnsiString( pPrinter->maDeviceName, TRUE );
666*cdf0e10cSrcweir     HANDLE hPrn;
667*cdf0e10cSrcweir     LPWSTR pPrinterNameW = reinterpret_cast<LPWSTR>(const_cast<sal_Unicode*>(pPrinter->maDeviceName.GetBuffer()));
668*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
669*cdf0e10cSrcweir     {
670*cdf0e10cSrcweir         if ( !OpenPrinterW( pPrinterNameW, &hPrn, NULL ) )
671*cdf0e10cSrcweir             return FALSE;
672*cdf0e10cSrcweir     }
673*cdf0e10cSrcweir     else
674*cdf0e10cSrcweir     {
675*cdf0e10cSrcweir         if ( !OpenPrinterA( (LPSTR)aPrinterNameA.GetBuffer(), &hPrn, NULL ) )
676*cdf0e10cSrcweir             return FALSE;
677*cdf0e10cSrcweir     }
678*cdf0e10cSrcweir     // #131642# hPrn==HGDI_ERROR even though OpenPrinter() succeeded!
679*cdf0e10cSrcweir     if( hPrn == HGDI_ERROR )
680*cdf0e10cSrcweir         return FALSE;
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir 	LONG			nRet;
683*cdf0e10cSrcweir 	LONG			nSysJobSize = -1;
684*cdf0e10cSrcweir 	HWND			hWnd = 0;
685*cdf0e10cSrcweir 	DWORD			nMode = DM_OUT_BUFFER;
686*cdf0e10cSrcweir 	sal_uLong			nDriverDataLen = 0;
687*cdf0e10cSrcweir 	SalDriverData*	pOutBuffer = NULL;
688*cdf0e10cSrcweir     BYTE*           pInBuffer = NULL;
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
691*cdf0e10cSrcweir     {
692*cdf0e10cSrcweir         nSysJobSize = DocumentPropertiesW( hWnd, hPrn,
693*cdf0e10cSrcweir                                            pPrinterNameW,
694*cdf0e10cSrcweir                                            NULL, NULL, 0 );
695*cdf0e10cSrcweir     }
696*cdf0e10cSrcweir     else
697*cdf0e10cSrcweir         nSysJobSize = DocumentPropertiesA( hWnd, hPrn,
698*cdf0e10cSrcweir                                            (LPSTR)ImplSalGetWinAnsiString( pPrinter->maDeviceName, TRUE ).GetBuffer(),
699*cdf0e10cSrcweir                                            NULL, NULL, 0 );
700*cdf0e10cSrcweir 	if ( nSysJobSize < 0 )
701*cdf0e10cSrcweir 	{
702*cdf0e10cSrcweir 		ClosePrinter( hPrn );
703*cdf0e10cSrcweir 		return FALSE;
704*cdf0e10cSrcweir 	}
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir 	// Outputbuffer anlegen
707*cdf0e10cSrcweir 	nDriverDataLen				= sizeof(SalDriverData) + nSysJobSize-1;
708*cdf0e10cSrcweir 	pOutBuffer					= (SalDriverData*)rtl_allocateZeroMemory( nDriverDataLen );
709*cdf0e10cSrcweir 	pOutBuffer->mnSysSignature	= SAL_DRIVERDATA_SYSSIGN;
710*cdf0e10cSrcweir 	pOutBuffer->mnVersion		= aSalShlData.mbWPrinter ? SAL_DRIVERDATA_VERSION_W : SAL_DRIVERDATA_VERSION_A;
711*cdf0e10cSrcweir     // calculate driver data offset including structure padding
712*cdf0e10cSrcweir 	pOutBuffer->mnDriverOffset	= sal::static_int_cast<sal_uInt16>(
713*cdf0e10cSrcweir                                     (char*)pOutBuffer->maDriverData -
714*cdf0e10cSrcweir                                     (char*)pOutBuffer );
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir 	// Testen, ob wir einen geeigneten Inputbuffer haben
717*cdf0e10cSrcweir 	if ( bIn && ImplTestSalJobSetup( pPrinter, pSetupData, FALSE ) )
718*cdf0e10cSrcweir 	{
719*cdf0e10cSrcweir 		pInBuffer = (BYTE*)pSetupData->mpDriverData + ((SalDriverData*)pSetupData->mpDriverData)->mnDriverOffset;
720*cdf0e10cSrcweir 		nMode |= DM_IN_BUFFER;
721*cdf0e10cSrcweir 	}
722*cdf0e10cSrcweir 
723*cdf0e10cSrcweir 	// Testen, ob Dialog angezeigt werden soll
724*cdf0e10cSrcweir 	if ( pVisibleDlgParent )
725*cdf0e10cSrcweir 	{
726*cdf0e10cSrcweir 		hWnd = pVisibleDlgParent->mhWnd;
727*cdf0e10cSrcweir 		nMode |= DM_IN_PROMPT;
728*cdf0e10cSrcweir 	}
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir 	// Release mutex, in the other case we don't get paints and so on
731*cdf0e10cSrcweir     sal_uLong nMutexCount=0;
732*cdf0e10cSrcweir     if ( pVisibleDlgParent )
733*cdf0e10cSrcweir         nMutexCount = ImplSalReleaseYieldMutex();
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir     BYTE* pOutDevMode = (((BYTE*)pOutBuffer) + pOutBuffer->mnDriverOffset);
736*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
737*cdf0e10cSrcweir     {
738*cdf0e10cSrcweir         nRet = DocumentPropertiesW( hWnd, hPrn,
739*cdf0e10cSrcweir                                     pPrinterNameW,
740*cdf0e10cSrcweir                                     (LPDEVMODEW)pOutDevMode, (LPDEVMODEW)pInBuffer, nMode );
741*cdf0e10cSrcweir     }
742*cdf0e10cSrcweir     else
743*cdf0e10cSrcweir     {
744*cdf0e10cSrcweir         nRet = DocumentPropertiesA( hWnd, hPrn,
745*cdf0e10cSrcweir                                     (LPSTR)ImplSalGetWinAnsiString( pPrinter->maDeviceName, TRUE ).GetBuffer(),
746*cdf0e10cSrcweir                                     (LPDEVMODEA)pOutDevMode, (LPDEVMODEA)pInBuffer, nMode );
747*cdf0e10cSrcweir     }
748*cdf0e10cSrcweir     if ( pVisibleDlgParent )
749*cdf0e10cSrcweir         ImplSalAcquireYieldMutex( nMutexCount );
750*cdf0e10cSrcweir 	ClosePrinter( hPrn );
751*cdf0e10cSrcweir 
752*cdf0e10cSrcweir 	if( (nRet < 0) || (pVisibleDlgParent && (nRet == IDCANCEL)) )
753*cdf0e10cSrcweir 	{
754*cdf0e10cSrcweir 		rtl_freeMemory( pOutBuffer );
755*cdf0e10cSrcweir 		return FALSE;
756*cdf0e10cSrcweir 	}
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir     // fill up string buffers with 0 so they do not influence a JobSetup's memcmp
759*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
760*cdf0e10cSrcweir     {
761*cdf0e10cSrcweir         if( ((LPDEVMODEW)pOutDevMode)->dmSize >= 64 )
762*cdf0e10cSrcweir         {
763*cdf0e10cSrcweir             sal_Int32 nLen = rtl_ustr_getLength( (const sal_Unicode*)((LPDEVMODEW)pOutDevMode)->dmDeviceName );
764*cdf0e10cSrcweir             if ( nLen < sizeof( ((LPDEVMODEW)pOutDevMode)->dmDeviceName )/sizeof(sal_Unicode) )
765*cdf0e10cSrcweir                 memset( ((LPDEVMODEW)pOutDevMode)->dmDeviceName+nLen, 0, sizeof( ((LPDEVMODEW)pOutDevMode)->dmDeviceName )-(nLen*sizeof(sal_Unicode)) );
766*cdf0e10cSrcweir         }
767*cdf0e10cSrcweir         if( ((LPDEVMODEW)pOutDevMode)->dmSize >= 166 )
768*cdf0e10cSrcweir         {
769*cdf0e10cSrcweir             sal_Int32 nLen = rtl_ustr_getLength( (const sal_Unicode*)((LPDEVMODEW)pOutDevMode)->dmFormName );
770*cdf0e10cSrcweir             if ( nLen < sizeof( ((LPDEVMODEW)pOutDevMode)->dmFormName )/sizeof(sal_Unicode) )
771*cdf0e10cSrcweir                 memset( ((LPDEVMODEW)pOutDevMode)->dmFormName+nLen, 0, sizeof( ((LPDEVMODEW)pOutDevMode)->dmFormName )-(nLen*sizeof(sal_Unicode)) );
772*cdf0e10cSrcweir         }
773*cdf0e10cSrcweir     }
774*cdf0e10cSrcweir     else
775*cdf0e10cSrcweir     {
776*cdf0e10cSrcweir         if( ((LPDEVMODEA)pOutDevMode)->dmSize >= 32 )
777*cdf0e10cSrcweir         {
778*cdf0e10cSrcweir             sal_Int32 nLen = strlen( (const char*)((LPDEVMODEA)pOutDevMode)->dmDeviceName );
779*cdf0e10cSrcweir             if ( nLen < sizeof( ((LPDEVMODEA)pOutDevMode)->dmDeviceName ) )
780*cdf0e10cSrcweir                 memset( ((LPDEVMODEA)pOutDevMode)->dmDeviceName+nLen, 0, sizeof( ((LPDEVMODEA)pOutDevMode)->dmDeviceName )-nLen );
781*cdf0e10cSrcweir         }
782*cdf0e10cSrcweir         if( ((LPDEVMODEA)pOutDevMode)->dmSize >= 102 )
783*cdf0e10cSrcweir         {
784*cdf0e10cSrcweir             sal_Int32 nLen = strlen( (const char*)((LPDEVMODEA)pOutDevMode)->dmFormName );
785*cdf0e10cSrcweir             if ( nLen < sizeof( ((LPDEVMODEA)pOutDevMode)->dmFormName ) )
786*cdf0e10cSrcweir                 memset( ((LPDEVMODEA)pOutDevMode)->dmFormName+nLen, 0, sizeof( ((LPDEVMODEA)pOutDevMode)->dmFormName )-nLen );
787*cdf0e10cSrcweir         }
788*cdf0e10cSrcweir     }
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir 	// update data
791*cdf0e10cSrcweir 	if ( pSetupData->mpDriverData )
792*cdf0e10cSrcweir 		rtl_freeMemory( pSetupData->mpDriverData );
793*cdf0e10cSrcweir 	pSetupData->mnDriverDataLen = nDriverDataLen;
794*cdf0e10cSrcweir 	pSetupData->mpDriverData	= (BYTE*)pOutBuffer;
795*cdf0e10cSrcweir 	pSetupData->mnSystem		= JOBSETUP_SYSTEM_WINDOWS;
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir 	return TRUE;
798*cdf0e10cSrcweir }
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir // -----------------------------------------------------------------------
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir #define DECLARE_DEVMODE( i )\
803*cdf0e10cSrcweir     DEVMODEA* pDevModeA = SAL_DEVMODE_A(i);\
804*cdf0e10cSrcweir     DEVMODEW* pDevModeW = SAL_DEVMODE_W(i);\
805*cdf0e10cSrcweir     if( pDevModeA == NULL && pDevModeW == NULL )\
806*cdf0e10cSrcweir         return
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir #define CHOOSE_DEVMODE(i)\
809*cdf0e10cSrcweir     (pDevModeW ? pDevModeW->i : pDevModeA->i)
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir static void ImplDevModeToJobSetup( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, sal_uLong nFlags )
812*cdf0e10cSrcweir {
813*cdf0e10cSrcweir 	if ( !pSetupData || !pSetupData->mpDriverData )
814*cdf0e10cSrcweir 		return;
815*cdf0e10cSrcweir 
816*cdf0e10cSrcweir     DECLARE_DEVMODE( pSetupData );
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir 	// Orientation
819*cdf0e10cSrcweir 	if ( nFlags & SAL_JOBSET_ORIENTATION )
820*cdf0e10cSrcweir 	{
821*cdf0e10cSrcweir 		if ( CHOOSE_DEVMODE(dmOrientation) == DMORIENT_PORTRAIT )
822*cdf0e10cSrcweir 			pSetupData->meOrientation = ORIENTATION_PORTRAIT;
823*cdf0e10cSrcweir 		else if ( CHOOSE_DEVMODE(dmOrientation) == DMORIENT_LANDSCAPE )
824*cdf0e10cSrcweir 			pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
825*cdf0e10cSrcweir 	}
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir 	// PaperBin
828*cdf0e10cSrcweir 	if ( nFlags & SAL_JOBSET_PAPERBIN )
829*cdf0e10cSrcweir 	{
830*cdf0e10cSrcweir 		sal_uLong nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir 		if ( nCount && (nCount != GDI_ERROR) )
833*cdf0e10cSrcweir 		{
834*cdf0e10cSrcweir 			WORD* pBins = (WORD*)rtl_allocateZeroMemory( nCount*sizeof(WORD) );
835*cdf0e10cSrcweir 			ImplDeviceCaps( pPrinter, DC_BINS, (BYTE*)pBins, pSetupData );
836*cdf0e10cSrcweir 			pSetupData->mnPaperBin = 0;
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 			// search the right bin and assign index to mnPaperBin
839*cdf0e10cSrcweir 			for( sal_uLong i = 0; i < nCount; i++ )
840*cdf0e10cSrcweir 			{
841*cdf0e10cSrcweir 				if( CHOOSE_DEVMODE(dmDefaultSource) == pBins[ i ] )
842*cdf0e10cSrcweir 				{
843*cdf0e10cSrcweir 					pSetupData->mnPaperBin = (sal_uInt16)i;
844*cdf0e10cSrcweir 					break;
845*cdf0e10cSrcweir 				}
846*cdf0e10cSrcweir 			}
847*cdf0e10cSrcweir 
848*cdf0e10cSrcweir 			rtl_freeMemory( pBins );
849*cdf0e10cSrcweir 		}
850*cdf0e10cSrcweir 	}
851*cdf0e10cSrcweir 
852*cdf0e10cSrcweir 	// PaperSize
853*cdf0e10cSrcweir 	if ( nFlags & SAL_JOBSET_PAPERSIZE )
854*cdf0e10cSrcweir 	{
855*cdf0e10cSrcweir 		if( (CHOOSE_DEVMODE(dmFields) & (DM_PAPERWIDTH|DM_PAPERLENGTH)) == (DM_PAPERWIDTH|DM_PAPERLENGTH) )
856*cdf0e10cSrcweir 		{
857*cdf0e10cSrcweir 		    pSetupData->mnPaperWidth  = CHOOSE_DEVMODE(dmPaperWidth)*10;
858*cdf0e10cSrcweir 		    pSetupData->mnPaperHeight = CHOOSE_DEVMODE(dmPaperLength)*10;
859*cdf0e10cSrcweir 		}
860*cdf0e10cSrcweir 		else
861*cdf0e10cSrcweir 		{
862*cdf0e10cSrcweir 			sal_uLong	nPaperCount = ImplDeviceCaps( pPrinter, DC_PAPERS, NULL, pSetupData );
863*cdf0e10cSrcweir 			WORD*	pPapers = NULL;
864*cdf0e10cSrcweir 			sal_uLong	nPaperSizeCount = ImplDeviceCaps( pPrinter, DC_PAPERSIZE, NULL, pSetupData );
865*cdf0e10cSrcweir 			POINT*	pPaperSizes = NULL;
866*cdf0e10cSrcweir 			if ( nPaperCount && (nPaperCount != GDI_ERROR) )
867*cdf0e10cSrcweir 			{
868*cdf0e10cSrcweir 				pPapers = (WORD*)rtl_allocateZeroMemory(nPaperCount*sizeof(WORD));
869*cdf0e10cSrcweir 				ImplDeviceCaps( pPrinter, DC_PAPERS, (BYTE*)pPapers, pSetupData );
870*cdf0e10cSrcweir 			}
871*cdf0e10cSrcweir 			if ( nPaperSizeCount && (nPaperSizeCount != GDI_ERROR) )
872*cdf0e10cSrcweir 			{
873*cdf0e10cSrcweir 				pPaperSizes = (POINT*)rtl_allocateZeroMemory(nPaperSizeCount*sizeof(POINT));
874*cdf0e10cSrcweir 				ImplDeviceCaps( pPrinter, DC_PAPERSIZE, (BYTE*)pPaperSizes, pSetupData );
875*cdf0e10cSrcweir 			}
876*cdf0e10cSrcweir 			if( nPaperSizeCount == nPaperCount && pPaperSizes && pPapers )
877*cdf0e10cSrcweir 			{
878*cdf0e10cSrcweir 				for( sal_uLong i = 0; i < nPaperCount; i++ )
879*cdf0e10cSrcweir 				{
880*cdf0e10cSrcweir 					if( pPapers[ i ] == CHOOSE_DEVMODE(dmPaperSize) )
881*cdf0e10cSrcweir 					{
882*cdf0e10cSrcweir 						pSetupData->mnPaperWidth  = pPaperSizes[ i ].x*10;
883*cdf0e10cSrcweir 						pSetupData->mnPaperHeight = pPaperSizes[ i ].y*10;
884*cdf0e10cSrcweir 						break;
885*cdf0e10cSrcweir 					}
886*cdf0e10cSrcweir 				}
887*cdf0e10cSrcweir 			}
888*cdf0e10cSrcweir 			if( pPapers )
889*cdf0e10cSrcweir 				rtl_freeMemory( pPapers );
890*cdf0e10cSrcweir 			if( pPaperSizes )
891*cdf0e10cSrcweir 				rtl_freeMemory( pPaperSizes );
892*cdf0e10cSrcweir 		}
893*cdf0e10cSrcweir 		switch( CHOOSE_DEVMODE(dmPaperSize) )
894*cdf0e10cSrcweir 		{
895*cdf0e10cSrcweir 			case( DMPAPER_LETTER ):
896*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_LETTER;
897*cdf0e10cSrcweir 				break;
898*cdf0e10cSrcweir 			case( DMPAPER_TABLOID ):
899*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_TABLOID;
900*cdf0e10cSrcweir 				break;
901*cdf0e10cSrcweir 			case( DMPAPER_LEDGER ):
902*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_LEDGER;
903*cdf0e10cSrcweir 				break;
904*cdf0e10cSrcweir 			case( DMPAPER_LEGAL ):
905*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_LEGAL;
906*cdf0e10cSrcweir 				break;
907*cdf0e10cSrcweir 			case( DMPAPER_STATEMENT ):
908*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_STATEMENT;
909*cdf0e10cSrcweir 				break;
910*cdf0e10cSrcweir 			case( DMPAPER_EXECUTIVE ):
911*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_EXECUTIVE;
912*cdf0e10cSrcweir 				break;
913*cdf0e10cSrcweir 			case( DMPAPER_A3 ):
914*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_A3;
915*cdf0e10cSrcweir 				break;
916*cdf0e10cSrcweir 			case( DMPAPER_A4 ):
917*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_A4;
918*cdf0e10cSrcweir 				break;
919*cdf0e10cSrcweir 			case( DMPAPER_A5 ):
920*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_A5;
921*cdf0e10cSrcweir 				break;
922*cdf0e10cSrcweir 			//See http://wiki.services.openoffice.org/wiki/DefaultPaperSize
923*cdf0e10cSrcweir 			//i.e.
924*cdf0e10cSrcweir 			//http://msdn.microsoft.com/en-us/library/dd319099(VS.85).aspx
925*cdf0e10cSrcweir 			//DMPAPER_B4	12	B4 (JIS) 257 x 364 mm
926*cdf0e10cSrcweir 			//http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf
927*cdf0e10cSrcweir 			//also says that the MS DMPAPER_B4 is JIS, which makes most sense. And
928*cdf0e10cSrcweir 			//matches our Excel filter's belief about the matching XlPaperSize
929*cdf0e10cSrcweir 			//enumeration.
930*cdf0e10cSrcweir 			//
931*cdf0e10cSrcweir 			//http://msdn.microsoft.com/en-us/library/ms776398(VS.85).aspx said
932*cdf0e10cSrcweir 			////"DMPAPER_B4 	12 	B4 (JIS) 250 x 354"
933*cdf0e10cSrcweir 			//which is bogus as it's either JIS 257 × 364 or ISO 250 × 353
934*cdf0e10cSrcweir 			//(cmc)
935*cdf0e10cSrcweir 			case( DMPAPER_B4 ):
936*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_B4_JIS;
937*cdf0e10cSrcweir 				break;
938*cdf0e10cSrcweir 			case( DMPAPER_B5 ):
939*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_B5_JIS;
940*cdf0e10cSrcweir 				break;
941*cdf0e10cSrcweir 			case( DMPAPER_QUARTO ):
942*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_QUARTO;
943*cdf0e10cSrcweir 				break;
944*cdf0e10cSrcweir 			case( DMPAPER_10X14 ):
945*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_10x14;
946*cdf0e10cSrcweir 				break;
947*cdf0e10cSrcweir 			case( DMPAPER_NOTE ):
948*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_LETTER;
949*cdf0e10cSrcweir 				break;
950*cdf0e10cSrcweir 			case( DMPAPER_ENV_9 ):
951*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_9;
952*cdf0e10cSrcweir 				break;
953*cdf0e10cSrcweir 			case( DMPAPER_ENV_10 ):
954*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_10;
955*cdf0e10cSrcweir 				break;
956*cdf0e10cSrcweir 			case( DMPAPER_ENV_11 ):
957*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_11;
958*cdf0e10cSrcweir 				break;
959*cdf0e10cSrcweir 			case( DMPAPER_ENV_12 ):
960*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_12;
961*cdf0e10cSrcweir 				break;
962*cdf0e10cSrcweir 			case( DMPAPER_ENV_14 ):
963*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_14;
964*cdf0e10cSrcweir 				break;
965*cdf0e10cSrcweir 			case( DMPAPER_CSHEET ):
966*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_C;
967*cdf0e10cSrcweir 				break;
968*cdf0e10cSrcweir 			case( DMPAPER_DSHEET ):
969*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_D;
970*cdf0e10cSrcweir 				break;
971*cdf0e10cSrcweir 			case( DMPAPER_ESHEET ):
972*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_E;
973*cdf0e10cSrcweir 				break;
974*cdf0e10cSrcweir 			case( DMPAPER_ENV_DL):
975*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_DL;
976*cdf0e10cSrcweir 				break;
977*cdf0e10cSrcweir 			case( DMPAPER_ENV_C5):
978*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_C5;
979*cdf0e10cSrcweir 				break;
980*cdf0e10cSrcweir 			case( DMPAPER_ENV_C3):
981*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_C3;
982*cdf0e10cSrcweir 				break;
983*cdf0e10cSrcweir 			case( DMPAPER_ENV_C4):
984*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_C4;
985*cdf0e10cSrcweir 				break;
986*cdf0e10cSrcweir 			case( DMPAPER_ENV_C6):
987*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_C6;
988*cdf0e10cSrcweir 				break;
989*cdf0e10cSrcweir 			case( DMPAPER_ENV_C65):
990*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_C65;
991*cdf0e10cSrcweir 				break;
992*cdf0e10cSrcweir 			case( DMPAPER_ENV_ITALY ):
993*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_ITALY;
994*cdf0e10cSrcweir 				break;
995*cdf0e10cSrcweir 			case( DMPAPER_ENV_MONARCH ):
996*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_MONARCH;
997*cdf0e10cSrcweir 				break;
998*cdf0e10cSrcweir 			case( DMPAPER_ENV_PERSONAL ):
999*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_PERSONAL;
1000*cdf0e10cSrcweir 				break;
1001*cdf0e10cSrcweir 			case( DMPAPER_FANFOLD_US ):
1002*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_FANFOLD_US;
1003*cdf0e10cSrcweir 				break;
1004*cdf0e10cSrcweir 			case( DMPAPER_FANFOLD_STD_GERMAN ):
1005*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_FANFOLD_DE;
1006*cdf0e10cSrcweir 				break;
1007*cdf0e10cSrcweir 			case( DMPAPER_FANFOLD_LGL_GERMAN ):
1008*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_FANFOLD_LEGAL_DE;
1009*cdf0e10cSrcweir 				break;
1010*cdf0e10cSrcweir 			case( DMPAPER_ISO_B4 ):
1011*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_B4_ISO;
1012*cdf0e10cSrcweir 				break;
1013*cdf0e10cSrcweir 			case( DMPAPER_JAPANESE_POSTCARD ):
1014*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_POSTCARD_JP;
1015*cdf0e10cSrcweir 				break;
1016*cdf0e10cSrcweir 			case( DMPAPER_9X11 ):
1017*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_9x11;
1018*cdf0e10cSrcweir 				break;
1019*cdf0e10cSrcweir 			case( DMPAPER_10X11 ):
1020*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_10x11;
1021*cdf0e10cSrcweir 				break;
1022*cdf0e10cSrcweir 			case( DMPAPER_15X11 ):
1023*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_15x11;
1024*cdf0e10cSrcweir 				break;
1025*cdf0e10cSrcweir 			case( DMPAPER_ENV_INVITE ):
1026*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_ENV_INVITE;
1027*cdf0e10cSrcweir 				break;
1028*cdf0e10cSrcweir 			case( DMPAPER_A_PLUS ):
1029*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_A_PLUS;
1030*cdf0e10cSrcweir 				break;
1031*cdf0e10cSrcweir 			case( DMPAPER_B_PLUS ):
1032*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_B_PLUS;
1033*cdf0e10cSrcweir 				break;
1034*cdf0e10cSrcweir 			case( DMPAPER_LETTER_PLUS ):
1035*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_LETTER_PLUS;
1036*cdf0e10cSrcweir 				break;
1037*cdf0e10cSrcweir 			case( DMPAPER_A4_PLUS ):
1038*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_A4_PLUS;
1039*cdf0e10cSrcweir 				break;
1040*cdf0e10cSrcweir 			case( DMPAPER_A2 ):
1041*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_A2;
1042*cdf0e10cSrcweir 				break;
1043*cdf0e10cSrcweir 			case( DMPAPER_DBL_JAPANESE_POSTCARD ):
1044*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_DOUBLEPOSTCARD_JP;
1045*cdf0e10cSrcweir 				break;
1046*cdf0e10cSrcweir 			case( DMPAPER_A6 ):
1047*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_A6;
1048*cdf0e10cSrcweir 				break;
1049*cdf0e10cSrcweir 			case( DMPAPER_B6_JIS ):
1050*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_B6_JIS;
1051*cdf0e10cSrcweir 				break;
1052*cdf0e10cSrcweir 			case( DMPAPER_12X11 ):
1053*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_12x11;
1054*cdf0e10cSrcweir 				break;
1055*cdf0e10cSrcweir 			default:
1056*cdf0e10cSrcweir 				pSetupData->mePaperFormat = PAPER_USER;
1057*cdf0e10cSrcweir 				break;
1058*cdf0e10cSrcweir 		}
1059*cdf0e10cSrcweir 	}
1060*cdf0e10cSrcweir 
1061*cdf0e10cSrcweir     if( nFlags & SAL_JOBSET_DUPLEXMODE )
1062*cdf0e10cSrcweir     {
1063*cdf0e10cSrcweir         DuplexMode eDuplex = DUPLEX_UNKNOWN;
1064*cdf0e10cSrcweir         if( (CHOOSE_DEVMODE(dmFields) & DM_DUPLEX) )
1065*cdf0e10cSrcweir         {
1066*cdf0e10cSrcweir             if( CHOOSE_DEVMODE(dmDuplex) == DMDUP_SIMPLEX )
1067*cdf0e10cSrcweir                 eDuplex = DUPLEX_OFF;
1068*cdf0e10cSrcweir             else if( CHOOSE_DEVMODE(dmDuplex) == DMDUP_VERTICAL )
1069*cdf0e10cSrcweir                 eDuplex = DUPLEX_LONGEDGE;
1070*cdf0e10cSrcweir             else if( CHOOSE_DEVMODE(dmDuplex) == DMDUP_HORIZONTAL )
1071*cdf0e10cSrcweir                 eDuplex = DUPLEX_SHORTEDGE;
1072*cdf0e10cSrcweir         }
1073*cdf0e10cSrcweir         pSetupData->meDuplexMode = eDuplex;
1074*cdf0e10cSrcweir     }
1075*cdf0e10cSrcweir }
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir // -----------------------------------------------------------------------
1078*cdf0e10cSrcweir 
1079*cdf0e10cSrcweir static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, sal_uLong nFlags )
1080*cdf0e10cSrcweir {
1081*cdf0e10cSrcweir 	if ( !pSetupData || !pSetupData->mpDriverData )
1082*cdf0e10cSrcweir 		return;
1083*cdf0e10cSrcweir 
1084*cdf0e10cSrcweir     DECLARE_DEVMODE( pSetupData );
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir 	// Orientation
1087*cdf0e10cSrcweir 	if ( nFlags & SAL_JOBSET_ORIENTATION )
1088*cdf0e10cSrcweir 	{
1089*cdf0e10cSrcweir 		CHOOSE_DEVMODE(dmFields) |= DM_ORIENTATION;
1090*cdf0e10cSrcweir 		if ( pSetupData->meOrientation == ORIENTATION_PORTRAIT )
1091*cdf0e10cSrcweir 			CHOOSE_DEVMODE(dmOrientation) = DMORIENT_PORTRAIT;
1092*cdf0e10cSrcweir 		else
1093*cdf0e10cSrcweir 			CHOOSE_DEVMODE(dmOrientation) = DMORIENT_LANDSCAPE;
1094*cdf0e10cSrcweir 	}
1095*cdf0e10cSrcweir 
1096*cdf0e10cSrcweir 	// PaperBin
1097*cdf0e10cSrcweir 	if ( nFlags & SAL_JOBSET_PAPERBIN )
1098*cdf0e10cSrcweir 	{
1099*cdf0e10cSrcweir 		sal_uLong nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
1100*cdf0e10cSrcweir 
1101*cdf0e10cSrcweir 		if ( nCount && (nCount != GDI_ERROR) )
1102*cdf0e10cSrcweir 		{
1103*cdf0e10cSrcweir 			WORD* pBins = (WORD*)rtl_allocateZeroMemory(nCount*sizeof(WORD));
1104*cdf0e10cSrcweir 			ImplDeviceCaps( pPrinter, DC_BINS, (BYTE*)pBins, pSetupData );
1105*cdf0e10cSrcweir 			CHOOSE_DEVMODE(dmFields) |= DM_DEFAULTSOURCE;
1106*cdf0e10cSrcweir 			CHOOSE_DEVMODE(dmDefaultSource) = pBins[ pSetupData->mnPaperBin ];
1107*cdf0e10cSrcweir 			rtl_freeMemory( pBins );
1108*cdf0e10cSrcweir 		}
1109*cdf0e10cSrcweir 	}
1110*cdf0e10cSrcweir 
1111*cdf0e10cSrcweir 	// PaperSize
1112*cdf0e10cSrcweir 	if ( nFlags & SAL_JOBSET_PAPERSIZE )
1113*cdf0e10cSrcweir 	{
1114*cdf0e10cSrcweir 		CHOOSE_DEVMODE(dmFields)		|= DM_PAPERSIZE;
1115*cdf0e10cSrcweir 		CHOOSE_DEVMODE(dmPaperWidth)	 = 0;
1116*cdf0e10cSrcweir 		CHOOSE_DEVMODE(dmPaperLength)    = 0;
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir 		switch( pSetupData->mePaperFormat )
1119*cdf0e10cSrcweir 		{
1120*cdf0e10cSrcweir 			case( PAPER_A2 ):
1121*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A2;
1122*cdf0e10cSrcweir 				break;
1123*cdf0e10cSrcweir 			case( PAPER_A3 ):
1124*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A3;
1125*cdf0e10cSrcweir 				break;
1126*cdf0e10cSrcweir 			case( PAPER_A4 ):
1127*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A4;
1128*cdf0e10cSrcweir 				break;
1129*cdf0e10cSrcweir 			case( PAPER_A5 ):
1130*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A5;
1131*cdf0e10cSrcweir 				break;
1132*cdf0e10cSrcweir 			case( PAPER_B4_ISO):
1133*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ISO_B4;
1134*cdf0e10cSrcweir 				break;
1135*cdf0e10cSrcweir 			case( PAPER_LETTER ):
1136*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_LETTER;
1137*cdf0e10cSrcweir 				break;
1138*cdf0e10cSrcweir 			case( PAPER_LEGAL ):
1139*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_LEGAL;
1140*cdf0e10cSrcweir 				break;
1141*cdf0e10cSrcweir 			case( PAPER_TABLOID ):
1142*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_TABLOID;
1143*cdf0e10cSrcweir 				break;
1144*cdf0e10cSrcweir #if 0
1145*cdf0e10cSrcweir 			//http://msdn.microsoft.com/en-us/library/ms776398(VS.85).aspx
1146*cdf0e10cSrcweir 			//DMPAPER_ENV_B6 is documented as:
1147*cdf0e10cSrcweir 			//"DMPAPER_ENV_B6 	35 	Envelope B6 176 x 125 mm"
1148*cdf0e10cSrcweir 			//which is the wrong way around, it is surely 125 x 176, i.e.
1149*cdf0e10cSrcweir 			//compare DMPAPER_ENV_B4 and DMPAPER_ENV_B4 as
1150*cdf0e10cSrcweir 			//DMPAPER_ENV_B4 	33 	Envelope B4 250 x 353 mm
1151*cdf0e10cSrcweir 			//DMPAPER_ENV_B5 	34 	Envelope B5 176 x 250 mm
1152*cdf0e10cSrcweir 			case( PAPER_B6_ISO ):
1153*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_B6;
1154*cdf0e10cSrcweir 				break;
1155*cdf0e10cSrcweir #endif
1156*cdf0e10cSrcweir 			case( PAPER_ENV_C4 ):
1157*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C4;
1158*cdf0e10cSrcweir 				break;
1159*cdf0e10cSrcweir 			case( PAPER_ENV_C5 ):
1160*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C5;
1161*cdf0e10cSrcweir 				break;
1162*cdf0e10cSrcweir 			case( PAPER_ENV_C6 ):
1163*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C6;
1164*cdf0e10cSrcweir 				break;
1165*cdf0e10cSrcweir 			case( PAPER_ENV_C65 ):
1166*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C65;
1167*cdf0e10cSrcweir 				break;
1168*cdf0e10cSrcweir 			case( PAPER_ENV_DL ):
1169*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_DL;
1170*cdf0e10cSrcweir 				break;
1171*cdf0e10cSrcweir 			case( PAPER_C ):
1172*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_CSHEET;
1173*cdf0e10cSrcweir 				break;
1174*cdf0e10cSrcweir 			case( PAPER_D ):
1175*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_DSHEET;
1176*cdf0e10cSrcweir 				break;
1177*cdf0e10cSrcweir 			case( PAPER_E ):
1178*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ESHEET;
1179*cdf0e10cSrcweir 				break;
1180*cdf0e10cSrcweir 			case( PAPER_EXECUTIVE ):
1181*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_EXECUTIVE;
1182*cdf0e10cSrcweir 				break;
1183*cdf0e10cSrcweir 			case( PAPER_FANFOLD_LEGAL_DE ):
1184*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_FANFOLD_LGL_GERMAN;
1185*cdf0e10cSrcweir 				break;
1186*cdf0e10cSrcweir 			case( PAPER_ENV_MONARCH ):
1187*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_MONARCH;
1188*cdf0e10cSrcweir 				break;
1189*cdf0e10cSrcweir 			case( PAPER_ENV_PERSONAL ):
1190*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_PERSONAL;
1191*cdf0e10cSrcweir 				break;
1192*cdf0e10cSrcweir 			case( PAPER_ENV_9 ):
1193*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_9;
1194*cdf0e10cSrcweir 				break;
1195*cdf0e10cSrcweir 			case( PAPER_ENV_10 ):
1196*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_10;
1197*cdf0e10cSrcweir 				break;
1198*cdf0e10cSrcweir 			case( PAPER_ENV_11 ):
1199*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_11;
1200*cdf0e10cSrcweir 				break;
1201*cdf0e10cSrcweir 			case( PAPER_ENV_12 ):
1202*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_12;
1203*cdf0e10cSrcweir 				break;
1204*cdf0e10cSrcweir 			//See the comments on DMPAPER_B4 above
1205*cdf0e10cSrcweir 			case( PAPER_B4_JIS ):
1206*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B4;
1207*cdf0e10cSrcweir 				break;
1208*cdf0e10cSrcweir 			case( PAPER_B5_JIS ):
1209*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B5;
1210*cdf0e10cSrcweir 				break;
1211*cdf0e10cSrcweir 			case( PAPER_B6_JIS ):
1212*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B6_JIS;
1213*cdf0e10cSrcweir 				break;
1214*cdf0e10cSrcweir 			case( PAPER_LEDGER ):
1215*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_LEDGER;
1216*cdf0e10cSrcweir 				break;
1217*cdf0e10cSrcweir 			case( PAPER_STATEMENT ):
1218*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_STATEMENT;
1219*cdf0e10cSrcweir 				break;
1220*cdf0e10cSrcweir 			case( PAPER_10x14 ):
1221*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_10X14;
1222*cdf0e10cSrcweir 				break;
1223*cdf0e10cSrcweir 			case( PAPER_ENV_14 ):
1224*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_14;
1225*cdf0e10cSrcweir 				break;
1226*cdf0e10cSrcweir 			case( PAPER_ENV_C3 ):
1227*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C3;
1228*cdf0e10cSrcweir 				break;
1229*cdf0e10cSrcweir 			case( PAPER_ENV_ITALY ):
1230*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_ITALY;
1231*cdf0e10cSrcweir 				break;
1232*cdf0e10cSrcweir 			case( PAPER_FANFOLD_US ):
1233*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_FANFOLD_US;
1234*cdf0e10cSrcweir 				break;
1235*cdf0e10cSrcweir 			case( PAPER_FANFOLD_DE ):
1236*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_FANFOLD_STD_GERMAN;
1237*cdf0e10cSrcweir 				break;
1238*cdf0e10cSrcweir 			case( PAPER_POSTCARD_JP ):
1239*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_JAPANESE_POSTCARD;
1240*cdf0e10cSrcweir 				break;
1241*cdf0e10cSrcweir 			case( PAPER_9x11 ):
1242*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_9X11;
1243*cdf0e10cSrcweir 				break;
1244*cdf0e10cSrcweir 			case( PAPER_10x11 ):
1245*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_10X11;
1246*cdf0e10cSrcweir 				break;
1247*cdf0e10cSrcweir 			case( PAPER_15x11 ):
1248*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_15X11;
1249*cdf0e10cSrcweir 				break;
1250*cdf0e10cSrcweir 			case( PAPER_ENV_INVITE ):
1251*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_INVITE;
1252*cdf0e10cSrcweir 				break;
1253*cdf0e10cSrcweir 			case( PAPER_A_PLUS ):
1254*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A_PLUS;
1255*cdf0e10cSrcweir 				break;
1256*cdf0e10cSrcweir 			case( PAPER_B_PLUS ):
1257*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B_PLUS;
1258*cdf0e10cSrcweir 				break;
1259*cdf0e10cSrcweir 			case( PAPER_LETTER_PLUS ):
1260*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_LETTER_PLUS;
1261*cdf0e10cSrcweir 				break;
1262*cdf0e10cSrcweir 			case( PAPER_A4_PLUS ):
1263*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A4_PLUS;
1264*cdf0e10cSrcweir 				break;
1265*cdf0e10cSrcweir 			case( PAPER_DOUBLEPOSTCARD_JP ):
1266*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_DBL_JAPANESE_POSTCARD;
1267*cdf0e10cSrcweir 				break;
1268*cdf0e10cSrcweir 			case( PAPER_A6 ):
1269*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A6;
1270*cdf0e10cSrcweir 				break;
1271*cdf0e10cSrcweir 			case( PAPER_12x11 ):
1272*cdf0e10cSrcweir 				CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_12X11;
1273*cdf0e10cSrcweir 				break;
1274*cdf0e10cSrcweir 			default:
1275*cdf0e10cSrcweir 			{
1276*cdf0e10cSrcweir 				short	nPaper = 0;
1277*cdf0e10cSrcweir 				sal_uLong	nPaperCount = ImplDeviceCaps( pPrinter, DC_PAPERS, NULL, pSetupData );
1278*cdf0e10cSrcweir 				WORD*	pPapers = NULL;
1279*cdf0e10cSrcweir 				sal_uLong	nPaperSizeCount = ImplDeviceCaps( pPrinter, DC_PAPERSIZE, NULL, pSetupData );
1280*cdf0e10cSrcweir 				POINT*	pPaperSizes = NULL;
1281*cdf0e10cSrcweir 				DWORD	nLandscapeAngle = ImplDeviceCaps( pPrinter, DC_ORIENTATION, NULL, pSetupData );
1282*cdf0e10cSrcweir 				if ( nPaperCount && (nPaperCount != GDI_ERROR) )
1283*cdf0e10cSrcweir 				{
1284*cdf0e10cSrcweir 					pPapers = (WORD*)rtl_allocateZeroMemory(nPaperCount*sizeof(WORD));
1285*cdf0e10cSrcweir 					ImplDeviceCaps( pPrinter, DC_PAPERS, (BYTE*)pPapers, pSetupData );
1286*cdf0e10cSrcweir 				}
1287*cdf0e10cSrcweir 				if ( nPaperSizeCount && (nPaperSizeCount != GDI_ERROR) )
1288*cdf0e10cSrcweir 				{
1289*cdf0e10cSrcweir 					pPaperSizes = (POINT*)rtl_allocateZeroMemory(nPaperSizeCount*sizeof(POINT));
1290*cdf0e10cSrcweir 					ImplDeviceCaps( pPrinter, DC_PAPERSIZE, (BYTE*)pPaperSizes, pSetupData );
1291*cdf0e10cSrcweir 				}
1292*cdf0e10cSrcweir 				if ( (nPaperSizeCount == nPaperCount) && pPapers && pPaperSizes )
1293*cdf0e10cSrcweir 				{
1294*cdf0e10cSrcweir                     PaperInfo aInfo(pSetupData->mnPaperWidth, pSetupData->mnPaperHeight);
1295*cdf0e10cSrcweir 					// compare paper formats and select a good match
1296*cdf0e10cSrcweir 					for ( sal_uLong i = 0; i < nPaperCount; i++ )
1297*cdf0e10cSrcweir 					{
1298*cdf0e10cSrcweir 						if ( aInfo.sloppyEqual(PaperInfo(pPaperSizes[i].x*10, pPaperSizes[i].y*10)))
1299*cdf0e10cSrcweir 						{
1300*cdf0e10cSrcweir 							nPaper = pPapers[i];
1301*cdf0e10cSrcweir 							break;
1302*cdf0e10cSrcweir 						}
1303*cdf0e10cSrcweir 					}
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir 					// If the printer supports landscape orientation, check paper sizes again
1306*cdf0e10cSrcweir 					// with landscape orientation. This is necessary as a printer driver provides
1307*cdf0e10cSrcweir 					// all paper sizes with portrait orientation only!!
1308*cdf0e10cSrcweir 					if ( !nPaper && nLandscapeAngle != 0 )
1309*cdf0e10cSrcweir 					{
1310*cdf0e10cSrcweir                         PaperInfo aRotatedInfo(pSetupData->mnPaperHeight, pSetupData->mnPaperWidth);
1311*cdf0e10cSrcweir 						for ( sal_uLong i = 0; i < nPaperCount; i++ )
1312*cdf0e10cSrcweir 						{
1313*cdf0e10cSrcweir 							if ( aRotatedInfo.sloppyEqual(PaperInfo(pPaperSizes[i].x*10, pPaperSizes[i].y*10)) )
1314*cdf0e10cSrcweir 							{
1315*cdf0e10cSrcweir 								nPaper = pPapers[i];
1316*cdf0e10cSrcweir 								break;
1317*cdf0e10cSrcweir 							}
1318*cdf0e10cSrcweir 						}
1319*cdf0e10cSrcweir 					}
1320*cdf0e10cSrcweir 
1321*cdf0e10cSrcweir 					if ( nPaper )
1322*cdf0e10cSrcweir 						CHOOSE_DEVMODE(dmPaperSize) = nPaper;
1323*cdf0e10cSrcweir 				}
1324*cdf0e10cSrcweir 
1325*cdf0e10cSrcweir 				if ( !nPaper )
1326*cdf0e10cSrcweir 				{
1327*cdf0e10cSrcweir 					CHOOSE_DEVMODE(dmFields)	   |= DM_PAPERLENGTH | DM_PAPERWIDTH;
1328*cdf0e10cSrcweir 					CHOOSE_DEVMODE(dmPaperSize)    	= DMPAPER_USER;
1329*cdf0e10cSrcweir 					CHOOSE_DEVMODE(dmPaperWidth)	= (short)(pSetupData->mnPaperWidth/10);
1330*cdf0e10cSrcweir 					CHOOSE_DEVMODE(dmPaperLength)   = (short)(pSetupData->mnPaperHeight/10);
1331*cdf0e10cSrcweir 				}
1332*cdf0e10cSrcweir 
1333*cdf0e10cSrcweir 				if ( pPapers )
1334*cdf0e10cSrcweir 					rtl_freeMemory(pPapers);
1335*cdf0e10cSrcweir 				if ( pPaperSizes )
1336*cdf0e10cSrcweir 					rtl_freeMemory(pPaperSizes);
1337*cdf0e10cSrcweir 
1338*cdf0e10cSrcweir 				break;
1339*cdf0e10cSrcweir 			}
1340*cdf0e10cSrcweir 		}
1341*cdf0e10cSrcweir 	}
1342*cdf0e10cSrcweir     if( (nFlags & SAL_JOBSET_DUPLEXMODE) )
1343*cdf0e10cSrcweir     {
1344*cdf0e10cSrcweir         switch( pSetupData->meDuplexMode )
1345*cdf0e10cSrcweir         {
1346*cdf0e10cSrcweir         case DUPLEX_OFF:
1347*cdf0e10cSrcweir             CHOOSE_DEVMODE(dmFields) |= DM_DUPLEX;
1348*cdf0e10cSrcweir             CHOOSE_DEVMODE(dmDuplex) = DMDUP_SIMPLEX;
1349*cdf0e10cSrcweir             break;
1350*cdf0e10cSrcweir         case DUPLEX_SHORTEDGE:
1351*cdf0e10cSrcweir             CHOOSE_DEVMODE(dmFields) |= DM_DUPLEX;
1352*cdf0e10cSrcweir             CHOOSE_DEVMODE(dmDuplex) = DMDUP_HORIZONTAL;
1353*cdf0e10cSrcweir             break;
1354*cdf0e10cSrcweir         case DUPLEX_LONGEDGE:
1355*cdf0e10cSrcweir             CHOOSE_DEVMODE(dmFields) |= DM_DUPLEX;
1356*cdf0e10cSrcweir             CHOOSE_DEVMODE(dmDuplex) = DMDUP_VERTICAL;
1357*cdf0e10cSrcweir             break;
1358*cdf0e10cSrcweir         case DUPLEX_UNKNOWN:
1359*cdf0e10cSrcweir             break;
1360*cdf0e10cSrcweir         }
1361*cdf0e10cSrcweir     }
1362*cdf0e10cSrcweir }
1363*cdf0e10cSrcweir 
1364*cdf0e10cSrcweir // -----------------------------------------------------------------------
1365*cdf0e10cSrcweir 
1366*cdf0e10cSrcweir static HDC ImplCreateICW_WithCatch( LPWSTR pDriver,
1367*cdf0e10cSrcweir 	                                LPCWSTR pDevice,
1368*cdf0e10cSrcweir                                     LPDEVMODEW pDevMode )
1369*cdf0e10cSrcweir {
1370*cdf0e10cSrcweir     HDC hDC = 0;
1371*cdf0e10cSrcweir 	CATCH_DRIVER_EX_BEGIN;
1372*cdf0e10cSrcweir     hDC = CreateICW( pDriver, pDevice, 0, pDevMode );
1373*cdf0e10cSrcweir 	CATCH_DRIVER_EX_END_2( "exception in CreateICW" );
1374*cdf0e10cSrcweir     return hDC;
1375*cdf0e10cSrcweir }
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir static HDC ImplCreateICA_WithCatch( char* pDriver,
1378*cdf0e10cSrcweir 	                                char* pDevice,
1379*cdf0e10cSrcweir                                     LPDEVMODEA pDevMode )
1380*cdf0e10cSrcweir {
1381*cdf0e10cSrcweir     HDC hDC = 0;
1382*cdf0e10cSrcweir 	CATCH_DRIVER_EX_BEGIN;
1383*cdf0e10cSrcweir     hDC = CreateICA( pDriver, pDevice, 0, pDevMode );
1384*cdf0e10cSrcweir 	CATCH_DRIVER_EX_END_2( "exception in CreateICW" );
1385*cdf0e10cSrcweir     return hDC;
1386*cdf0e10cSrcweir }
1387*cdf0e10cSrcweir 
1388*cdf0e10cSrcweir 
1389*cdf0e10cSrcweir static HDC ImplCreateSalPrnIC( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
1390*cdf0e10cSrcweir {
1391*cdf0e10cSrcweir     HDC hDC = 0;
1392*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
1393*cdf0e10cSrcweir     {
1394*cdf0e10cSrcweir         LPDEVMODEW pDevMode;
1395*cdf0e10cSrcweir         if ( pSetupData && pSetupData->mpDriverData )
1396*cdf0e10cSrcweir             pDevMode = SAL_DEVMODE_W( pSetupData );
1397*cdf0e10cSrcweir         else
1398*cdf0e10cSrcweir             pDevMode = NULL;
1399*cdf0e10cSrcweir         // #95347 some buggy drivers (eg, OKI) write to those buffers in CreateIC, although declared const - so provide some space
1400*cdf0e10cSrcweir         // pl: does this hold true for Unicode functions ?
1401*cdf0e10cSrcweir         if( pPrinter->maDriverName.Len() > 2048 || pPrinter->maDeviceName.Len() > 2048 )
1402*cdf0e10cSrcweir             return 0;
1403*cdf0e10cSrcweir         sal_Unicode pDriverName[ 4096 ];
1404*cdf0e10cSrcweir         sal_Unicode pDeviceName[ 4096 ];
1405*cdf0e10cSrcweir         rtl_copyMemory( pDriverName, pPrinter->maDriverName.GetBuffer(), pPrinter->maDriverName.Len()*sizeof(sal_Unicode));
1406*cdf0e10cSrcweir         memset( pDriverName+pPrinter->maDriverName.Len(), 0, 32 );
1407*cdf0e10cSrcweir         rtl_copyMemory( pDeviceName, pPrinter->maDeviceName.GetBuffer(), pPrinter->maDeviceName.Len()*sizeof(sal_Unicode));
1408*cdf0e10cSrcweir         memset( pDeviceName+pPrinter->maDeviceName.Len(), 0, 32 );
1409*cdf0e10cSrcweir         hDC = ImplCreateICW_WithCatch( reinterpret_cast< LPWSTR >(pDriverName),
1410*cdf0e10cSrcweir                                        reinterpret_cast< LPCWSTR >(pDeviceName),
1411*cdf0e10cSrcweir                                        pDevMode );
1412*cdf0e10cSrcweir     }
1413*cdf0e10cSrcweir     else
1414*cdf0e10cSrcweir     {
1415*cdf0e10cSrcweir         LPDEVMODEA pDevMode;
1416*cdf0e10cSrcweir         if ( pSetupData && pSetupData->mpDriverData )
1417*cdf0e10cSrcweir             pDevMode = SAL_DEVMODE_A( pSetupData );
1418*cdf0e10cSrcweir         else
1419*cdf0e10cSrcweir             pDevMode = NULL;
1420*cdf0e10cSrcweir         // #95347 some buggy drivers (eg, OKI) write to those buffers in CreateIC, although declared const - so provide some space
1421*cdf0e10cSrcweir         ByteString aDriver ( ImplSalGetWinAnsiString( pPrinter->maDriverName, TRUE ) );
1422*cdf0e10cSrcweir         ByteString aDevice ( ImplSalGetWinAnsiString( pPrinter->maDeviceName, TRUE ) );
1423*cdf0e10cSrcweir         int n = aDriver.Len() > aDevice.Len() ? aDriver.Len() : aDevice.Len();
1424*cdf0e10cSrcweir             // #125813# under some circumstances many printer drivers really
1425*cdf0e10cSrcweir         // seem to have a problem with the names and their conversions.
1426*cdf0e10cSrcweir         // We need to get on to of this, but haven't been able to reproduce
1427*cdf0e10cSrcweir         // the problem yet. Put the names on the stack so we get them
1428*cdf0e10cSrcweir         // with an eventual crash report.
1429*cdf0e10cSrcweir         if( n >= 2048 )
1430*cdf0e10cSrcweir             return 0;
1431*cdf0e10cSrcweir         n += 2048;
1432*cdf0e10cSrcweir         char lpszDriverName[ 4096 ];
1433*cdf0e10cSrcweir         char lpszDeviceName[ 4096 ];
1434*cdf0e10cSrcweir         strncpy( lpszDriverName, aDriver.GetBuffer(), n );
1435*cdf0e10cSrcweir         strncpy( lpszDeviceName, aDevice.GetBuffer(), n );
1436*cdf0e10cSrcweir         // HDU: the crashes usually happen in a MBCS to unicode conversion,
1437*cdf0e10cSrcweir         // so I suspect the MBCS string's end is not properly recognized.
1438*cdf0e10cSrcweir         // The longest MBCS encoding I'm aware of has six bytes per code
1439*cdf0e10cSrcweir         // => add a couple of zeroes...
1440*cdf0e10cSrcweir         memset( lpszDriverName+aDriver.Len(), 0, 16 );
1441*cdf0e10cSrcweir         memset( lpszDeviceName+aDevice.Len(), 0, 16 );
1442*cdf0e10cSrcweir         hDC = ImplCreateICA_WithCatch( lpszDriverName,
1443*cdf0e10cSrcweir                                        lpszDeviceName,
1444*cdf0e10cSrcweir                                        pDevMode );
1445*cdf0e10cSrcweir     }
1446*cdf0e10cSrcweir     return hDC;
1447*cdf0e10cSrcweir }
1448*cdf0e10cSrcweir 
1449*cdf0e10cSrcweir // -----------------------------------------------------------------------
1450*cdf0e10cSrcweir 
1451*cdf0e10cSrcweir static WinSalGraphics* ImplCreateSalPrnGraphics( HDC hDC )
1452*cdf0e10cSrcweir {
1453*cdf0e10cSrcweir 	WinSalGraphics* pGraphics = new WinSalGraphics;
1454*cdf0e10cSrcweir     pGraphics->SetLayout( 0 );
1455*cdf0e10cSrcweir 	pGraphics->mhDC		= hDC;
1456*cdf0e10cSrcweir 	pGraphics->mhWnd 	= 0;
1457*cdf0e10cSrcweir 	pGraphics->mbPrinter = TRUE;
1458*cdf0e10cSrcweir 	pGraphics->mbVirDev	= FALSE;
1459*cdf0e10cSrcweir 	pGraphics->mbWindow	= FALSE;
1460*cdf0e10cSrcweir 	pGraphics->mbScreen	= FALSE;
1461*cdf0e10cSrcweir 	ImplSalInitGraphics( pGraphics );
1462*cdf0e10cSrcweir 	return pGraphics;
1463*cdf0e10cSrcweir }
1464*cdf0e10cSrcweir 
1465*cdf0e10cSrcweir // -----------------------------------------------------------------------
1466*cdf0e10cSrcweir 
1467*cdf0e10cSrcweir static sal_Bool ImplUpdateSalPrnIC( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
1468*cdf0e10cSrcweir {
1469*cdf0e10cSrcweir 	HDC hNewDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
1470*cdf0e10cSrcweir 	if ( !hNewDC )
1471*cdf0e10cSrcweir 		return FALSE;
1472*cdf0e10cSrcweir 
1473*cdf0e10cSrcweir 	if ( pPrinter->mpGraphics )
1474*cdf0e10cSrcweir 	{
1475*cdf0e10cSrcweir 		ImplSalDeInitGraphics( pPrinter->mpGraphics );
1476*cdf0e10cSrcweir 		DeleteDC( pPrinter->mpGraphics->mhDC );
1477*cdf0e10cSrcweir 		delete pPrinter->mpGraphics;
1478*cdf0e10cSrcweir 	}
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir 	pPrinter->mpGraphics = ImplCreateSalPrnGraphics( hNewDC );
1481*cdf0e10cSrcweir 	pPrinter->mhDC		= hNewDC;
1482*cdf0e10cSrcweir 
1483*cdf0e10cSrcweir 	return TRUE;
1484*cdf0e10cSrcweir }
1485*cdf0e10cSrcweir 
1486*cdf0e10cSrcweir // =======================================================================
1487*cdf0e10cSrcweir 
1488*cdf0e10cSrcweir SalInfoPrinter* WinSalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
1489*cdf0e10cSrcweir                                                    ImplJobSetup* pSetupData )
1490*cdf0e10cSrcweir {
1491*cdf0e10cSrcweir 	WinSalInfoPrinter* pPrinter = new WinSalInfoPrinter;
1492*cdf0e10cSrcweir     if( ! pQueueInfo->mpSysData )
1493*cdf0e10cSrcweir         GetPrinterQueueState( pQueueInfo );
1494*cdf0e10cSrcweir 	pPrinter->maDriverName	= pQueueInfo->maDriver;
1495*cdf0e10cSrcweir 	pPrinter->maDeviceName	= pQueueInfo->maPrinterName;
1496*cdf0e10cSrcweir 	pPrinter->maPortName	= pQueueInfo->mpSysData ?
1497*cdf0e10cSrcweir                                 *(String*)(pQueueInfo->mpSysData)
1498*cdf0e10cSrcweir                               : String();
1499*cdf0e10cSrcweir 
1500*cdf0e10cSrcweir     // check if the provided setup data match the actual printer
1501*cdf0e10cSrcweir 	ImplTestSalJobSetup( pPrinter, pSetupData, TRUE );
1502*cdf0e10cSrcweir 
1503*cdf0e10cSrcweir 	HDC hDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
1504*cdf0e10cSrcweir 	if ( !hDC )
1505*cdf0e10cSrcweir 	{
1506*cdf0e10cSrcweir 		delete pPrinter;
1507*cdf0e10cSrcweir 		return NULL;
1508*cdf0e10cSrcweir 	}
1509*cdf0e10cSrcweir 
1510*cdf0e10cSrcweir     pPrinter->mpGraphics = ImplCreateSalPrnGraphics( hDC );
1511*cdf0e10cSrcweir 	pPrinter->mhDC		= hDC;
1512*cdf0e10cSrcweir 	if ( !pSetupData->mpDriverData )
1513*cdf0e10cSrcweir 		ImplUpdateSalJobSetup( pPrinter, pSetupData, FALSE, NULL );
1514*cdf0e10cSrcweir 	ImplDevModeToJobSetup( pPrinter, pSetupData, SAL_JOBSET_ALL );
1515*cdf0e10cSrcweir 	pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS;
1516*cdf0e10cSrcweir 
1517*cdf0e10cSrcweir 	return pPrinter;
1518*cdf0e10cSrcweir }
1519*cdf0e10cSrcweir 
1520*cdf0e10cSrcweir // -----------------------------------------------------------------------
1521*cdf0e10cSrcweir 
1522*cdf0e10cSrcweir void WinSalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
1523*cdf0e10cSrcweir {
1524*cdf0e10cSrcweir 	delete pPrinter;
1525*cdf0e10cSrcweir }
1526*cdf0e10cSrcweir 
1527*cdf0e10cSrcweir // =======================================================================
1528*cdf0e10cSrcweir 
1529*cdf0e10cSrcweir WinSalInfoPrinter::WinSalInfoPrinter() :
1530*cdf0e10cSrcweir     mpGraphics( NULL ),
1531*cdf0e10cSrcweir     mhDC( 0 ),
1532*cdf0e10cSrcweir     mbGraphics( FALSE )
1533*cdf0e10cSrcweir {
1534*cdf0e10cSrcweir     m_bPapersInit = FALSE;
1535*cdf0e10cSrcweir }
1536*cdf0e10cSrcweir 
1537*cdf0e10cSrcweir // -----------------------------------------------------------------------
1538*cdf0e10cSrcweir 
1539*cdf0e10cSrcweir WinSalInfoPrinter::~WinSalInfoPrinter()
1540*cdf0e10cSrcweir {
1541*cdf0e10cSrcweir 	if ( mpGraphics )
1542*cdf0e10cSrcweir 	{
1543*cdf0e10cSrcweir 		ImplSalDeInitGraphics( mpGraphics );
1544*cdf0e10cSrcweir 		DeleteDC( mpGraphics->mhDC );
1545*cdf0e10cSrcweir 		delete mpGraphics;
1546*cdf0e10cSrcweir 	}
1547*cdf0e10cSrcweir }
1548*cdf0e10cSrcweir 
1549*cdf0e10cSrcweir // -----------------------------------------------------------------------
1550*cdf0e10cSrcweir 
1551*cdf0e10cSrcweir void WinSalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData )
1552*cdf0e10cSrcweir {
1553*cdf0e10cSrcweir     m_aPaperFormats.clear();
1554*cdf0e10cSrcweir 
1555*cdf0e10cSrcweir     DWORD nCount = ImplDeviceCaps( this, DC_PAPERSIZE, NULL, pSetupData );
1556*cdf0e10cSrcweir     if( nCount == GDI_ERROR )
1557*cdf0e10cSrcweir         nCount = 0;
1558*cdf0e10cSrcweir 
1559*cdf0e10cSrcweir     POINT* pPaperSizes = NULL;
1560*cdf0e10cSrcweir     if( nCount )
1561*cdf0e10cSrcweir 	{
1562*cdf0e10cSrcweir 		pPaperSizes = (POINT*)rtl_allocateZeroMemory(nCount*sizeof(POINT));
1563*cdf0e10cSrcweir 		ImplDeviceCaps( this, DC_PAPERSIZE, (BYTE*)pPaperSizes, pSetupData );
1564*cdf0e10cSrcweir 
1565*cdf0e10cSrcweir         if( aSalShlData.mbWPrinter )
1566*cdf0e10cSrcweir         {
1567*cdf0e10cSrcweir             sal_Unicode* pNamesBuffer = (sal_Unicode*)rtl_allocateMemory(nCount*64*sizeof(sal_Unicode));
1568*cdf0e10cSrcweir             ImplDeviceCaps( this, DC_PAPERNAMES, (BYTE*)pNamesBuffer, pSetupData );
1569*cdf0e10cSrcweir             for( DWORD i = 0; i < nCount; ++i )
1570*cdf0e10cSrcweir             {
1571*cdf0e10cSrcweir                 PaperInfo aInfo(pPaperSizes[i].x * 10, pPaperSizes[i].y * 10);
1572*cdf0e10cSrcweir                 m_aPaperFormats.push_back( aInfo );
1573*cdf0e10cSrcweir             }
1574*cdf0e10cSrcweir             rtl_freeMemory( pNamesBuffer );
1575*cdf0e10cSrcweir         }
1576*cdf0e10cSrcweir         else
1577*cdf0e10cSrcweir         {
1578*cdf0e10cSrcweir             char* pNamesBuffer = (char*)rtl_allocateMemory(nCount*64);
1579*cdf0e10cSrcweir             ImplDeviceCaps( this, DC_PAPERNAMES, (BYTE*)pNamesBuffer, pSetupData );
1580*cdf0e10cSrcweir             for( DWORD i = 0; i < nCount; ++i )
1581*cdf0e10cSrcweir             {
1582*cdf0e10cSrcweir                 PaperInfo aInfo(pPaperSizes[i].x * 10, pPaperSizes[i].y * 10);
1583*cdf0e10cSrcweir                 m_aPaperFormats.push_back( aInfo );
1584*cdf0e10cSrcweir             }
1585*cdf0e10cSrcweir             rtl_freeMemory( pNamesBuffer );
1586*cdf0e10cSrcweir         }
1587*cdf0e10cSrcweir         rtl_freeMemory( pPaperSizes );
1588*cdf0e10cSrcweir 	}
1589*cdf0e10cSrcweir 
1590*cdf0e10cSrcweir     m_bPapersInit = true;
1591*cdf0e10cSrcweir }
1592*cdf0e10cSrcweir 
1593*cdf0e10cSrcweir // -----------------------------------------------------------------------
1594*cdf0e10cSrcweir 
1595*cdf0e10cSrcweir int WinSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* pSetupData )
1596*cdf0e10cSrcweir {
1597*cdf0e10cSrcweir     int nRet = ImplDeviceCaps( this, DC_ORIENTATION, NULL, pSetupData );
1598*cdf0e10cSrcweir 
1599*cdf0e10cSrcweir     if( nRet != GDI_ERROR )
1600*cdf0e10cSrcweir         return nRet * 10;
1601*cdf0e10cSrcweir     else
1602*cdf0e10cSrcweir         return 900; // guess
1603*cdf0e10cSrcweir }
1604*cdf0e10cSrcweir 
1605*cdf0e10cSrcweir // -----------------------------------------------------------------------
1606*cdf0e10cSrcweir 
1607*cdf0e10cSrcweir SalGraphics* WinSalInfoPrinter::GetGraphics()
1608*cdf0e10cSrcweir {
1609*cdf0e10cSrcweir 	if ( mbGraphics )
1610*cdf0e10cSrcweir 		return NULL;
1611*cdf0e10cSrcweir 
1612*cdf0e10cSrcweir 	if ( mpGraphics )
1613*cdf0e10cSrcweir 		mbGraphics = TRUE;
1614*cdf0e10cSrcweir 
1615*cdf0e10cSrcweir 	return mpGraphics;
1616*cdf0e10cSrcweir }
1617*cdf0e10cSrcweir 
1618*cdf0e10cSrcweir // -----------------------------------------------------------------------
1619*cdf0e10cSrcweir 
1620*cdf0e10cSrcweir void WinSalInfoPrinter::ReleaseGraphics( SalGraphics* )
1621*cdf0e10cSrcweir {
1622*cdf0e10cSrcweir 	mbGraphics = FALSE;
1623*cdf0e10cSrcweir }
1624*cdf0e10cSrcweir 
1625*cdf0e10cSrcweir // -----------------------------------------------------------------------
1626*cdf0e10cSrcweir 
1627*cdf0e10cSrcweir sal_Bool WinSalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData )
1628*cdf0e10cSrcweir {
1629*cdf0e10cSrcweir 	if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, static_cast<WinSalFrame*>(pFrame) ) )
1630*cdf0e10cSrcweir 	{
1631*cdf0e10cSrcweir 		ImplDevModeToJobSetup( this, pSetupData, SAL_JOBSET_ALL );
1632*cdf0e10cSrcweir 		return ImplUpdateSalPrnIC( this, pSetupData );
1633*cdf0e10cSrcweir 	}
1634*cdf0e10cSrcweir 
1635*cdf0e10cSrcweir 	return FALSE;
1636*cdf0e10cSrcweir }
1637*cdf0e10cSrcweir 
1638*cdf0e10cSrcweir // -----------------------------------------------------------------------
1639*cdf0e10cSrcweir 
1640*cdf0e10cSrcweir sal_Bool WinSalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData )
1641*cdf0e10cSrcweir {
1642*cdf0e10cSrcweir 	if ( !ImplTestSalJobSetup( this, pSetupData, FALSE ) )
1643*cdf0e10cSrcweir 		return FALSE;
1644*cdf0e10cSrcweir 	return ImplUpdateSalPrnIC( this, pSetupData );
1645*cdf0e10cSrcweir }
1646*cdf0e10cSrcweir 
1647*cdf0e10cSrcweir // -----------------------------------------------------------------------
1648*cdf0e10cSrcweir 
1649*cdf0e10cSrcweir sal_Bool WinSalInfoPrinter::SetData( sal_uLong nFlags, ImplJobSetup* pSetupData )
1650*cdf0e10cSrcweir {
1651*cdf0e10cSrcweir 	ImplJobSetupToDevMode( this, pSetupData, nFlags );
1652*cdf0e10cSrcweir 	if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, NULL ) )
1653*cdf0e10cSrcweir 	{
1654*cdf0e10cSrcweir 		ImplDevModeToJobSetup( this, pSetupData, nFlags );
1655*cdf0e10cSrcweir 		return ImplUpdateSalPrnIC( this, pSetupData );
1656*cdf0e10cSrcweir 	}
1657*cdf0e10cSrcweir 
1658*cdf0e10cSrcweir 	return FALSE;
1659*cdf0e10cSrcweir }
1660*cdf0e10cSrcweir 
1661*cdf0e10cSrcweir // -----------------------------------------------------------------------
1662*cdf0e10cSrcweir 
1663*cdf0e10cSrcweir sal_uLong WinSalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pSetupData )
1664*cdf0e10cSrcweir {
1665*cdf0e10cSrcweir 	DWORD nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
1666*cdf0e10cSrcweir 	if ( nRet && (nRet != GDI_ERROR) )
1667*cdf0e10cSrcweir 		return nRet;
1668*cdf0e10cSrcweir 	else
1669*cdf0e10cSrcweir 		return 0;
1670*cdf0e10cSrcweir }
1671*cdf0e10cSrcweir 
1672*cdf0e10cSrcweir // -----------------------------------------------------------------------
1673*cdf0e10cSrcweir 
1674*cdf0e10cSrcweir XubString WinSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pSetupData, sal_uLong nPaperBin )
1675*cdf0e10cSrcweir {
1676*cdf0e10cSrcweir 	XubString aPaperBinName;
1677*cdf0e10cSrcweir 
1678*cdf0e10cSrcweir 	DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, NULL, pSetupData );
1679*cdf0e10cSrcweir 	if ( (nPaperBin < nBins) && (nBins != GDI_ERROR) )
1680*cdf0e10cSrcweir 	{
1681*cdf0e10cSrcweir         if( aSalShlData.mbWPrinter )
1682*cdf0e10cSrcweir         {
1683*cdf0e10cSrcweir             sal_Unicode* pBuffer = new sal_Unicode[nBins*24];
1684*cdf0e10cSrcweir             DWORD nRet = ImplDeviceCaps( this, DC_BINNAMES, (BYTE*)pBuffer, pSetupData );
1685*cdf0e10cSrcweir             if ( nRet && (nRet != GDI_ERROR) )
1686*cdf0e10cSrcweir                 aPaperBinName = pBuffer + (nPaperBin*24);
1687*cdf0e10cSrcweir             delete [] pBuffer;
1688*cdf0e10cSrcweir         }
1689*cdf0e10cSrcweir         else
1690*cdf0e10cSrcweir         {
1691*cdf0e10cSrcweir             char* pBuffer = new char[nBins*24];
1692*cdf0e10cSrcweir             DWORD nRet = ImplDeviceCaps( this, DC_BINNAMES, (BYTE*)pBuffer, pSetupData );
1693*cdf0e10cSrcweir             if ( nRet && (nRet != GDI_ERROR) )
1694*cdf0e10cSrcweir                 aPaperBinName = ImplSalGetUniString( (const char*)(pBuffer + (nPaperBin*24)) );
1695*cdf0e10cSrcweir             delete [] pBuffer;
1696*cdf0e10cSrcweir         }
1697*cdf0e10cSrcweir 	}
1698*cdf0e10cSrcweir 
1699*cdf0e10cSrcweir 	return aPaperBinName;
1700*cdf0e10cSrcweir }
1701*cdf0e10cSrcweir 
1702*cdf0e10cSrcweir // -----------------------------------------------------------------------
1703*cdf0e10cSrcweir 
1704*cdf0e10cSrcweir sal_uLong WinSalInfoPrinter::GetCapabilities( const ImplJobSetup* pSetupData, sal_uInt16 nType )
1705*cdf0e10cSrcweir {
1706*cdf0e10cSrcweir 	DWORD nRet;
1707*cdf0e10cSrcweir 
1708*cdf0e10cSrcweir 	switch ( nType )
1709*cdf0e10cSrcweir 	{
1710*cdf0e10cSrcweir 		case PRINTER_CAPABILITIES_SUPPORTDIALOG:
1711*cdf0e10cSrcweir 			return TRUE;
1712*cdf0e10cSrcweir 		case PRINTER_CAPABILITIES_COPIES:
1713*cdf0e10cSrcweir 			nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
1714*cdf0e10cSrcweir 			if ( nRet && (nRet != GDI_ERROR) )
1715*cdf0e10cSrcweir 				return nRet;
1716*cdf0e10cSrcweir 			return 0;
1717*cdf0e10cSrcweir 		case PRINTER_CAPABILITIES_COLLATECOPIES:
1718*cdf0e10cSrcweir 			if ( aSalShlData.mbW40 )
1719*cdf0e10cSrcweir 			{
1720*cdf0e10cSrcweir 				nRet = ImplDeviceCaps( this, DC_COLLATE, NULL, pSetupData );
1721*cdf0e10cSrcweir 				if ( nRet && (nRet != GDI_ERROR) )
1722*cdf0e10cSrcweir 				{
1723*cdf0e10cSrcweir 					nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
1724*cdf0e10cSrcweir 					if ( nRet && (nRet != GDI_ERROR) )
1725*cdf0e10cSrcweir 						 return nRet;
1726*cdf0e10cSrcweir 				}
1727*cdf0e10cSrcweir 			}
1728*cdf0e10cSrcweir 			return 0;
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir 		case PRINTER_CAPABILITIES_SETORIENTATION:
1731*cdf0e10cSrcweir 			nRet = ImplDeviceCaps( this, DC_ORIENTATION, NULL, pSetupData );
1732*cdf0e10cSrcweir 			if ( nRet && (nRet != GDI_ERROR) )
1733*cdf0e10cSrcweir 				return TRUE;
1734*cdf0e10cSrcweir 			return FALSE;
1735*cdf0e10cSrcweir 
1736*cdf0e10cSrcweir 		case PRINTER_CAPABILITIES_SETPAPERBIN:
1737*cdf0e10cSrcweir 			nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
1738*cdf0e10cSrcweir 			if ( nRet && (nRet != GDI_ERROR) )
1739*cdf0e10cSrcweir 				return TRUE;
1740*cdf0e10cSrcweir 			return FALSE;
1741*cdf0e10cSrcweir 
1742*cdf0e10cSrcweir 		case PRINTER_CAPABILITIES_SETPAPERSIZE:
1743*cdf0e10cSrcweir 		case PRINTER_CAPABILITIES_SETPAPER:
1744*cdf0e10cSrcweir 			nRet = ImplDeviceCaps( this, DC_PAPERS, NULL, pSetupData );
1745*cdf0e10cSrcweir 			if ( nRet && (nRet != GDI_ERROR) )
1746*cdf0e10cSrcweir 				return TRUE;
1747*cdf0e10cSrcweir 			return FALSE;
1748*cdf0e10cSrcweir 	}
1749*cdf0e10cSrcweir 
1750*cdf0e10cSrcweir 	return 0;
1751*cdf0e10cSrcweir }
1752*cdf0e10cSrcweir 
1753*cdf0e10cSrcweir // -----------------------------------------------------------------------
1754*cdf0e10cSrcweir 
1755*cdf0e10cSrcweir void WinSalInfoPrinter::GetPageInfo( const ImplJobSetup*,
1756*cdf0e10cSrcweir 								  long& rOutWidth, long& rOutHeight,
1757*cdf0e10cSrcweir 								  long& rPageOffX, long& rPageOffY,
1758*cdf0e10cSrcweir 								  long& rPageWidth, long& rPageHeight )
1759*cdf0e10cSrcweir {
1760*cdf0e10cSrcweir 	HDC hDC = mhDC;
1761*cdf0e10cSrcweir 
1762*cdf0e10cSrcweir 	rOutWidth	= GetDeviceCaps( hDC, HORZRES );
1763*cdf0e10cSrcweir 	rOutHeight	= GetDeviceCaps( hDC, VERTRES );
1764*cdf0e10cSrcweir 
1765*cdf0e10cSrcweir 	rPageOffX	= GetDeviceCaps( hDC, PHYSICALOFFSETX );
1766*cdf0e10cSrcweir 	rPageOffY	= GetDeviceCaps( hDC, PHYSICALOFFSETY );
1767*cdf0e10cSrcweir 	rPageWidth	= GetDeviceCaps( hDC, PHYSICALWIDTH );
1768*cdf0e10cSrcweir 	rPageHeight = GetDeviceCaps( hDC, PHYSICALHEIGHT );
1769*cdf0e10cSrcweir }
1770*cdf0e10cSrcweir 
1771*cdf0e10cSrcweir // =======================================================================
1772*cdf0e10cSrcweir 
1773*cdf0e10cSrcweir SalPrinter* WinSalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
1774*cdf0e10cSrcweir {
1775*cdf0e10cSrcweir 	WinSalPrinter* pPrinter = new WinSalPrinter;
1776*cdf0e10cSrcweir 	pPrinter->mpInfoPrinter = static_cast<WinSalInfoPrinter*>(pInfoPrinter);
1777*cdf0e10cSrcweir 	return pPrinter;
1778*cdf0e10cSrcweir }
1779*cdf0e10cSrcweir 
1780*cdf0e10cSrcweir // -----------------------------------------------------------------------
1781*cdf0e10cSrcweir 
1782*cdf0e10cSrcweir void WinSalInstance::DestroyPrinter( SalPrinter* pPrinter )
1783*cdf0e10cSrcweir {
1784*cdf0e10cSrcweir 	delete pPrinter;
1785*cdf0e10cSrcweir }
1786*cdf0e10cSrcweir 
1787*cdf0e10cSrcweir // =======================================================================
1788*cdf0e10cSrcweir 
1789*cdf0e10cSrcweir BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ )
1790*cdf0e10cSrcweir {
1791*cdf0e10cSrcweir 	SalData*	pSalData = GetSalData();
1792*cdf0e10cSrcweir 	WinSalPrinter* pPrinter;
1793*cdf0e10cSrcweir 	sal_Bool		bWhile = TRUE;
1794*cdf0e10cSrcweir 	int 		i = 0;
1795*cdf0e10cSrcweir 
1796*cdf0e10cSrcweir 	do
1797*cdf0e10cSrcweir 	{
1798*cdf0e10cSrcweir 		// Messages verarbeiten
1799*cdf0e10cSrcweir 		MSG aMsg;
1800*cdf0e10cSrcweir 		if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
1801*cdf0e10cSrcweir 		{
1802*cdf0e10cSrcweir             if ( !ImplInterceptChildWindowKeyDown( aMsg ) )
1803*cdf0e10cSrcweir             {
1804*cdf0e10cSrcweir                 TranslateMessage( &aMsg );
1805*cdf0e10cSrcweir                 ImplDispatchMessage( &aMsg );
1806*cdf0e10cSrcweir             }
1807*cdf0e10cSrcweir 			i++;
1808*cdf0e10cSrcweir 			if ( i > 15 )
1809*cdf0e10cSrcweir 				bWhile = FALSE;
1810*cdf0e10cSrcweir 		}
1811*cdf0e10cSrcweir 		else
1812*cdf0e10cSrcweir 			bWhile = FALSE;
1813*cdf0e10cSrcweir 
1814*cdf0e10cSrcweir 		pPrinter = pSalData->mpFirstPrinter;
1815*cdf0e10cSrcweir 		while ( pPrinter )
1816*cdf0e10cSrcweir 		{
1817*cdf0e10cSrcweir 			if( pPrinter->mhDC == hPrnDC )
1818*cdf0e10cSrcweir 				break;
1819*cdf0e10cSrcweir 
1820*cdf0e10cSrcweir 			pPrinter = pPrinter->mpNextPrinter;
1821*cdf0e10cSrcweir 		}
1822*cdf0e10cSrcweir 
1823*cdf0e10cSrcweir 		if ( !pPrinter || pPrinter->mbAbort )
1824*cdf0e10cSrcweir 			return FALSE;
1825*cdf0e10cSrcweir 	}
1826*cdf0e10cSrcweir 	while ( bWhile );
1827*cdf0e10cSrcweir 
1828*cdf0e10cSrcweir 	return TRUE;
1829*cdf0e10cSrcweir }
1830*cdf0e10cSrcweir 
1831*cdf0e10cSrcweir // -----------------------------------------------------------------------
1832*cdf0e10cSrcweir 
1833*cdf0e10cSrcweir static LPDEVMODEA ImplSalSetCopies( LPDEVMODEA pDevMode, sal_uLong nCopies, sal_Bool bCollate )
1834*cdf0e10cSrcweir {
1835*cdf0e10cSrcweir 	LPDEVMODEA pNewDevMode = pDevMode;
1836*cdf0e10cSrcweir 	if ( pDevMode && (nCopies > 1) )
1837*cdf0e10cSrcweir 	{
1838*cdf0e10cSrcweir 		if ( nCopies > 32765 )
1839*cdf0e10cSrcweir 			nCopies = 32765;
1840*cdf0e10cSrcweir 		sal_uLong nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra;
1841*cdf0e10cSrcweir 		pNewDevMode = (LPDEVMODEA)rtl_allocateMemory( nDevSize );
1842*cdf0e10cSrcweir 		memcpy( pNewDevMode, pDevMode, nDevSize );
1843*cdf0e10cSrcweir 		pDevMode = pNewDevMode;
1844*cdf0e10cSrcweir 		pDevMode->dmFields |= DM_COPIES;
1845*cdf0e10cSrcweir 		pDevMode->dmCopies	= (short)(sal_uInt16)nCopies;
1846*cdf0e10cSrcweir 		if ( aSalShlData.mbW40 )
1847*cdf0e10cSrcweir 		{
1848*cdf0e10cSrcweir 			pDevMode->dmFields |= DM_COLLATE;
1849*cdf0e10cSrcweir 			if ( bCollate )
1850*cdf0e10cSrcweir 				pDevMode->dmCollate = DMCOLLATE_TRUE;
1851*cdf0e10cSrcweir 			else
1852*cdf0e10cSrcweir 				pDevMode->dmCollate = DMCOLLATE_FALSE;
1853*cdf0e10cSrcweir 		}
1854*cdf0e10cSrcweir 	}
1855*cdf0e10cSrcweir 
1856*cdf0e10cSrcweir 	return pNewDevMode;
1857*cdf0e10cSrcweir }
1858*cdf0e10cSrcweir 
1859*cdf0e10cSrcweir static LPDEVMODEW ImplSalSetCopies( LPDEVMODEW pDevMode, sal_uLong nCopies, sal_Bool bCollate )
1860*cdf0e10cSrcweir {
1861*cdf0e10cSrcweir 	LPDEVMODEW pNewDevMode = pDevMode;
1862*cdf0e10cSrcweir 	if ( pDevMode && (nCopies > 1) )
1863*cdf0e10cSrcweir 	{
1864*cdf0e10cSrcweir 		if ( nCopies > 32765 )
1865*cdf0e10cSrcweir 			nCopies = 32765;
1866*cdf0e10cSrcweir 		sal_uLong nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra;
1867*cdf0e10cSrcweir 		pNewDevMode = (LPDEVMODEW)rtl_allocateMemory( nDevSize );
1868*cdf0e10cSrcweir 		memcpy( pNewDevMode, pDevMode, nDevSize );
1869*cdf0e10cSrcweir 		pDevMode = pNewDevMode;
1870*cdf0e10cSrcweir 		pDevMode->dmFields |= DM_COPIES;
1871*cdf0e10cSrcweir 		pDevMode->dmCopies	= (short)(sal_uInt16)nCopies;
1872*cdf0e10cSrcweir 		if ( aSalShlData.mbW40 )
1873*cdf0e10cSrcweir 		{
1874*cdf0e10cSrcweir 			pDevMode->dmFields |= DM_COLLATE;
1875*cdf0e10cSrcweir 			if ( bCollate )
1876*cdf0e10cSrcweir 				pDevMode->dmCollate = DMCOLLATE_TRUE;
1877*cdf0e10cSrcweir 			else
1878*cdf0e10cSrcweir 				pDevMode->dmCollate = DMCOLLATE_FALSE;
1879*cdf0e10cSrcweir 		}
1880*cdf0e10cSrcweir 	}
1881*cdf0e10cSrcweir 
1882*cdf0e10cSrcweir 	return pNewDevMode;
1883*cdf0e10cSrcweir }
1884*cdf0e10cSrcweir 
1885*cdf0e10cSrcweir // -----------------------------------------------------------------------
1886*cdf0e10cSrcweir 
1887*cdf0e10cSrcweir WinSalPrinter::WinSalPrinter() :
1888*cdf0e10cSrcweir     mpGraphics( NULL ),
1889*cdf0e10cSrcweir     mpInfoPrinter( NULL ),
1890*cdf0e10cSrcweir     mpNextPrinter( NULL ),
1891*cdf0e10cSrcweir     mhDC( 0 ),
1892*cdf0e10cSrcweir     mnError( 0 ),
1893*cdf0e10cSrcweir     mnCopies( 0 ),
1894*cdf0e10cSrcweir     mbCollate( FALSE ),
1895*cdf0e10cSrcweir     mbAbort( FALSE ),
1896*cdf0e10cSrcweir     mbValid( true )
1897*cdf0e10cSrcweir {
1898*cdf0e10cSrcweir 	SalData* pSalData = GetSalData();
1899*cdf0e10cSrcweir 	// insert printer in printerlist
1900*cdf0e10cSrcweir 	mpNextPrinter = pSalData->mpFirstPrinter;
1901*cdf0e10cSrcweir 	pSalData->mpFirstPrinter = this;
1902*cdf0e10cSrcweir }
1903*cdf0e10cSrcweir 
1904*cdf0e10cSrcweir // -----------------------------------------------------------------------
1905*cdf0e10cSrcweir 
1906*cdf0e10cSrcweir WinSalPrinter::~WinSalPrinter()
1907*cdf0e10cSrcweir {
1908*cdf0e10cSrcweir 	SalData* pSalData = GetSalData();
1909*cdf0e10cSrcweir 
1910*cdf0e10cSrcweir     // release DC if there is one still around because of AbortJob
1911*cdf0e10cSrcweir 	HDC hDC = mhDC;
1912*cdf0e10cSrcweir 	if ( hDC )
1913*cdf0e10cSrcweir 	{
1914*cdf0e10cSrcweir 		if ( mpGraphics )
1915*cdf0e10cSrcweir 		{
1916*cdf0e10cSrcweir 			ImplSalDeInitGraphics( mpGraphics );
1917*cdf0e10cSrcweir 			delete mpGraphics;
1918*cdf0e10cSrcweir 		}
1919*cdf0e10cSrcweir 
1920*cdf0e10cSrcweir 		DeleteDC( hDC );
1921*cdf0e10cSrcweir 	}
1922*cdf0e10cSrcweir 
1923*cdf0e10cSrcweir 	// remove printer from printerlist
1924*cdf0e10cSrcweir 	if ( this == pSalData->mpFirstPrinter )
1925*cdf0e10cSrcweir 		pSalData->mpFirstPrinter = mpNextPrinter;
1926*cdf0e10cSrcweir 	else
1927*cdf0e10cSrcweir 	{
1928*cdf0e10cSrcweir 		WinSalPrinter* pTempPrinter = pSalData->mpFirstPrinter;
1929*cdf0e10cSrcweir 
1930*cdf0e10cSrcweir 		while( pTempPrinter->mpNextPrinter != this )
1931*cdf0e10cSrcweir 			pTempPrinter = pTempPrinter->mpNextPrinter;
1932*cdf0e10cSrcweir 
1933*cdf0e10cSrcweir 		pTempPrinter->mpNextPrinter = mpNextPrinter;
1934*cdf0e10cSrcweir 	}
1935*cdf0e10cSrcweir     mbValid = false;
1936*cdf0e10cSrcweir }
1937*cdf0e10cSrcweir 
1938*cdf0e10cSrcweir // -----------------------------------------------------------------------
1939*cdf0e10cSrcweir 
1940*cdf0e10cSrcweir void WinSalPrinter::markInvalid()
1941*cdf0e10cSrcweir {
1942*cdf0e10cSrcweir     mbValid = false;
1943*cdf0e10cSrcweir }
1944*cdf0e10cSrcweir 
1945*cdf0e10cSrcweir // -----------------------------------------------------------------------
1946*cdf0e10cSrcweir 
1947*cdf0e10cSrcweir // need wrappers for StarTocW/A to use structured exception handling
1948*cdf0e10cSrcweir // since SEH does not mix with standard exception handling's cleanup
1949*cdf0e10cSrcweir static int lcl_StartDocW( HDC hDC, DOCINFOW* pInfo, WinSalPrinter* pPrt )
1950*cdf0e10cSrcweir {
1951*cdf0e10cSrcweir     int nRet = 0;
1952*cdf0e10cSrcweir     CATCH_DRIVER_EX_BEGIN;
1953*cdf0e10cSrcweir     nRet = ::StartDocW( hDC, pInfo );
1954*cdf0e10cSrcweir     CATCH_DRIVER_EX_END( "exception in StartDocW", pPrt );
1955*cdf0e10cSrcweir     return nRet;
1956*cdf0e10cSrcweir }
1957*cdf0e10cSrcweir 
1958*cdf0e10cSrcweir static int lcl_StartDocA( HDC hDC, DOCINFOA* pInfo, WinSalPrinter* pPrt )
1959*cdf0e10cSrcweir {
1960*cdf0e10cSrcweir     int nRet = 0;
1961*cdf0e10cSrcweir     CATCH_DRIVER_EX_BEGIN;
1962*cdf0e10cSrcweir     nRet = ::StartDocA( hDC, pInfo );
1963*cdf0e10cSrcweir     CATCH_DRIVER_EX_END( "exception in StartDocW", pPrt );
1964*cdf0e10cSrcweir     return nRet;
1965*cdf0e10cSrcweir }
1966*cdf0e10cSrcweir 
1967*cdf0e10cSrcweir sal_Bool WinSalPrinter::StartJob( const XubString* pFileName,
1968*cdf0e10cSrcweir 						   const XubString& rJobName,
1969*cdf0e10cSrcweir 						   const XubString&,
1970*cdf0e10cSrcweir 						   sal_uLong nCopies,
1971*cdf0e10cSrcweir                            bool bCollate,
1972*cdf0e10cSrcweir                            bool /*bDirect*/,
1973*cdf0e10cSrcweir 						   ImplJobSetup* pSetupData )
1974*cdf0e10cSrcweir {
1975*cdf0e10cSrcweir 	mnError		= 0;
1976*cdf0e10cSrcweir 	mbAbort		= FALSE;
1977*cdf0e10cSrcweir 	mnCopies		= nCopies;
1978*cdf0e10cSrcweir 	mbCollate 	= bCollate;
1979*cdf0e10cSrcweir 
1980*cdf0e10cSrcweir 	LPDEVMODEA	pOrgDevModeA = NULL;
1981*cdf0e10cSrcweir 	LPDEVMODEA	pDevModeA = NULL;
1982*cdf0e10cSrcweir 	LPDEVMODEW	pOrgDevModeW = NULL;
1983*cdf0e10cSrcweir 	LPDEVMODEW	pDevModeW = NULL;
1984*cdf0e10cSrcweir     HDC hDC = 0;
1985*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
1986*cdf0e10cSrcweir     {
1987*cdf0e10cSrcweir         if ( pSetupData && pSetupData->mpDriverData )
1988*cdf0e10cSrcweir         {
1989*cdf0e10cSrcweir             pOrgDevModeW = SAL_DEVMODE_W( pSetupData );
1990*cdf0e10cSrcweir             pDevModeW = ImplSalSetCopies( pOrgDevModeW, nCopies, bCollate );
1991*cdf0e10cSrcweir         }
1992*cdf0e10cSrcweir         else
1993*cdf0e10cSrcweir             pDevModeW = NULL;
1994*cdf0e10cSrcweir 
1995*cdf0e10cSrcweir         // #95347 some buggy drivers (eg, OKI) write to those buffers in CreateDC, although declared const - so provide some space
1996*cdf0e10cSrcweir         sal_Unicode aDrvBuf[4096];
1997*cdf0e10cSrcweir         sal_Unicode aDevBuf[4096];
1998*cdf0e10cSrcweir         rtl_copyMemory( aDrvBuf, mpInfoPrinter->maDriverName.GetBuffer(), (mpInfoPrinter->maDriverName.Len()+1)*sizeof(sal_Unicode));
1999*cdf0e10cSrcweir         rtl_copyMemory( aDevBuf, mpInfoPrinter->maDeviceName.GetBuffer(), (mpInfoPrinter->maDeviceName.Len()+1)*sizeof(sal_Unicode));
2000*cdf0e10cSrcweir         hDC = CreateDCW( reinterpret_cast<LPCWSTR>(aDrvBuf),
2001*cdf0e10cSrcweir                          reinterpret_cast<LPCWSTR>(aDevBuf),
2002*cdf0e10cSrcweir                          NULL,
2003*cdf0e10cSrcweir                          pDevModeW );
2004*cdf0e10cSrcweir 
2005*cdf0e10cSrcweir         if ( pDevModeW != pOrgDevModeW )
2006*cdf0e10cSrcweir             rtl_freeMemory( pDevModeW );
2007*cdf0e10cSrcweir     }
2008*cdf0e10cSrcweir     else
2009*cdf0e10cSrcweir     {
2010*cdf0e10cSrcweir         if ( pSetupData && pSetupData->mpDriverData )
2011*cdf0e10cSrcweir         {
2012*cdf0e10cSrcweir             pOrgDevModeA = SAL_DEVMODE_A( pSetupData );
2013*cdf0e10cSrcweir             pDevModeA = ImplSalSetCopies( pOrgDevModeA, nCopies, bCollate );
2014*cdf0e10cSrcweir         }
2015*cdf0e10cSrcweir         else
2016*cdf0e10cSrcweir             pDevModeA = NULL;
2017*cdf0e10cSrcweir 
2018*cdf0e10cSrcweir         // #95347 some buggy drivers (eg, OKI) write to those buffers in CreateDC, although declared const - so provide some space
2019*cdf0e10cSrcweir         ByteString aDriver ( ImplSalGetWinAnsiString( mpInfoPrinter->maDriverName, TRUE ) );
2020*cdf0e10cSrcweir         ByteString aDevice ( ImplSalGetWinAnsiString( mpInfoPrinter->maDeviceName, TRUE ) );
2021*cdf0e10cSrcweir         int n = aDriver.Len() > aDevice.Len() ? aDriver.Len() : aDevice.Len();
2022*cdf0e10cSrcweir         n += 2048;
2023*cdf0e10cSrcweir         char *lpszDriverName = new char[n];
2024*cdf0e10cSrcweir         char *lpszDeviceName = new char[n];
2025*cdf0e10cSrcweir         strncpy( lpszDriverName, aDriver.GetBuffer(), n );
2026*cdf0e10cSrcweir         strncpy( lpszDeviceName, aDevice.GetBuffer(), n );
2027*cdf0e10cSrcweir         hDC = CreateDCA( lpszDriverName,
2028*cdf0e10cSrcweir                          lpszDeviceName,
2029*cdf0e10cSrcweir                          NULL,
2030*cdf0e10cSrcweir                          pDevModeA );
2031*cdf0e10cSrcweir 
2032*cdf0e10cSrcweir         delete [] lpszDriverName;
2033*cdf0e10cSrcweir         delete [] lpszDeviceName;
2034*cdf0e10cSrcweir 
2035*cdf0e10cSrcweir         if ( pDevModeA != pOrgDevModeA )
2036*cdf0e10cSrcweir             rtl_freeMemory( pDevModeA );
2037*cdf0e10cSrcweir     }
2038*cdf0e10cSrcweir 
2039*cdf0e10cSrcweir 	if ( !hDC )
2040*cdf0e10cSrcweir 	{
2041*cdf0e10cSrcweir 		mnError = SAL_PRINTER_ERROR_GENERALERROR;
2042*cdf0e10cSrcweir 		return FALSE;
2043*cdf0e10cSrcweir 	}
2044*cdf0e10cSrcweir 
2045*cdf0e10cSrcweir     // make sure mhDC is set before the printer driver may call our abortproc
2046*cdf0e10cSrcweir     mhDC = hDC;
2047*cdf0e10cSrcweir 	if ( SetAbortProc( hDC, SalPrintAbortProc ) <= 0 )
2048*cdf0e10cSrcweir 	{
2049*cdf0e10cSrcweir 		mnError = SAL_PRINTER_ERROR_GENERALERROR;
2050*cdf0e10cSrcweir 		return FALSE;
2051*cdf0e10cSrcweir 	}
2052*cdf0e10cSrcweir 
2053*cdf0e10cSrcweir 	mnError	= 0;
2054*cdf0e10cSrcweir 	mbAbort	= FALSE;
2055*cdf0e10cSrcweir 
2056*cdf0e10cSrcweir 	// Wegen Telocom Balloon Fax-Treiber, der uns unsere Messages
2057*cdf0e10cSrcweir 	// ansonsten oefters schickt, versuchen wir vorher alle
2058*cdf0e10cSrcweir 	// zu verarbeiten und dann eine Dummy-Message reinstellen
2059*cdf0e10cSrcweir 	sal_Bool bWhile = TRUE;
2060*cdf0e10cSrcweir 	int  i = 0;
2061*cdf0e10cSrcweir 	do
2062*cdf0e10cSrcweir 	{
2063*cdf0e10cSrcweir 		// Messages verarbeiten
2064*cdf0e10cSrcweir 		MSG aMsg;
2065*cdf0e10cSrcweir 		if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
2066*cdf0e10cSrcweir 		{
2067*cdf0e10cSrcweir             if ( !ImplInterceptChildWindowKeyDown( aMsg ) )
2068*cdf0e10cSrcweir             {
2069*cdf0e10cSrcweir                 TranslateMessage( &aMsg );
2070*cdf0e10cSrcweir                 ImplDispatchMessage( &aMsg );
2071*cdf0e10cSrcweir             }
2072*cdf0e10cSrcweir 
2073*cdf0e10cSrcweir 			i++;
2074*cdf0e10cSrcweir 			if ( i > 15 )
2075*cdf0e10cSrcweir 				bWhile = FALSE;
2076*cdf0e10cSrcweir 		}
2077*cdf0e10cSrcweir 		else
2078*cdf0e10cSrcweir 			bWhile = FALSE;
2079*cdf0e10cSrcweir 	}
2080*cdf0e10cSrcweir 	while ( bWhile );
2081*cdf0e10cSrcweir 	ImplPostMessage( GetSalData()->mpFirstInstance->mhComWnd, SAL_MSG_DUMMY, 0, 0 );
2082*cdf0e10cSrcweir 
2083*cdf0e10cSrcweir     // bring up a file choser if printing to file port but no file name given
2084*cdf0e10cSrcweir     OUString aOutFileName;
2085*cdf0e10cSrcweir     if( mpInfoPrinter->maPortName.EqualsIgnoreCaseAscii( "FILE:" ) && !(pFileName && pFileName->Len()) )
2086*cdf0e10cSrcweir     {
2087*cdf0e10cSrcweir 
2088*cdf0e10cSrcweir         uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
2089*cdf0e10cSrcweir         if( xFactory.is() )
2090*cdf0e10cSrcweir         {
2091*cdf0e10cSrcweir             uno::Reference< XFilePicker > xFilePicker( xFactory->createInstance(
2092*cdf0e10cSrcweir                 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ) ) ),
2093*cdf0e10cSrcweir                 UNO_QUERY );
2094*cdf0e10cSrcweir             DBG_ASSERT( xFilePicker.is(), "could not get FilePicker service" );
2095*cdf0e10cSrcweir 
2096*cdf0e10cSrcweir             uno::Reference< XInitialization > xInit( xFilePicker, UNO_QUERY );
2097*cdf0e10cSrcweir             uno::Reference< XFilterManager > xFilterMgr( xFilePicker, UNO_QUERY );
2098*cdf0e10cSrcweir             if( xInit.is() && xFilePicker.is() && xFilterMgr.is() )
2099*cdf0e10cSrcweir             {
2100*cdf0e10cSrcweir                 Sequence< Any > aServiceType( 1 );
2101*cdf0e10cSrcweir                 aServiceType[0] <<= TemplateDescription::FILESAVE_SIMPLE;
2102*cdf0e10cSrcweir                 xInit->initialize( aServiceType );
2103*cdf0e10cSrcweir                 if( xFilePicker->execute() == ExecutableDialogResults::OK )
2104*cdf0e10cSrcweir                 {
2105*cdf0e10cSrcweir                     Sequence< OUString > aPathSeq( xFilePicker->getFiles() );
2106*cdf0e10cSrcweir 				    INetURLObject aObj( aPathSeq[0] );
2107*cdf0e10cSrcweir                     // we're using ansi calls (StartDocA) so convert the string
2108*cdf0e10cSrcweir                     aOutFileName = aObj.PathToFileName();
2109*cdf0e10cSrcweir                 }
2110*cdf0e10cSrcweir                 else
2111*cdf0e10cSrcweir                 {
2112*cdf0e10cSrcweir                     mnError = SAL_PRINTER_ERROR_ABORT;
2113*cdf0e10cSrcweir                     return FALSE;
2114*cdf0e10cSrcweir                 }
2115*cdf0e10cSrcweir             }
2116*cdf0e10cSrcweir         }
2117*cdf0e10cSrcweir     }
2118*cdf0e10cSrcweir 
2119*cdf0e10cSrcweir     if( aSalShlData.mbWPrinter )
2120*cdf0e10cSrcweir     {
2121*cdf0e10cSrcweir         DOCINFOW aInfo;
2122*cdf0e10cSrcweir         memset( &aInfo, 0, sizeof( DOCINFOW ) );
2123*cdf0e10cSrcweir         aInfo.cbSize = sizeof( aInfo );
2124*cdf0e10cSrcweir         aInfo.lpszDocName = (LPWSTR)rJobName.GetBuffer();
2125*cdf0e10cSrcweir         if ( pFileName || aOutFileName.getLength() )
2126*cdf0e10cSrcweir         {
2127*cdf0e10cSrcweir             if ( (pFileName && pFileName->Len()) || aOutFileName.getLength() )
2128*cdf0e10cSrcweir             {
2129*cdf0e10cSrcweir                 aInfo.lpszOutput = (LPWSTR)( (pFileName && pFileName->Len()) ? pFileName->GetBuffer() : aOutFileName.getStr());
2130*cdf0e10cSrcweir             }
2131*cdf0e10cSrcweir             else
2132*cdf0e10cSrcweir                 aInfo.lpszOutput = L"FILE:";
2133*cdf0e10cSrcweir         }
2134*cdf0e10cSrcweir         else
2135*cdf0e10cSrcweir             aInfo.lpszOutput = NULL;
2136*cdf0e10cSrcweir 
2137*cdf0e10cSrcweir         // start Job
2138*cdf0e10cSrcweir         int nRet = lcl_StartDocW( hDC, &aInfo, this );
2139*cdf0e10cSrcweir 
2140*cdf0e10cSrcweir         if ( nRet <= 0 )
2141*cdf0e10cSrcweir         {
2142*cdf0e10cSrcweir             long nError = GetLastError();
2143*cdf0e10cSrcweir             if ( (nRet == SP_USERABORT) || (nRet == SP_APPABORT) || (nError == ERROR_PRINT_CANCELLED) || (nError == ERROR_CANCELLED) )
2144*cdf0e10cSrcweir                 mnError = SAL_PRINTER_ERROR_ABORT;
2145*cdf0e10cSrcweir             else
2146*cdf0e10cSrcweir                 mnError = SAL_PRINTER_ERROR_GENERALERROR;
2147*cdf0e10cSrcweir             return FALSE;
2148*cdf0e10cSrcweir         }
2149*cdf0e10cSrcweir     }
2150*cdf0e10cSrcweir     else
2151*cdf0e10cSrcweir     {
2152*cdf0e10cSrcweir         // Both strings must exist, if StartJob() is called
2153*cdf0e10cSrcweir         ByteString aJobName( ImplSalGetWinAnsiString( rJobName, TRUE ) );
2154*cdf0e10cSrcweir         ByteString aFileName;
2155*cdf0e10cSrcweir 
2156*cdf0e10cSrcweir         DOCINFOA aInfo;
2157*cdf0e10cSrcweir         memset( &aInfo, 0, sizeof( DOCINFOA ) );
2158*cdf0e10cSrcweir         aInfo.cbSize = sizeof( aInfo );
2159*cdf0e10cSrcweir         aInfo.lpszDocName = (LPCSTR)aJobName.GetBuffer();
2160*cdf0e10cSrcweir         if ( pFileName || aOutFileName.getLength() )
2161*cdf0e10cSrcweir         {
2162*cdf0e10cSrcweir             if ( pFileName->Len() || aOutFileName.getLength() )
2163*cdf0e10cSrcweir             {
2164*cdf0e10cSrcweir                 aFileName = ImplSalGetWinAnsiString( pFileName ? *pFileName : static_cast<const XubString>(aOutFileName), TRUE );
2165*cdf0e10cSrcweir                 aInfo.lpszOutput = (LPCSTR)aFileName.GetBuffer();
2166*cdf0e10cSrcweir             }
2167*cdf0e10cSrcweir             else
2168*cdf0e10cSrcweir                 aInfo.lpszOutput = "FILE:";
2169*cdf0e10cSrcweir         }
2170*cdf0e10cSrcweir         else
2171*cdf0e10cSrcweir             aInfo.lpszOutput = NULL;
2172*cdf0e10cSrcweir 
2173*cdf0e10cSrcweir         // start Job
2174*cdf0e10cSrcweir         int nRet = lcl_StartDocA( hDC, &aInfo, this );
2175*cdf0e10cSrcweir         if ( nRet <= 0 )
2176*cdf0e10cSrcweir         {
2177*cdf0e10cSrcweir             long nError = GetLastError();
2178*cdf0e10cSrcweir             if ( (nRet == SP_USERABORT) || (nRet == SP_APPABORT) || (nError == ERROR_PRINT_CANCELLED) || (nError == ERROR_CANCELLED) )
2179*cdf0e10cSrcweir                 mnError = SAL_PRINTER_ERROR_ABORT;
2180*cdf0e10cSrcweir             else
2181*cdf0e10cSrcweir                 mnError = SAL_PRINTER_ERROR_GENERALERROR;
2182*cdf0e10cSrcweir             return FALSE;
2183*cdf0e10cSrcweir         }
2184*cdf0e10cSrcweir     }
2185*cdf0e10cSrcweir 
2186*cdf0e10cSrcweir 	return TRUE;
2187*cdf0e10cSrcweir }
2188*cdf0e10cSrcweir 
2189*cdf0e10cSrcweir // -----------------------------------------------------------------------
2190*cdf0e10cSrcweir 
2191*cdf0e10cSrcweir sal_Bool WinSalPrinter::EndJob()
2192*cdf0e10cSrcweir {
2193*cdf0e10cSrcweir 	DWORD err = 0;
2194*cdf0e10cSrcweir 	HDC hDC = mhDC;
2195*cdf0e10cSrcweir 	if ( isValid() && hDC )
2196*cdf0e10cSrcweir 	{
2197*cdf0e10cSrcweir 		if ( mpGraphics )
2198*cdf0e10cSrcweir 		{
2199*cdf0e10cSrcweir 			ImplSalDeInitGraphics( mpGraphics );
2200*cdf0e10cSrcweir 			delete mpGraphics;
2201*cdf0e10cSrcweir 			mpGraphics = NULL;
2202*cdf0e10cSrcweir 		}
2203*cdf0e10cSrcweir 
2204*cdf0e10cSrcweir         // #i54419# Windows fax printer brings up a dialog in EndDoc
2205*cdf0e10cSrcweir         // which text previously copied in soffice process can be
2206*cdf0e10cSrcweir         // pasted to -> deadlock due to mutex not released.
2207*cdf0e10cSrcweir         // it should be safe to release the yield mutex over the EndDoc
2208*cdf0e10cSrcweir         // call, however the real solution is supposed to be the threading
2209*cdf0e10cSrcweir         // framework yet to come.
2210*cdf0e10cSrcweir         SalData* pSalData = GetSalData();
2211*cdf0e10cSrcweir 		sal_uLong nAcquire = pSalData->mpFirstInstance->ReleaseYieldMutex();
2212*cdf0e10cSrcweir         CATCH_DRIVER_EX_BEGIN;
2213*cdf0e10cSrcweir         if( ::EndDoc( hDC ) <= 0 )
2214*cdf0e10cSrcweir             err = GetLastError();
2215*cdf0e10cSrcweir         CATCH_DRIVER_EX_END( "exception in EndDoc", this );
2216*cdf0e10cSrcweir 
2217*cdf0e10cSrcweir 		pSalData->mpFirstInstance->AcquireYieldMutex( nAcquire );
2218*cdf0e10cSrcweir 		DeleteDC( hDC );
2219*cdf0e10cSrcweir         mhDC = 0;
2220*cdf0e10cSrcweir 	}
2221*cdf0e10cSrcweir 
2222*cdf0e10cSrcweir 	return TRUE;
2223*cdf0e10cSrcweir }
2224*cdf0e10cSrcweir 
2225*cdf0e10cSrcweir // -----------------------------------------------------------------------
2226*cdf0e10cSrcweir 
2227*cdf0e10cSrcweir sal_Bool WinSalPrinter::AbortJob()
2228*cdf0e10cSrcweir {
2229*cdf0e10cSrcweir 	mbAbort = TRUE;
2230*cdf0e10cSrcweir 
2231*cdf0e10cSrcweir 	// Abort asyncron ausloesen
2232*cdf0e10cSrcweir 	HDC hDC = mhDC;
2233*cdf0e10cSrcweir 	if ( hDC )
2234*cdf0e10cSrcweir 	{
2235*cdf0e10cSrcweir 		SalData* pSalData = GetSalData();
2236*cdf0e10cSrcweir 		ImplPostMessage( pSalData->mpFirstInstance->mhComWnd,
2237*cdf0e10cSrcweir 						 SAL_MSG_PRINTABORTJOB, (WPARAM)hDC, 0 );
2238*cdf0e10cSrcweir 	}
2239*cdf0e10cSrcweir 
2240*cdf0e10cSrcweir 	return TRUE;
2241*cdf0e10cSrcweir }
2242*cdf0e10cSrcweir 
2243*cdf0e10cSrcweir // -----------------------------------------------------------------------
2244*cdf0e10cSrcweir 
2245*cdf0e10cSrcweir void ImplSalPrinterAbortJobAsync( HDC hPrnDC )
2246*cdf0e10cSrcweir {
2247*cdf0e10cSrcweir 	SalData*	pSalData = GetSalData();
2248*cdf0e10cSrcweir 	WinSalPrinter* pPrinter = pSalData->mpFirstPrinter;
2249*cdf0e10cSrcweir 
2250*cdf0e10cSrcweir 	// Feststellen, ob Printer noch existiert
2251*cdf0e10cSrcweir 	while ( pPrinter )
2252*cdf0e10cSrcweir 	{
2253*cdf0e10cSrcweir 		if ( pPrinter->mhDC == hPrnDC )
2254*cdf0e10cSrcweir 			break;
2255*cdf0e10cSrcweir 
2256*cdf0e10cSrcweir 		pPrinter = pPrinter->mpNextPrinter;
2257*cdf0e10cSrcweir 	}
2258*cdf0e10cSrcweir 
2259*cdf0e10cSrcweir 	// Wenn Printer noch existiert, dann den Job abbrechen
2260*cdf0e10cSrcweir 	if ( pPrinter )
2261*cdf0e10cSrcweir 	{
2262*cdf0e10cSrcweir 		HDC hDC = pPrinter->mhDC;
2263*cdf0e10cSrcweir 		if ( hDC )
2264*cdf0e10cSrcweir 		{
2265*cdf0e10cSrcweir 			if ( pPrinter->mpGraphics )
2266*cdf0e10cSrcweir 			{
2267*cdf0e10cSrcweir 				ImplSalDeInitGraphics( pPrinter->mpGraphics );
2268*cdf0e10cSrcweir 				delete pPrinter->mpGraphics;
2269*cdf0e10cSrcweir 				pPrinter->mpGraphics = NULL;
2270*cdf0e10cSrcweir 			}
2271*cdf0e10cSrcweir 
2272*cdf0e10cSrcweir             CATCH_DRIVER_EX_BEGIN;
2273*cdf0e10cSrcweir             ::AbortDoc( hDC );
2274*cdf0e10cSrcweir             CATCH_DRIVER_EX_END( "exception in AbortDoc", pPrinter );
2275*cdf0e10cSrcweir 
2276*cdf0e10cSrcweir 			DeleteDC( hDC );
2277*cdf0e10cSrcweir             pPrinter->mhDC = 0;
2278*cdf0e10cSrcweir 		}
2279*cdf0e10cSrcweir 	}
2280*cdf0e10cSrcweir }
2281*cdf0e10cSrcweir 
2282*cdf0e10cSrcweir // -----------------------------------------------------------------------
2283*cdf0e10cSrcweir 
2284*cdf0e10cSrcweir SalGraphics* WinSalPrinter::StartPage( ImplJobSetup* pSetupData, sal_Bool bNewJobData )
2285*cdf0e10cSrcweir {
2286*cdf0e10cSrcweir     if( ! isValid() || mhDC == 0 )
2287*cdf0e10cSrcweir         return NULL;
2288*cdf0e10cSrcweir 
2289*cdf0e10cSrcweir 	HDC hDC = mhDC;
2290*cdf0e10cSrcweir 	if ( pSetupData && pSetupData->mpDriverData && bNewJobData )
2291*cdf0e10cSrcweir 	{
2292*cdf0e10cSrcweir         if( aSalShlData.mbWPrinter )
2293*cdf0e10cSrcweir         {
2294*cdf0e10cSrcweir             LPDEVMODEW	pOrgDevModeW;
2295*cdf0e10cSrcweir             LPDEVMODEW	pDevModeW;
2296*cdf0e10cSrcweir             pOrgDevModeW = SAL_DEVMODE_W( pSetupData );
2297*cdf0e10cSrcweir             pDevModeW = ImplSalSetCopies( pOrgDevModeW, mnCopies, mbCollate );
2298*cdf0e10cSrcweir             ResetDCW( hDC, pDevModeW );
2299*cdf0e10cSrcweir             if ( pDevModeW != pOrgDevModeW )
2300*cdf0e10cSrcweir                 rtl_freeMemory( pDevModeW );
2301*cdf0e10cSrcweir         }
2302*cdf0e10cSrcweir         else
2303*cdf0e10cSrcweir         {
2304*cdf0e10cSrcweir             LPDEVMODEA	pOrgDevModeA;
2305*cdf0e10cSrcweir             LPDEVMODEA	pDevModeA;
2306*cdf0e10cSrcweir             pOrgDevModeA = SAL_DEVMODE_A( pSetupData );
2307*cdf0e10cSrcweir             pDevModeA = ImplSalSetCopies( pOrgDevModeA, mnCopies, mbCollate );
2308*cdf0e10cSrcweir             ResetDCA( hDC, pDevModeA );
2309*cdf0e10cSrcweir             if ( pDevModeA != pOrgDevModeA )
2310*cdf0e10cSrcweir                 rtl_freeMemory( pDevModeA );
2311*cdf0e10cSrcweir         }
2312*cdf0e10cSrcweir 	}
2313*cdf0e10cSrcweir 	int nRet = 0;
2314*cdf0e10cSrcweir     CATCH_DRIVER_EX_BEGIN;
2315*cdf0e10cSrcweir     nRet = ::StartPage( hDC );
2316*cdf0e10cSrcweir     CATCH_DRIVER_EX_END( "exception in StartPage", this );
2317*cdf0e10cSrcweir 
2318*cdf0e10cSrcweir 	if ( nRet <= 0 )
2319*cdf0e10cSrcweir 	{
2320*cdf0e10cSrcweir 		GetLastError();
2321*cdf0e10cSrcweir 		mnError = SAL_PRINTER_ERROR_GENERALERROR;
2322*cdf0e10cSrcweir 		return NULL;
2323*cdf0e10cSrcweir 	}
2324*cdf0e10cSrcweir 
2325*cdf0e10cSrcweir 	// Hack to work around old PostScript printer drivers optimizing away empty pages
2326*cdf0e10cSrcweir     // TODO: move into ImplCreateSalPrnGraphics()?
2327*cdf0e10cSrcweir 	HPEN	hTempPen = SelectPen( hDC, GetStockPen( NULL_PEN ) );
2328*cdf0e10cSrcweir 	HBRUSH	hTempBrush = SelectBrush( hDC, GetStockBrush( NULL_BRUSH ) );
2329*cdf0e10cSrcweir 	WIN_Rectangle( hDC, -8000, -8000, -7999, -7999 );
2330*cdf0e10cSrcweir 	SelectPen( hDC, hTempPen );
2331*cdf0e10cSrcweir 	SelectBrush( hDC, hTempBrush );
2332*cdf0e10cSrcweir 
2333*cdf0e10cSrcweir     mpGraphics = ImplCreateSalPrnGraphics( hDC );
2334*cdf0e10cSrcweir     return mpGraphics;
2335*cdf0e10cSrcweir }
2336*cdf0e10cSrcweir 
2337*cdf0e10cSrcweir // -----------------------------------------------------------------------
2338*cdf0e10cSrcweir 
2339*cdf0e10cSrcweir sal_Bool WinSalPrinter::EndPage()
2340*cdf0e10cSrcweir {
2341*cdf0e10cSrcweir 	HDC hDC = mhDC;
2342*cdf0e10cSrcweir 	if ( hDC && mpGraphics )
2343*cdf0e10cSrcweir 	{
2344*cdf0e10cSrcweir 		ImplSalDeInitGraphics( mpGraphics );
2345*cdf0e10cSrcweir 		delete mpGraphics;
2346*cdf0e10cSrcweir 		mpGraphics = NULL;
2347*cdf0e10cSrcweir 	}
2348*cdf0e10cSrcweir 
2349*cdf0e10cSrcweir     if( ! isValid() )
2350*cdf0e10cSrcweir         return FALSE;
2351*cdf0e10cSrcweir 
2352*cdf0e10cSrcweir 	int nRet = 0;
2353*cdf0e10cSrcweir     CATCH_DRIVER_EX_BEGIN;
2354*cdf0e10cSrcweir     nRet = ::EndPage( hDC );
2355*cdf0e10cSrcweir     CATCH_DRIVER_EX_END( "exception in EndPage", this );
2356*cdf0e10cSrcweir 
2357*cdf0e10cSrcweir 	if ( nRet > 0 )
2358*cdf0e10cSrcweir 		return TRUE;
2359*cdf0e10cSrcweir 	else
2360*cdf0e10cSrcweir 	{
2361*cdf0e10cSrcweir 		GetLastError();
2362*cdf0e10cSrcweir 		mnError = SAL_PRINTER_ERROR_GENERALERROR;
2363*cdf0e10cSrcweir 		return FALSE;
2364*cdf0e10cSrcweir 	}
2365*cdf0e10cSrcweir }
2366*cdf0e10cSrcweir 
2367*cdf0e10cSrcweir // -----------------------------------------------------------------------
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir sal_uLong WinSalPrinter::GetErrorCode()
2370*cdf0e10cSrcweir {
2371*cdf0e10cSrcweir 	return mnError;
2372*cdf0e10cSrcweir }
2373