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