summaryrefslogtreecommitdiffstats
path: root/src/printsupport/kernel/qprintengine_pdf.cpp
diff options
context:
space:
mode:
authorRohan McGovern <rohan.mcgovern@nokia.com>2012-05-08 12:56:45 +1000
committerQt by Nokia <qt-info@nokia.com>2012-05-08 06:58:27 +0200
commitde11b9f5a7aaab79e816983a72b8e92ac84ce5d6 (patch)
treeaafbf1b22400bbaf90046b415490667164a2d93a /src/printsupport/kernel/qprintengine_pdf.cpp
parent80f7a388906f94f58bf765a32b9abbb16f967db2 (diff)
Revert "QtPrintSupport: Remove remaining LPR specific code"
This doesn't compile with a typical cross-compilation setup, which generally won't include cups headers. The commit should have been rejected, but wasn't, due to a bug in the Qt Project CI. Since it now causes all other modules depending on qtbase to fail their CI, it must be reverted to minimize disruption while the commit can be amended and/or the test toolchain updated to include cups headers. This reverts commit 80f7a388906f94f58bf765a32b9abbb16f967db2. Change-Id: I315ae275b37de358a74af28ab7bd691c9849acba Reviewed-by: Sergio Ahumada <sergio.ahumada@nokia.com> Reviewed-by: Toby Tomkins <toby.tomkins@nokia.com>
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
}