/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
void executeCall()
{ // This CUPS method is not at all thread-safe we need // to dup the pointer to a static buffer it returns ASAP
SAL_WNODEPRECATED_DECLARATIONS_PUSH constchar* pResult = cupsGetPPD(m_aParameter.getStr());
OString aResult = pResult ? OString(pResult) : OString();
SAL_WNODEPRECATED_DECLARATIONS_POP
MutexGuard aGuard( *m_pSyncMutex );
m_aResult = std::move(aResult);
m_aCondition.set();
unref();
}
// n#722902 - do a fast-failing check for cups working *at all* first
http_t* p_http;
SAL_WNODEPRECATED_DECLARATIONS_PUSH if( (p_http=httpConnectEncrypt(
cupsServer(),
ippPort(),
cupsEncryption())) == nullptr ) return;
int nDests = cupsGetDests2(p_http, &pDests);
SAL_INFO("vcl.unx.print", "came out of cupsGetDests");
staticvoid SetIfCustomOption(const PPDContext& rContext, const cups_option_t& rOption, rtl_TextEncoding aEncoding)
{ if (strncmp(rOption.value, RTL_CONSTASCII_STRINGPARAM("Custom.")) == 0)
{ const PPDParser* pParser = rContext.getParser(); if (!pParser)
{ // normal for first sight of this printer return;
}
const PPDValue* pCustomValue = rContext.getValue(pKey); if (!pCustomValue)
{
SAL_WARN("vcl.unx.print", "Value for " << rOption.name << " not found"); return;
}
if (!pCustomValue->m_bCustomOption)
{
SAL_WARN("vcl.unx.print", "Value for " << rOption.name << " not set to custom option"); return;
}
// seems sensible to keep a value the user explicitly set even if lpoptions was used to set // another default if (pCustomValue->m_bCustomOptionSetViaApp) return;
pCustomValue->m_aCustomOption = OStringToOUString(rOption.value, aEncoding);
}
}
void CUPSManager::initialize()
{ // get normal printers, clear printer list
PrinterInfoManager::initialize();
// check whether thread has completed // if not behave like old printing system
osl::MutexGuard aGuard( m_aCUPSMutex );
if( ! m_bNewDests ) return;
// dest thread has run, clean up if( m_aDestThread )
{
osl_joinWithThread( m_aDestThread );
osl_destroyThread( m_aDestThread );
m_aDestThread = nullptr;
}
m_bNewDests = false;
// clear old stuff
m_aCUPSDestMap.clear();
if( ! (m_nDests && m_pDests ) ) return;
// check for CUPS server(?) > 1.2 // since there is no API to query, check for options that were // introduced in dests with 1.2 // this is needed to check for %%IncludeFeature support // (#i65684#, #i65491#)
cups_dest_t* pDest = m_pDests;
rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); int nPrinter = m_nDests;
// reset global default PPD options; these are queried on demand from CUPS
m_aGlobalDefaults.m_pParser = nullptr;
m_aGlobalDefaults.m_aContext = PPDContext();
// add CUPS printers, should there be a printer // with the same name as a CUPS printer, overwrite it while( nPrinter-- )
{
pDest = m_pDests+nPrinter;
OUString aPrinterName = OStringToOUString( pDest->name, aEncoding ); if( pDest->instance && *pDest->instance )
{
aPrinterName += "/" +
OStringToOUString( pDest->instance, aEncoding );
}
// note: the parser that goes with the PrinterInfo // is created implicitly by the JobData::operator=() // when it detects the NULL ptr m_pParser. // if we wanted to fill in the parser here this // would mean we'd have to download PPDs for each and // every printer - which would be really bad runtime // behaviour
aPrinter.m_aInfo.m_pParser = nullptr;
aPrinter.m_aInfo.m_aContext.setParser( nullptr );
std::unordered_map< OUString, PPDContext >::const_iterator c_it = m_aDefaultContexts.find( aPrinterName ); if( c_it != m_aDefaultContexts.end() )
{
aPrinter.m_aInfo.m_pParser = c_it->second.getParser();
aPrinter.m_aInfo.m_aContext = c_it->second;
}
aPrinter.m_aInfo.m_aDriverName = "CUPS:" + aPrinterName;
for( int k = 0; k < pDest->num_options; k++ )
{ if(!strcmp(pDest->options[k].name, "printer-info"))
aPrinter.m_aInfo.m_aComment=OStringToOUString(pDest->options[k].value, aEncoding); if(!strcmp(pDest->options[k].name, "printer-location"))
aPrinter.m_aInfo.m_aLocation=OStringToOUString(pDest->options[k].value, aEncoding); if(!strcmp(pDest->options[k].name, "auth-info-required"))
aPrinter.m_aInfo.m_aAuthInfoRequired=OStringToOUString(pDest->options[k].value, aEncoding); // tdf#149439 Update Custom values that may have changed if this is not a newly discovered printer
SetIfCustomOption(aPrinter.m_aInfo.m_aContext, pDest->options[k], aEncoding);
}
// remove everything that is not a CUPS printer and not // a special purpose printer (PDF, Fax)
std::unordered_map< OUString, Printer >::iterator it = m_aPrinters.begin(); while(it != m_aPrinters.end())
{ if( m_aCUPSDestMap.contains( it->first ) )
{
++it; continue;
}
// remember the default context for later use
PPDContext& rContext = m_aDefaultContexts[ aPrinter ];
rContext.setParser( pNewParser ); // set system default paper; printer CUPS PPD options // may overwrite it
setDefaultPaper( rContext ); for( int i = 0; i < pPPD->num_groups; i++ )
updatePrinterContextInfo( pPPD->groups + i, rContext );
// tdf#149439 Set Custom values. for (int k = 0; k < pDest->num_options; ++k)
SetIfCustomOption(rContext, pDest->options[k], aEncoding);
//fax4CUPS, "the job name will be dialled for you" //so override the jobname with the desired number if (!rFaxNumber.isEmpty())
{
sJobName = OUStringToOString(rFaxNumber, aEnc);
}
bool CUPSManager::checkPrintersChanged( bool bWait )
{ bool bChanged = false; if( bWait )
{ if( m_aDestThread )
{ // initial asynchronous detection still running
SAL_INFO("vcl.unx.print", "syncing cups discovery thread");
osl_joinWithThread( m_aDestThread );
osl_destroyThread( m_aDestThread );
m_aDestThread = nullptr;
SAL_INFO("vcl.unx.print", "done: syncing cups discovery thread");
} else
{ // #i82321# check for cups printer updates // with this change the whole asynchronous detection in a thread is // almost useless. The only relevance left is for some stalled systems // where the user can set SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION // (see vcl/unx/source/gdi/salprnpsp.cxx) // so that checkPrintersChanged( true ) will never be called
// there is no way to query CUPS whether the printer list has changed // so get the dest list anew if( m_nDests && m_pDests )
cupsFreeDests( m_nDests, m_pDests );
m_nDests = 0;
m_pDests = nullptr;
runDests();
}
} if( m_aCUPSMutex.tryToAcquire() )
{
bChanged = m_bNewDests;
m_aCUPSMutex.release();
}
if( ! bChanged )
{
bChanged = PrinterInfoManager::checkPrintersChanged( bWait ); // #i54375# ensure new merging with CUPS list in :initialize if( bChanged )
m_bNewDests = true;
}
if( bChanged )
initialize();
return bChanged;
}
constchar* CUPSManager::authenticateUser()
{ constchar* pRet = nullptr;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.