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