summaryrefslogtreecommitdiffstats
path: root/scribus/util_printer.cpp
diff options
context:
space:
mode:
authorcraig <craig@11d20701-8431-0410-a711-e3c959e3b870>2012-01-01 11:40:09 +0000
committercraig <craig@11d20701-8431-0410-a711-e3c959e3b870>2012-01-01 11:40:09 +0000
commit7ed83b6c6666eb8b6b104c211ae7e52907350372 (patch)
tree4430b556abac0ad660a0aacf1887d77f85d8be02 /scribus/util_printer.cpp
downloadscribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.gz
scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.xz
scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.zip
Branch 1.3.5 tree to 1.4.x tree, goodbye 1.3.x
git-svn-id: svn://scribus.net/branches/Version14x/Scribus@17163 11d20701-8431-0410-a711-e3c959e3b870
Diffstat (limited to 'scribus/util_printer.cpp')
-rw-r--r--scribus/util_printer.cpp318
1 files changed, 318 insertions, 0 deletions
diff --git a/scribus/util_printer.cpp b/scribus/util_printer.cpp
new file mode 100644
index 0000000..1b173cd
--- /dev/null
+++ b/scribus/util_printer.cpp
@@ -0,0 +1,318 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+#include "util_printer.h"
+#include "scconfig.h"
+
+#if defined( HAVE_CUPS )
+ #include <cups/cups.h>
+ #include <cups/ppd.h>
+#elif defined(_WIN32)
+ #include <windows.h>
+ #include <winspool.h>
+#endif
+
+#include <QStringList>
+#include <QDataStream>
+#include <QByteArray>
+#include "util.h"
+#include "commonstrings.h"
+#include "scribus.h"
+#include "scribuscore.h"
+
+QStringList PrinterUtil::getPrinterNames()
+{
+ QString printerName;
+ QStringList printerNames;
+#if defined (HAVE_CUPS)
+ cups_dest_t *dests;
+ int num_dests = cupsGetDests(&dests);
+ for (int pr = 0; pr < num_dests; ++pr)
+ {
+ printerName = QString(dests[pr].name);
+ printerNames.append(printerName);
+ }
+ cupsFreeDests(num_dests, dests);
+#elif defined(_WIN32)
+ DWORD size;
+ DWORD numPrinters;
+ PRINTER_INFO_2W* printerInfos = NULL;
+ EnumPrintersW ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &size, &numPrinters );
+ printerInfos = (PRINTER_INFO_2W*) malloc(size);
+ if ( EnumPrintersW ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) printerInfos, size, &size, &numPrinters ) )
+ {
+ for ( uint i = 0; i < numPrinters; i++)
+ {
+ printerName = QString::fromUtf16( (const ushort*) printerInfos[i].pPrinterName );
+ printerNames.append(printerName);
+ }
+ printerNames.sort();
+ }
+ if ( printerInfos) free(printerInfos);
+#else
+ QString tmp;
+ QString Pcap;
+ QStringList wt;
+ if (loadText("/etc/printcap", &Pcap))
+ {
+ QDataStream ts(&Pcap, QIODevice::ReadOnly);
+ while(!ts.atEnd())
+ {
+ tmp = readLinefromDataStream(ts);
+ if (tmp.isEmpty())
+ continue;
+ if ((tmp[0] != '#') && (tmp[0] != ' ') && (tmp[0] != '\n') && (tmp[0] != '\t'))
+ {
+ tmp = tmp.trimmed();
+ tmp = tmp.left(tmp.length() - (tmp.right(2) == ":\\" ? 2 : 1));
+ wt = tmp.split("|", QString::SkipEmptyParts);
+ printerName = wt[0];
+ printerNames.append(printerName);
+ }
+ }
+ }
+#endif
+ return printerNames;
+}
+
+#if defined(_WIN32)
+bool PrinterUtil::getDefaultSettings( QString printerName, QByteArray& devModeA )
+{
+ bool done;
+ uint size;
+ LONG result = IDOK+1;
+ Qt::HANDLE handle = NULL;
+ // Get the printer handle
+ done = OpenPrinterW( (LPWSTR) printerName.utf16(), &handle, NULL );
+ if(!done)
+ return false;
+ // Get size of DEVMODE structure (public + private data)
+ size = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), NULL, NULL, 0);
+ // Allocate the memory needed by the DEVMODE structure
+ devModeA.resize( size );
+ // Retrieve printer default settings
+ result = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), (DEVMODEW*) devModeA.data(), NULL, DM_OUT_BUFFER);
+ // Free the printer handle
+ ClosePrinter( handle );
+ return ( result == IDOK );
+}
+#endif
+
+#if defined(_WIN32)
+bool PrinterUtil::initDeviceSettings( QString printerName, QByteArray& devModeA )
+{
+ bool done;
+ uint size;
+ LONG result = IDOK+1;
+ Qt::HANDLE handle = NULL;
+ // Get the printer handle
+ done = OpenPrinterW( (LPWSTR) printerName.utf16(), &handle, NULL );
+ if(!done)
+ return false;
+ // Get size of DEVMODE structure (public + private data)
+ size = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), NULL, NULL, 0);
+ // Compare size with DevMode structure size
+ if( devModeA.size() == size )
+ {
+ // Merge printer settings
+ result = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), (DEVMODEW*) devModeA.data(), (DEVMODEW*) devModeA.data(), DM_IN_BUFFER | DM_OUT_BUFFER);
+ }
+ else
+ {
+ // Retrieve default settings
+ devModeA.resize( size );
+ result = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), (DEVMODEW*) devModeA.data(), NULL, DM_OUT_BUFFER);
+ }
+ done = ( result == IDOK);
+ // Free the printer handle
+ ClosePrinter( handle );
+ return done;
+}
+#endif
+
+bool PrinterUtil::getPrinterMarginValues(const QString& printerName, const QString& pageSize, double& ptsTopMargin, double& ptsBottomMargin, double& ptsLeftMargin, double& ptsRightMargin)
+{
+ bool retVal=false;
+#if defined(HAVE_CUPS)
+ const char *filename; // tmp PPD filename
+ filename=cupsGetPPD(printerName.toLocal8Bit().constData());
+ if (filename!=NULL)
+ {
+ ppd_file_t *ppd; // PPD data
+ ppd = ppdOpenFile(filename);
+ if (ppd!=NULL)
+ {
+ ppd_size_t *size; // page size data, null if printer doesnt support selected size
+ size = ppdPageSize(ppd, pageSize.toLocal8Bit().constData());
+ if (size!=NULL)
+ {
+ //Store in pts for returning via getNewPrinterMargins in pts
+ retVal=true;
+ ptsTopMargin=size->length-size->top;
+ ptsBottomMargin=size->bottom;
+ ptsLeftMargin=size->left;
+ ptsRightMargin=size->width-size->right;
+ }
+ ppdClose(ppd);
+ }
+ }
+#elif defined(_WIN32)
+ DWORD nPaper;
+ DWORD nPaperNames;
+ typedef WCHAR wchar64[64];
+ nPaper = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERS, NULL, NULL );
+ nPaperNames = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERNAMES, NULL, NULL );
+ if ( (nPaper > 0) && (nPaperNames > 0) && (nPaper == nPaperNames) )
+ {
+ int paperIndex = -1;
+ DWORD *papers = new DWORD[nPaper];
+ wchar64 *paperNames = new wchar64[nPaperNames];
+ DWORD s1 = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERS, (LPWSTR) papers, NULL );
+ DWORD s2 = DeviceCapabilitiesW( (LPCWSTR) printerName.utf16(), NULL, DC_PAPERNAMES, (LPWSTR) paperNames, NULL );
+ for ( uint i = 0; i < nPaperNames; i++ )
+ {
+ if ( pageSize == QString::fromUtf16((const ushort*) paperNames[i]) )
+ {
+ paperIndex = i;
+ break;
+ }
+ }
+ if ( paperIndex >= 0 )
+ {
+ Qt::HANDLE handle = NULL;
+ if( OpenPrinterW( (LPWSTR) printerName.utf16(), &handle, NULL ) )
+ {
+ // Retrieve DEVMODE structure for selected device
+ uint size = DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), NULL, NULL, 0);
+ QByteArray devModeW(size, 0);
+ DEVMODEW* devMode = (DEVMODEW*) devModeW.data();
+ DocumentPropertiesW( ScCore->primaryMainWindow()->winId(), handle, (LPWSTR) printerName.utf16(), devMode, NULL, DM_OUT_BUFFER);
+ ClosePrinter( handle );
+ // Set paper size
+ devMode->dmPaperSize = papers[paperIndex];
+ // Create device context
+ HDC printerDC = CreateDCW( NULL, (LPWSTR) printerName.utf16(), NULL, devMode );
+ if( printerDC )
+ {
+ retVal = true;
+ int logPixelsX = GetDeviceCaps( printerDC, LOGPIXELSX );
+ int logPixelsY = GetDeviceCaps( printerDC, LOGPIXELSY );
+ int physicalOffsetX = GetDeviceCaps( printerDC, PHYSICALOFFSETX );
+ int physicalOffsetY = GetDeviceCaps( printerDC, PHYSICALOFFSETY );
+ ptsLeftMargin = ptsRightMargin = ( physicalOffsetX / (double) logPixelsX * 72 );
+ ptsTopMargin = ptsBottomMargin = ( physicalOffsetY / (double) logPixelsY * 72 );
+ DeleteDC(printerDC);
+ }
+ }
+ }
+ delete[] papers;
+ delete[] paperNames;
+ }
+#endif
+ return retVal;
+}
+
+PrintEngine PrinterUtil::getDefaultPrintEngine(const QString& printerName, bool toFile)
+{
+ if(!toFile)
+ {
+#if defined(_WIN32)
+ return WindowsGDI;
+#else
+ return PostScript3;
+#endif
+ }
+ return PostScript3;
+}
+
+PrintEngineMap PrinterUtil::getPrintEngineSupport(const QString& printerName, bool toFile)
+{
+ PrintEngineMap prnMap;
+ if (toFile || PrinterUtil::isPostscriptPrinter(printerName))
+ {
+ if (ScCore->haveGS())
+ {
+ prnMap.insert(CommonStrings::trPostScript1, PostScript1);
+ prnMap.insert(CommonStrings::trPostScript2, PostScript2);
+ }
+ prnMap.insert(CommonStrings::trPostScript3, PostScript3);
+ }
+#if defined(_WIN32)
+ if (!toFile)
+ prnMap.insert(CommonStrings::trWindowsGDI, WindowsGDI);
+#endif
+ return prnMap;
+}
+
+bool PrinterUtil::checkPrintEngineSupport(const QString& printerName, PrintEngine engine, bool toFile)
+{
+ bool psSupported = toFile || PrinterUtil::isPostscriptPrinter(printerName);
+ if (psSupported && (engine >= PostScript1 && engine <= PostScript3))
+ return true;
+ else if (!psSupported && (engine >= PostScript1 && engine <= PostScript3))
+ return false;
+ else if (engine == WindowsGDI)
+ {
+#if defined(_WIN32)
+ return true; //WindowsGDI
+#else
+ return false;
+#endif
+ }
+ return false;
+}
+
+//Parameter needed on win32..
+bool PrinterUtil::isPostscriptPrinter( QString printerName)
+{
+#ifdef _WIN32
+ HDC dc;
+ int escapeCode;
+ char technology[MAX_PATH] = {0};
+
+ // Create the default device context
+ dc = CreateDCW( NULL, (LPCWSTR) printerName.utf16(), NULL, NULL );
+ if ( !dc )
+ {
+ qWarning("isPostscriptPrinter() failed to create device context for %s", printerName.toAscii().data());
+ return false;
+ }
+ // test if printer support the POSTSCRIPT_PASSTHROUGH escape code
+ escapeCode = POSTSCRIPT_PASSTHROUGH;
+ if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 )
+ {
+ DeleteDC( dc );
+ return true;
+ }
+ // test if printer support the POSTSCRIPT_DATA escape code
+ escapeCode = POSTSCRIPT_DATA;
+ if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 )
+ {
+ DeleteDC( dc );
+ return true;
+ }
+ // try to get postscript support by testing the printer technology
+ escapeCode = GETTECHNOLOGY;
+ if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 )
+ {
+ // if GETTECHNOLOGY is supported, then ... get technology
+ if ( ExtEscape( dc, GETTECHNOLOGY, 0, NULL, MAX_PATH, (LPSTR) technology ) > 0 )
+ {
+ // check technology string for postscript word
+ strupr( technology );
+ if ( strstr( technology, "POSTSCRIPT" ) )
+ {
+ DeleteDC( dc );
+ return true;
+ }
+ }
+ }
+ DeleteDC( dc );
+ return false;
+#else
+ return true;
+#endif
+}