diff options
Diffstat (limited to 'src/printsupport/kernel/qprintengine_pdf.cpp')
-rw-r--r-- | src/printsupport/kernel/qprintengine_pdf.cpp | 171 |
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 } |