Back to index

scribus-ng  1.3.4.dfsg+svn20071115
printerutil.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 #include "printerutil.h"
00008 #include "scconfig.h"
00009 
00010 #if defined( HAVE_CUPS )
00011  #include <cups/cups.h>
00012 #elif defined(_WIN32)
00013  #include <windows.h>
00014  #include <winspool.h>
00015 #endif
00016 
00017 #include <qstringlist.h>
00018 #include "util.h"
00019 #include "scribus.h"
00020 #include "scribuscore.h"
00021 
00022 QStringList PrinterUtil::getPrinterNames()
00023 {
00024        QString printerName;
00025        QStringList printerNames;
00026 #if defined (HAVE_CUPS)
00027        cups_dest_t *dests;
00028        int num_dests = cupsGetDests(&dests);
00029        for (int pr = 0; pr < num_dests; ++pr)
00030        {
00031               printerName = QString(dests[pr].name);
00032               printerNames.append(printerName);
00033        }
00034        cupsFreeDests(num_dests, dests);
00035 #elif defined(_WIN32)
00036        DWORD size;
00037        DWORD numPrinters;
00038        PRINTER_INFO_2* printerInfos = NULL;
00039     EnumPrinters ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &size, &numPrinters );
00040        printerInfos = (PRINTER_INFO_2*) malloc(size);
00041        if ( EnumPrinters ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) printerInfos, size, &size, &numPrinters ) )
00042        {
00043               for ( uint i = 0; i < numPrinters; i++)
00044               {
00045                      printerName = printerInfos[i].pPrinterName;
00046                      printerNames.append(printerName);
00047               }
00048               printerNames.sort(); 
00049        }
00050        if ( printerInfos) free(printerInfos);
00051 #else
00052        QString tmp;
00053        QString Pcap;
00054        QStringList wt;
00055        if (loadText("/etc/printcap", &Pcap))
00056        {
00057               QTextStream ts(&Pcap, IO_ReadOnly);
00058               while(!ts.atEnd())
00059               {
00060                      tmp = ts.readLine();
00061                      if (tmp.isEmpty())
00062                             continue;
00063                      if ((tmp[0] != '#') && (tmp[0] != ' ') && (tmp[0] != '\n') && (tmp[0] != '\t'))
00064                      {
00065                             tmp = tmp.stripWhiteSpace();
00066                             tmp = tmp.left(tmp.length() - (tmp.right(2) == ":\\" ? 2 : 1));
00067                             wt = QStringList::split("|", tmp);
00068                             printerName = wt[0];
00069                             printerNames.append(printerName);
00070                      }
00071               }
00072        }
00073 #endif
00074        return printerNames;
00075 }
00076 
00077 #if defined(_WIN32)
00078 bool PrinterUtil::getDefaultSettings( QString printerName, QByteArray& devModeA )
00079 {
00080        bool done;
00081        uint size;
00082        QCString printer;
00083        LONG result = IDOK+1;
00084        HANDLE handle = NULL;
00085        printer = printerName.local8Bit();
00086        // Get the printer handle
00087        done = OpenPrinter( printer.data(), &handle, NULL );
00088        if(!done)
00089               return false;
00090        // Get size of DEVMODE structure (public + private data)
00091        size = DocumentProperties( ScCore->primaryMainWindow()->winId(), handle, printer.data(), NULL, NULL, 0);
00092        // Allocate the memory needed by the DEVMODE structure
00093        devModeA.resize( size );
00094        // Retrieve printer default settings
00095        result = DocumentProperties( ScCore->primaryMainWindow()->winId(), handle, printer.data(), (DEVMODE*) devModeA.data(), NULL, DM_OUT_BUFFER);
00096        // Free the printer handle
00097        ClosePrinter( handle );
00098        return ( result == IDOK );
00099 }
00100 #endif
00101 
00102 #if defined(_WIN32)
00103 bool PrinterUtil::initDeviceSettings( QString printerName, QByteArray& devModeA )
00104 {
00105        bool done;
00106        uint size;
00107        QCString printer;
00108        LONG result = IDOK+1;
00109        HANDLE handle = NULL;
00110        printer = printerName.local8Bit();
00111        // Get the printer handle
00112        done = OpenPrinter( printer.data(), &handle, NULL );
00113        if(!done)
00114               return false;
00115        // Get size of DEVMODE structure (public + private data)
00116        size = DocumentProperties( ScCore->primaryMainWindow()->winId(), handle, printer.data(), NULL, NULL, 0);
00117        // Compare size with DevMode structure size
00118        if( devModeA.size() == size )
00119        {
00120               // Merge printer settings
00121               result = DocumentProperties( ScCore->primaryMainWindow()->winId(), handle, printer.data(), (DEVMODE*) devModeA.data(), (DEVMODE*) devModeA.data(), DM_IN_BUFFER | DM_OUT_BUFFER);
00122        }
00123        else
00124        {
00125               // Retrieve default settings
00126               devModeA.resize( size );
00127               result = DocumentProperties( ScCore->primaryMainWindow()->winId(), handle, printer.data(), (DEVMODE*) devModeA.data(), NULL, DM_OUT_BUFFER);
00128        }
00129        done = ( result == IDOK);
00130        // Free the printer handle
00131        ClosePrinter( handle );
00132        return done;
00133 }
00134 #endif
00135 
00136 bool PrinterUtil::getPrinterMarginValues(const QString& printerName, const QString& pageSize, double& ptsTopMargin, double& ptsBottomMargin, double& ptsLeftMargin, double& ptsRightMargin)
00137 {
00138        bool retVal=false;
00139 #if defined(HAVE_CUPS)
00140        const char *filename; // tmp PPD filename
00141        filename=cupsGetPPD(printerName);
00142        if (filename!=NULL)
00143        {
00144               ppd_file_t *ppd; // PPD data
00145               ppd = ppdOpenFile(filename);
00146               if (ppd!=NULL)
00147               {
00148                      ppd_size_t *size; // page size data, null if printer doesnt support selected size
00149                      size = ppdPageSize(ppd, pageSize);
00150                      if (size!=NULL)
00151                      {
00152                             //Store in pts for returning via getNewPrinterMargins in pts
00153                             retVal=true;
00154                             ptsTopMargin=size->length-size->top;
00155                             ptsBottomMargin=size->bottom;
00156                             ptsLeftMargin=size->left;
00157                             ptsRightMargin=size->width-size->right;
00158                      }
00159                      ppdClose(ppd);
00160               }
00161        }
00162 #elif defined(_WIN32)
00163        DWORD nPaper;
00164        DWORD nPaperNames;
00165        QCString printer;
00166        typedef char char64[64];
00167        printer = printerName.local8Bit();
00168        nPaper = DeviceCapabilities( printerName.data(), NULL, DC_PAPERS, NULL, NULL );
00169        nPaperNames = DeviceCapabilities( printerName.data(), NULL, DC_PAPERNAMES, NULL, NULL );
00170        if ( (nPaper > 0) && (nPaperNames > 0) && (nPaper == nPaperNames) )
00171        {
00172               int paperIndex = -1;
00173               DWORD *papers = new DWORD[nPaper];
00174               char64 *paperNames = new char64[nPaperNames];
00175               DWORD s1 = DeviceCapabilities( printerName.data(), NULL, DC_PAPERS, (LPSTR) papers, NULL );
00176               DWORD s2 = DeviceCapabilities( printerName.data(), NULL, DC_PAPERNAMES, (LPSTR) paperNames, NULL );
00177               for ( uint i = 0; i < nPaperNames; i++ )
00178               {
00179                      if ( pageSize == QString(paperNames[i]) )
00180                      {
00181                             paperIndex = i;
00182                             break;
00183                      }
00184               }
00185               if ( paperIndex >= 0 )
00186               {
00187                      HANDLE handle = NULL;
00188                      if( OpenPrinter( printer.data(), &handle, NULL ) )
00189                      {
00190                             // Retrieve DEVMODE structure for selected device
00191                             uint size = DocumentProperties( ScCore->primaryMainWindow()->winId(), handle, printer.data(), NULL, NULL, 0);
00192                             QByteArray devModeA(size);
00193                             DEVMODE* devMode = (DEVMODE*) devModeA.data();
00194                             DocumentProperties( ScCore->primaryMainWindow()->winId(), handle, printer.data(), devMode, NULL, DM_OUT_BUFFER);
00195                             ClosePrinter( handle );
00196                             // Set paper size
00197                             devMode->dmPaperSize = papers[paperIndex];
00198                             // Create device context
00199                             HDC printerDC = CreateDC( NULL, printer.data(), NULL, devMode );
00200                             if( printerDC )
00201                             {
00202                                    retVal = true;
00203                                    int logPixelsX = GetDeviceCaps( printerDC, LOGPIXELSX );
00204                                    int logPixelsY = GetDeviceCaps( printerDC, LOGPIXELSY );
00205                                    int physicalOffsetX = GetDeviceCaps( printerDC, PHYSICALOFFSETX );
00206                                    int physicalOffsetY = GetDeviceCaps( printerDC, PHYSICALOFFSETY );
00207                                    ptsLeftMargin = ptsRightMargin = ( physicalOffsetX / (double) logPixelsX * 72 );
00208                                    ptsTopMargin = ptsBottomMargin = ( physicalOffsetY / (double) logPixelsY * 72 );
00209                                    DeleteDC(printerDC);
00210                             }
00211                      }
00212               }
00213               delete[] papers;
00214               delete[] paperNames;
00215        }
00216 #endif
00217        return retVal;
00218 }
00219 
00220 //Parameter needed on win32..
00221 bool PrinterUtil::isPostscriptPrinter( QString printerName)
00222 {
00223 #ifdef _WIN32
00224        HDC dc;
00225        int    escapeCode;
00226        char technology[MAX_PATH] = {0};
00227        QCString printer = printerName.local8Bit();
00228        
00229        // Create the default device context
00230        dc = CreateDC( NULL, printer.data(), NULL, NULL );
00231        if ( !dc )
00232        {
00233               qWarning( QString("isPostscriptPrinter() failed to create device context for %1").arg(printerName) );
00234               return false;
00235        }
00236        // test if printer support the POSTSCRIPT_PASSTHROUGH escape code
00237        escapeCode = POSTSCRIPT_PASSTHROUGH;
00238        if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 )
00239        {
00240               DeleteDC( dc );
00241               return true;
00242        }
00243        // test if printer support the POSTSCRIPT_DATA escape code
00244        escapeCode = POSTSCRIPT_DATA;
00245        if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 )
00246        {
00247               DeleteDC( dc );
00248               return true;
00249        }
00250        // try to get postscript support by testing the printer technology
00251        escapeCode = GETTECHNOLOGY;
00252        if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 )
00253        {
00254               // if GETTECHNOLOGY is supported, then ... get technology
00255               if ( ExtEscape( dc, GETTECHNOLOGY, 0, NULL, MAX_PATH, (LPSTR) technology ) > 0 )
00256               {
00257                      // check technology string for postscript word
00258                      strupr( technology );
00259                      if ( strstr( technology, "POSTSCRIPT" ) )
00260                      {
00261                             DeleteDC( dc );
00262                             return true;
00263                      }
00264               }
00265        }
00266        DeleteDC( dc );
00267        return false;
00268 #else
00269        return true;
00270 #endif
00271 }