xref: /aoo41x/main/vcl/os2/source/gdi/salprn.cxx (revision f98951f3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // use this define to disable the DJP support
25 // #define NO_DJP
26 
27 #define INCL_DOSMODULEMGR
28 #define INCL_DEV
29 #define INCL_SPL
30 #define INCL_SPLERRORS
31 #define INCL_SPLDOSPRINT
32 #define INCL_DEVDJP
33 
34 #define INCL_GPI
35 #define INCL_DOSSEMAPHORES
36 #define INCL_PM
37 #include <svpm.h>
38 #include <pmdjp.h>
39 
40 #include <string.h>
41 
42 #include <osl/module.h>
43 
44 #include <tools/urlobj.hxx>
45 #include <tools/svwin.h>
46 #ifdef __MINGW32__
47 #include <excpt.h>
48 #endif
49 
50 #include <os2/saldata.hxx>
51 #include <os2/salinst.h>
52 #include <os2/salgdi.h>
53 #include <os2/salframe.h>
54 #include <os2/salprn.h>
55 
56 #include <salptype.hxx>
57 #include <print.h>
58 #include <jobset.h>
59 
60 /*
61 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
62 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
63 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
64 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
65 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
66 #include <com/sun/star/lang/XInitialization.hpp>
67 #include <comphelper/processfactory.hxx>
68 */
69 
70 #include <malloc.h>
71 
72 /*
73 #define _SV_SALPRN_CXX
74 #include <tools/debug.hxx>
75 #include <saldata.hxx>
76 #include <salinst.h>
77 #include <salgdi.h>
78 #include <salframe.h>
79 #include <vcl/salptype.hxx>
80 #include <salprn.h>
81 #include <vcl/print.h>
82 #include <vcl/jobset.h>
83 
84 */
85 
86 #ifndef __H_FT2LIB
87 #include <os2/wingdi.h>
88 #include <ft2lib.h>
89 #endif
90 
91 // =======================================================================
92 
93 // -----------------------
94 // - struct ImplFormInfo -
95 // -----------------------
96 
97 struct ImplFormInfo
98 {
99 	long					mnPaperWidth;
100 	long					mnPaperHeight;
101 #ifndef NO_DJP
102 	DJPT_PAPERSIZE			mnId;
103 #endif
104 };
105 
106 // =======================================================================
107 
108 // -----------------------
109 // - struct ImplTrayInfo -
110 // -----------------------
111 
112 struct ImplTrayInfo
113 {
114 	CHAR			maName[32];
115 	CHAR			maDisplayName[64];
116 	DJPT_TRAYTYPE	mnId;
117 
118 	ImplTrayInfo( const char* pTrayName,
119 				  const char* pTrayDisplayName )
120 	{
121 		strcpy( maName, pTrayName);
122 		strcpy( maDisplayName, pTrayDisplayName);
123 	}
124 };
125 
126 // =======================================================================
127 
128 struct ImplQueueSalSysData
129 {
130 	ByteString		maPrinterName;			// pszPrinters
131 	ByteString		maName; 				// pszName bzw. LogAddress
132 	ByteString		maOrgDriverName;		// pszDriverName (maDriverName.maDeviceName)
133 	ByteString		maDriverName;			// pszDriverName bis .
134 	ByteString		maDeviceName;			// pszDriverName nach .
135 	PDRIVDATA		mpDrivData;
136 
137 					ImplQueueSalSysData( const ByteString& rPrinterName,
138 										 const ByteString& rName,
139 										 const ByteString& rDriverName,
140 										 const ByteString& rDeviceName,
141 										 const ByteString& rOrgDriverName,
142 										 PDRIVDATA pDrivData  );
143 					~ImplQueueSalSysData();
144 };
145 
146 // -----------------------------------------------------------------------
147 
148 ImplQueueSalSysData::ImplQueueSalSysData( const ByteString& rPrinterName,
149 										  const ByteString& rName,
150 										  const ByteString& rOrgDriverName,
151 										  const ByteString& rDriverName,
152 										  const ByteString& rDeviceName,
153 										  PDRIVDATA pDrivData ) :
154 	maPrinterName( rPrinterName ),
155 	maName( rName ),
156 	maOrgDriverName( rName ),
157 	maDriverName( rDriverName ),
158 	maDeviceName( rDeviceName )
159 {
160 	if ( pDrivData )
161 	{
162 		mpDrivData = (PDRIVDATA)new PM_BYTE[pDrivData->cb];
163 		memcpy( mpDrivData, pDrivData, pDrivData->cb );
164 	}
165 	else
166 		mpDrivData = NULL;
167 }
168 
169 // -----------------------------------------------------------------------
170 
171 ImplQueueSalSysData::~ImplQueueSalSysData()
172 {
173 	delete mpDrivData;
174 }
175 
176 // =======================================================================
177 
178 static ULONG ImplPMQueueStatusToSal( USHORT nPMStatus )
179 {
180 	ULONG nStatus = 0;
181 	if ( nPMStatus & PRQ3_PAUSED )
182 		nStatus |= QUEUE_STATUS_PAUSED;
183 	if ( nPMStatus & PRQ3_PENDING )
184 		nStatus |= QUEUE_STATUS_PENDING_DELETION;
185 	if ( !nStatus )
186 		nStatus |= QUEUE_STATUS_READY;
187 	return nStatus;
188 }
189 
190 // -----------------------------------------------------------------------
191 
192 void Os2SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
193 {
194 	APIRET rc;
195 	ULONG  nNeeded;
196 	ULONG  nReturned;
197 	ULONG  nTotal;
198 
199 	// query needed size of the buffer for the QueueInfo
200 	rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL );
201 	if( nNeeded == 0 )
202 		return;
203 
204 	// create the buffer for the QueueInfo
205 	PCHAR pQueueData = new CHAR[nNeeded];
206 
207 	// query QueueInfos
208 	rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL );
209 
210 	PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData;
211 	for ( int i = 0; i < nReturned; i++ )
212 	{
213 		// create entry for the QueueInfo array
214 		SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
215 
216 		ByteString aOrgDriverName( pPrqInfo->pszDriverName);
217 		ByteString aName( pPrqInfo->pszName);
218 #if OSL_DEBUG_LEVEL>0
219 		printf("GetPrinterQueueInfo pszDriverName %s\n", pPrqInfo->pszDriverName);
220 		printf("GetPrinterQueueInfo pszName %s\n", pPrqInfo->pszDriverName);
221 #endif
222 		pInfo->maDriver 	 = ::rtl::OStringToOUString (aOrgDriverName, gsl_getSystemTextEncoding());
223 		pInfo->maPrinterName = ::rtl::OStringToOUString (pPrqInfo->pszComment, gsl_getSystemTextEncoding());
224 		pInfo->maLocation	 = ::rtl::OStringToOUString (aName, gsl_getSystemTextEncoding());
225 		pInfo->mnStatus 	 = ImplPMQueueStatusToSal( pPrqInfo->fsStatus );
226 		pInfo->mnJobs		 = pPrqInfo->cJobs;
227 		// pInfo->maComment = !!!
228 
229 		// Feststellen, ob Name doppelt
230 		PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData;
231 		for ( int j = 0; j < nReturned; j++ )
232 		{
233 			// Wenn Name doppelt, erweitern wir diesen um die Location
234 			if ( (j != i) &&
235 				 (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) )
236 			{
237 				pInfo->maPrinterName += ';';
238 				pInfo->maPrinterName += pInfo->maLocation;
239 			}
240 			pTempPrqInfo++;
241 		}
242 
243 		// pszDriver in DriverName (bis .) und DeviceName (nach .) aufsplitten
244 		PSZ pDriverName;
245 		PSZ pDeviceName;
246 		if ( (pDriverName = strchr( pPrqInfo->pszDriverName, '.' )) != 0 )
247 		{
248 		   *pDriverName = 0;
249 		   pDeviceName	= pDriverName + 1;
250 		}
251 		else
252 			pDeviceName = NULL;
253 
254 		// Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit
255 		// ein memcmp vom JobSetup auch funktioniert
256 		if ( pPrqInfo->pDriverData &&
257 			 (pPrqInfo->pDriverData->cb >= sizeof( pPrqInfo->pDriverData )) )
258 		{
259 			int nDeviceNameLen = strlen( pPrqInfo->pDriverData->szDeviceName );
260 			memset( pPrqInfo->pDriverData->szDeviceName+nDeviceNameLen,
261 					0,
262 					sizeof( pPrqInfo->pDriverData->szDeviceName )-nDeviceNameLen );
263 		}
264 
265 		// save driver data and driver names
266 		ByteString aPrinterName( pPrqInfo->pszPrinters);
267 		ByteString aDriverName( pPrqInfo->pszDriverName);
268 		ByteString aDeviceName;
269 		if ( pDeviceName )
270 			aDeviceName = pDeviceName;
271 		pInfo->mpSysData = new ImplQueueSalSysData( aPrinterName, aName,
272 													aOrgDriverName,
273 													aDriverName, aDeviceName,
274 													pPrqInfo->pDriverData );
275 
276 		// add queue to the list
277 		pList->Add( pInfo );
278 
279 		// increment to next element of the QueueInfo array
280 		pPrqInfo++;
281 	}
282 
283 	delete [] pQueueData;
284 }
285 
286 // -----------------------------------------------------------------------
287 
288 void Os2SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
289 {
290 	APIRET rc;
291 	ULONG  nNeeded;
292 	ULONG  nReturned;
293 	ULONG  nTotal;
294 
295 	// query needed size of the buffer for the QueueInfo
296 	rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL );
297 	if( nNeeded == 0 )
298 		return;
299 
300 	// create the buffer for the QueueInfo
301 	PCHAR pQueueData = new CHAR[nNeeded];
302 
303 	// query QueueInfos
304 	rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL );
305 
306 	PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData;
307 	for ( int i = 0; i < nReturned; i++ )
308 	{
309 		ImplQueueSalSysData* pSysData = (ImplQueueSalSysData*)(pInfo->mpSysData);
310 		if ( pSysData->maPrinterName.Equals( pPrqInfo->pszPrinters ) &&
311 			 pSysData->maName.Equals( pPrqInfo->pszName ) &&
312 			 pSysData->maOrgDriverName.Equals( pPrqInfo->pszDriverName ) )
313 		{
314 			pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus );
315 			pInfo->mnJobs	= pPrqInfo->cJobs;
316 			break;
317 		}
318 
319 		// increment to next element of the QueueInfo array
320 		pPrqInfo++;
321 	}
322 
323 	delete [] pQueueData;
324 }
325 
326 // -----------------------------------------------------------------------
327 
328 void Os2SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
329 {
330 	delete ((ImplQueueSalSysData*)(pInfo->mpSysData));
331 	delete pInfo;
332 }
333 
334 // -----------------------------------------------------------------------
335 
336 XubString Os2SalInstance::GetDefaultPrinter()
337 {
338 	APIRET		rc;
339 	ULONG		nNeeded;
340 	ULONG		nReturned;
341 	ULONG		nTotal;
342 	char		szQueueName[255];
343 	XubString	aDefaultName;
344 
345 	// query default queue
346 	if ( !PrfQueryProfileString( HINI_PROFILE, SPL_INI_SPOOLER, "QUEUE", 0, szQueueName, sizeof( szQueueName ) ) )
347 		return aDefaultName;
348 
349 	// extract first queue name
350 	PSZ pStr;
351 	if ( (pStr = strchr( szQueueName, ';' )) != 0 )
352 		*pStr = 0;
353 
354 	// query needed size of the buffer for the QueueInfo
355 	rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL );
356 	if ( nNeeded == 0 )
357 		return aDefaultName;
358 
359 	// create the buffer for the QueueInfo
360 	PCHAR pQueueData = new CHAR[ nNeeded ];
361 
362 	// query QueueInfos
363 	rc = SplEnumQueue ((PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL );
364 
365 	// find printer name for default queue
366 	PPRQINFO3 pPrqInfo = (PPRQINFO3) pQueueData;
367 	for ( int i = 0; i < nReturned; i++ )
368 	{
369 		if ( strcmp( pPrqInfo->pszName, szQueueName ) == 0 )
370 		{
371 			aDefaultName = ::rtl::OStringToOUString (pPrqInfo->pszComment, gsl_getSystemTextEncoding());
372 
373 			// Feststellen, ob Name doppelt
374 			PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData;
375 			for ( int j = 0; j < nReturned; j++ )
376 			{
377 				// Wenn Name doppelt, erweitern wir diesen um die Location
378 				if ( (j != i) &&
379 					 (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) )
380 				{
381 					String pszName( ::rtl::OStringToOUString (pPrqInfo->pszName, gsl_getSystemTextEncoding()));
382 					aDefaultName += ';';
383 					aDefaultName += pszName;
384 				}
385 				pTempPrqInfo++;
386 			}
387 			break;
388 		}
389 
390 		// increment to next element of the QueueInfo array
391 		pPrqInfo++;
392 	}
393 
394 	delete [] pQueueData;
395 
396 	return aDefaultName;
397 }
398 
399 // =======================================================================
400 
401 static void* ImplAllocPrnMemory( size_t n )
402 {
403 	return calloc( n, 1);
404 }
405 
406 // -----------------------------------------------------------------------
407 
408 inline void ImplFreePrnMemory( void* p )
409 {
410 	free( p );
411 }
412 
413 // -----------------------------------------------------------------------
414 
415 static PDRIVDATA ImplPrnDrivData( const ImplJobSetup* pSetupData )
416 {
417 	// Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf
418 	// unseren Daten arbeiten, da es durch Konfigurationsprobleme
419 	// sein kann, das der Druckertreiber bei uns Daten ueberschreibt.
420 	// Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw.
421 	// sind dadurch leichter zu finden
422 
423 	if ( !pSetupData->mpDriverData )
424 		return NULL;
425 
426 	DBG_ASSERT( ((PDRIVDATA)(pSetupData->mpDriverData))->cb == pSetupData->mnDriverDataLen,
427 				"ImplPrnDrivData() - SetupDataLen != DriverDataLen" );
428 
429 	PDRIVDATA pDrivData = (PDRIVDATA)ImplAllocPrnMemory( pSetupData->mnDriverDataLen );
430 	memcpy( pDrivData, pSetupData->mpDriverData, pSetupData->mnDriverDataLen );
431 	return pDrivData;
432 }
433 
434 // -----------------------------------------------------------------------
435 
436 static void ImplUpdateSetupData( const PDRIVDATA pDrivData, ImplJobSetup* pSetupData )
437 {
438 	// Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf
439 	// unseren Daten arbeiten, da es durch Konfigurationsprobleme
440 	// sein kann, das der Druckertreiber bei uns Daten ueberschreibt.
441 	// Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw.
442 	// sind dadurch leichter zu finden
443 
444 	if ( !pDrivData || !pDrivData->cb )
445 	{
446 		if ( pSetupData->mpDriverData )
447 			rtl_freeMemory( pSetupData->mpDriverData );
448 		pSetupData->mpDriverData = NULL;
449 		pSetupData->mnDriverDataLen = 0;
450 	}
451 	else
452 	{
453 		// Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit
454 		// ein memcmp vom JobSetup auch funktioniert
455 		if ( pDrivData->cb >= sizeof( pDrivData ) )
456 		{
457 			int nDeviceNameLen = strlen( pDrivData->szDeviceName );
458 			memset( pDrivData->szDeviceName+nDeviceNameLen,
459 					0,
460 					sizeof( pDrivData->szDeviceName )-nDeviceNameLen );
461 		}
462 
463 		if ( pSetupData->mpDriverData )
464 		{
465 			if ( pSetupData->mnDriverDataLen != pDrivData->cb )
466 				rtl_freeMemory( pSetupData->mpDriverData );
467 			pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDrivData->cb);
468 		}
469 		else
470 			pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDrivData->cb);
471 		pSetupData->mnDriverDataLen = pDrivData->cb;
472 		memcpy( pSetupData->mpDriverData, pDrivData, pDrivData->cb );
473 	}
474 
475 	if ( pDrivData )
476 		ImplFreePrnMemory( pDrivData );
477 }
478 
479 // -----------------------------------------------------------------------
480 
481 static sal_Bool ImplPaperSizeEqual( long nPaperWidth1, long nPaperHeight1,
482 								long nPaperWidth2, long nPaperHeight2 )
483 {
484 	return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) &&
485 			((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1)));
486 }
487 
488 // -----------------------------------------------------------------------
489 
490 static sal_Bool ImplIsDriverDJPEnabled( HDC hDC )
491 {
492 #ifdef NO_DJP
493 	return FALSE;
494 #else
495 	// Ueber OS2-Ini kann DJP disablte werden
496 	if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_USEDJP, 1 ) )
497 		return FALSE;
498 
499 	// Testen, ob DJP-Interface am Drucker vorhanden
500 	LONG   lQuery;
501 	APIRET rc;
502 
503 	lQuery = DEVESC_QUERYSIZE;
504 	rc = DevEscape( hDC,
505 					DEVESC_QUERYESCSUPPORT,
506 					sizeof( lQuery ),
507 					(PBYTE)&lQuery,
508 					0,
509 					(PBYTE)NULL );
510 	if ( DEV_OK != rc )
511 		return FALSE;
512 
513 	lQuery = DEVESC_QUERYJOBPROPERTIES;
514 	rc = DevEscape( hDC,
515 					DEVESC_QUERYESCSUPPORT,
516 					sizeof( lQuery ),
517 					(PBYTE)&lQuery,
518 					0,
519 					(PBYTE)NULL );
520 	if ( DEV_OK != rc )
521 		return FALSE;
522 
523 	lQuery = DEVESC_SETJOBPROPERTIES;
524 	rc = DevEscape( hDC,
525 					DEVESC_QUERYESCSUPPORT,
526 					sizeof( lQuery ),
527 					(PBYTE)&lQuery,
528 					0,
529 					(PBYTE)NULL );
530 	if ( DEV_OK != rc )
531 		return FALSE;
532 
533 	return TRUE;
534 #endif
535 }
536 
537 // -----------------------------------------------------------------------
538 
539 static void ImplFormatInputList( PDJP_ITEM pDJP, PQUERYTUPLE pTuple )
540 {
541    // Loop through the query elements
542    sal_Bool fContinue = TRUE;
543    do
544    {
545 	  pDJP->cb			  = sizeof (DJP_ITEM);
546 	  pDJP->ulProperty	  = pTuple->ulProperty;
547 	  pDJP->lType		  = pTuple->lType;
548 	  pDJP->ulNumReturned = 0;
549 	  pDJP->ulValue 	  = DJP_NONE;
550 
551 	  // at EOL?
552 	  fContinue = DJP_NONE != pTuple->ulProperty;
553 
554 	  // Move to next item structure and tuplet
555 	  pDJP++;
556 	  pTuple++;
557    }
558    while ( fContinue );
559 }
560 
561 // -----------------------------------------------------------------------
562 
563 static void ImplFreeFormAndTrayList( Os2SalInfoPrinter* pOs2SalInfoPrinter )
564 {
565 	if ( pOs2SalInfoPrinter->mnFormCount )
566 	{
567 		for ( USHORT i = 0; i < pOs2SalInfoPrinter->mnFormCount; i++ )
568 			delete pOs2SalInfoPrinter->mpFormArray[i];
569 		delete [] pOs2SalInfoPrinter->mpFormArray;
570 		pOs2SalInfoPrinter->mnFormCount = 0;
571 	}
572 
573 	if ( pOs2SalInfoPrinter->mnTrayCount )
574 	{
575 		for ( USHORT i = 0; i < pOs2SalInfoPrinter->mnTrayCount; i++ )
576 			delete pOs2SalInfoPrinter->mpTrayArray[i];
577 		delete [] pOs2SalInfoPrinter->mpTrayArray;
578 		pOs2SalInfoPrinter->mnTrayCount = 0;
579 	}
580 }
581 
582 // -----------------------------------------------------------------------
583 
584 static void ImplGetFormAndTrayList( Os2SalInfoPrinter* pOs2SalInfoPrinter, const ImplJobSetup* pSetupData )
585 {
586 	ImplFreeFormAndTrayList( pOs2SalInfoPrinter );
587 
588 	LONG alQuery[] =
589 	{
590 		0,					0,				// First two members of QUERYSIZE
591 		DJP_CJ_FORM,		DJP_ALL,
592 		DJP_CJ_TRAYNAME,	DJP_ALL,
593 		DJP_NONE,			DJP_NONE		// EOL marker
594 	};
595 
596 	APIRET		rc;
597 	PQUERYSIZE	pQuerySize			= (PQUERYSIZE)alQuery;
598 	PBYTE		pBuffer 			= NULL;
599 	LONG		nAlloc				= 0;
600 	PDRIVDATA	pCopyDrivData		= ImplPrnDrivData( pSetupData );
601 	LONG		nDrivDataSize		= pCopyDrivData->cb;
602 	PBYTE		pDrivData			= (PBYTE)pCopyDrivData;
603 
604 	// find out how many bytes to allocate
605 	pQuerySize->cb = sizeof( alQuery );
606 	rc = DevEscape( pOs2SalInfoPrinter->mhDC,
607 					DEVESC_QUERYSIZE,
608 					sizeof( alQuery ),
609 					(PBYTE)pQuerySize,
610 					&nDrivDataSize,
611 					pDrivData );
612 	if ( DEV_OK != rc )
613 	{
614 		ImplFreePrnMemory( pCopyDrivData );
615 		return;
616 	}
617 
618 	// allocate the memory
619 	nAlloc = pQuerySize->ulSizeNeeded;
620 	pBuffer = (PBYTE)new PM_BYTE[nAlloc];
621 
622 	// set up the input
623 	PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
624 	ImplFormatInputList( pDJP, pQuerySize->aTuples );
625 
626 	// do it!
627 	rc = DevEscape( pOs2SalInfoPrinter->mhDC,
628 					DEVESC_QUERYJOBPROPERTIES,
629 					nAlloc,
630 					pBuffer,
631 					&nDrivDataSize,
632 					pDrivData );
633 	ImplFreePrnMemory( pCopyDrivData );
634 
635 	if ( (DEV_OK == rc) || (DEV_WARNING == rc) )
636 	{
637 		// Loop through the query elements
638 		PQUERYTUPLE pTuple = pQuerySize->aTuples;
639 		while ( DJP_NONE != pTuple->ulProperty )
640 		{
641 			if ( pDJP->ulProperty == DJP_CJ_FORM )
642 			{
643 				if ( pDJP->ulNumReturned )
644 				{
645 					PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM );
646 
647 					pOs2SalInfoPrinter->mnFormCount = pDJP->ulNumReturned;
648 					pOs2SalInfoPrinter->mpFormArray = new PIMPLFORMINFO[pOs2SalInfoPrinter->mnFormCount];
649 					for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ )
650 					{
651 						ImplFormInfo* pInfo 	= new ImplFormInfo;
652 						pInfo->mnPaperWidth 	= pElm->hcInfo.cx;
653 						pInfo->mnPaperHeight	= pElm->hcInfo.cy;
654 #if OSL_DEBUG_LEVEL>0
655 		printf("ImplGetFormAndTrayList mnPaperWidth %d\n", pInfo->mnPaperWidth);
656 		printf("ImplGetFormAndTrayList mnPaperHeight %d\n", pInfo->mnPaperHeight);
657 #endif
658 						pInfo->mnId 			= pElm->djppsFormID;
659 						pOs2SalInfoPrinter->mpFormArray[i] = pInfo;
660 					}
661 				}
662 			}
663 			else if ( pDJP->ulProperty == DJP_CJ_TRAYNAME )
664 			{
665 				if ( pDJP->ulNumReturned )
666 				{
667 					PDJPT_TRAYNAME pElm = DJP_ELEMENTP( *pDJP, DJPT_TRAYNAME );
668 
669 					pOs2SalInfoPrinter->mnTrayCount = pDJP->ulNumReturned;
670 					pOs2SalInfoPrinter->mpTrayArray = new PIMPLTRAYINFO[pOs2SalInfoPrinter->mnTrayCount];
671 					for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ )
672 					{
673 						ImplTrayInfo* pInfo 	= new ImplTrayInfo( pElm->szTrayname, pElm->szDisplayTrayname );
674 						pInfo->mnId 			= pElm->djpttTrayID;
675 						pOs2SalInfoPrinter->mpTrayArray[i] = pInfo;
676 					}
677 				}
678 			}
679 
680 			pDJP = DJP_NEXT_STRUCTP( pDJP );
681 			pTuple++;
682 		}
683 	}
684 
685 	delete [] pBuffer;
686 }
687 
688 // -----------------------------------------------------------------------
689 
690 static sal_Bool ImplGetCurrentSettings( Os2SalInfoPrinter* pOs2SalInfoPrinter, ImplJobSetup* pSetupData )
691 {
692 	// Um den aktuellen Tray zu ermitteln, brauchen wir auch die Listen dazu
693 	if ( !pOs2SalInfoPrinter->mnFormCount )
694 		ImplGetFormAndTrayList( pOs2SalInfoPrinter, pSetupData );
695 
696 	LONG alQuery[] =
697 	{
698 		0,						0,				// First two members of QUERYSIZE
699 		DJP_SJ_ORIENTATION, 	DJP_CURRENT,
700 		DJP_CJ_FORM,			DJP_CURRENT,
701 		DJP_NONE,				DJP_NONE		// EOL marker
702 	};
703 
704 	APIRET		rc;
705 	PQUERYSIZE	pQuerySize			= (PQUERYSIZE)alQuery;
706 	PBYTE		pBuffer 			= NULL;
707 	LONG		nAlloc				= 0;
708 	PDRIVDATA	pCopyDrivData		= ImplPrnDrivData( pSetupData );
709 	LONG		nDrivDataSize		= pCopyDrivData->cb;
710 	PBYTE		pDrivData			= (PBYTE)pCopyDrivData;
711 	sal_Bool		bResult;
712 
713 	// find out how many bytes to allocate
714 	pQuerySize->cb = sizeof( alQuery );
715 	rc = DevEscape( pOs2SalInfoPrinter->mhDC,
716 					DEVESC_QUERYSIZE,
717 					sizeof( alQuery ),
718 					(PBYTE)pQuerySize,
719 					&nDrivDataSize,
720 					pDrivData );
721 	if ( DEV_OK != rc )
722 	{
723 		ImplFreePrnMemory( pCopyDrivData );
724 		return FALSE;
725 	}
726 
727 	// allocate the memory
728 	nAlloc = pQuerySize->ulSizeNeeded;
729 	pBuffer = (PBYTE)new PM_BYTE[nAlloc];
730 
731 	// set up the input
732 	PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
733 	ImplFormatInputList( pDJP, pQuerySize->aTuples );
734 
735 	rc = DevEscape( pOs2SalInfoPrinter->mhDC,
736 					DEVESC_QUERYJOBPROPERTIES,
737 					nAlloc,
738 					pBuffer,
739 					&nDrivDataSize,
740 					pDrivData );
741 	if ( (DEV_OK == rc) || (DEV_WARNING == rc) )
742 	{
743 		// aktuelle Setup-Daten uebernehmen
744 		ImplUpdateSetupData( pCopyDrivData, pSetupData );
745 
746 		// Loop through the query elements
747 		PQUERYTUPLE pTuple = pQuerySize->aTuples;
748 		while ( DJP_NONE != pTuple->ulProperty )
749 		{
750 			if ( pDJP->ulProperty == DJP_SJ_ORIENTATION )
751 			{
752 				if ( pDJP->ulNumReturned )
753 				{
754 					PDJPT_ORIENTATION pElm = DJP_ELEMENTP( *pDJP, DJPT_ORIENTATION );
755 					if ( (DJP_ORI_PORTRAIT == *pElm) || (DJP_ORI_REV_PORTRAIT == *pElm) )
756 						pSetupData->meOrientation = ORIENTATION_PORTRAIT;
757 					else
758 						pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
759 				}
760 			}
761 			else if ( pDJP->ulProperty == DJP_CJ_FORM )
762 			{
763 				if ( pDJP->ulNumReturned )
764 				{
765 					PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM );
766 
767 					pSetupData->mnPaperWidth  = pElm->hcInfo.cx*100;
768 					pSetupData->mnPaperHeight = pElm->hcInfo.cy*100;
769 					switch( pElm->djppsFormID )
770 					{
771 						case DJP_PSI_A3:
772 							pSetupData->mePaperFormat = PAPER_A3;
773 							break;
774 
775 						case DJP_PSI_A4:
776 							pSetupData->mePaperFormat = PAPER_A4;
777 							break;
778 
779 						case DJP_PSI_A5:
780 							pSetupData->mePaperFormat = PAPER_A5;
781 							break;
782 
783 						case DJP_PSI_B4:
784 							pSetupData->mePaperFormat = PAPER_B4_JIS;
785 							break;
786 
787 						case DJP_PSI_B5:
788 							pSetupData->mePaperFormat = PAPER_B5_JIS;
789 							break;
790 
791 						case DJP_PSI_LETTER:
792 							pSetupData->mePaperFormat = PAPER_LETTER;
793 							break;
794 
795 						case DJP_PSI_LEGAL:
796 							pSetupData->mePaperFormat = PAPER_LEGAL;
797 							break;
798 
799 						case DJP_PSI_TABLOID:
800 							pSetupData->mePaperFormat = PAPER_TABLOID;
801 							break;
802 
803 						default:
804 							pSetupData->mePaperFormat = PAPER_USER;
805 							break;
806 					}
807 
808 					// Wir suchen zuerst ueber den Namen/Id und dann ueber die Id
809 					sal_Bool	bTrayFound = FALSE;
810 					USHORT	j;
811 					for ( j = 0; j < pOs2SalInfoPrinter->mnTrayCount; j++ )
812 					{
813 						if ( (pOs2SalInfoPrinter->mpTrayArray[j]->mnId == pElm->djpttTrayID) &&
814 							 (pOs2SalInfoPrinter->mpTrayArray[j]->maName == pElm->szTrayname) )
815 						{
816 							pSetupData->mnPaperBin = j;
817 							bTrayFound = TRUE;
818 							break;
819 						}
820 					}
821 					if ( !bTrayFound )
822 					{
823 						for ( j = 0; j < pOs2SalInfoPrinter->mnTrayCount; j++ )
824 						{
825 							if ( pOs2SalInfoPrinter->mpTrayArray[j]->mnId == pElm->djpttTrayID )
826 							{
827 								pSetupData->mnPaperBin = j;
828 								bTrayFound = TRUE;
829 								break;
830 							}
831 						}
832 					}
833 					// Wenn wir Ihn immer noch nicht gefunden haben, setzen
834 					// wir ihn auf DontKnow
835 					if ( !bTrayFound )
836 						pSetupData->mnPaperBin = 0xFFFF;
837 				}
838 			}
839 
840 			pDJP = DJP_NEXT_STRUCTP( pDJP );
841 			pTuple++;
842 		}
843 
844 		bResult = TRUE;
845 	}
846 	else
847 	{
848 		ImplFreePrnMemory( pCopyDrivData );
849 		bResult = FALSE;
850 	}
851 
852 	delete [] pBuffer;
853 
854 	return bResult;
855 }
856 
857 // -----------------------------------------------------------------------
858 
859 static sal_Bool ImplSetOrientation( HDC hPrinterDC, PDRIVDATA pDriverData,
860 								Orientation eOrientation )
861 {
862 	LONG alQuery[] =
863 	{
864 		0,						0,				// First two members of QUERYSIZE
865 		DJP_SJ_ORIENTATION, 	DJP_CURRENT,
866 		DJP_NONE,				DJP_NONE		// EOL marker
867 	};
868 
869 	APIRET		rc;
870 	PQUERYSIZE	pQuerySize		= (PQUERYSIZE)alQuery;
871 	PBYTE		pBuffer 		= NULL;
872 	LONG		nAlloc			= 0;
873 	LONG		nDrivDataSize	= pDriverData->cb;
874 
875 	// find out how many bytes to allocate
876 	pQuerySize->cb = sizeof( alQuery );
877 	rc = DevEscape( hPrinterDC,
878 					DEVESC_QUERYSIZE,
879 					sizeof( alQuery ),
880 					(PBYTE)pQuerySize,
881 					&nDrivDataSize,
882 					(PBYTE)pDriverData );
883 	if ( DEV_OK != rc )
884 		return FALSE;
885 
886 	// allocate the memory
887 	nAlloc = pQuerySize->ulSizeNeeded;
888 	pBuffer = (PBYTE)new PM_BYTE[nAlloc];
889 
890 	// set up the input
891 	PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
892 	ImplFormatInputList( pDJP, pQuerySize->aTuples );
893 
894 	pDJP->cb		 = sizeof( DJP_ITEM );
895 	pDJP->ulProperty = DJP_SJ_ORIENTATION;
896 	pDJP->lType 	 = DJP_CURRENT;
897 	pDJP->ulValue	 = (eOrientation == ORIENTATION_PORTRAIT)
898 						   ? DJP_ORI_PORTRAIT
899 						   : DJP_ORI_LANDSCAPE;
900 
901 	// do it!
902 	rc = DevEscape( hPrinterDC,
903 					DEVESC_SETJOBPROPERTIES,
904 					nAlloc,
905 					pBuffer,
906 					&nDrivDataSize,
907 					(PBYTE)pDriverData );
908 
909 	delete [] pBuffer;
910 
911 	return ((DEV_OK == rc) || (DEV_WARNING == rc));
912 }
913 
914 // -----------------------------------------------------------------------
915 
916 static sal_Bool ImplSetPaperSize( HDC hPrinterDC, PDRIVDATA pDriverData,
917 							  DJPT_PAPERSIZE nOS2PaperFormat )
918 {
919 	LONG alQuery[] =
920 	{
921 		0,						0,				// First two members of QUERYSIZE
922 		DJP_SJ_PAPERSIZE,		DJP_CURRENT,
923 		DJP_NONE,				DJP_NONE		// EOL marker
924 	};
925 
926 	APIRET		rc;
927 	PQUERYSIZE	pQuerySize		= (PQUERYSIZE)alQuery;
928 	PBYTE		pBuffer 		= NULL;
929 	LONG		nAlloc			= 0;
930 	LONG		nDrivDataSize	= pDriverData->cb;
931 
932 	// find out how many bytes to allocate
933 	pQuerySize->cb = sizeof( alQuery );
934 	rc = DevEscape( hPrinterDC,
935 					DEVESC_QUERYSIZE,
936 					sizeof( alQuery ),
937 					(PBYTE)pQuerySize,
938 					&nDrivDataSize,
939 					(PBYTE)pDriverData );
940 	if ( DEV_OK != rc )
941 		return FALSE;
942 
943 	// allocate the memory
944 	nAlloc = pQuerySize->ulSizeNeeded;
945 	pBuffer = (PBYTE)new PM_BYTE[nAlloc];
946 
947 	// set up the input
948 	PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
949 	PDJP_ITEM pStartDJP = pDJP;
950 	ImplFormatInputList( pDJP, pQuerySize->aTuples );
951 
952 	// Neue Daten zuweisen
953 	pDJP->cb		 = sizeof( DJP_ITEM );
954 	pDJP->ulProperty = DJP_SJ_PAPERSIZE;
955 	pDJP->lType 	 = DJP_CURRENT;
956 	pDJP->ulValue	 = nOS2PaperFormat;
957 
958 	// und setzen
959 	rc = DevEscape( hPrinterDC,
960 					DEVESC_SETJOBPROPERTIES,
961 					nAlloc,
962 					pBuffer,
963 					&nDrivDataSize,
964 					(PBYTE)pDriverData );
965 
966 	delete [] pBuffer;
967 
968 	return ((DEV_OK == rc) || (DEV_WARNING == rc));
969 }
970 
971 // -----------------------------------------------------------------------
972 
973 static sal_Bool ImplSetPaperBin( HDC hPrinterDC, PDRIVDATA pDriverData,
974 							 ImplTrayInfo* pTrayInfo )
975 {
976 	LONG alQuery[] =
977 	{
978 		0,						0,				// First two members of QUERYSIZE
979 		DJP_SJ_TRAYTYPE,		DJP_CURRENT,
980 		DJP_NONE,				DJP_NONE		// EOL marker
981 	};
982 
983 	APIRET		rc;
984 	PQUERYSIZE	pQuerySize		= (PQUERYSIZE)alQuery;
985 	PBYTE		pBuffer 		= NULL;
986 	LONG		nAlloc			= 0;
987 	LONG		nDrivDataSize	= pDriverData->cb;
988 
989 	// find out how many bytes to allocate
990 	pQuerySize->cb = sizeof( alQuery );
991 	rc = DevEscape( hPrinterDC,
992 					DEVESC_QUERYSIZE,
993 					sizeof( alQuery ),
994 					(PBYTE)pQuerySize,
995 					&nDrivDataSize,
996 					(PBYTE)pDriverData );
997 	if ( DEV_OK != rc )
998 		return FALSE;
999 
1000 	// allocate the memory
1001 	nAlloc = pQuerySize->ulSizeNeeded;
1002 	pBuffer = (PBYTE)new PM_BYTE[nAlloc];
1003 
1004 	// set up the input
1005 	PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer;
1006 	ImplFormatInputList( pDJP, pQuerySize->aTuples );
1007 
1008 	// Neue Daten zuweisen
1009 	pDJP->cb		 = sizeof( DJP_ITEM );
1010 	pDJP->ulProperty = DJP_SJ_TRAYTYPE;
1011 	pDJP->lType 	 = DJP_CURRENT;
1012 	pDJP->ulValue	 = pTrayInfo->mnId;
1013 
1014 	// und setzen
1015 	rc = DevEscape( hPrinterDC,
1016 					DEVESC_SETJOBPROPERTIES,
1017 					nAlloc,
1018 					pBuffer,
1019 					&nDrivDataSize,
1020 					(PBYTE)pDriverData );
1021 
1022 	delete [] pBuffer;
1023 
1024 	return ((DEV_OK == rc) || (DEV_WARNING == rc));
1025 }
1026 
1027 // =======================================================================
1028 
1029 static sal_Bool ImplSalCreateInfoPrn( Os2SalInfoPrinter* pPrinter, PDRIVDATA pDriverData,
1030 								  HDC& rDC, HPS& rPS )
1031 {
1032 	SalData* pSalData = GetSalData();
1033 
1034 	// create info context
1035 	DEVOPENSTRUC  devOpenStruc;
1036 	memset( &devOpenStruc, 0, sizeof( devOpenStruc ) );
1037 	devOpenStruc.pszLogAddress		= (char*)pPrinter->maName.GetBuffer();
1038 	devOpenStruc.pszDriverName		= (char*)pPrinter->maDriverName.GetBuffer();
1039 	devOpenStruc.pdriv				= pDriverData;
1040 	devOpenStruc.pszDataType		= "PM_Q_STD";
1041 
1042 	HDC hDC = DevOpenDC( pSalData->mhAB, OD_INFO, "*",
1043 						 4, (PDEVOPENDATA)&devOpenStruc, (HDC)NULL);
1044 	if ( !hDC )
1045 		return FALSE;
1046 
1047 	// create presentation space
1048 	SIZEL sizel;
1049 	sizel.cx = 0;
1050 	sizel.cy = 0;
1051 	HPS hPS = Ft2CreatePS( pSalData->mhAB, hDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS );
1052 	if ( !hPS )
1053 	{
1054 		DevCloseDC( hDC );
1055 		return FALSE;
1056 	}
1057 
1058 	rDC = hDC;
1059 	rPS = hPS;
1060 	return TRUE;
1061 }
1062 
1063 // -----------------------------------------------------------------------
1064 
1065 static void ImplSalDestroyInfoPrn( Os2SalInfoPrinter* pPrinter )
1066 {
1067 	ImplSalDeInitGraphics( pPrinter->mpGraphics);
1068 	Ft2Associate( pPrinter->mhPS, 0 );
1069 	Ft2DestroyPS( pPrinter->mhPS );
1070 	DevCloseDC( pPrinter->mhDC );
1071 }
1072 
1073 // =======================================================================
1074 
1075 SalInfoPrinter* Os2SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
1076 												ImplJobSetup* pSetupData )
1077 {
1078 	ImplQueueSalSysData* pSysQueueData = (ImplQueueSalSysData*)(pQueueInfo->mpSysData);
1079 	Os2SalInfoPrinter* pPrinter = new Os2SalInfoPrinter;
1080 	pPrinter->maPrinterName	= pSysQueueData->maPrinterName;
1081 	pPrinter->maName			= pSysQueueData->maName;
1082 	pPrinter->maDriverName	= pSysQueueData->maDriverName;
1083 	pPrinter->maDeviceName	= pSysQueueData->maDeviceName;
1084 
1085 	// Nur Setup-Daten uebernehmen, wenn Treiber und Laenge der Treiberdaten
1086 	// uebereinstimmt
1087 	PDRIVDATA	pDriverData;
1088 	sal_Bool		bUpdateDriverData;
1089 	if ( pSetupData->mpDriverData && pSysQueueData->mpDrivData &&
1090 		 (pSetupData->mnSystem == JOBSETUP_SYSTEM_OS2) &&
1091 		 (pSetupData->mnDriverDataLen == pSysQueueData->mpDrivData->cb) &&
1092 		 (strcmp( ((PDRIVDATA)pSetupData->mpDriverData)->szDeviceName,
1093 				  pSysQueueData->mpDrivData->szDeviceName ) == 0) )
1094 	{
1095 		pDriverData = PDRIVDATA( pSetupData->mpDriverData );
1096 		bUpdateDriverData = FALSE;
1097 	}
1098 	else
1099 	{
1100 		pDriverData = pSysQueueData->mpDrivData;
1101 		bUpdateDriverData = TRUE;
1102 	}
1103 	if ( pDriverData )
1104 		pPrinter->maJobSetupDeviceName = pDriverData->szDeviceName;
1105 
1106 	if ( !ImplSalCreateInfoPrn( pPrinter, pDriverData,
1107 								pPrinter->mhDC,
1108 								pPrinter->mhPS ) )
1109 	{
1110 		delete pPrinter;
1111 		return NULL;
1112 	}
1113 
1114 	// create graphics object for output
1115 	Os2SalGraphics* pGraphics = new Os2SalGraphics;
1116 	pGraphics->mhDC				= pPrinter->mhDC;
1117 	pGraphics->mhPS				= pPrinter->mhPS;
1118 	pGraphics->mhWnd 			= 0;
1119 	pGraphics->mbPrinter 		= TRUE;
1120 	pGraphics->mbVirDev			= FALSE;
1121 	pGraphics->mbWindow			= FALSE;
1122 	pGraphics->mbScreen			= FALSE;
1123 
1124 	ImplSalInitGraphics( pGraphics );
1125 	pPrinter->mpGraphics			= pGraphics;
1126 
1127 	// check printer driver for DJP support
1128 	pPrinter->mbDJPSupported = ImplIsDriverDJPEnabled( pPrinter->mhDC );
1129 
1130 	if ( bUpdateDriverData )
1131 	{
1132 		if ( pSetupData->mpDriverData )
1133 			rtl_freeMemory( pSetupData->mpDriverData);
1134 		pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDriverData->cb);
1135 		memcpy( pSetupData->mpDriverData, pDriverData, pDriverData->cb );
1136 		pSetupData->mnDriverDataLen = pDriverData->cb;
1137 	}
1138 
1139 	// retrieve current settings from printer driver and store them to system independend data!
1140 	if ( pPrinter->mbDJPSupported )
1141 		ImplGetCurrentSettings( pPrinter, pSetupData );
1142 	pSetupData->mnSystem = JOBSETUP_SYSTEM_OS2;
1143 
1144 	return pPrinter;
1145 }
1146 
1147 // -----------------------------------------------------------------------
1148 
1149 void Os2SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
1150 {
1151 	delete pPrinter;
1152 }
1153 
1154 // =======================================================================
1155 
1156 Os2SalInfoPrinter::Os2SalInfoPrinter()
1157 {
1158 	mhDC					= 0;
1159 	mhPS					= 0;
1160 	mpGraphics			= NULL;
1161 	mbGraphics			= FALSE;
1162 	mbDJPSupported		= FALSE;
1163 	mnFormCount			= 0;
1164 	mpFormArray			= NULL;
1165 	mnTrayCount			= 0;
1166 	mpTrayArray			= NULL;
1167 }
1168 
1169 // -----------------------------------------------------------------------
1170 
1171 Os2SalInfoPrinter::~Os2SalInfoPrinter()
1172 {
1173 	if ( mpGraphics )
1174 	{
1175 		ImplSalDestroyInfoPrn( this );
1176 		delete mpGraphics;
1177 	}
1178 
1179 	ImplFreeFormAndTrayList( this );
1180 }
1181 
1182 // -----------------------------------------------------------------------
1183 
1184 SalGraphics* Os2SalInfoPrinter::GetGraphics()
1185 {
1186 	if ( mbGraphics )
1187 		return NULL;
1188 
1189 	if ( mpGraphics )
1190 		mbGraphics = TRUE;
1191 
1192 	return mpGraphics;
1193 }
1194 
1195 // -----------------------------------------------------------------------
1196 
1197 void Os2SalInfoPrinter::ReleaseGraphics( SalGraphics* )
1198 {
1199 	mbGraphics = FALSE;
1200 }
1201 
1202 // -----------------------------------------------------------------------
1203 
1204 sal_Bool Os2SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData )
1205 {
1206 	PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData );
1207 	if ( !pDrivData )
1208 		return FALSE;
1209 
1210 	APIRET rc = DevPostDeviceModes( GetSalData()->mhAB, pDrivData,
1211 									maDriverName.GetBuffer(),
1212 									maDeviceName.GetBuffer(),
1213 									maPrinterName.GetBuffer(),
1214 									DPDM_POSTJOBPROP );
1215 	if ( rc == DEV_OK )
1216 	{
1217 		ImplUpdateSetupData( pDrivData, pSetupData );
1218 
1219 		// update DC and PS
1220 		HDC hDC;
1221 		HPS hPS;
1222 		if ( !ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) )
1223 			return FALSE;
1224 
1225 		// Alten Printer DC/PS zerstoeren
1226 		ImplSalDestroyInfoPrn( this );
1227 
1228 		// Neue Daten setzen und initialisieren
1229 		mhDC = hDC;
1230 		mhPS = hPS;
1231 		mpGraphics->mhDC = mhDC;
1232 		mpGraphics->mhPS = mhPS;
1233 		ImplSalInitGraphics( mpGraphics );
1234 
1235 		// retrieve current settings from printer driver and store them to system independend data!
1236 		ImplFreeFormAndTrayList( this );
1237 		if ( mbDJPSupported )
1238 			ImplGetCurrentSettings( this, pSetupData );
1239 
1240 		return TRUE;
1241 	}
1242 	else
1243 	{
1244 		ImplFreePrnMemory( pDrivData );
1245 		return FALSE;
1246 	}
1247 }
1248 
1249 // -----------------------------------------------------------------------
1250 
1251 sal_Bool Os2SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData )
1252 {
1253 	// Wir koennen nur Treiberdaten von OS2 setzen
1254 	if ( pSetupData->mnSystem != JOBSETUP_SYSTEM_OS2 )
1255 		return FALSE;
1256 
1257 	PDRIVDATA pNewDrivData = (PDRIVDATA)(pSetupData->mpDriverData);
1258 	if ( !pNewDrivData )
1259 		return FALSE;
1260 
1261 	// Testen, ob Printerdaten fuer den gleichen Printer uebergeben werden,
1262 	// da einige Treiber zu Abstuerzen neigen, wenn Daten von einem anderen
1263 	// Printer gesetzt werden
1264 	if ( !maJobSetupDeviceName.Equals( pNewDrivData->szDeviceName ))
1265 		return FALSE;
1266 
1267 	// update DC and PS
1268 	HDC hDC;
1269 	HPS hPS;
1270 	if ( !ImplSalCreateInfoPrn( this, pNewDrivData, hDC, hPS ) )
1271 		return FALSE;
1272 
1273 	// Alten Printer DC/PS zerstoeren
1274 	ImplSalDestroyInfoPrn( this );
1275 
1276 	// Neue Daten setzen und initialisieren
1277 	mhDC = hDC;
1278 	mhPS = hPS;
1279 	mpGraphics->mhDC = mhDC;
1280 	mpGraphics->mhPS = mhPS;
1281 	ImplSalInitGraphics( mpGraphics );
1282 
1283 	// retrieve current settings from printer driver and store them to system independend data!
1284 	ImplFreeFormAndTrayList( this );
1285 	if ( mbDJPSupported )
1286 		ImplGetCurrentSettings( this, pSetupData );
1287 
1288 	return TRUE;
1289 }
1290 
1291 // -----------------------------------------------------------------------
1292 
1293 sal_Bool Os2SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData )
1294 {
1295 	// needs DJP support
1296 	if ( !mbDJPSupported )
1297 		return FALSE;
1298 
1299 	PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData );
1300 
1301 	if ( !pDrivData )
1302 		return FALSE;
1303 
1304 	sal_Bool bOK = FALSE;
1305 
1306 	// set orientation
1307 	if ( nFlags & SAL_JOBSET_ORIENTATION )
1308 	{
1309 		if ( ImplSetOrientation( mhDC, pDrivData, pSetupData->meOrientation ) )
1310 			bOK = TRUE;
1311 	}
1312 
1313 	// set paper size
1314 	if ( nFlags & SAL_JOBSET_PAPERSIZE )
1315 	{
1316 		// Papierformat ermitteln
1317 		DJPT_PAPERSIZE nOS2PaperFormat;
1318 		switch ( pSetupData->mePaperFormat )
1319 		{
1320 			case PAPER_A3:
1321 				nOS2PaperFormat = DJP_PSI_A3;
1322 				break;
1323 
1324 			case PAPER_A4:
1325 				nOS2PaperFormat = DJP_PSI_A4;
1326 				break;
1327 
1328 			case PAPER_A5:
1329 				nOS2PaperFormat = DJP_PSI_A5;
1330 				break;
1331 
1332 			case PAPER_B4_JIS:
1333 				nOS2PaperFormat = DJP_PSI_B4;
1334 				break;
1335 
1336 			case PAPER_B5_JIS:
1337 				nOS2PaperFormat = DJP_PSI_B5;
1338 				break;
1339 
1340 			case PAPER_LETTER:
1341 				nOS2PaperFormat = DJP_PSI_LETTER;
1342 				break;
1343 
1344 			case PAPER_LEGAL:
1345 				nOS2PaperFormat = DJP_PSI_LEGAL;
1346 				break;
1347 
1348 			case PAPER_TABLOID:
1349 				nOS2PaperFormat = DJP_PSI_TABLOID;
1350 				break;
1351 
1352 			default:
1353 				{
1354 				nOS2PaperFormat = DJP_PSI_NONE;
1355 				// OS2 rechnet in Millimetern
1356 				long nPaperWidth	 = pSetupData->mnPaperWidth  / 100;
1357 				long nPaperHeight	 = pSetupData->mnPaperHeight / 100;
1358 				// Ansonsten ueber die Papiergroesse suchen
1359 				for( int i = 0; i < mnFormCount; i++ )
1360 				{
1361 					ImplFormInfo* pFormInfo = mpFormArray[i];
1362 					if ( ImplPaperSizeEqual( nPaperWidth, nPaperHeight,
1363 											 pFormInfo->mnPaperWidth, pFormInfo->mnPaperHeight ) )
1364 					{
1365 						nOS2PaperFormat = pFormInfo->mnId;
1366 						break;
1367 					}
1368 				}
1369 				}
1370 				break;
1371 		}
1372 
1373 		if ( nOS2PaperFormat != DJP_PSI_NONE )
1374 		{
1375 			if ( ImplSetPaperSize( mhDC, pDrivData, nOS2PaperFormat ) )
1376 				bOK = TRUE;
1377 		}
1378 	}
1379 
1380 	// set paper tray
1381 	if ( (nFlags & SAL_JOBSET_PAPERBIN) && (pSetupData->mnPaperBin < mnTrayCount) )
1382 	{
1383 		if ( ImplSetPaperBin( mhDC, pDrivData,
1384 							  mpTrayArray[pSetupData->mnPaperBin] ) )
1385 			bOK = TRUE;
1386 	}
1387 
1388 	if ( bOK )
1389 	{
1390 		ImplUpdateSetupData( pDrivData, pSetupData );
1391 
1392 		// query current driver settings
1393 		ImplFreeFormAndTrayList( this );
1394 		if ( ImplGetCurrentSettings( this, pSetupData ) )
1395 		{
1396 			// update DC and PS
1397 			HDC hDC;
1398 			HPS hPS;
1399 			if ( ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) )
1400 			{
1401 				// Alten Printer DC/PS zerstoeren
1402 				ImplSalDestroyInfoPrn( this );
1403 
1404 				// Neue Daten setzen und initialisieren
1405 				mhDC = hDC;
1406 				mhPS = hPS;
1407 				mpGraphics->mhDC = mhDC;
1408 				mpGraphics->mhPS = mhPS;
1409 				ImplSalInitGraphics( mpGraphics );
1410 			}
1411 			else
1412 				bOK = FALSE;
1413 		}
1414 		else
1415 			bOK = FALSE;
1416 	}
1417 
1418 	return bOK;
1419 }
1420 
1421 // -----------------------------------------------------------------------
1422 
1423 ULONG Os2SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup )
1424 {
1425 	if ( !mbDJPSupported )
1426 		return 1;
1427 
1428 	// init paperbinlist if empty
1429 	if ( !mnTrayCount )
1430 		ImplGetFormAndTrayList( this, pJobSetup );
1431 
1432 	// Wir haben immer einen PaperTray und wenn, das eben einen ohne
1433 	// Namen
1434 	if ( !mnTrayCount )
1435 		return 1;
1436 	else
1437 		return mnTrayCount;
1438 }
1439 
1440 // -----------------------------------------------------------------------
1441 
1442 XubString Os2SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup,
1443 										  ULONG nPaperBin )
1444 {
1445 	XubString aPaperBinName;
1446 
1447 	if ( mbDJPSupported )
1448 	{
1449 		// init paperbinlist if empty
1450 		if ( !mnTrayCount )
1451 			ImplGetFormAndTrayList( this, pJobSetup );
1452 
1453 		if ( nPaperBin < mnTrayCount )
1454 			aPaperBinName = ::rtl::OStringToOUString (mpTrayArray[nPaperBin]->maDisplayName, gsl_getSystemTextEncoding());
1455 	}
1456 
1457 	return aPaperBinName;
1458 }
1459 
1460 // -----------------------------------------------------------------------
1461 
1462 ULONG Os2SalInfoPrinter::GetCapabilities( const ImplJobSetup*, USHORT nType )
1463 {
1464 	switch ( nType )
1465 	{
1466 		case PRINTER_CAPABILITIES_SUPPORTDIALOG:
1467 			return TRUE;
1468 		case PRINTER_CAPABILITIES_COPIES:
1469 			return 0xFFFF;
1470 		case PRINTER_CAPABILITIES_COLLATECOPIES:
1471 			return 0;
1472 		case PRINTER_CAPABILITIES_SETORIENTATION:
1473 		case PRINTER_CAPABILITIES_SETPAPERBIN:
1474 		case PRINTER_CAPABILITIES_SETPAPERSIZE:
1475 		case PRINTER_CAPABILITIES_SETPAPER:
1476 			return mbDJPSupported;
1477 	}
1478 
1479 	return 0;
1480 }
1481 
1482 // -----------------------------------------------------------------------
1483 
1484 void Os2SalInfoPrinter::GetPageInfo( const ImplJobSetup*,
1485 								  long& rOutWidth, long& rOutHeight,
1486 								  long& rPageOffX, long& rPageOffY,
1487 								  long& rPageWidth, long& rPageHeight )
1488 {
1489 	HDC hDC = mhDC;
1490 
1491 	// search current form
1492 	HCINFO	aInfo;
1493 	int nForms = DevQueryHardcopyCaps( hDC, 0, 0, &aInfo );
1494 	for( int i = 0; i < nForms; i++ )
1495 	{
1496 		if ( DevQueryHardcopyCaps( hDC, i, 1, &aInfo ) >= 0 )
1497 		{
1498 			if ( aInfo.flAttributes & HCAPS_CURRENT )
1499 			{
1500 				// query resolution
1501 				long nXResolution;
1502 				long nYResolution;
1503 				DevQueryCaps( hDC, CAPS_HORIZONTAL_RESOLUTION, 1, &nXResolution );
1504 				DevQueryCaps( hDC, CAPS_VERTICAL_RESOLUTION, 1, &nYResolution );
1505 				rPageOffX	= aInfo.xLeftClip * nXResolution / 1000;
1506 				rPageOffY	= (aInfo.cy-aInfo.yTopClip) * nYResolution / 1000;
1507 				rPageWidth	= aInfo.cx * nXResolution / 1000;
1508 				rPageHeight = aInfo.cy * nYResolution / 1000;
1509 				rOutWidth	= aInfo.xPels;
1510 				rOutHeight	= aInfo.yPels;
1511 				return;
1512 			}
1513 		}
1514 	}
1515 
1516 	// use device caps if no form selected/found
1517 	long lCapsWidth = 0;
1518 	long lCapsHeight = 0;
1519 	DevQueryCaps( hDC, CAPS_WIDTH, 1L, &lCapsWidth );
1520 	DevQueryCaps( hDC, CAPS_HEIGHT, 1L, &lCapsHeight );
1521 	rPageOffX	 = 0;
1522 	rPageOffY	 = 0;
1523 	rOutWidth	 = lCapsWidth;
1524 	rOutHeight	 = lCapsHeight;
1525 	rPageWidth	 = rOutWidth;
1526 	rPageHeight  = rOutHeight;
1527 }
1528 
1529 // =======================================================================
1530 
1531 static sal_Bool ImplIsDriverPrintDJPEnabled( HDC hDC )
1532 {
1533 #ifdef NO_DJP
1534 	return FALSE;
1535 #else
1536 	// Ueber OS2-Ini kann DJP disablte werden
1537 	if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTDJP, 1 ) )
1538 		return FALSE;
1539 
1540 	// Testen, ob DJP-Interface am Drucker vorhanden
1541 	LONG   lQuery;
1542 	APIRET rc;
1543 
1544 	lQuery = DEVESC_QUERYSIZE;
1545 	rc = DevEscape( hDC,
1546 					DEVESC_QUERYESCSUPPORT,
1547 					sizeof( lQuery ),
1548 					(PBYTE)&lQuery,
1549 					0,
1550 					(PBYTE)NULL );
1551 	if ( DEV_OK != rc )
1552 		return FALSE;
1553 
1554 	return TRUE;
1555 #endif
1556 }
1557 
1558 // =======================================================================
1559 
1560 SalPrinter* Os2SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
1561 {
1562 	Os2SalPrinter* pPrinter = new Os2SalPrinter;
1563 	pPrinter->mpInfoPrinter = static_cast<Os2SalInfoPrinter*>(pInfoPrinter);
1564 	return pPrinter;
1565 }
1566 
1567 // -----------------------------------------------------------------------
1568 
1569 void Os2SalInstance::DestroyPrinter( SalPrinter* pPrinter )
1570 {
1571 	delete pPrinter;
1572 }
1573 
1574 // =======================================================================
1575 
1576 Os2SalPrinter::Os2SalPrinter()
1577 {
1578 	mhDC					= 0;
1579 	mhPS					= 0;
1580 	mpGraphics			= NULL;
1581 	mbAbort				= FALSE;
1582 	mbPrintDJPSupported	= FALSE;
1583 }
1584 
1585 // -----------------------------------------------------------------------
1586 
1587 Os2SalPrinter::~Os2SalPrinter()
1588 {
1589 }
1590 
1591 // -----------------------------------------------------------------------
1592 
1593 sal_Bool Os2SalPrinter::StartJob( const XubString* pFileName,
1594 						   const XubString& rJobName,
1595 						   const XubString& rAppName,
1596 						   ULONG nCopies,
1597                            bool bCollate,
1598                            bool bDirect,
1599 						   ImplJobSetup* pSetupData )
1600 {
1601 	DEVOPENSTRUC	aDevOpenStruc;
1602 	LONG			lType;
1603 	APIRET			rc;
1604 
1605 	// prepare queue information
1606 	memset( &aDevOpenStruc, 0, sizeof( aDevOpenStruc ) );
1607 	aDevOpenStruc.pszDriverName = (PSZ)(mpInfoPrinter->maDriverName.GetBuffer());
1608 
1609 	// print into file?
1610 	if ( pFileName )
1611 	{
1612 		aDevOpenStruc.pszLogAddress = (PSZ)pFileName->GetBuffer();
1613 		aDevOpenStruc.pszDataType = "PM_Q_RAW";
1614 		lType = OD_DIRECT;
1615 	}
1616 	else
1617 	{
1618 		aDevOpenStruc.pszLogAddress = (PSZ)(mpInfoPrinter->maName.GetBuffer());
1619 		if ( PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTRAW, 0 ) )
1620 			aDevOpenStruc.pszDataType = "PM_Q_RAW";
1621 		else
1622 			aDevOpenStruc.pszDataType = "PM_Q_STD";
1623 		lType = OD_QUEUED;
1624 	}
1625 
1626 #if 0 // YD FIXME
1627 	// Set comment (AppName nur bis zum 1. Space-Zeichen nehmen)
1628 	const xub_Unicode*	pComment = rAppName;
1629 	USHORT			nCommentLen = 0;
1630 	memset( maCommentBuf, 0, sizeof( maCommentBuf ) );
1631 	while ( (nCommentLen < 32) &&
1632 			(((*pComment >= 'a') && (*pComment <= 'z')) ||
1633 			 ((*pComment >= 'A') && (*pComment <= 'Z')) ||
1634 			 ((*pComment >= '0') && (*pComment <= '9')) ||
1635 			 (*pComment == '-')))
1636 	{
1637 		maCommentBuf[nCommentLen] = (char)(*pComment);
1638 		nCommentLen++;
1639 		pComment++;
1640 	}
1641 	aDevOpenStruc.pszComment = (PSZ)maCommentBuf;
1642 #endif
1643 	ByteString jobName( rJobName, gsl_getSystemTextEncoding());
1644 	aDevOpenStruc.pszComment = (PSZ)jobName.GetBuffer();
1645 
1646 	// Kopien
1647 	if ( nCopies > 1 )
1648 	{
1649 		// OS2 kann maximal 999 Kopien
1650 		if ( nCopies > 999 )
1651 			nCopies = 999;
1652 		sprintf( maCopyBuf, "COP=%d", nCopies);
1653 		aDevOpenStruc.pszQueueProcParams = (PSZ)maCopyBuf;
1654 	}
1655 
1656 	// open device context
1657 	SalData*	pSalData = GetSalData();
1658 	HAB 		hAB = pSalData->mhAB;
1659 	aDevOpenStruc.pdriv = (PDRIVDATA)pSetupData->mpDriverData;
1660 	mhDC = DevOpenDC( hAB,
1661 									lType,
1662 									"*",
1663 									7,
1664 									(PDEVOPENDATA)&aDevOpenStruc,
1665 									0 );
1666 	if ( mhDC == 0 )
1667 	{
1668 		ERRORID nLastError = WinGetLastError( hAB );
1669 		if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT )
1670 			mnError = SAL_PRINTER_ERROR_ABORT;
1671 		else
1672 			mnError = SAL_PRINTER_ERROR_GENERALERROR;
1673 		return FALSE;
1674 	}
1675 
1676 	// open presentation space
1677 	SIZEL sizel;
1678 	sizel.cx = 0;
1679 	sizel.cy = 0;
1680 	mhPS = Ft2CreatePS( hAB, mhDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS );
1681 	if ( !mhPS )
1682 	{
1683 		DevCloseDC( mhDC );
1684 		mnError = SAL_PRINTER_ERROR_GENERALERROR;
1685 		return NULL;
1686 	}
1687 
1688 	// Can we print with DJP
1689 	mbPrintDJPSupported = ImplIsDriverPrintDJPEnabled( mhDC );
1690 
1691 	// JobName ermitteln und Job starten
1692 	PSZ pszJobName = NULL;
1693 	int nJobNameLen = 0;
1694 	if ( jobName.Len() > 0 )
1695 	{
1696 		pszJobName = (PSZ)jobName.GetBuffer();
1697 		nJobNameLen = jobName.Len();
1698 	}
1699 	rc = DevEscape( mhDC,
1700 					DEVESC_STARTDOC,
1701 					nJobNameLen, (PBYTE)pszJobName,
1702 					0, (PBYTE)NULL );
1703 
1704 	if ( rc != DEV_OK )
1705 	{
1706 		ERRORID nLastError = WinGetLastError( hAB );
1707 		if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT )
1708 			mnError = SAL_PRINTER_ERROR_ABORT;
1709 		else
1710 			mnError = SAL_PRINTER_ERROR_GENERALERROR;
1711 		Ft2Associate( mhPS, NULL );
1712 		Ft2DestroyPS( mhPS );
1713 		DevCloseDC( mhDC );
1714 		return FALSE;
1715 	}
1716 
1717 	// init for first page
1718 	mbFirstPage = TRUE;
1719 	mnError = 0;
1720 
1721 	return TRUE;
1722 }
1723 
1724 // -----------------------------------------------------------------------
1725 
1726 sal_Bool Os2SalPrinter::EndJob()
1727 {
1728 	APIRET rc;
1729 	rc = DevEscape( mhDC,
1730 					DEVESC_ENDDOC,
1731 					0, NULL,
1732 					0, NULL);
1733 
1734 	// destroy presentation space and device context
1735 	Ft2Associate( mhPS, NULL );
1736 	Ft2DestroyPS( mhPS );
1737 	DevCloseDC( mhDC );
1738 	return TRUE;
1739 }
1740 
1741 // -----------------------------------------------------------------------
1742 
1743 sal_Bool Os2SalPrinter::AbortJob()
1744 {
1745 	APIRET rc;
1746 
1747 	rc = DevEscape( mhDC,
1748 					DEVESC_ABORTDOC,
1749 					0, NULL,
1750 					0, NULL );
1751 
1752 	// destroy SalGraphics
1753 	if ( mpGraphics )
1754 	{
1755 		ImplSalDeInitGraphics( mpGraphics );
1756 		delete mpGraphics;
1757 		mpGraphics = NULL;
1758 	}
1759 
1760 	// destroy presentation space and device context
1761 	Ft2Associate( mhPS, NULL );
1762 	Ft2DestroyPS( mhPS );
1763 	DevCloseDC( mhDC );
1764 	return TRUE;
1765 }
1766 
1767 // -----------------------------------------------------------------------
1768 
1769 SalGraphics* Os2SalPrinter::StartPage( ImplJobSetup* pSetupData, sal_Bool bNewJobSetup )
1770 {
1771 	APIRET rc;
1772 
1773 	if ( mbFirstPage )
1774 		mbFirstPage = FALSE;
1775 	else
1776 	{
1777 		PBYTE	pJobData;
1778 		LONG	nJobDataSize;
1779 		LONG	nEscape;
1780 		if ( mbPrintDJPSupported && bNewJobSetup )
1781 		{
1782 			nEscape 		= DEVESC_NEWFRAME_WPROP;
1783 			nJobDataSize	= ((PDRIVDATA)(pSetupData->mpDriverData))->cb;
1784 			pJobData		= (PBYTE)(pSetupData->mpDriverData);
1785 		}
1786 		else
1787 		{
1788 			nEscape 		= DEVESC_NEWFRAME;
1789 			nJobDataSize	= 0;
1790 			pJobData		= NULL;
1791 		}
1792 		rc = DevEscape( mhDC,
1793 						nEscape,
1794 						0, NULL,
1795 						&nJobDataSize, pJobData );
1796 
1797 		if ( rc != DEV_OK )
1798 		{
1799 			DevEscape( mhDC, DEVESC_ENDDOC, 0, NULL, 0, NULL);
1800 			Ft2Associate( mhPS, NULL );
1801 			Ft2DestroyPS( mhPS );
1802 			DevCloseDC( mhDC );
1803 			mnError = SAL_PRINTER_ERROR_GENERALERROR;
1804 			return NULL;
1805 		}
1806 	}
1807 
1808 	// create SalGraphics with copy of hPS
1809 	Os2SalGraphics* pGraphics = new Os2SalGraphics;
1810 	pGraphics->mhDC				= mhDC;
1811 	pGraphics->mhPS				= mhPS;
1812 	pGraphics->mhWnd 			= 0;
1813 	pGraphics->mbPrinter 		= TRUE;
1814 	pGraphics->mbVirDev			= FALSE;
1815 	pGraphics->mbWindow			= FALSE;
1816 	pGraphics->mbScreen			= FALSE;
1817 	pGraphics->mnHeight			= 0;
1818 	// search current form for actual page height
1819 	HCINFO	aInfo;
1820 	int 	nForms = DevQueryHardcopyCaps( mhDC, 0, 0, &aInfo );
1821 	for( int i = 0; i < nForms; i++ )
1822 	{
1823 		if ( DevQueryHardcopyCaps( mhDC, i, 1, &aInfo ) >= 0 )
1824 		{
1825 			if ( aInfo.flAttributes & HCAPS_CURRENT )
1826 				pGraphics->mnHeight	= aInfo.yPels;
1827 		}
1828 	}
1829 	// use device caps if no form selected/found
1830 	if ( !pGraphics->mnHeight )
1831 		DevQueryCaps( mhDC, CAPS_HEIGHT, 1L, &pGraphics->mnHeight );
1832 
1833 	ImplSalInitGraphics( pGraphics );
1834 	mpGraphics = pGraphics;
1835 
1836 	return pGraphics;
1837 }
1838 
1839 // -----------------------------------------------------------------------
1840 
1841 sal_Bool Os2SalPrinter::EndPage()
1842 {
1843 	if ( mpGraphics )
1844 	{
1845 		// destroy SalGraphics
1846 		ImplSalDeInitGraphics( mpGraphics );
1847 		delete mpGraphics;
1848 		mpGraphics = NULL;
1849 	}
1850 
1851 	return TRUE;
1852 }
1853 
1854 // -----------------------------------------------------------------------
1855 
1856 ULONG Os2SalPrinter::GetErrorCode()
1857 {
1858 	return mnError;
1859 }
1860 
1861 void Os2SalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData )
1862 {
1863 	printf("Os2SalInfoPrinter::InitPaperFormats\n");
1864 }
1865 int Os2SalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* pSetupData )
1866 {
1867 	printf("Os2SalInfoPrinter::GetLandscapeAngle\n");
1868 	return 0;
1869 }
1870 
1871