Codebase list splix / upstream/2.0.0+svn308 src / printer.cpp
upstream/2.0.0+svn308

Tree @upstream/2.0.0+svn308 (Download .tar.gz)

printer.cpp @upstream/2.0.0+svn308

f5f6764
970703d
f5f6764
 
 
 
 
 
 
 
 
 
 
 
 
e6011e5
f5f6764
e6011e5
970703d
f5f6764
 
 
970703d
 
 
 
f5f6764
 
 
 
 
 
 
970703d
f5f6764
970703d
 
 
 
f5f6764
 
 
 
970703d
 
 
 
 
 
 
 
f5f6764
 
 
970703d
f5f6764
970703d
 
f5f6764
970703d
f5f6764
970703d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
030bc01
970703d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0b7f07c
970703d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0b7f07c
 
 
 
 
970703d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f5f6764
 
0b7f07c
 
 
 
f5f6764
970703d
 
 
 
 
 
 
 
 
0b7f07c
 
 
 
 
 
970703d
 
 
 
 
 
0b7f07c
 
 
970703d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0b7f07c
 
 
 
 
 
 
 
 
970703d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0b7f07c
 
 
 
 
970703d
 
 
 
 
f5f6764
970703d
 
 
 
f5f6764
970703d
f5f6764
 
970703d
f5f6764
/*
 * 	    printer.cpp               (C) 2006-2008, Aurélien Croc (AP²C)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the
 *  Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 *  $Id: printer.cpp 301 2012-02-29 14:11:09Z tillkamppeter $
 * 
 */
#include "printer.h"
#include <time.h>
#include <string.h>
#include "errlog.h"
#include "request.h"
#include "ppdfile.h"



/*
 * Constructeur - Destructeur
 * Init - Uninit
 */
Printer::Printer()
{
    _manufacturer = NULL;
    _model = NULL;
    _beginPJL = NULL;
    _endPJL = NULL;
}

Printer::~Printer()
{
    if (_manufacturer)
        delete[] _manufacturer;
    if (_model)
        delete [] _model;
    if (_beginPJL)
        delete [] _beginPJL;
    if (_endPJL)
        delete [] _endPJL;
}



/*
 * Chargement des informations sur l'imprimante
 * Load the printer information
 */
bool Printer::loadInformation(const Request& request)
{
    const char *paperType, *paperSource;
    PPDValue value;

    // Get some printer information
    if (request.ppd()->get("BandSize", "QPDL").isNull()) {
        ERRORMSG(_("Unknown band size. Operation aborted."));
        return false;
    }
    _bandHeight = request.ppd()->get("BandSize", "QPDL");
    _packetSize = request.ppd()->get("PacketSize", "QPDL");
    _packetSize *= 1024;
    _manufacturer = request.ppd()->get("Manufacturer").deepCopy();
    _model = request.ppd()->get("ModelName").deepCopy();
    _color = request.ppd()->get("ColorDevice");
    _qpdlVersion = request.ppd()->get("QPDLVersion", "QPDL");
    if (!_qpdlVersion || (_qpdlVersion > 3 && _qpdlVersion != 5)) {
        ERRORMSG(_("Invalid QPDL version. Operation aborted."));
        return false;
    }
    value = request.ppd()->get("DocHeaderValues", "General");
    value.setPreformatted();
    if (value.isNull()) {
        ERRORMSG(_("Unknown header values. Operation aborted."));
        return false;
    }
    _unknownByte1 = ((const char *)value)[0];
    _unknownByte2 = ((const char *)value)[1];
    _unknownByte3 = ((const char *)value)[2];

    // Get PJL information
    value = request.ppd()->get("BeginPJL", "PJL");
    value.setPreformatted();
    if (value.isNull()) {
        ERRORMSG(_("No PJL header found. Operation aborted."));
        return false;
    }
    _beginPJL = value.deepCopy();
    value = request.ppd()->get("EndPJL", "PJL");
    value.setPreformatted();
    if (value.isNull()) {
        ERRORMSG(_("No PJL footer found. Operation aborted."));
        return false;
    }
    _endPJL = value.deepCopy();

    // Get the paper information
    paperType = request.ppd()->get("MediaSize");
    if (!paperType)
        paperType = request.ppd()->get("PageSize");
    if (!paperType) {
        ERRORMSG(_("Cannot get paper size information. Operation aborted."));
        return false;
    }
    if (!(strcasecmp(paperType, "Letter"))) _paperType = 0;
    else if (!(strcasecmp(paperType, "Legal"))) _paperType = 1;
    else if (!(strcasecmp(paperType, "A4"))) _paperType = 2;
    else if (!(strcasecmp(paperType, "Executive"))) _paperType = 3;
    else if (!(strcasecmp(paperType, "Ledger"))) _paperType = 4;
    else if (!(strcasecmp(paperType, "A3"))) _paperType = 5;
    else if (!(strcasecmp(paperType, "Env10"))) _paperType = 6;
    else if (!(strcasecmp(paperType, "Monarch"))) _paperType = 7;
    else if (!(strcasecmp(paperType, "C5"))) _paperType = 8;
    else if (!(strcasecmp(paperType, "DL"))) _paperType = 9;
    else if (!(strcasecmp(paperType, "B4"))) _paperType = 10;
    else if (!(strcasecmp(paperType, "B5"))) _paperType = 11;
    else if (!(strcasecmp(paperType, "EnvISOB5"))) _paperType = 12;
    else if (!(strcasecmp(paperType, "Postcard"))) _paperType = 14;
    else if (!(strcasecmp(paperType, "DoublePostcardRotated"))) _paperType = 15;
    else if (!(strcasecmp(paperType, "A5"))) _paperType = 16;
    else if (!(strcasecmp(paperType, "A6"))) _paperType = 17;
    else if (!(strcasecmp(paperType, "B6"))) _paperType = 18;
    else if (!(strcasecmp(paperType, "Custom"))) _paperType = 21;
    else if (!(strcasecmp(paperType, "C6"))) _paperType = 23;
    else if (!(strcasecmp(paperType, "Folio"))) _paperType = 24;
    else if (!(strcasecmp(paperType, "EnvPersonal"))) _paperType = 25;
    else if (!(strcasecmp(paperType, "Env9"))) _paperType = 26;
    else if (!(strcasecmp(paperType, "Oficio"))) _paperType = 28;
    else {
        ERRORMSG(_("Invalid paper size \"%s\". Operation aborted."), paperType);
        return false;
    }

    value = request.ppd()->getPageSize(paperType);
    if (value.width() == 0. || value.height() == 0.) {
        ERRORMSG(_("Null paper size \"%s\" found. Operation aborted."), 
            paperType);
        return false;
    }
    _pageWidth = value.width();
    _pageHeight = value.height();
    _hardMarginX = value.marginX();
    _hardMarginY = value.marginY();

    paperSource = request.ppd()->get("InputSlot");
    if (!paperSource) {
        paperSource = request.ppd()->get("DefaultInputSlot");
        if (!paperSource) {
            paperSource = "Auto";
            ERRORMSG(_("Cannot get input slot information."));
        }
    }
    if (!(strcasecmp(paperSource, "Auto"))) _paperSource = 1;
    else if (!(strcasecmp(paperSource, "Manual"))) _paperSource = 2;
    else if (!(strcasecmp(paperSource, "Multi"))) _paperSource = 3;
    else if (!(strcasecmp(paperSource, "Upper"))) _paperSource = 4;
    else if (!(strcasecmp(paperSource, "Lower"))) _paperSource = 5;
    else if (!(strcasecmp(paperSource, "Envelope"))) _paperSource = 6;
    else if (!(strcasecmp(paperSource, "Tray3"))) _paperSource = 7;
    else {
        ERRORMSG(_("Invalid paper source \"%s\". Operation aborted."), 
            paperSource);
        return false;
    }

    DEBUGMSG(_("%s printer %s with QPDL v. %lu"), _color ? "Color" : 
        "Monochrome", _model, _qpdlVersion);

    return true;
}

bool Printer::sendPJLHeader(const Request& request,
                         unsigned long    compression,
                         unsigned long    xResolution,
                         unsigned long    yResolution ) const
{
    const char *reverse;
    struct tm *timeinfo;
    time_t timestamp;

    time(&timestamp);
    timeinfo = localtime(&timestamp);

    printf("%s", _beginPJL);

    if (0x15 == compression) {
        printf("@PJL COMMENT USERNAME=\"Username: %s\"\n", request.userName());
        printf("@PJL COMMENT DOCNAME=\"%s\"\n", request.jobTitle());
        printf("@PJL JOB NAME=\"%s\"\n", request.jobTitle());
    }

    // Information about the job
    printf("@PJL DEFAULT SERVICEDATE=%04u%02u%02u\n", 1900+timeinfo->tm_year,
        timeinfo->tm_mon+1, timeinfo->tm_mday);
    printf("@PJL SET USERNAME=\"%s\"\n", request.userName());
    printf("@PJL SET JOBNAME=\"%s\"\n", request.jobTitle());

    if (0x15 == compression)
        printf("@PJL SET MULTIBINMODE=%s\n", "PRINTERDEFAULT");

   // Set some printer options
    if (!request.ppd()->get("EconoMode").isNull() && 
        request.ppd()->get("EconoMode") != "0")
        printf("@PJL SET ECONOMODE=%s\n", (const char *)request.ppd()->
                get("EconoMode"));
    if (!request.ppd()->get("PowerSave").isNull()) {
        if (request.ppd()->get("PowerSave") != "False") {
            printf("@PJL DEFAULT POWERSAVE=ON\n");
            printf("@PJL DEFAULT POWERSAVETIME=%s\n",
                (const char *)request.ppd()->get("PowerSave"));
        } else
            printf("@PJL DEFAULT POWERSAVE=OFF\n");
    }

    if (request.ppd()->get("JamRecovery").isTrue())
        printf("@PJL SET JAMRECOVERY=ON\n");
    else
        printf("@PJL SET JAMRECOVERY=OFF\n");
    if (request.printer()->color()) {
        if (!strcasecmp(request.ppd()->get("ColorModel"), "CMYK"))
            printf("@PJL SET COLORMODE=COLOR\n");
        else
            printf("@PJL SET COLORMODE=MONO\n");
    }

    if (0x15 == compression) {
        printf("@PJL SET RESOLUTION=%lu\n", yResolution);
        if ((600 == xResolution) && (600 == yResolution))
            printf("@PJL SET IMAGEQUALITY=0\n");
        if ((1200 == xResolution) && (600 == yResolution))
            printf("@PJL SET IMAGEQUALITY=1\n");
        printf("@PJL SET RGBCOLOR=%s\n", "STANDARD");
    }

    // Information about the duplex
    reverse = request.reverseDuplex() ? "REVERSE_" : "";
    switch (request.duplex()) {
        case Request::Simplex:
            printf("@PJL SET DUPLEX=OFF\n");
            break;
        case Request::LongEdge:
            printf("@PJL SET DUPLEX=ON\n");
            printf("@PJL SET BINDING=%sLONGEDGE\n", reverse);
            break;
        case Request::ShortEdge:
            printf("@PJL SET DUPLEX=ON\n");
            printf("@PJL SET BINDING=%sSHORTEDGE\n", reverse);
            break;
        case Request::ManualLongEdge:
            printf("@PJL SET DUPLEX=MANUAL\n");
            printf("@PJL SET BINDING=LONGEDGE\n");
            break;
        case Request::ManualShortEdge:
            printf("@PJL SET DUPLEX=MANUAL\n");
            printf("@PJL SET BINDING=SHORTEDGE\n");
            break;
    }
 
    // Set some job options
    if (request.ppd()->get("MediaType").isNull())
        printf("@PJL SET PAPERTYPE=OFF\n");
    else
        printf("@PJL SET PAPERTYPE=%s\n", (const char *)request.ppd()->
                get("MediaType"));
    if (request.ppd()->get("Altitude").isNull())
        printf("@PJL SET ALTITUDE=LOW\n");
    else
        printf("@PJL SET ALTITUDE=%s\n", (const char *)request.ppd()->
                get("Altitude"));
    if (request.ppd()->get("TonerDensity").isNull())
        printf("@PJL SET DENSITY=3\n");
    else
        printf("@PJL SET DENSITY=%s\n", (const char *)request.ppd()->
                get("TonerDensity"));
    if (request.ppd()->get("SRTMode").isNull())
        printf("@PJL SET RET=NORMAL\n");
    else
        printf("@PJL SET RET=%s\n", (const char *)request.ppd()->
                get("SRTMode"));

    if (0x15 == compression) {
        printf("@PJL SET BANNERSHEET=%s\n", "OFF");
        printf("@PJL SET TIMESTAMP=%s\n", "OFF");
    }

    printf("@PJL ENTER LANGUAGE = QPDL\n");
    fflush(stdout);

    return true;
}

bool Printer::sendPJLFooter(const Request& request) const
{
    printf("%s", _endPJL);
    fflush(stdout);

    return true;
}

/* vim: set expandtab tabstop=4 shiftwidth=4 smarttab tw=80 cin enc=utf8: */