/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // use this define to disable the DJP support // #define NO_DJP #define INCL_DOSMODULEMGR #define INCL_DEV #define INCL_SPL #define INCL_SPLERRORS #define INCL_SPLDOSPRINT #define INCL_DEVDJP #define INCL_GPI #define INCL_DOSSEMAPHORES #define INCL_PM #include #include #include #include #include #include #ifdef __MINGW32__ #include #endif #include #include #include #include #include #include #include #include #include #ifndef __H_FT2LIB #include #include #endif // ======================================================================= // ----------------------- // - struct ImplFormInfo - // ----------------------- struct ImplFormInfo { long mnPaperWidth; long mnPaperHeight; #ifndef NO_DJP DJPT_PAPERSIZE mnId; #endif }; // ======================================================================= // ----------------------- // - struct ImplTrayInfo - // ----------------------- struct ImplTrayInfo { CHAR maName[32]; CHAR maDisplayName[64]; DJPT_TRAYTYPE mnId; ImplTrayInfo( const char* pTrayName, const char* pTrayDisplayName ) { strcpy( maName, pTrayName); strcpy( maDisplayName, pTrayDisplayName); } }; // ======================================================================= struct ImplQueueSalSysData { ByteString maPrinterName; // pszPrinters ByteString maName; // pszName bzw. LogAddress ByteString maOrgDriverName; // pszDriverName (maDriverName.maDeviceName) ByteString maDriverName; // pszDriverName bis . ByteString maDeviceName; // pszDriverName nach . PDRIVDATA mpDrivData; ImplQueueSalSysData( const ByteString& rPrinterName, const ByteString& rName, const ByteString& rDriverName, const ByteString& rDeviceName, const ByteString& rOrgDriverName, PDRIVDATA pDrivData ); ~ImplQueueSalSysData(); }; // ----------------------------------------------------------------------- ImplQueueSalSysData::ImplQueueSalSysData( const ByteString& rPrinterName, const ByteString& rName, const ByteString& rOrgDriverName, const ByteString& rDriverName, const ByteString& rDeviceName, PDRIVDATA pDrivData ) : maPrinterName( rPrinterName ), maName( rName ), maOrgDriverName( rName ), maDriverName( rDriverName ), maDeviceName( rDeviceName ) { if ( pDrivData ) { mpDrivData = (PDRIVDATA)new PM_BYTE[pDrivData->cb]; memcpy( mpDrivData, pDrivData, pDrivData->cb ); } else mpDrivData = NULL; } // ----------------------------------------------------------------------- ImplQueueSalSysData::~ImplQueueSalSysData() { delete mpDrivData; } // ======================================================================= static ULONG ImplPMQueueStatusToSal( 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 Os2SalInstance::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; ByteString aOrgDriverName( pPrqInfo->pszDriverName); ByteString aName( pPrqInfo->pszName); #if OSL_DEBUG_LEVEL>0 printf("GetPrinterQueueInfo pszDriverName %s\n", pPrqInfo->pszDriverName); printf("GetPrinterQueueInfo pszName %s\n", pPrqInfo->pszDriverName); #endif pInfo->maDriver = ::rtl::OStringToOUString (aOrgDriverName, gsl_getSystemTextEncoding()); pInfo->maPrinterName = ::rtl::OStringToOUString (pPrqInfo->pszComment, gsl_getSystemTextEncoding()); pInfo->maLocation = ::rtl::OStringToOUString (aName, gsl_getSystemTextEncoding()); 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 ByteString aPrinterName( pPrqInfo->pszPrinters); ByteString aDriverName( pPrqInfo->pszDriverName); ByteString 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 Os2SalInstance::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 ( pSysData->maPrinterName.Equals( pPrqInfo->pszPrinters ) && pSysData->maName.Equals( pPrqInfo->pszName ) && pSysData->maOrgDriverName.Equals( pPrqInfo->pszDriverName ) ) { pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus ); pInfo->mnJobs = pPrqInfo->cJobs; break; } // increment to next element of the QueueInfo array pPrqInfo++; } delete [] pQueueData; } // ----------------------------------------------------------------------- void Os2SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo ) { delete ((ImplQueueSalSysData*)(pInfo->mpSysData)); delete pInfo; } // ----------------------------------------------------------------------- XubString Os2SalInstance::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 = ::rtl::OStringToOUString (pPrqInfo->pszComment, gsl_getSystemTextEncoding()); // 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) ) { String pszName( ::rtl::OStringToOUString (pPrqInfo->pszName, gsl_getSystemTextEncoding())); aDefaultName += ';'; aDefaultName += pszName; } pTempPrqInfo++; } break; } // increment to next element of the QueueInfo array pPrqInfo++; } delete [] pQueueData; return aDefaultName; } // ======================================================================= static void* ImplAllocPrnMemory( size_t n ) { return calloc( n, 1); } // ----------------------------------------------------------------------- inline void ImplFreePrnMemory( void* p ) { free( 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( ((PDRIVDATA)(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 ) rtl_freeMemory( pSetupData->mpDriverData ); pSetupData->mpDriverData = NULL; 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 ) rtl_freeMemory( pSetupData->mpDriverData ); pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDrivData->cb); } else pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDrivData->cb); pSetupData->mnDriverDataLen = pDrivData->cb; memcpy( pSetupData->mpDriverData, pDrivData, pDrivData->cb ); } if ( pDrivData ) ImplFreePrnMemory( pDrivData ); } // ----------------------------------------------------------------------- static sal_Bool ImplPaperSizeEqual( long nPaperWidth1, long nPaperHeight1, long nPaperWidth2, long nPaperHeight2 ) { return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) && ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1))); } // ----------------------------------------------------------------------- static sal_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 sal_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( Os2SalInfoPrinter* pOs2SalInfoPrinter ) { if ( pOs2SalInfoPrinter->mnFormCount ) { for ( USHORT i = 0; i < pOs2SalInfoPrinter->mnFormCount; i++ ) delete pOs2SalInfoPrinter->mpFormArray[i]; delete [] pOs2SalInfoPrinter->mpFormArray; pOs2SalInfoPrinter->mnFormCount = 0; } if ( pOs2SalInfoPrinter->mnTrayCount ) { for ( USHORT i = 0; i < pOs2SalInfoPrinter->mnTrayCount; i++ ) delete pOs2SalInfoPrinter->mpTrayArray[i]; delete [] pOs2SalInfoPrinter->mpTrayArray; pOs2SalInfoPrinter->mnTrayCount = 0; } } // ----------------------------------------------------------------------- static void ImplGetFormAndTrayList( Os2SalInfoPrinter* pOs2SalInfoPrinter, const ImplJobSetup* pSetupData ) { // if not defined, suppose default orientation is portrait Orientation orientation = ORIENTATION_PORTRAIT; ImplFreeFormAndTrayList( pOs2SalInfoPrinter ); LONG alQuery[] = { 0, 0, // First two members of QUERYSIZE DJP_SJ_ORIENTATION, DJP_CURRENT, 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( pOs2SalInfoPrinter->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 PM_BYTE[nAlloc]; // set up the input PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; ImplFormatInputList( pDJP, pQuerySize->aTuples ); // do it! rc = DevEscape( pOs2SalInfoPrinter->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_SJ_ORIENTATION ) { if ( pDJP->ulNumReturned ) { PDJPT_ORIENTATION pElm = DJP_ELEMENTP( *pDJP, DJPT_ORIENTATION ); if ( (DJP_ORI_PORTRAIT == *pElm) || (DJP_ORI_REV_PORTRAIT == *pElm) ) orientation = ORIENTATION_PORTRAIT; else orientation = ORIENTATION_LANDSCAPE; } } else if ( pDJP->ulProperty == DJP_CJ_FORM ) { if ( pDJP->ulNumReturned ) { PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM ); pOs2SalInfoPrinter->mnFormCount = pDJP->ulNumReturned; pOs2SalInfoPrinter->mpFormArray = new PIMPLFORMINFO[pOs2SalInfoPrinter->mnFormCount]; for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ ) { ImplFormInfo* pInfo = new ImplFormInfo; // AOO expects form size always in portrait mode if (orientation == ORIENTATION_PORTRAIT) { pInfo->mnPaperWidth = pElm->hcInfo.cx; pInfo->mnPaperHeight = pElm->hcInfo.cy; } else { pInfo->mnPaperWidth = pElm->hcInfo.cy; pInfo->mnPaperHeight = pElm->hcInfo.cx; } #if OSL_DEBUG_LEVEL>0 debug_printf("ImplGetFormAndTrayList #%d: %d x %d", i, pInfo->mnPaperWidth, pInfo->mnPaperHeight); #endif pInfo->mnId = pElm->djppsFormID; pOs2SalInfoPrinter->mpFormArray[i] = pInfo; } } } else if ( pDJP->ulProperty == DJP_CJ_TRAYNAME ) { if ( pDJP->ulNumReturned ) { PDJPT_TRAYNAME pElm = DJP_ELEMENTP( *pDJP, DJPT_TRAYNAME ); pOs2SalInfoPrinter->mnTrayCount = pDJP->ulNumReturned; pOs2SalInfoPrinter->mpTrayArray = new PIMPLTRAYINFO[pOs2SalInfoPrinter->mnTrayCount]; for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ ) { ImplTrayInfo* pInfo = new ImplTrayInfo( pElm->szTrayname, pElm->szDisplayTrayname ); pInfo->mnId = pElm->djpttTrayID; pOs2SalInfoPrinter->mpTrayArray[i] = pInfo; } } } pDJP = DJP_NEXT_STRUCTP( pDJP ); pTuple++; } } delete [] pBuffer; } // ----------------------------------------------------------------------- static sal_Bool ImplGetCurrentSettings( Os2SalInfoPrinter* pOs2SalInfoPrinter, ImplJobSetup* pSetupData ) { // Um den aktuellen Tray zu ermitteln, brauchen wir auch die Listen dazu if ( !pOs2SalInfoPrinter->mnFormCount ) ImplGetFormAndTrayList( pOs2SalInfoPrinter, 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; sal_Bool bResult; // find out how many bytes to allocate pQuerySize->cb = sizeof( alQuery ); rc = DevEscape( pOs2SalInfoPrinter->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 PM_BYTE[nAlloc]; // set up the input PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; ImplFormatInputList( pDJP, pQuerySize->aTuples ); rc = DevEscape( pOs2SalInfoPrinter->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_JIS; break; case DJP_PSI_B5: pSetupData->mePaperFormat = PAPER_B5_JIS; 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 sal_Bool bTrayFound = FALSE; USHORT j; for ( j = 0; j < pOs2SalInfoPrinter->mnTrayCount; j++ ) { if ( (pOs2SalInfoPrinter->mpTrayArray[j]->mnId == pElm->djpttTrayID) && (pOs2SalInfoPrinter->mpTrayArray[j]->maName == pElm->szTrayname) ) { pSetupData->mnPaperBin = j; bTrayFound = TRUE; break; } } if ( !bTrayFound ) { for ( j = 0; j < pOs2SalInfoPrinter->mnTrayCount; j++ ) { if ( pOs2SalInfoPrinter->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 sal_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 }; #if OSL_DEBUG_LEVEL>0 debug_printf( "ImplSetOrientation mhDC %x, %d", hPrinterDC, eOrientation); #endif 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 PM_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 sal_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 PM_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 sal_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 PM_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 sal_Bool ImplSalCreateInfoPrn( Os2SalInfoPrinter* pPrinter, PDRIVDATA pDriverData, HDC& rDC, HPS& rPS ) { SalData* pSalData = GetSalData(); // create info context DEVOPENSTRUC devOpenStruc; memset( &devOpenStruc, 0, sizeof( devOpenStruc ) ); devOpenStruc.pszLogAddress = (char*)pPrinter->maName.GetBuffer(); devOpenStruc.pszDriverName = (char*)pPrinter->maDriverName.GetBuffer(); 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 = Ft2CreatePS( 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( Os2SalInfoPrinter* pPrinter ) { ImplSalDeInitGraphics( pPrinter->mpGraphics); Ft2Associate( pPrinter->mhPS, 0 ); Ft2DestroyPS( pPrinter->mhPS ); DevCloseDC( pPrinter->mhDC ); } // ======================================================================= SalInfoPrinter* Os2SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, ImplJobSetup* pSetupData ) { ImplQueueSalSysData* pSysQueueData = (ImplQueueSalSysData*)(pQueueInfo->mpSysData); Os2SalInfoPrinter* pPrinter = new Os2SalInfoPrinter; pPrinter->maPrinterName = pSysQueueData->maPrinterName; pPrinter->maName = pSysQueueData->maName; pPrinter->maDriverName = pSysQueueData->maDriverName; pPrinter->maDeviceName = pSysQueueData->maDeviceName; // Nur Setup-Daten uebernehmen, wenn Treiber und Laenge der Treiberdaten // uebereinstimmt PDRIVDATA pDriverData; sal_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->maJobSetupDeviceName = pDriverData->szDeviceName; if ( !ImplSalCreateInfoPrn( pPrinter, pDriverData, pPrinter->mhDC, pPrinter->mhPS ) ) { delete pPrinter; return NULL; } // create graphics object for output Os2SalGraphics* pGraphics = new Os2SalGraphics; pGraphics->mhDC = pPrinter->mhDC; pGraphics->mhPS = pPrinter->mhPS; pGraphics->mhWnd = 0; pGraphics->mbPrinter = TRUE; pGraphics->mbVirDev = FALSE; pGraphics->mbWindow = FALSE; pGraphics->mbScreen = FALSE; ImplSalInitGraphics( pGraphics ); pPrinter->mpGraphics = pGraphics; // check printer driver for DJP support pPrinter->mbDJPSupported = ImplIsDriverDJPEnabled( pPrinter->mhDC ); if ( bUpdateDriverData ) { if ( pSetupData->mpDriverData ) rtl_freeMemory( pSetupData->mpDriverData); pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( 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->mbDJPSupported ) ImplGetCurrentSettings( pPrinter, pSetupData ); pSetupData->mnSystem = JOBSETUP_SYSTEM_OS2; return pPrinter; } // ----------------------------------------------------------------------- void Os2SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter ) { delete pPrinter; } // ======================================================================= Os2SalInfoPrinter::Os2SalInfoPrinter() { mhDC = 0; mhPS = 0; mpGraphics = NULL; mbGraphics = FALSE; mbDJPSupported = FALSE; mnFormCount = 0; mpFormArray = NULL; mnTrayCount = 0; mpTrayArray = NULL; m_bPapersInit = FALSE; } // ----------------------------------------------------------------------- Os2SalInfoPrinter::~Os2SalInfoPrinter() { if ( mpGraphics ) { ImplSalDestroyInfoPrn( this ); delete mpGraphics; } ImplFreeFormAndTrayList( this ); } // ----------------------------------------------------------------------- void Os2SalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData ) { #if OSL_DEBUG_LEVEL>0 debug_printf( "Os2SalInfoPrinter::InitPaperFormats pSetupData %x", pSetupData); #endif m_aPaperFormats.clear(); m_bPapersInit = true; // init paperbinlist if empty if ( !mnTrayCount ) ImplGetFormAndTrayList( this, pSetupData ); for( int i = 0; i < mnFormCount; i++) { PaperInfo aInfo( mpFormArray[i]->mnPaperWidth * 100, mpFormArray[i]->mnPaperHeight * 100); #if OSL_DEBUG_LEVEL>0 debug_printf( "Os2SalInfoPrinter::InitPaperFormats #%d: %d x %d", i, mpFormArray[i]->mnPaperWidth * 100, mpFormArray[i]->mnPaperHeight * 100); #endif m_aPaperFormats.push_back( aInfo ); } } // ----------------------------------------------------------------------- int Os2SalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* pSetupData ) { return 900; } // ----------------------------------------------------------------------- SalGraphics* Os2SalInfoPrinter::GetGraphics() { if ( mbGraphics ) return NULL; if ( mpGraphics ) mbGraphics = TRUE; return mpGraphics; } // ----------------------------------------------------------------------- void Os2SalInfoPrinter::ReleaseGraphics( SalGraphics* ) { mbGraphics = FALSE; } // ----------------------------------------------------------------------- sal_Bool Os2SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData ) { PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData ); if ( !pDrivData ) return FALSE; APIRET rc = DevPostDeviceModes( GetSalData()->mhAB, pDrivData, maDriverName.GetBuffer(), maDeviceName.GetBuffer(), maPrinterName.GetBuffer(), 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 mhDC = hDC; mhPS = hPS; mpGraphics->mhDC = mhDC; mpGraphics->mhPS = mhPS; ImplSalInitGraphics( mpGraphics ); // retrieve current settings from printer driver and store them to system independend data! ImplFreeFormAndTrayList( this ); if ( mbDJPSupported ) ImplGetCurrentSettings( this, pSetupData ); return TRUE; } else { ImplFreePrnMemory( pDrivData ); return FALSE; } } // ----------------------------------------------------------------------- sal_Bool Os2SalInfoPrinter::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 ( !maJobSetupDeviceName.Equals( pNewDrivData->szDeviceName )) 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 mhDC = hDC; mhPS = hPS; mpGraphics->mhDC = mhDC; mpGraphics->mhPS = mhPS; ImplSalInitGraphics( mpGraphics ); // retrieve current settings from printer driver and store them to system independend data! ImplFreeFormAndTrayList( this ); if ( mbDJPSupported ) ImplGetCurrentSettings( this, pSetupData ); return TRUE; } // ----------------------------------------------------------------------- sal_Bool Os2SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData ) { #if OSL_DEBUG_LEVEL>0 debug_printf( "Os2SalInfoPrinter::SetData nFlags %x, pSetupData %x", nFlags, pSetupData); #endif // needs DJP support if ( !mbDJPSupported ) return FALSE; PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData ); if ( !pDrivData ) return FALSE; sal_Bool bOK = FALSE; // set orientation if ( nFlags & SAL_JOBSET_ORIENTATION ) { #if OSL_DEBUG_LEVEL>0 debug_printf( "Os2SalInfoPrinter::SetData meOrientation %d", pSetupData->meOrientation); #endif if ( ImplSetOrientation( 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_JIS: nOS2PaperFormat = DJP_PSI_B4; break; case PAPER_B5_JIS: 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 < mnFormCount; i++ ) { ImplFormInfo* pFormInfo = mpFormArray[i]; if ( ImplPaperSizeEqual( nPaperWidth, nPaperHeight, pFormInfo->mnPaperWidth, pFormInfo->mnPaperHeight ) ) { nOS2PaperFormat = pFormInfo->mnId; break; } } } break; } if ( nOS2PaperFormat != DJP_PSI_NONE ) { if ( ImplSetPaperSize( mhDC, pDrivData, nOS2PaperFormat ) ) bOK = TRUE; } } // set paper tray if ( (nFlags & SAL_JOBSET_PAPERBIN) && (pSetupData->mnPaperBin < mnTrayCount) ) { if ( ImplSetPaperBin( mhDC, pDrivData, 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 mhDC = hDC; mhPS = hPS; mpGraphics->mhDC = mhDC; mpGraphics->mhPS = mhPS; ImplSalInitGraphics( mpGraphics ); } else bOK = FALSE; } else bOK = FALSE; } return bOK; } // ----------------------------------------------------------------------- ULONG Os2SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup ) { if ( !mbDJPSupported ) return 1; // init paperbinlist if empty if ( !mnTrayCount ) ImplGetFormAndTrayList( this, pJobSetup ); // Wir haben immer einen PaperTray und wenn, das eben einen ohne // Namen if ( !mnTrayCount ) return 1; else return mnTrayCount; } // ----------------------------------------------------------------------- XubString Os2SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, ULONG nPaperBin ) { XubString aPaperBinName; if ( mbDJPSupported ) { // init paperbinlist if empty if ( !mnTrayCount ) ImplGetFormAndTrayList( this, pJobSetup ); if ( nPaperBin < mnTrayCount ) aPaperBinName = ::rtl::OStringToOUString (mpTrayArray[nPaperBin]->maDisplayName, gsl_getSystemTextEncoding()); } return aPaperBinName; } // ----------------------------------------------------------------------- ULONG Os2SalInfoPrinter::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 mbDJPSupported; } return 0; } // ----------------------------------------------------------------------- void Os2SalInfoPrinter::GetPageInfo( const ImplJobSetup*, long& rOutWidth, long& rOutHeight, long& rPageOffX, long& rPageOffY, long& rPageWidth, long& rPageHeight ) { HDC hDC = 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 sal_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* Os2SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter ) { Os2SalPrinter* pPrinter = new Os2SalPrinter; pPrinter->mpInfoPrinter = static_cast(pInfoPrinter); return pPrinter; } // ----------------------------------------------------------------------- void Os2SalInstance::DestroyPrinter( SalPrinter* pPrinter ) { delete pPrinter; } // ======================================================================= Os2SalPrinter::Os2SalPrinter() { mhDC = 0; mhPS = 0; mpGraphics = NULL; mbAbort = FALSE; mbPrintDJPSupported = FALSE; } // ----------------------------------------------------------------------- Os2SalPrinter::~Os2SalPrinter() { } // ----------------------------------------------------------------------- sal_Bool Os2SalPrinter::StartJob( const XubString* pFileName, const XubString& rJobName, const XubString& rAppName, ULONG nCopies, bool bCollate, bool bDirect, ImplJobSetup* pSetupData ) { DEVOPENSTRUC aDevOpenStruc; LONG lType; APIRET rc; // prepare queue information memset( &aDevOpenStruc, 0, sizeof( aDevOpenStruc ) ); aDevOpenStruc.pszDriverName = (PSZ)(mpInfoPrinter->maDriverName.GetBuffer()); // print into file? if ( pFileName ) { aDevOpenStruc.pszLogAddress = (PSZ)pFileName->GetBuffer(); aDevOpenStruc.pszDataType = "PM_Q_RAW"; lType = OD_DIRECT; } else { aDevOpenStruc.pszLogAddress = (PSZ)(mpInfoPrinter->maName.GetBuffer()); 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 using application name ByteString appName( rAppName, gsl_getSystemTextEncoding()); aDevOpenStruc.pszComment = (PSZ)appName.GetBuffer(); // Kopien if ( nCopies > 1 ) { // OS2 kann maximal 999 Kopien if ( nCopies > 999 ) nCopies = 999; sprintf( maCopyBuf, "COP=%d", nCopies); aDevOpenStruc.pszQueueProcParams = (PSZ)maCopyBuf; } // open device context SalData* pSalData = GetSalData(); HAB hAB = pSalData->mhAB; aDevOpenStruc.pdriv = (PDRIVDATA)pSetupData->mpDriverData; mhDC = DevOpenDC( hAB, lType, "*", 7, (PDEVOPENDATA)&aDevOpenStruc, 0 ); if ( mhDC == 0 ) { ERRORID nLastError = WinGetLastError( hAB ); if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT ) mnError = SAL_PRINTER_ERROR_ABORT; else mnError = SAL_PRINTER_ERROR_GENERALERROR; return FALSE; } // open presentation space SIZEL sizel; sizel.cx = 0; sizel.cy = 0; mhPS = Ft2CreatePS( hAB, mhDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS ); if ( !mhPS ) { DevCloseDC( mhDC ); mnError = SAL_PRINTER_ERROR_GENERALERROR; return NULL; } // Can we print with DJP mbPrintDJPSupported = ImplIsDriverPrintDJPEnabled( mhDC ); #if OSL_DEBUG_LEVEL>0 debug_printf( "mbPrintDJPSupported %d", mbPrintDJPSupported); #endif // JobName ermitteln und Job starten ByteString jobName( rJobName, gsl_getSystemTextEncoding()); PSZ pszJobName = NULL; int nJobNameLen = 0; if ( jobName.Len() > 0 ) { pszJobName = (PSZ)jobName.GetBuffer(); nJobNameLen = jobName.Len(); } rc = DevEscape( mhDC, mbPrintDJPSupported ? DEVESC_STARTDOC_WPROP : DEVESC_STARTDOC, nJobNameLen, (PBYTE)pszJobName, &((PDRIVDATA)(pSetupData->mpDriverData))->cb, (PBYTE)(pSetupData->mpDriverData)); if ( rc != DEV_OK ) { ERRORID nLastError = WinGetLastError( hAB ); if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT ) mnError = SAL_PRINTER_ERROR_ABORT; else mnError = SAL_PRINTER_ERROR_GENERALERROR; Ft2Associate( mhPS, NULL ); Ft2DestroyPS( mhPS ); DevCloseDC( mhDC ); return FALSE; } // init for first page mbFirstPage = TRUE; mnError = 0; return TRUE; } // ----------------------------------------------------------------------- sal_Bool Os2SalPrinter::EndJob() { APIRET rc; rc = DevEscape( mhDC, DEVESC_ENDDOC, 0, NULL, 0, NULL); // destroy presentation space and device context Ft2Associate( mhPS, NULL ); Ft2DestroyPS( mhPS ); DevCloseDC( mhDC ); return TRUE; } // ----------------------------------------------------------------------- sal_Bool Os2SalPrinter::AbortJob() { APIRET rc; rc = DevEscape( mhDC, DEVESC_ABORTDOC, 0, NULL, 0, NULL ); // destroy SalGraphics if ( mpGraphics ) { ImplSalDeInitGraphics( mpGraphics ); delete mpGraphics; mpGraphics = NULL; } // destroy presentation space and device context Ft2Associate( mhPS, NULL ); Ft2DestroyPS( mhPS ); DevCloseDC( mhDC ); return TRUE; } // ----------------------------------------------------------------------- SalGraphics* Os2SalPrinter::StartPage( ImplJobSetup* pSetupData, sal_Bool bNewJobSetup ) { APIRET rc; #if OSL_DEBUG_LEVEL>0 debug_printf( "Os2SalPrinter::StartPage mhDC %x, mbFirstPage %d, bNewJobSetup %d", mhDC, mbFirstPage, bNewJobSetup); debug_printf( "Os2SalPrinter::StartPage pSetupData %x", pSetupData); #endif if ( mbFirstPage ) mbFirstPage = FALSE; else { PBYTE pJobData; LONG nJobDataSize; LONG nEscape; if ( 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( mhDC, nEscape, 0, NULL, &nJobDataSize, pJobData ); if ( rc != DEV_OK ) { DevEscape( mhDC, DEVESC_ENDDOC, 0, NULL, 0, NULL); Ft2Associate( mhPS, NULL ); Ft2DestroyPS( mhPS ); DevCloseDC( mhDC ); mnError = SAL_PRINTER_ERROR_GENERALERROR; return NULL; } } // create SalGraphics with copy of hPS Os2SalGraphics* pGraphics = new Os2SalGraphics; pGraphics->mhDC = mhDC; pGraphics->mhPS = mhPS; pGraphics->mhWnd = 0; pGraphics->mbPrinter = TRUE; pGraphics->mbVirDev = FALSE; pGraphics->mbWindow = FALSE; pGraphics->mbScreen = FALSE; pGraphics->mnHeight = 0; // search current form for actual page height HCINFO aInfo; int nForms = DevQueryHardcopyCaps( mhDC, 0, 0, &aInfo ); for( int i = 0; i < nForms; i++ ) { if ( DevQueryHardcopyCaps( mhDC, i, 1, &aInfo ) >= 0 ) { if ( aInfo.flAttributes & HCAPS_CURRENT ) pGraphics->mnHeight = aInfo.yPels; } } // use device caps if no form selected/found if ( !pGraphics->mnHeight ) DevQueryCaps( mhDC, CAPS_HEIGHT, 1L, &pGraphics->mnHeight ); ImplSalInitGraphics( pGraphics ); mpGraphics = pGraphics; return pGraphics; } // ----------------------------------------------------------------------- sal_Bool Os2SalPrinter::EndPage() { #if OSL_DEBUG_LEVEL>0 debug_printf( "Os2SalPrinter::EndPage mhDC %x", mhDC); #endif if ( mpGraphics ) { // destroy SalGraphics ImplSalDeInitGraphics( mpGraphics ); delete mpGraphics; mpGraphics = NULL; } return TRUE; } // ----------------------------------------------------------------------- ULONG Os2SalPrinter::GetErrorCode() { return mnError; }