summaryrefslogtreecommitdiffstats
path: root/src/printsupport/kernel/qprintengine_pdf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/printsupport/kernel/qprintengine_pdf.cpp')
-rw-r--r--src/printsupport/kernel/qprintengine_pdf.cpp171
1 files changed, 156 insertions, 15 deletions
diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp
index a1690aadb3..9c2e209b9c 100644
--- a/src/printsupport/kernel/qprintengine_pdf.cpp
+++ b/src/printsupport/kernel/qprintengine_pdf.cpp
@@ -39,22 +39,20 @@
**
****************************************************************************/
-#include "qprintengine_pdf_p.h"
-
-#ifndef QT_NO_PRINTER
+#include <QtPrintSupport/qprintengine.h>
#include <qiodevice.h>
#include <qfile.h>
#include <qdebug.h>
#include <qbuffer.h>
-#if !defined(QT_NO_CUPS)
#include "private/qcups_p.h"
-#endif
#include "qprinterinfo.h"
+#ifndef QT_NO_PRINTER
#include <limits.h>
#include <math.h>
+#include "qprintengine_pdf_p.h"
#ifdef Q_OS_UNIX
#include "private/qcore_unix_p.h" // overrides QT_OPEN
@@ -98,7 +96,7 @@ QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m)
: QPdfEngine(*new QPdfPrintEnginePrivate(m))
{
Q_D(QPdfPrintEngine);
-#if !defined(QT_NO_CUPS)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
if (QCUPSSupport::isAvailable()) {
QCUPSSupport cups;
const cups_dest_t* printers = cups.availablePrinters();
@@ -111,8 +109,17 @@ QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m)
}
}
+ } else
+#endif
+ {
+ d->printerName = QString::fromLocal8Bit(qgetenv("PRINTER"));
+ if (d->printerName.isEmpty())
+ d->printerName = QString::fromLocal8Bit(qgetenv("LPDEST"));
+ if (d->printerName.isEmpty())
+ d->printerName = QString::fromLocal8Bit(qgetenv("NPRINTER"));
+ if (d->printerName.isEmpty())
+ d->printerName = QString::fromLocal8Bit(qgetenv("NGPRINTER"));
}
-#endif // QT_NO_CUPS
state = QPrinter::Idle;
}
@@ -271,19 +278,19 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
ret = d->copies;
break;
case PPK_SupportsMultipleCopies:
-#if !defined(QT_NO_CUPS)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
if (QCUPSSupport::isAvailable())
ret = true;
else
-#endif // QT_NO_CUPS
+#endif
ret = false;
break;
case PPK_NumberOfCopies:
-#if !defined(QT_NO_CUPS)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
if (QCUPSSupport::isAvailable())
ret = 1;
else
-#endif // QT_NO_CUPS
+#endif
ret = d->copies;
break;
case PPK_Orientation:
@@ -358,6 +365,28 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
}
+#ifndef QT_NO_LPR
+static void closeAllOpenFds()
+{
+ // hack time... getting the maximum number of open
+ // files, if possible. if not we assume it's the
+ // larger of 256 and the fd we got
+ int i;
+#if defined(_SC_OPEN_MAX)
+ i = (int)sysconf(_SC_OPEN_MAX);
+#elif defined(_POSIX_OPEN_MAX)
+ i = (int)_POSIX_OPEN_MAX;
+#elif defined(OPEN_MAX)
+ i = (int)OPEN_MAX;
+#else
+ i = 256;
+#endif
+ // leave stdin/out/err untouched
+ while(--i > 2)
+ QT_CLOSE(i);
+}
+#endif
+
bool QPdfPrintEnginePrivate::openPrintDevice()
{
if (outDevice)
@@ -370,7 +399,7 @@ bool QPdfPrintEnginePrivate::openPrintDevice()
return false;
}
outDevice = file;
-#if !defined(QT_NO_CUPS)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
} else if (QCUPSSupport::isAvailable()) {
QCUPSSupport cups;
QPair<int, QString> ret = cups.tempFd();
@@ -381,7 +410,119 @@ bool QPdfPrintEnginePrivate::openPrintDevice()
cupsTempFile = ret.second;
outDevice = new QFile();
static_cast<QFile *>(outDevice)->open(ret.first, QIODevice::WriteOnly);
-#endif // QT_NO_CUPS
+#endif
+#ifndef QT_NO_LPR
+ } else {
+ QString pr;
+ if (!printerName.isEmpty())
+ pr = printerName;
+ int fds[2];
+ if (qt_safe_pipe(fds) != 0) {
+ qWarning("QPdfPrinter: Could not open pipe to print");
+ return false;
+ }
+
+ pid_t pid = fork();
+ if (pid == 0) { // child process
+ // if possible, exit quickly, so the actual lp/lpr
+ // becomes a child of init, and ::waitpid() is
+ // guaranteed not to wait.
+ if (fork() > 0) {
+ closeAllOpenFds();
+
+ // try to replace this process with "true" - this prevents
+ // global destructors from being called (that could possibly
+ // do wrong things to the parent process)
+ (void)execlp("true", "true", (char *)0);
+ (void)execl("/bin/true", "true", (char *)0);
+ (void)execl("/usr/bin/true", "true", (char *)0);
+ ::_exit(0);
+ }
+ qt_safe_dup2(fds[0], 0, 0);
+
+ closeAllOpenFds();
+
+ if (!printProgram.isEmpty()) {
+ if (!selectionOption.isEmpty())
+ pr.prepend(selectionOption);
+ else
+ pr.prepend(QLatin1String("-P"));
+ (void)execlp(printProgram.toLocal8Bit().data(), printProgram.toLocal8Bit().data(),
+ pr.toLocal8Bit().data(), (char *)0);
+ } else {
+ // if no print program has been specified, be smart
+ // about the option string too.
+ QList<QByteArray> lprhack;
+ QList<QByteArray> lphack;
+ QByteArray media;
+ if (!pr.isEmpty() || !selectionOption.isEmpty()) {
+ if (!selectionOption.isEmpty()) {
+ QStringList list = selectionOption.split(QLatin1Char(' '));
+ for (int i = 0; i < list.size(); ++i)
+ lprhack.append(list.at(i).toLocal8Bit());
+ lphack = lprhack;
+ } else {
+ lprhack.append("-P");
+ lphack.append("-d");
+ }
+ lprhack.append(pr.toLocal8Bit());
+ lphack.append(pr.toLocal8Bit());
+ }
+ lphack.append("-s");
+
+ char ** lpargs = new char *[lphack.size()+6];
+ char lp[] = "lp";
+ lpargs[0] = lp;
+ int i;
+ for (i = 0; i < lphack.size(); ++i)
+ lpargs[i+1] = (char *)lphack.at(i).constData();
+#ifndef Q_OS_OSF
+ if (QPdf::paperSizeToString(printerPaperSize)) {
+ char dash_o[] = "-o";
+ lpargs[++i] = dash_o;
+ lpargs[++i] = const_cast<char *>(QPdf::paperSizeToString(printerPaperSize));
+ lpargs[++i] = dash_o;
+ media = "media=";
+ media += QPdf::paperSizeToString(printerPaperSize);
+ lpargs[++i] = media.data();
+ }
+#endif
+ lpargs[++i] = 0;
+ char **lprargs = new char *[lprhack.size()+2];
+ char lpr[] = "lpr";
+ lprargs[0] = lpr;
+ for (int i = 0; i < lprhack.size(); ++i)
+ lprargs[i+1] = (char *)lprhack[i].constData();
+ lprargs[lprhack.size() + 1] = 0;
+ (void)execvp("lp", lpargs);
+ (void)execvp("lpr", lprargs);
+ (void)execv("/bin/lp", lpargs);
+ (void)execv("/bin/lpr", lprargs);
+ (void)execv("/usr/bin/lp", lpargs);
+ (void)execv("/usr/bin/lpr", lprargs);
+
+ delete []lpargs;
+ delete []lprargs;
+ }
+ // if we couldn't exec anything, close the fd,
+ // wait for a second so the parent process (the
+ // child of the GUI process) has exited. then
+ // exit.
+ QT_CLOSE(0);
+ (void)::sleep(1);
+ ::_exit(0);
+ }
+ // parent process
+ QT_CLOSE(fds[0]);
+ fd = fds[1];
+ (void)qt_safe_waitpid(pid, 0, 0);
+
+ if (fd < 0)
+ return false;
+
+ outDevice = new QFile();
+ static_cast<QFile *>(outDevice)->open(fd, QIODevice::WriteOnly);
+#endif
}
return true;
@@ -402,7 +543,7 @@ void QPdfPrintEnginePrivate::closePrintDevice()
outDevice = 0;
}
-#if !defined(QT_NO_CUPS)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
if (!cupsTempFile.isEmpty()) {
QString tempFile = cupsTempFile;
cupsTempFile.clear();
@@ -479,7 +620,7 @@ void QPdfPrintEnginePrivate::closePrintDevice()
QFile::remove(tempFile);
}
-#endif // QT_NO_CUPS
+#endif
}