summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2015-02-26 15:56:24 +0100
committerLuboš Luňák <l.lunak@collabora.com>2015-02-27 00:18:29 +0100
commit7012d882fe7b8a4ea2104cbcf81cb019bd54efe9 (patch)
tree0b8cdcc64fad9fa20b8b8546c4c4414effa2f8b0 /vcl
parenta3dae6b5b63687ed1dfde476dc826f1f3eff23ab (diff)
support fast MM printing in non-single-file mode only for CUPS private/llunak/mailmerge_02
As said in the comment, the non-single-file mode could create way too many print jobs, so enable this only for the CUPS backend, which has been modified to send them as a single batch. Change-Id: I4c02ca0e8b91323b1d02f004c7b4813433064a11
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/cupsmgr.hxx23
-rw-r--r--vcl/unx/generic/printer/cupsmgr.cxx113
-rw-r--r--vcl/unx/generic/printer/jobdata.cxx18
-rw-r--r--vcl/unx/generic/printer/printerinfomanager.cxx15
4 files changed, 149 insertions, 20 deletions
diff --git a/vcl/inc/cupsmgr.hxx b/vcl/inc/cupsmgr.hxx
index 9a84b7790889..79c1ae70501b 100644
--- a/vcl/inc/cupsmgr.hxx
+++ b/vcl/inc/cupsmgr.hxx
@@ -58,6 +58,22 @@ class CUPSManager : public PrinterInfoManager
osl::Mutex m_aGetPPDMutex;
bool m_bPPDThreadRunning;
+ struct PendingJob
+ {
+ OUString printerName;
+ OUString jobTitle;
+ JobData jobData;
+ bool banner;
+ OString file;
+ PendingJob( const OUString& printerName_, const OUString& jobTitle_, const JobData& jobData_,
+ bool banner_, const OString& file_ )
+ : printerName( printerName_ ), jobTitle( jobTitle_ ), jobData( jobData_ ), banner( banner_ ), file( file_ )
+ {}
+ PendingJob() : banner( false ) {}
+ };
+ std::list< PendingJob > pendingJobs;
+ bool batchMode;
+
CUPSManager();
virtual ~CUPSManager();
@@ -66,6 +82,9 @@ class CUPSManager : public PrinterInfoManager
void getOptionsFromDocumentSetup( const JobData& rJob, bool bBanner, int& rNumOptions, void** rOptions ) const;
void runDests();
OString threadedCupsGetPPD(const char* pPrinter);
+
+ bool processPendingJobs();
+ bool printJobs( const PendingJob& job, const std::vector< OString >& files );
public:
// public for stub
static void runDestThread(void* pMgr);
@@ -81,6 +100,10 @@ public:
virtual int endSpool( const OUString& rPrinterName, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner );
virtual void setupJobContextData( JobData& rData );
+ virtual bool startBatchPrint() SAL_OVERRIDE;
+ virtual bool flushBatchPrint() SAL_OVERRIDE;
+ virtual bool supportsBatchPrint() const SAL_OVERRIDE;
+
// changes the info about a named printer
virtual void changePrinterInfo( const OUString& rPrinter, const PrinterInfo& rNewInfo );
diff --git a/vcl/unx/generic/printer/cupsmgr.cxx b/vcl/unx/generic/printer/cupsmgr.cxx
index 6b06596df614..5169d29199a4 100644
--- a/vcl/unx/generic/printer/cupsmgr.cxx
+++ b/vcl/unx/generic/printer/cupsmgr.cxx
@@ -646,8 +646,6 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit
rDocumentJobData.m_nCopies
);
- int nJobID = 0;
-
osl::MutexGuard aGuard( m_aCUPSMutex );
boost::unordered_map< OUString, int, OUStringHash >::iterator dest_it =
@@ -659,25 +657,98 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit
}
boost::unordered_map< FILE*, OString, FPtrHash >::const_iterator it = m_aSpoolFiles.find( pFile );
- if( it != m_aSpoolFiles.end() )
+ if( it == m_aSpoolFiles.end() )
+ return false;
+ fclose( pFile );
+ PendingJob job( rPrintername, rJobTitle, rDocumentJobData, bBanner, it->second );
+ m_aSpoolFiles.erase( pFile );
+ pendingJobs.push_back( job );
+ if( !batchMode ) // process immediately, otherwise will be handled by flushBatchPrint()
+ return processPendingJobs();
+ return true;
+}
+
+bool CUPSManager::startBatchPrint()
+{
+ batchMode = true;
+ return true;
+}
+
+bool CUPSManager::supportsBatchPrint() const
+{
+ return true;
+}
+
+bool CUPSManager::flushBatchPrint()
+{
+ osl::MutexGuard aGuard( m_aCUPSMutex );
+ return processPendingJobs();
+}
+
+bool CUPSManager::processPendingJobs()
+{
+ // Print all jobs that have the same data using one CUPS call (i.e. merge all jobs that differ only in files to print).
+ PendingJob currentJobData;
+ bool first = true;
+ std::vector< OString > files;
+ bool ok = true;
+ while( !pendingJobs.empty())
+ {
+ if( first )
+ {
+ currentJobData = pendingJobs.front();
+ first = false;
+ }
+ else if( currentJobData.printerName != pendingJobs.front().printerName
+ || currentJobData.jobTitle != pendingJobs.front().jobTitle
+ || currentJobData.jobData != pendingJobs.front().jobData
+ || currentJobData.banner != pendingJobs.front().banner )
+ {
+ if( !printJobs( currentJobData, files ))
+ ok = false;
+ files.clear();
+ currentJobData = pendingJobs.front();
+ }
+ files.push_back( pendingJobs.front().file );
+ pendingJobs.pop_front();
+ }
+ if( !first )
{
- fclose( pFile );
- rtl_TextEncoding aEnc = osl_getThreadTextEncoding();
+ if( !printJobs( currentJobData, files )) // print the last batch
+ ok = false;
+ }
+ return ok;
+}
- // setup cups options
- int nNumOptions = 0;
- cups_option_t* pOptions = NULL;
- getOptionsFromDocumentSetup( rDocumentJobData, bBanner, nNumOptions, (void**)&pOptions );
+bool CUPSManager::printJobs( const PendingJob& job, const std::vector< OString >& files )
+{
+ boost::unordered_map< OUString, int, OUStringHash >::iterator dest_it =
+ m_aCUPSDestMap.find( job.printerName );
+
+ rtl_TextEncoding aEnc = osl_getThreadTextEncoding();
+
+ // setup cups options
+ int nNumOptions = 0;
+ cups_option_t* pOptions = NULL;
+ getOptionsFromDocumentSetup( job.jobData, job.banner, nNumOptions, reinterpret_cast<void**>(&pOptions) );
+
+ cups_dest_t* pDest = ((cups_dest_t*)m_pDests) + dest_it->second;
- cups_dest_t* pDest = ((cups_dest_t*)m_pDests) + dest_it->second;
- nJobID = cupsPrintFile( pDest->name,
- it->second.getStr(),
- OUStringToOString( rJobTitle, aEnc ).getStr(),
- nNumOptions, pOptions );
+ std::vector< const char* > fnames;
+ for( std::vector< OString >::const_iterator it = files.begin();
+ it != files.end();
+ ++it )
+ fnames.push_back( it->getStr());
+
+ int nJobID = cupsPrintFiles(pDest->name,
+ fnames.size(),
+ fnames.data(),
+ OUStringToOString( job.jobTitle, aEnc ).getStr(),
+ nNumOptions, pOptions);
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "cupsPrintFile( %s, %s, %s, %d, %p ) returns %d\n",
pDest->name,
- it->second.getStr(),
+ ( fnames.size() == 1 ? files.front() : OString::number( fnames.size()) ).getStr(),
OUStringToOString( rJobTitle, aEnc ).getStr(),
nNumOptions,
pOptions,
@@ -691,11 +762,13 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit
system( aCmd.getStr() );
#endif
- unlink( it->second.getStr() );
- m_aSpoolFiles.erase( pFile );
- if( pOptions )
- cupsFreeOptions( nNumOptions, pOptions );
- }
+ for( std::vector< OString >::const_iterator it = files.begin();
+ it != files.end();
+ ++it )
+ unlink( it->getStr());
+
+ if( pOptions )
+ cupsFreeOptions( nNumOptions, pOptions );
return nJobID;
}
diff --git a/vcl/unx/generic/printer/jobdata.cxx b/vcl/unx/generic/printer/jobdata.cxx
index d40fffd913a7..16adb96b4b90 100644
--- a/vcl/unx/generic/printer/jobdata.cxx
+++ b/vcl/unx/generic/printer/jobdata.cxx
@@ -52,6 +52,24 @@ JobData& JobData::operator=(const JobData& rRight)
return *this;
}
+bool psp::operator==(const psp::JobData& rLeft, const psp::JobData& rRight)
+{
+ return rLeft.m_nCopies == rRight.m_nCopies
+// && rLeft.m_bCollate == rRight.m_bCollate
+ && rLeft.m_nLeftMarginAdjust == rRight.m_nLeftMarginAdjust
+ && rLeft.m_nRightMarginAdjust == rRight.m_nRightMarginAdjust
+ && rLeft.m_nTopMarginAdjust == rRight.m_nTopMarginAdjust
+ && rLeft.m_nBottomMarginAdjust == rRight.m_nBottomMarginAdjust
+ && rLeft.m_nColorDepth == rRight.m_nColorDepth
+ && rLeft.m_eOrientation == rRight.m_eOrientation
+ && rLeft.m_aPrinterName == rRight.m_aPrinterName
+ && rLeft.m_pParser == rRight.m_pParser
+// && rLeft.m_aContext == rRight.m_aContext
+ && rLeft.m_nPSLevel == rRight.m_nPSLevel
+ && rLeft.m_nPDFDevice == rRight.m_nPDFDevice
+ && rLeft.m_nColorDevice == rRight.m_nColorDevice;
+}
+
void JobData::setCollate( bool bCollate )
{
const PPDParser* pParser = m_aContext.getParser();
diff --git a/vcl/unx/generic/printer/printerinfomanager.cxx b/vcl/unx/generic/printer/printerinfomanager.cxx
index 7def80fd5564..b895f8208f98 100644
--- a/vcl/unx/generic/printer/printerinfomanager.cxx
+++ b/vcl/unx/generic/printer/printerinfomanager.cxx
@@ -1180,6 +1180,21 @@ void PrinterInfoManager::setDefaultPaper( PPDContext& rContext ) const
// -----------------------------------------------------------------
+bool PrinterInfoManager::startBatchPrint()
+{
+ return false; // not implemented
+}
+
+bool PrinterInfoManager::supportsBatchPrint() const
+{
+ return false;
+}
+
+bool PrinterInfoManager::flushBatchPrint()
+{
+ return false;
+}
+
SystemQueueInfo::SystemQueueInfo() :
m_bChanged( false )
{