diff options
Diffstat (limited to 'vcl/os2/source/gdi/salprn.cxx')
-rw-r--r-- | vcl/os2/source/gdi/salprn.cxx | 1878 |
1 files changed, 1878 insertions, 0 deletions
diff --git a/vcl/os2/source/gdi/salprn.cxx b/vcl/os2/source/gdi/salprn.cxx new file mode 100644 index 000000000000..95e6baa2d6fb --- /dev/null +++ b/vcl/os2/source/gdi/salprn.cxx @@ -0,0 +1,1878 @@ +/************************************************************************* + * + * $RCSfile: salprn.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// use this define to disable the DJP support +// #define NO_DJP + +#define INCL_DOSMODULEMGR +#define INCL_DEV +#define INCL_SPL +#define INCL_SPLDOSPRINT +#define INCL_DEVDJP + +#define BOOL PM_BOOL +#define BYTE PM_BYTE +#define USHORT PM_USHORT +#define ULONG PM_ULONG + +#define INCL_PM +#include <os2.h> +#include "pmdjp.h" + +#undef BOOL +#undef BYTE +#undef USHORT +#undef ULONG + +#include <string.h> + +#define _SV_SALPRN_CXX + +#ifndef _NEW_HXX +#include <tools/new.hxx> +#endif +#ifndef _DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif +#ifndef _SV_SALINST_HXX +#include <salinst.hxx> +#endif +#ifndef _SV_SALGDI_HXX +#include <salgdi.hxx> +#endif +#ifndef _SV_SALFRAME_HXX +#include <salframe.hxx> +#endif +#ifndef _SV_SALPTYPE_HXX +#include <salptype.hxx> +#endif +#ifndef _SV_SALPRN_HXX +#include <salprn.hxx> +#endif + +#ifndef _SV_PRINT_H +#include <print.h> +#endif +#ifndef _SV_JOBSET_H +#include <jobset.h> +#endif + +// ======================================================================= + +// ----------------------- +// - struct ImplFormInfo - +// ----------------------- + +struct ImplFormInfo +{ + long mnPaperWidth; + long mnPaperHeight; + DJPT_PAPERSIZE mnId; +}; + +// ======================================================================= + +// ----------------------- +// - struct ImplTrayInfo - +// ----------------------- + +struct ImplTrayInfo +{ + XubString maName; + XubString maDisplayName; + DJPT_TRAYTYPE mnId; + + ImplTrayInfo( const char* pTrayName, + const char* pTrayDisplayName ) : + maName( pTrayName ), + maDisplayName( pTrayDisplayName ) + {} +}; + +// ======================================================================= + +struct ImplQueueSalSysData +{ + String maPrinterName; // pszPrinters + String maName; // pszName bzw. LogAddress + String maOrgDriverName; // pszDriverName (maDriverName.maDeviceName) + String maDriverName; // pszDriverName bis . + String maDeviceName; // pszDriverName nach . + PDRIVDATA mpDrivData; + + ImplQueueSalSysData( const String& rPrinterName, + const String& rName, + const String& rDriverName, + const String& rDeviceName, + const String& rOrgDriverName, + PDRIVDATA pDrivData ); + ~ImplQueueSalSysData(); +}; + +// ----------------------------------------------------------------------- + +ImplQueueSalSysData::ImplQueueSalSysData( const String& rPrinterName, + const String& rName, + const String& rOrgDriverName, + const String& rDriverName, + const String& rDeviceName, + PDRIVDATA pDrivData ) : + maPrinterName( rPrinterName ), + maName( rName ), + maOrgDriverName( rName ), + maDriverName( rDriverName ), + maDeviceName( rDeviceName ) +{ + if ( pDrivData ) + { + mpDrivData = (PDRIVDATA)new BYTE[pDrivData->cb]; + memcpy( mpDrivData, pDrivData, pDrivData->cb ); + } + else + mpDrivData = NULL; +} + +// ----------------------------------------------------------------------- + +ImplQueueSalSysData::~ImplQueueSalSysData() +{ + delete mpDrivData; +} + +// ======================================================================= + +static ULONG ImplPMQueueStatusToSal( PM_USHORT nPMStatus ) +{ + ULONG nStatus = 0; + if ( nPMStatus & PRQ3_PAUSED ) + nStatus |= QUEUE_STATUS_PAUSED; + if ( nPMStatus & PRQ3_PENDING ) + nStatus |= QUEUE_STATUS_PENDING_DELETION; + if ( !nStatus ) + nStatus |= QUEUE_STATUS_READY; + return nStatus; +} + +// ----------------------------------------------------------------------- + +void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList ) +{ + APIRET rc; + ULONG nNeeded; + ULONG nReturned; + ULONG nTotal; + + // query needed size of the buffer for the QueueInfo + rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL ); + if( nNeeded == 0 ) + return; + + // create the buffer for the QueueInfo + PCHAR pQueueData = new CHAR[nNeeded]; + + // query QueueInfos + rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL ); + + PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData; + for ( int i = 0; i < nReturned; i++ ) + { + // create entry for the QueueInfo array + SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo; + + String aOrgDriverName( pPrqInfo->pszDriverName ); + String aName( pPrqInfo->pszName ); + pInfo->maDriver = aOrgDriverName; + pInfo->maPrinterName = pPrqInfo->pszComment; + pInfo->maLocation = aName; + pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus ); + pInfo->mnJobs = pPrqInfo->cJobs; + // pInfo->maComment = !!! + + // Feststellen, ob Name doppelt + PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData; + for ( int j = 0; j < nReturned; j++ ) + { + // Wenn Name doppelt, erweitern wir diesen um die Location + if ( (j != i) && + (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) ) + { + pInfo->maPrinterName += ';'; + pInfo->maPrinterName += pInfo->maLocation; + } + pTempPrqInfo++; + } + + // pszDriver in DriverName (bis .) und DeviceName (nach .) aufsplitten + PSZ pDriverName; + PSZ pDeviceName; + if ( (pDriverName = strchr( pPrqInfo->pszDriverName, '.' )) != 0 ) + { + *pDriverName = 0; + pDeviceName = pDriverName + 1; + } + else + pDeviceName = NULL; + + // Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit + // ein memcmp vom JobSetup auch funktioniert + if ( pPrqInfo->pDriverData && + (pPrqInfo->pDriverData->cb >= sizeof( pPrqInfo->pDriverData )) ) + { + int nDeviceNameLen = strlen( pPrqInfo->pDriverData->szDeviceName ); + memset( pPrqInfo->pDriverData->szDeviceName+nDeviceNameLen, + 0, + sizeof( pPrqInfo->pDriverData->szDeviceName )-nDeviceNameLen ); + } + + // save driver data and driver names + String aPrinterName( pPrqInfo->pszPrinters ); + String aDriverName( pPrqInfo->pszDriverName ); + String aDeviceName; + if ( pDeviceName ) + aDeviceName = pDeviceName; + pInfo->mpSysData = new ImplQueueSalSysData( aPrinterName, aName, + aOrgDriverName, + aDriverName, aDeviceName, + pPrqInfo->pDriverData ); + + // add queue to the list + pList->Add( pInfo ); + + // increment to next element of the QueueInfo array + pPrqInfo++; + } + + delete [] pQueueData; +} + +// ----------------------------------------------------------------------- + +void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo ) +{ + APIRET rc; + ULONG nNeeded; + ULONG nReturned; + ULONG nTotal; + + // query needed size of the buffer for the QueueInfo + rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL ); + if( nNeeded == 0 ) + return; + + // create the buffer for the QueueInfo + PCHAR pQueueData = new CHAR[nNeeded]; + + // query QueueInfos + rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL ); + + PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData; + for ( int i = 0; i < nReturned; i++ ) + { + ImplQueueSalSysData* pSysData = (ImplQueueSalSysData*)(pInfo->mpSysData); + if ( (strcmp( pSysData->maPrinterName, pPrqInfo->pszPrinters ) == 0) && + (strcmp( pSysData->maName, pPrqInfo->pszName ) == 0) && + (strcmp( pSysData->maOrgDriverName, pPrqInfo->pszDriverName ) == 0) ) + { + pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus ); + pInfo->mnJobs = pPrqInfo->cJobs; + break; + } + + // increment to next element of the QueueInfo array + pPrqInfo++; + } + + delete [] pQueueData; +} + +// ----------------------------------------------------------------------- + +void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo ) +{ + delete ((ImplQueueSalSysData*)(pInfo->mpSysData)); + delete pInfo; +} + +// ----------------------------------------------------------------------- + +XubString SalInstance::GetDefaultPrinter() +{ + APIRET rc; + ULONG nNeeded; + ULONG nReturned; + ULONG nTotal; + char szQueueName[255]; + XubString aDefaultName; + + // query default queue + if ( !PrfQueryProfileString( HINI_PROFILE, SPL_INI_SPOOLER, "QUEUE", 0, szQueueName, sizeof( szQueueName ) ) ) + return aDefaultName; + + // extract first queue name + PSZ pStr; + if ( (pStr = strchr( szQueueName, ';' )) != 0 ) + *pStr = 0; + + // query needed size of the buffer for the QueueInfo + rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL ); + if ( nNeeded == 0 ) + return aDefaultName; + + // create the buffer for the QueueInfo + PCHAR pQueueData = new CHAR[ nNeeded ]; + + // query QueueInfos + rc = SplEnumQueue ((PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL ); + + // find printer name for default queue + PPRQINFO3 pPrqInfo = (PPRQINFO3) pQueueData; + for ( int i = 0; i < nReturned; i++ ) + { + if ( strcmp( pPrqInfo->pszName, szQueueName ) == 0 ) + { + aDefaultName = pPrqInfo->pszComment; + + // Feststellen, ob Name doppelt + PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData; + for ( int j = 0; j < nReturned; j++ ) + { + // Wenn Name doppelt, erweitern wir diesen um die Location + if ( (j != i) && + (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) ) + { + aDefaultName += ';'; + aDefaultName += pPrqInfo->pszName; + } + pTempPrqInfo++; + } + break; + } + + // increment to next element of the QueueInfo array + pPrqInfo++; + } + + delete [] pQueueData; + + return aDefaultName; +} + +// ======================================================================= + +static void* ImplAllocPrnMemory( size_t n ) +{ + PVOID pVoid = 0; + + if ( DosAllocMem( &pVoid, n, PAG_COMMIT | PAG_READ | PAG_WRITE ) ) + return 0; + + return pVoid; +} + +// ----------------------------------------------------------------------- + +inline void ImplFreePrnMemory( void* p ) +{ + DosFreeMem( p ); +} + +// ----------------------------------------------------------------------- + +static PDRIVDATA ImplPrnDrivData( const ImplJobSetup* pSetupData ) +{ + // Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf + // unseren Daten arbeiten, da es durch Konfigurationsprobleme + // sein kann, das der Druckertreiber bei uns Daten ueberschreibt. + // Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw. + // sind dadurch leichter zu finden + + if ( !pSetupData->mpDriverData ) + return NULL; + + DBG_ASSERT( ((PRIVDATA)(pSetupData->mpDriverData))->cb == pSetupData->mnDriverDataLen, + "ImplPrnDrivData() - SetupDataLen != DriverDataLen" ); + + PDRIVDATA pDrivData = (PDRIVDATA)ImplAllocPrnMemory( pSetupData->mnDriverDataLen ); + memcpy( pDrivData, pSetupData->mpDriverData, pSetupData->mnDriverDataLen ); + return pDrivData; +} + +// ----------------------------------------------------------------------- + +static void ImplUpdateSetupData( const PDRIVDATA pDrivData, ImplJobSetup* pSetupData ) +{ + // Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf + // unseren Daten arbeiten, da es durch Konfigurationsprobleme + // sein kann, das der Druckertreiber bei uns Daten ueberschreibt. + // Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw. + // sind dadurch leichter zu finden + + if ( !pDrivData || !pDrivData->cb ) + { + if ( pSetupData->mpDriverData ) + delete pSetupData->mpDriverData; + pSetupData->mnDriverDataLen = 0; + } + else + { + // Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit + // ein memcmp vom JobSetup auch funktioniert + if ( pDrivData->cb >= sizeof( pDrivData ) ) + { + int nDeviceNameLen = strlen( pDrivData->szDeviceName ); + memset( pDrivData->szDeviceName+nDeviceNameLen, + 0, + sizeof( pDrivData->szDeviceName )-nDeviceNameLen ); + } + + if ( pSetupData->mpDriverData ) + { + if ( pSetupData->mnDriverDataLen != pDrivData->cb ) + delete pSetupData->mpDriverData; + pSetupData->mpDriverData = new BYTE[pDrivData->cb]; + } + else + pSetupData->mpDriverData = new BYTE[pDrivData->cb]; + pSetupData->mnDriverDataLen = pDrivData->cb; + memcpy( pSetupData->mpDriverData, pDrivData, pDrivData->cb ); + } + + if ( pDrivData ) + ImplFreePrnMemory( pDrivData ); +} + +// ----------------------------------------------------------------------- + +static BOOL ImplPaperSizeEqual( long nPaperWidth1, long nPaperHeight1, + long nPaperWidth2, long nPaperHeight2 ) +{ + return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) && + ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1))); +} + +// ----------------------------------------------------------------------- + +static BOOL ImplIsDriverDJPEnabled( HDC hDC ) +{ +#ifdef NO_DJP + return FALSE; +#else + // Ueber OS2-Ini kann DJP disablte werden + if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_USEDJP, 1 ) ) + return FALSE; + + // Testen, ob DJP-Interface am Drucker vorhanden + LONG lQuery; + APIRET rc; + + lQuery = DEVESC_QUERYSIZE; + rc = DevEscape( hDC, + DEVESC_QUERYESCSUPPORT, + sizeof( lQuery ), + (PBYTE)&lQuery, + 0, + (PBYTE)NULL ); + if ( DEV_OK != rc ) + return FALSE; + + lQuery = DEVESC_QUERYJOBPROPERTIES; + rc = DevEscape( hDC, + DEVESC_QUERYESCSUPPORT, + sizeof( lQuery ), + (PBYTE)&lQuery, + 0, + (PBYTE)NULL ); + if ( DEV_OK != rc ) + return FALSE; + + lQuery = DEVESC_SETJOBPROPERTIES; + rc = DevEscape( hDC, + DEVESC_QUERYESCSUPPORT, + sizeof( lQuery ), + (PBYTE)&lQuery, + 0, + (PBYTE)NULL ); + if ( DEV_OK != rc ) + return FALSE; + + return TRUE; +#endif +} + +// ----------------------------------------------------------------------- + +static void ImplFormatInputList( PDJP_ITEM pDJP, PQUERYTUPLE pTuple ) +{ + // Loop through the query elements + BOOL fContinue = TRUE; + do + { + pDJP->cb = sizeof (DJP_ITEM); + pDJP->ulProperty = pTuple->ulProperty; + pDJP->lType = pTuple->lType; + pDJP->ulNumReturned = 0; + pDJP->ulValue = DJP_NONE; + + // at EOL? + fContinue = DJP_NONE != pTuple->ulProperty; + + // Move to next item structure and tuplet + pDJP++; + pTuple++; + } + while ( fContinue ); +} + +// ----------------------------------------------------------------------- + +static void ImplFreeFormAndTrayList( SalInfoPrinter* pSalInfoPrinter ) +{ + if ( pSalInfoPrinter->maPrinterData.mnFormCount ) + { + for ( USHORT i = 0; i < pSalInfoPrinter->maPrinterData.mnFormCount; i++ ) + delete pSalInfoPrinter->maPrinterData.mpFormArray[i]; + delete [] pSalInfoPrinter->maPrinterData.mpFormArray; + pSalInfoPrinter->maPrinterData.mnFormCount = 0; + } + + if ( pSalInfoPrinter->maPrinterData.mnTrayCount ) + { + for ( USHORT i = 0; i < pSalInfoPrinter->maPrinterData.mnTrayCount; i++ ) + delete pSalInfoPrinter->maPrinterData.mpTrayArray[i]; + delete [] pSalInfoPrinter->maPrinterData.mpTrayArray; + pSalInfoPrinter->maPrinterData.mnTrayCount = 0; + } +} + +// ----------------------------------------------------------------------- + +static void ImplGetFormAndTrayList( SalInfoPrinter* pSalInfoPrinter, const ImplJobSetup* pSetupData ) +{ + ImplFreeFormAndTrayList( pSalInfoPrinter ); + + LONG alQuery[] = + { + 0, 0, // First two members of QUERYSIZE + DJP_CJ_FORM, DJP_ALL, + DJP_CJ_TRAYNAME, DJP_ALL, + DJP_NONE, DJP_NONE // EOL marker + }; + + APIRET rc; + PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; + PBYTE pBuffer = NULL; + LONG nAlloc = 0; + PDRIVDATA pCopyDrivData = ImplPrnDrivData( pSetupData ); + LONG nDrivDataSize = pCopyDrivData->cb; + PBYTE pDrivData = (PBYTE)pCopyDrivData; + + // find out how many bytes to allocate + pQuerySize->cb = sizeof( alQuery ); + rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC, + DEVESC_QUERYSIZE, + sizeof( alQuery ), + (PBYTE)pQuerySize, + &nDrivDataSize, + pDrivData ); + if ( DEV_OK != rc ) + { + ImplFreePrnMemory( pCopyDrivData ); + return; + } + + // allocate the memory + nAlloc = pQuerySize->ulSizeNeeded; + pBuffer = (PBYTE)new BYTE[nAlloc]; + + // set up the input + PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; + ImplFormatInputList( pDJP, pQuerySize->aTuples ); + + // do it! + rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC, + DEVESC_QUERYJOBPROPERTIES, + nAlloc, + pBuffer, + &nDrivDataSize, + pDrivData ); + ImplFreePrnMemory( pCopyDrivData ); + + if ( (DEV_OK == rc) || (DEV_WARNING == rc) ) + { + // Loop through the query elements + PQUERYTUPLE pTuple = pQuerySize->aTuples; + while ( DJP_NONE != pTuple->ulProperty ) + { + if ( pDJP->ulProperty == DJP_CJ_FORM ) + { + if ( pDJP->ulNumReturned ) + { + PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM ); + + pSalInfoPrinter->maPrinterData.mnFormCount = pDJP->ulNumReturned; + pSalInfoPrinter->maPrinterData.mpFormArray = new PIMPLFORMINFO[pSalInfoPrinter->maPrinterData.mnFormCount]; + for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ ) + { + ImplFormInfo* pInfo = new ImplFormInfo; + pInfo->mnPaperWidth = pElm->hcInfo.cx; + pInfo->mnPaperHeight = pElm->hcInfo.cy; + pInfo->mnId = pElm->djppsFormID; + pSalInfoPrinter->maPrinterData.mpFormArray[i] = pInfo; + } + } + } + else if ( pDJP->ulProperty == DJP_CJ_TRAYNAME ) + { + if ( pDJP->ulNumReturned ) + { + PDJPT_TRAYNAME pElm = DJP_ELEMENTP( *pDJP, DJPT_TRAYNAME ); + + pSalInfoPrinter->maPrinterData.mnTrayCount = pDJP->ulNumReturned; + pSalInfoPrinter->maPrinterData.mpTrayArray = new PIMPLTRAYINFO[pSalInfoPrinter->maPrinterData.mnTrayCount]; + for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ ) + { + ImplTrayInfo* pInfo = new ImplTrayInfo( pElm->szTrayname, pElm->szDisplayTrayname ); + pInfo->mnId = pElm->djpttTrayID; + pSalInfoPrinter->maPrinterData.mpTrayArray[i] = pInfo; + } + } + } + + pDJP = DJP_NEXT_STRUCTP( pDJP ); + pTuple++; + } + } + + delete [] pBuffer; +} + +// ----------------------------------------------------------------------- + +static BOOL ImplGetCurrentSettings( SalInfoPrinter* pSalInfoPrinter, ImplJobSetup* pSetupData ) +{ + // Um den aktuellen Tray zu ermitteln, brauchen wir auch die Listen dazu + if ( !pSalInfoPrinter->maPrinterData.mnFormCount ) + ImplGetFormAndTrayList( pSalInfoPrinter, pSetupData ); + + LONG alQuery[] = + { + 0, 0, // First two members of QUERYSIZE + DJP_SJ_ORIENTATION, DJP_CURRENT, + DJP_CJ_FORM, DJP_CURRENT, + DJP_NONE, DJP_NONE // EOL marker + }; + + APIRET rc; + PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; + PBYTE pBuffer = NULL; + LONG nAlloc = 0; + PDRIVDATA pCopyDrivData = ImplPrnDrivData( pSetupData ); + LONG nDrivDataSize = pCopyDrivData->cb; + PBYTE pDrivData = (PBYTE)pCopyDrivData; + BOOL bResult; + + // find out how many bytes to allocate + pQuerySize->cb = sizeof( alQuery ); + rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC, + DEVESC_QUERYSIZE, + sizeof( alQuery ), + (PBYTE)pQuerySize, + &nDrivDataSize, + pDrivData ); + if ( DEV_OK != rc ) + { + ImplFreePrnMemory( pCopyDrivData ); + return FALSE; + } + + // allocate the memory + nAlloc = pQuerySize->ulSizeNeeded; + pBuffer = (PBYTE)new BYTE[nAlloc]; + + // set up the input + PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; + ImplFormatInputList( pDJP, pQuerySize->aTuples ); + + rc = DevEscape( pSalInfoPrinter->maPrinterData.mhDC, + DEVESC_QUERYJOBPROPERTIES, + nAlloc, + pBuffer, + &nDrivDataSize, + pDrivData ); + if ( (DEV_OK == rc) || (DEV_WARNING == rc) ) + { + // aktuelle Setup-Daten uebernehmen + ImplUpdateSetupData( pCopyDrivData, pSetupData ); + + // Loop through the query elements + PQUERYTUPLE pTuple = pQuerySize->aTuples; + while ( DJP_NONE != pTuple->ulProperty ) + { + if ( pDJP->ulProperty == DJP_SJ_ORIENTATION ) + { + if ( pDJP->ulNumReturned ) + { + PDJPT_ORIENTATION pElm = DJP_ELEMENTP( *pDJP, DJPT_ORIENTATION ); + if ( (DJP_ORI_PORTRAIT == *pElm) || (DJP_ORI_REV_PORTRAIT == *pElm) ) + pSetupData->meOrientation = ORIENTATION_PORTRAIT; + else + pSetupData->meOrientation = ORIENTATION_LANDSCAPE; + } + } + else if ( pDJP->ulProperty == DJP_CJ_FORM ) + { + if ( pDJP->ulNumReturned ) + { + PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM ); + + pSetupData->mnPaperWidth = pElm->hcInfo.cx*100; + pSetupData->mnPaperHeight = pElm->hcInfo.cy*100; + switch( pElm->djppsFormID ) + { + case DJP_PSI_A3: + pSetupData->mePaperFormat = PAPER_A3; + break; + + case DJP_PSI_A4: + pSetupData->mePaperFormat = PAPER_A4; + break; + + case DJP_PSI_A5: + pSetupData->mePaperFormat = PAPER_A5; + break; + + case DJP_PSI_B4: + pSetupData->mePaperFormat = PAPER_B4; + break; + + case DJP_PSI_B5: + pSetupData->mePaperFormat = PAPER_B5; + break; + + case DJP_PSI_LETTER: + pSetupData->mePaperFormat = PAPER_LETTER; + break; + + case DJP_PSI_LEGAL: + pSetupData->mePaperFormat = PAPER_LEGAL; + break; + + case DJP_PSI_TABLOID: + pSetupData->mePaperFormat = PAPER_TABLOID; + break; + + default: + pSetupData->mePaperFormat = PAPER_USER; + break; + } + + // Wir suchen zuerst ueber den Namen/Id und dann ueber die Id + BOOL bTrayFound = FALSE; + USHORT j; + for ( j = 0; j < pSalInfoPrinter->maPrinterData.mnTrayCount; j++ ) + { + if ( (pSalInfoPrinter->maPrinterData.mpTrayArray[j]->mnId == pElm->djpttTrayID) && + (pSalInfoPrinter->maPrinterData.mpTrayArray[j]->maName == pElm->szTrayname) ) + { + pSetupData->mnPaperBin = j; + bTrayFound = TRUE; + break; + } + } + if ( !bTrayFound ) + { + for ( j = 0; j < pSalInfoPrinter->maPrinterData.mnTrayCount; j++ ) + { + if ( pSalInfoPrinter->maPrinterData.mpTrayArray[j]->mnId == pElm->djpttTrayID ) + { + pSetupData->mnPaperBin = j; + bTrayFound = TRUE; + break; + } + } + } + // Wenn wir Ihn immer noch nicht gefunden haben, setzen + // wir ihn auf DontKnow + if ( !bTrayFound ) + pSetupData->mnPaperBin = 0xFFFF; + } + } + + pDJP = DJP_NEXT_STRUCTP( pDJP ); + pTuple++; + } + + bResult = TRUE; + } + else + { + ImplFreePrnMemory( pCopyDrivData ); + bResult = FALSE; + } + + delete [] pBuffer; + + return bResult; +} + +// ----------------------------------------------------------------------- + +static BOOL ImplSetOrientation( HDC hPrinterDC, PDRIVDATA pDriverData, + Orientation eOrientation ) +{ + LONG alQuery[] = + { + 0, 0, // First two members of QUERYSIZE + DJP_SJ_ORIENTATION, DJP_CURRENT, + DJP_NONE, DJP_NONE // EOL marker + }; + + APIRET rc; + PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; + PBYTE pBuffer = NULL; + LONG nAlloc = 0; + LONG nDrivDataSize = pDriverData->cb; + + // find out how many bytes to allocate + pQuerySize->cb = sizeof( alQuery ); + rc = DevEscape( hPrinterDC, + DEVESC_QUERYSIZE, + sizeof( alQuery ), + (PBYTE)pQuerySize, + &nDrivDataSize, + (PBYTE)pDriverData ); + if ( DEV_OK != rc ) + return FALSE; + + // allocate the memory + nAlloc = pQuerySize->ulSizeNeeded; + pBuffer = (PBYTE)new BYTE[nAlloc]; + + // set up the input + PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; + ImplFormatInputList( pDJP, pQuerySize->aTuples ); + + pDJP->cb = sizeof( DJP_ITEM ); + pDJP->ulProperty = DJP_SJ_ORIENTATION; + pDJP->lType = DJP_CURRENT; + pDJP->ulValue = (eOrientation == ORIENTATION_PORTRAIT) + ? DJP_ORI_PORTRAIT + : DJP_ORI_LANDSCAPE; + + // do it! + rc = DevEscape( hPrinterDC, + DEVESC_SETJOBPROPERTIES, + nAlloc, + pBuffer, + &nDrivDataSize, + (PBYTE)pDriverData ); + + delete [] pBuffer; + + return ((DEV_OK == rc) || (DEV_WARNING == rc)); +} + +// ----------------------------------------------------------------------- + +static BOOL ImplSetPaperSize( HDC hPrinterDC, PDRIVDATA pDriverData, + DJPT_PAPERSIZE nOS2PaperFormat ) +{ + LONG alQuery[] = + { + 0, 0, // First two members of QUERYSIZE + DJP_SJ_PAPERSIZE, DJP_CURRENT, + DJP_NONE, DJP_NONE // EOL marker + }; + + APIRET rc; + PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; + PBYTE pBuffer = NULL; + LONG nAlloc = 0; + LONG nDrivDataSize = pDriverData->cb; + + // find out how many bytes to allocate + pQuerySize->cb = sizeof( alQuery ); + rc = DevEscape( hPrinterDC, + DEVESC_QUERYSIZE, + sizeof( alQuery ), + (PBYTE)pQuerySize, + &nDrivDataSize, + (PBYTE)pDriverData ); + if ( DEV_OK != rc ) + return FALSE; + + // allocate the memory + nAlloc = pQuerySize->ulSizeNeeded; + pBuffer = (PBYTE)new BYTE[nAlloc]; + + // set up the input + PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; + PDJP_ITEM pStartDJP = pDJP; + ImplFormatInputList( pDJP, pQuerySize->aTuples ); + + // Neue Daten zuweisen + pDJP->cb = sizeof( DJP_ITEM ); + pDJP->ulProperty = DJP_SJ_PAPERSIZE; + pDJP->lType = DJP_CURRENT; + pDJP->ulValue = nOS2PaperFormat; + + // und setzen + rc = DevEscape( hPrinterDC, + DEVESC_SETJOBPROPERTIES, + nAlloc, + pBuffer, + &nDrivDataSize, + (PBYTE)pDriverData ); + + delete [] pBuffer; + + return ((DEV_OK == rc) || (DEV_WARNING == rc)); +} + +// ----------------------------------------------------------------------- + +static BOOL ImplSetPaperBin( HDC hPrinterDC, PDRIVDATA pDriverData, + ImplTrayInfo* pTrayInfo ) +{ + LONG alQuery[] = + { + 0, 0, // First two members of QUERYSIZE + DJP_SJ_TRAYTYPE, DJP_CURRENT, + DJP_NONE, DJP_NONE // EOL marker + }; + + APIRET rc; + PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; + PBYTE pBuffer = NULL; + LONG nAlloc = 0; + LONG nDrivDataSize = pDriverData->cb; + + // find out how many bytes to allocate + pQuerySize->cb = sizeof( alQuery ); + rc = DevEscape( hPrinterDC, + DEVESC_QUERYSIZE, + sizeof( alQuery ), + (PBYTE)pQuerySize, + &nDrivDataSize, + (PBYTE)pDriverData ); + if ( DEV_OK != rc ) + return FALSE; + + // allocate the memory + nAlloc = pQuerySize->ulSizeNeeded; + pBuffer = (PBYTE)new BYTE[nAlloc]; + + // set up the input + PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; + ImplFormatInputList( pDJP, pQuerySize->aTuples ); + + // Neue Daten zuweisen + pDJP->cb = sizeof( DJP_ITEM ); + pDJP->ulProperty = DJP_SJ_TRAYTYPE; + pDJP->lType = DJP_CURRENT; + pDJP->ulValue = pTrayInfo->mnId; + + // und setzen + rc = DevEscape( hPrinterDC, + DEVESC_SETJOBPROPERTIES, + nAlloc, + pBuffer, + &nDrivDataSize, + (PBYTE)pDriverData ); + + delete [] pBuffer; + + return ((DEV_OK == rc) || (DEV_WARNING == rc)); +} + +// ======================================================================= + +static BOOL ImplSalCreateInfoPrn( SalInfoPrinter* pPrinter, PDRIVDATA pDriverData, + HDC& rDC, HPS& rPS ) +{ + SalData* pSalData = GetSalData(); + + // create info context + DEVOPENSTRUC devOpenStruc; + memset( &devOpenStruc, 0, sizeof( devOpenStruc ) ); + devOpenStruc.pszLogAddress = (char*)(const char*)pPrinter->maPrinterData.maName; + devOpenStruc.pszDriverName = (char*)(const char*)pPrinter->maPrinterData.maDriverName; + devOpenStruc.pdriv = pDriverData; + devOpenStruc.pszDataType = "PM_Q_STD"; + + HDC hDC = DevOpenDC( pSalData->mhAB, OD_INFO, "*", + 4, (PDEVOPENDATA)&devOpenStruc, (HDC)NULL); + if ( !hDC ) + return FALSE; + + // create presentation space + SIZEL sizel; + sizel.cx = 0; + sizel.cy = 0; + HPS hPS = GpiCreatePS( pSalData->mhAB, hDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS ); + if ( !hPS ) + { + DevCloseDC( hDC ); + return FALSE; + } + + rDC = hDC; + rPS = hPS; + return TRUE; +} + +// ----------------------------------------------------------------------- + +static void ImplSalDestroyInfoPrn( SalInfoPrinter* pPrinter ) +{ + ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) ); + GpiAssociate( pPrinter->maPrinterData.mhPS, 0 ); + GpiDestroyPS( pPrinter->maPrinterData.mhPS ); + DevCloseDC( pPrinter->maPrinterData.mhDC ); +} + +// ======================================================================= + +SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, + ImplJobSetup* pSetupData ) +{ + ImplQueueSalSysData* pSysQueueData = (ImplQueueSalSysData*)(pQueueInfo->mpSysData); + SalInfoPrinter* pPrinter = new SalInfoPrinter; + pPrinter->maPrinterData.maPrinterName = pSysQueueData->maPrinterName; + pPrinter->maPrinterData.maName = pSysQueueData->maName; + pPrinter->maPrinterData.maDriverName = pSysQueueData->maDriverName; + pPrinter->maPrinterData.maDeviceName = pSysQueueData->maDeviceName; + + // Nur Setup-Daten uebernehmen, wenn Treiber und Laenge der Treiberdaten + // uebereinstimmt + PDRIVDATA pDriverData; + BOOL bUpdateDriverData; + if ( pSetupData->mpDriverData && pSysQueueData->mpDrivData && + (pSetupData->mnSystem == JOBSETUP_SYSTEM_OS2) && + (pSetupData->mnDriverDataLen == pSysQueueData->mpDrivData->cb) && + (strcmp( ((PDRIVDATA)pSetupData->mpDriverData)->szDeviceName, + pSysQueueData->mpDrivData->szDeviceName ) == 0) ) + { + pDriverData = PDRIVDATA( pSetupData->mpDriverData ); + bUpdateDriverData = FALSE; + } + else + { + pDriverData = pSysQueueData->mpDrivData; + bUpdateDriverData = TRUE; + } + if ( pDriverData ) + pPrinter->maPrinterData.maJobSetupDeviceName = pDriverData->szDeviceName; + + if ( !ImplSalCreateInfoPrn( pPrinter, pDriverData, + pPrinter->maPrinterData.mhDC, + pPrinter->maPrinterData.mhPS ) ) + { + delete pPrinter; + return NULL; + } + + // create graphics object for output + SalGraphics* pGraphics = new SalGraphics; + pGraphics->maGraphicsData.mhDC = pPrinter->maPrinterData.mhDC; + pGraphics->maGraphicsData.mhPS = pPrinter->maPrinterData.mhPS; + pGraphics->maGraphicsData.mhWnd = 0; + pGraphics->maGraphicsData.mbPrinter = TRUE; + pGraphics->maGraphicsData.mbVirDev = FALSE; + pGraphics->maGraphicsData.mbWindow = FALSE; + pGraphics->maGraphicsData.mbScreen = FALSE; + + ImplSalInitGraphics( &(pGraphics->maGraphicsData) ); + pPrinter->maPrinterData.mpGraphics = pGraphics; + + // check printer driver for DJP support + pPrinter->maPrinterData.mbDJPSupported = ImplIsDriverDJPEnabled( pPrinter->maPrinterData.mhDC ); + + if ( bUpdateDriverData ) + { + if ( pSetupData->mpDriverData ) + delete pSetupData->mpDriverData; + pSetupData->mpDriverData = new BYTE[pDriverData->cb]; + memcpy( pSetupData->mpDriverData, pDriverData, pDriverData->cb ); + pSetupData->mnDriverDataLen = pDriverData->cb; + } + + // retrieve current settings from printer driver and store them to system independend data! + if ( pPrinter->maPrinterData.mbDJPSupported ) + ImplGetCurrentSettings( pPrinter, pSetupData ); + pSetupData->mnSystem = JOBSETUP_SYSTEM_OS2; + + return pPrinter; +} + +// ----------------------------------------------------------------------- + +void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter ) +{ + delete pPrinter; +} + +// ======================================================================= + +SalInfoPrinter::SalInfoPrinter() +{ + maPrinterData.mhDC = 0; + maPrinterData.mhPS = 0; + maPrinterData.mpGraphics = NULL; + maPrinterData.mbGraphics = FALSE; + maPrinterData.mbDJPSupported = FALSE; + maPrinterData.mnFormCount = 0; + maPrinterData.mpFormArray = NULL; + maPrinterData.mnTrayCount = 0; + maPrinterData.mpTrayArray = NULL; +} + +// ----------------------------------------------------------------------- + +SalInfoPrinter::~SalInfoPrinter() +{ + if ( maPrinterData.mpGraphics ) + { + ImplSalDestroyInfoPrn( this ); + delete maPrinterData.mpGraphics; + } + + ImplFreeFormAndTrayList( this ); +} + +// ----------------------------------------------------------------------- + +SalGraphics* SalInfoPrinter::GetGraphics() +{ + if ( maPrinterData.mbGraphics ) + return NULL; + + if ( maPrinterData.mpGraphics ) + maPrinterData.mbGraphics = TRUE; + + return maPrinterData.mpGraphics; +} + +// ----------------------------------------------------------------------- + +void SalInfoPrinter::ReleaseGraphics( SalGraphics* ) +{ + maPrinterData.mbGraphics = FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData ) +{ + PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData ); + if ( !pDrivData ) + return FALSE; + + APIRET rc = DevPostDeviceModes( GetSalData()->mhAB, pDrivData, + maPrinterData.maDriverName.GetStr(), + maPrinterData.maDeviceName.GetStr(), + maPrinterData.maPrinterName.GetStr(), + DPDM_POSTJOBPROP ); + if ( rc == DEV_OK ) + { + ImplUpdateSetupData( pDrivData, pSetupData ); + + // update DC and PS + HDC hDC; + HPS hPS; + if ( !ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) ) + return FALSE; + + // Alten Printer DC/PS zerstoeren + ImplSalDestroyInfoPrn( this ); + + // Neue Daten setzen und initialisieren + maPrinterData.mhDC = hDC; + maPrinterData.mhPS = hPS; + maPrinterData.mpGraphics->maGraphicsData.mhDC = maPrinterData.mhDC; + maPrinterData.mpGraphics->maGraphicsData.mhPS = maPrinterData.mhPS; + ImplSalInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + + // retrieve current settings from printer driver and store them to system independend data! + ImplFreeFormAndTrayList( this ); + if ( maPrinterData.mbDJPSupported ) + ImplGetCurrentSettings( this, pSetupData ); + + return TRUE; + } + else + { + ImplFreePrnMemory( pDrivData ); + return FALSE; + } +} + +// ----------------------------------------------------------------------- + +BOOL SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData ) +{ + // Wir koennen nur Treiberdaten von OS2 setzen + if ( pSetupData->mnSystem != JOBSETUP_SYSTEM_OS2 ) + return FALSE; + + PDRIVDATA pNewDrivData = (PDRIVDATA)(pSetupData->mpDriverData); + if ( !pNewDrivData ) + return FALSE; + + // Testen, ob Printerdaten fuer den gleichen Printer uebergeben werden, + // da einige Treiber zu Abstuerzen neigen, wenn Daten von einem anderen + // Printer gesetzt werden + if ( strcmp( maPrinterData.maJobSetupDeviceName, pNewDrivData->szDeviceName ) != 0 ) + return FALSE; + + // update DC and PS + HDC hDC; + HPS hPS; + if ( !ImplSalCreateInfoPrn( this, pNewDrivData, hDC, hPS ) ) + return FALSE; + + // Alten Printer DC/PS zerstoeren + ImplSalDestroyInfoPrn( this ); + + // Neue Daten setzen und initialisieren + maPrinterData.mhDC = hDC; + maPrinterData.mhPS = hPS; + maPrinterData.mpGraphics->maGraphicsData.mhDC = maPrinterData.mhDC; + maPrinterData.mpGraphics->maGraphicsData.mhPS = maPrinterData.mhPS; + ImplSalInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + + // retrieve current settings from printer driver and store them to system independend data! + ImplFreeFormAndTrayList( this ); + if ( maPrinterData.mbDJPSupported ) + ImplGetCurrentSettings( this, pSetupData ); + + return TRUE; +} + +// ----------------------------------------------------------------------- + +BOOL SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData ) +{ + // needs DJP support + if ( !maPrinterData.mbDJPSupported ) + return FALSE; + + PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData ); + + if ( !pDrivData ) + return FALSE; + + BOOL bOK = FALSE; + + // set orientation + if ( nFlags & SAL_JOBSET_ORIENTATION ) + { + if ( ImplSetOrientation( maPrinterData.mhDC, pDrivData, pSetupData->meOrientation ) ) + bOK = TRUE; + } + + // set paper size + if ( nFlags & SAL_JOBSET_PAPERSIZE ) + { + // Papierformat ermitteln + DJPT_PAPERSIZE nOS2PaperFormat; + switch ( pSetupData->mePaperFormat ) + { + case PAPER_A3: + nOS2PaperFormat = DJP_PSI_A3; + break; + + case PAPER_A4: + nOS2PaperFormat = DJP_PSI_A4; + break; + + case PAPER_A5: + nOS2PaperFormat = DJP_PSI_A5; + break; + + case PAPER_B4: + nOS2PaperFormat = DJP_PSI_B4; + break; + + case PAPER_B5: + nOS2PaperFormat = DJP_PSI_B5; + break; + + case PAPER_LETTER: + nOS2PaperFormat = DJP_PSI_LETTER; + break; + + case PAPER_LEGAL: + nOS2PaperFormat = DJP_PSI_LEGAL; + break; + + case PAPER_TABLOID: + nOS2PaperFormat = DJP_PSI_TABLOID; + break; + + default: + { + nOS2PaperFormat = DJP_PSI_NONE; + // OS2 rechnet in Millimetern + long nPaperWidth = pSetupData->mnPaperWidth / 100; + long nPaperHeight = pSetupData->mnPaperHeight / 100; + // Ansonsten ueber die Papiergroesse suchen + for( int i = 0; i < maPrinterData.mnFormCount; i++ ) + { + ImplFormInfo* pFormInfo = maPrinterData.mpFormArray[i]; + if ( ImplPaperSizeEqual( nPaperWidth, nPaperHeight, + pFormInfo->mnPaperWidth, pFormInfo->mnPaperHeight ) ) + { + nOS2PaperFormat = pFormInfo->mnId; + break; + } + } + } + break; + } + + if ( nOS2PaperFormat != DJP_PSI_NONE ) + { + if ( ImplSetPaperSize( maPrinterData.mhDC, pDrivData, nOS2PaperFormat ) ) + bOK = TRUE; + } + } + + // set paper tray + if ( (nFlags & SAL_JOBSET_PAPERBIN) && (pSetupData->mnPaperBin < maPrinterData.mnTrayCount) ) + { + if ( ImplSetPaperBin( maPrinterData.mhDC, pDrivData, + maPrinterData.mpTrayArray[pSetupData->mnPaperBin] ) ) + bOK = TRUE; + } + + if ( bOK ) + { + ImplUpdateSetupData( pDrivData, pSetupData ); + + // query current driver settings + ImplFreeFormAndTrayList( this ); + if ( ImplGetCurrentSettings( this, pSetupData ) ) + { + // update DC and PS + HDC hDC; + HPS hPS; + if ( ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) ) + { + // Alten Printer DC/PS zerstoeren + ImplSalDestroyInfoPrn( this ); + + // Neue Daten setzen und initialisieren + maPrinterData.mhDC = hDC; + maPrinterData.mhPS = hPS; + maPrinterData.mpGraphics->maGraphicsData.mhDC = maPrinterData.mhDC; + maPrinterData.mpGraphics->maGraphicsData.mhPS = maPrinterData.mhPS; + ImplSalInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + } + else + bOK = FALSE; + } + else + bOK = FALSE; + } + + return bOK; +} + +// ----------------------------------------------------------------------- + +ULONG SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup ) +{ + if ( !maPrinterData.mbDJPSupported ) + return 1; + + // init paperbinlist if empty + if ( !maPrinterData.mnTrayCount ) + ImplGetFormAndTrayList( this, pJobSetup ); + + // Wir haben immer einen PaperTray und wenn, das eben einen ohne + // Namen + if ( !maPrinterData.mnTrayCount ) + return 1; + else + return maPrinterData.mnTrayCount; +} + +// ----------------------------------------------------------------------- + +XubString SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, + ULONG nPaperBin ) +{ + XubString aPaperBinName; + + if ( maPrinterData.mbDJPSupported ) + { + // init paperbinlist if empty + if ( !maPrinterData.mnTrayCount ) + ImplGetFormAndTrayList( this, pJobSetup ); + + if ( nPaperBin < maPrinterData.mnTrayCount ) + aPaperBinName = maPrinterData.mpTrayArray[nPaperBin]->maDisplayName; + } + + return aPaperBinName; +} + +// ----------------------------------------------------------------------- + +ULONG SalInfoPrinter::GetCapabilities( const ImplJobSetup*, USHORT nType ) +{ + switch ( nType ) + { + case PRINTER_CAPABILITIES_SUPPORTDIALOG: + return TRUE; + case PRINTER_CAPABILITIES_COPIES: + return 0xFFFF; + case PRINTER_CAPABILITIES_COLLATECOPIES: + return 0; + case PRINTER_CAPABILITIES_SETORIENTATION: + case PRINTER_CAPABILITIES_SETPAPERBIN: + case PRINTER_CAPABILITIES_SETPAPERSIZE: + case PRINTER_CAPABILITIES_SETPAPER: + return maPrinterData.mbDJPSupported; + } + + return 0; +} + +// ----------------------------------------------------------------------- + +void SalInfoPrinter::GetPageInfo( const ImplJobSetup*, + long& rOutWidth, long& rOutHeight, + long& rPageOffX, long& rPageOffY, + long& rPageWidth, long& rPageHeight ) +{ + HDC hDC = maPrinterData.mhDC; + + // search current form + HCINFO aInfo; + int nForms = DevQueryHardcopyCaps( hDC, 0, 0, &aInfo ); + for( int i = 0; i < nForms; i++ ) + { + if ( DevQueryHardcopyCaps( hDC, i, 1, &aInfo ) >= 0 ) + { + if ( aInfo.flAttributes & HCAPS_CURRENT ) + { + // query resolution + long nXResolution; + long nYResolution; + DevQueryCaps( hDC, CAPS_HORIZONTAL_RESOLUTION, 1, &nXResolution ); + DevQueryCaps( hDC, CAPS_VERTICAL_RESOLUTION, 1, &nYResolution ); + rPageOffX = aInfo.xLeftClip * nXResolution / 1000; + rPageOffY = (aInfo.cy-aInfo.yTopClip) * nYResolution / 1000; + rPageWidth = aInfo.cx * nXResolution / 1000; + rPageHeight = aInfo.cy * nYResolution / 1000; + rOutWidth = aInfo.xPels; + rOutHeight = aInfo.yPels; + return; + } + } + } + + // use device caps if no form selected/found + long lCapsWidth = 0; + long lCapsHeight = 0; + DevQueryCaps( hDC, CAPS_WIDTH, 1L, &lCapsWidth ); + DevQueryCaps( hDC, CAPS_HEIGHT, 1L, &lCapsHeight ); + rPageOffX = 0; + rPageOffY = 0; + rOutWidth = lCapsWidth; + rOutHeight = lCapsHeight; + rPageWidth = rOutWidth; + rPageHeight = rOutHeight; +} + +// ======================================================================= + +static BOOL ImplIsDriverPrintDJPEnabled( HDC hDC ) +{ +#ifdef NO_DJP + return FALSE; +#else + // Ueber OS2-Ini kann DJP disablte werden + if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTDJP, 1 ) ) + return FALSE; + + // Testen, ob DJP-Interface am Drucker vorhanden + LONG lQuery; + APIRET rc; + + lQuery = DEVESC_QUERYSIZE; + rc = DevEscape( hDC, + DEVESC_QUERYESCSUPPORT, + sizeof( lQuery ), + (PBYTE)&lQuery, + 0, + (PBYTE)NULL ); + if ( DEV_OK != rc ) + return FALSE; + + return TRUE; +#endif +} + +// ======================================================================= + +SalPrinter* SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter ) +{ + SalPrinter* pPrinter = new SalPrinter; + pPrinter->maPrinterData.mpInfoPrinter = pInfoPrinter; + return pPrinter; +} + +// ----------------------------------------------------------------------- + +void SalInstance::DestroyPrinter( SalPrinter* pPrinter ) +{ + delete pPrinter; +} + +// ======================================================================= + +SalPrinter::SalPrinter() +{ + maPrinterData.mhDC = 0; + maPrinterData.mhPS = 0; + maPrinterData.mpGraphics = NULL; + maPrinterData.mbAbort = FALSE; + maPrinterData.mbPrintDJPSupported = FALSE; +} + +// ----------------------------------------------------------------------- + +SalPrinter::~SalPrinter() +{ +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::StartJob( const XubString* pFileName, + const XubString& rJobName, + const XubString& rAppName, + ULONG nCopies, BOOL bCollate, + ImplJobSetup* pSetupData ) +{ + DEVOPENSTRUC aDevOpenStruc; + LONG lType; + APIRET rc; + + // prepare queue information + memset( &aDevOpenStruc, 0, sizeof( aDevOpenStruc ) ); + aDevOpenStruc.pszDriverName = (PSZ)(maPrinterData.mpInfoPrinter->maPrinterData.maDriverName.GetStr()); + + // print into file? + if ( pFileName ) + { + aDevOpenStruc.pszLogAddress = (PSZ)pFileName->GetStr(); + aDevOpenStruc.pszDataType = "PM_Q_RAW"; + lType = OD_DIRECT; + } + else + { + aDevOpenStruc.pszLogAddress = (PSZ)(maPrinterData.mpInfoPrinter->maPrinterData.maName.GetStr()); + if ( PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTRAW, 0 ) ) + aDevOpenStruc.pszDataType = "PM_Q_RAW"; + else + aDevOpenStruc.pszDataType = "PM_Q_STD"; + lType = OD_QUEUED; + } + + // Set comment (AppName nur bis zum 1. Space-Zeichen nehmen) + const xub_Unicode* pComment = rAppName; + USHORT nCommentLen = 0; + memset( maPrinterData.maCommentBuf, 0, sizeof( maPrinterData.maCommentBuf ) ); + while ( (nCommentLen < 32) && + (((*pComment >= 'a') && (*pComment <= 'z')) || + ((*pComment >= 'A') && (*pComment <= 'Z')) || + ((*pComment >= '0') && (*pComment <= '9')) || + (*pComment == '-'))) + { + maPrinterData.maCommentBuf[nCommentLen] = (char)(*pComment); + nCommentLen++; + pComment++; + } + aDevOpenStruc.pszComment = (PSZ)maPrinterData.maCommentBuf; + + // Kopien + if ( nCopies > 1 ) + { + // OS2 kann maximal 999 Kopien + if ( nCopies > 999 ) + nCopies = 999; + String aCopyStr( nCopies ); + strcpy( maPrinterData.maCopyBuf, "COP=" ); + strcat( maPrinterData.maCopyBuf+4, aCopyStr.GetStr() ); + aDevOpenStruc.pszQueueProcParams = (PSZ)maPrinterData.maCopyBuf; + } + + // open device context + SalData* pSalData = GetSalData(); + HAB hAB = pSalData->mhAB; + aDevOpenStruc.pdriv = (PDRIVDATA)pSetupData->mpDriverData; + maPrinterData.mhDC = DevOpenDC( hAB, + lType, + "*", + 7, + (PDEVOPENDATA)&aDevOpenStruc, + 0 ); + if ( maPrinterData.mhDC == 0 ) + { + ERRORID nLastError = WinGetLastError( hAB ); + if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT ) + maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT; + else + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return FALSE; + } + + // open presentation space + SIZEL sizel; + sizel.cx = 0; + sizel.cy = 0; + maPrinterData.mhPS = GpiCreatePS( hAB, maPrinterData.mhDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS ); + if ( !maPrinterData.mhPS ) + { + DevCloseDC( maPrinterData.mhDC ); + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return NULL; + } + + // Can we print with DJP + maPrinterData.mbPrintDJPSupported = ImplIsDriverPrintDJPEnabled( maPrinterData.mhDC ); + + // JobName ermitteln und Job starten + PSZ pszJobName = NULL; + int nJobNameLen = 0; + if ( rJobName.Len() > 0 ) + { + pszJobName = (PSZ)rJobName.GetStr(); + nJobNameLen = rJobName.Len(); + } + rc = DevEscape( maPrinterData.mhDC, + DEVESC_STARTDOC, + nJobNameLen, pszJobName, + 0, NULL ); + + if ( rc != DEV_OK ) + { + ERRORID nLastError = WinGetLastError( hAB ); + if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT ) + maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT; + else + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + GpiAssociate( maPrinterData.mhPS, NULL ); + GpiDestroyPS( maPrinterData.mhPS ); + DevCloseDC( maPrinterData.mhDC ); + return FALSE; + } + + // init for first page + maPrinterData.mbFirstPage = TRUE; + maPrinterData.mnError = 0; + + return TRUE; +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::EndJob() +{ + APIRET rc; + rc = DevEscape( maPrinterData.mhDC, + DEVESC_ENDDOC, + 0, NULL, + 0, NULL); + + // destroy presentation space and device context + GpiAssociate( maPrinterData.mhPS, NULL ); + GpiDestroyPS( maPrinterData.mhPS ); + DevCloseDC( maPrinterData.mhDC ); + return TRUE; +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::AbortJob() +{ + APIRET rc; + + rc = DevEscape( maPrinterData.mhDC, + DEVESC_ABORTDOC, + 0, NULL, + 0, NULL ); + + // destroy SalGraphics + if ( maPrinterData.mpGraphics ) + { + ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + delete maPrinterData.mpGraphics; + maPrinterData.mpGraphics = NULL; + } + + // destroy presentation space and device context + GpiAssociate( maPrinterData.mhPS, NULL ); + GpiDestroyPS( maPrinterData.mhPS ); + DevCloseDC( maPrinterData.mhDC ); + return TRUE; +} + +// ----------------------------------------------------------------------- + +SalGraphics* SalPrinter::StartPage( ImplJobSetup* pSetupData, BOOL bNewJobSetup ) +{ + APIRET rc; + + if ( maPrinterData.mbFirstPage ) + maPrinterData.mbFirstPage = FALSE; + else + { + PBYTE pJobData; + LONG nJobDataSize; + LONG nEscape; + if ( maPrinterData.mbPrintDJPSupported && bNewJobSetup ) + { + nEscape = DEVESC_NEWFRAME_WPROP; + nJobDataSize = ((PDRIVDATA)(pSetupData->mpDriverData))->cb; + pJobData = (PBYTE)(pSetupData->mpDriverData); + } + else + { + nEscape = DEVESC_NEWFRAME; + nJobDataSize = 0; + pJobData = NULL; + } + rc = DevEscape( maPrinterData.mhDC, + nEscape, + 0, NULL, + &nJobDataSize, pJobData ); + + if ( rc != DEV_OK ) + { + DevEscape( maPrinterData.mhDC, DEVESC_ENDDOC, 0, NULL, 0, NULL); + GpiAssociate( maPrinterData.mhPS, NULL ); + GpiDestroyPS( maPrinterData.mhPS ); + DevCloseDC( maPrinterData.mhDC ); + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return NULL; + } + } + + // create SalGraphics with copy of hPS + SalGraphics* pGraphics = new SalGraphics; + pGraphics->maGraphicsData.mhDC = maPrinterData.mhDC; + pGraphics->maGraphicsData.mhPS = maPrinterData.mhPS; + pGraphics->maGraphicsData.mhWnd = 0; + pGraphics->maGraphicsData.mbPrinter = TRUE; + pGraphics->maGraphicsData.mbVirDev = FALSE; + pGraphics->maGraphicsData.mbWindow = FALSE; + pGraphics->maGraphicsData.mbScreen = FALSE; + pGraphics->maGraphicsData.mnHeight = 0; + // search current form for actual page height + HCINFO aInfo; + int nForms = DevQueryHardcopyCaps( maPrinterData.mhDC, 0, 0, &aInfo ); + for( int i = 0; i < nForms; i++ ) + { + if ( DevQueryHardcopyCaps( maPrinterData.mhDC, i, 1, &aInfo ) >= 0 ) + { + if ( aInfo.flAttributes & HCAPS_CURRENT ) + pGraphics->maGraphicsData.mnHeight = aInfo.yPels; + } + } + // use device caps if no form selected/found + if ( !pGraphics->maGraphicsData.mnHeight ) + DevQueryCaps( maPrinterData.mhDC, CAPS_HEIGHT, 1L, &pGraphics->maGraphicsData.mnHeight ); + + ImplSalInitGraphics( &(pGraphics->maGraphicsData) ); + maPrinterData.mpGraphics = pGraphics; + + return pGraphics; +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::EndPage() +{ + if ( maPrinterData.mpGraphics ) + { + // destroy SalGraphics + ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + delete maPrinterData.mpGraphics; + maPrinterData.mpGraphics = NULL; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +ULONG SalPrinter::GetErrorCode() +{ + return maPrinterData.mnError; +} |