xref: /AOO41X/main/vcl/os2/source/gdi/salprn.cxx (revision 54628ca40d27d15cc98fe861da7fff7e60c2f7d6)
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