~ubuntu-branches/ubuntu/raring/hplip/raring

« back to all changes in this revision

Viewing changes to prnt/hpcups/Encapsulator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2009-12-14 20:08:44 UTC
  • mfrom: (2.1.118 lucid)
  • Revision ID: james.westby@ubuntu.com-20091214200844-z8qhqwgppbu3t7ze
Tags: 3.9.10-4
KBSD patch from KiBi (Closes: #560796)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************\
 
2
  Encapsulator.cpp : Encapsulator class implementation
 
3
 
 
4
  Copyright (c) 1996 - 2001, Hewlett-Packard Co.
 
5
  All rights reserved.
 
6
 
 
7
  Redistribution and use in source and binary forms, with or without
 
8
  modification, are permitted provided that the following conditions
 
9
  are met:
 
10
  1. Redistributions of source code must retain the above copyright
 
11
     notice, this list of conditions and the following disclaimer.
 
12
  2. Redistributions in binary form must reproduce the above copyright
 
13
     notice, this list of conditions and the following disclaimer in the
 
14
     documentation and/or other materials provided with the distribution.
 
15
  3. Neither the name of Hewlett-Packard nor the names of its
 
16
     contributors may be used to endorse or promote products derived
 
17
     from this software without specific prior written permission.
 
18
 
 
19
  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
 
20
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
21
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 
22
  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
23
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 
24
  TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 
25
  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 
26
  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
27
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
28
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
\*****************************************************************************/
 
30
#include "CommonDefinitions.h"
 
31
#include "Encapsulator.h"
 
32
#include "PrinterCommands.h"
 
33
 
 
34
Encapsulator::Encapsulator()
 
35
{
 
36
    page_number = 0;
 
37
    pcl_buffer = NULL;
 
38
    cur_pcl_buffer_size = 0;
 
39
    m_pJA = NULL;
 
40
    m_pMA = NULL;
 
41
    m_pQA = NULL;
 
42
}
 
43
Encapsulator::~Encapsulator()
 
44
{
 
45
    if (pcl_buffer) {
 
46
        delete [] pcl_buffer;
 
47
    }
 
48
}
 
49
 
 
50
DRIVER_ERROR Encapsulator::StartJob(SystemServices *pSystemServices, JobAttributes *pJA)
 
51
{
 
52
    DRIVER_ERROR    err = NO_ERROR;
 
53
 
 
54
    m_pSystemServices = pSystemServices;
 
55
 
 
56
    m_pJA = pJA;
 
57
    m_pMA = &pJA->media_attributes;
 
58
    m_pQA = &pJA->quality_attributes;
 
59
 
 
60
    cur_pcl_buffer_size = PCL_BUFFER_SIZE;
 
61
    pcl_buffer = new BYTE[cur_pcl_buffer_size + 2];
 
62
    if (pcl_buffer == NULL) {
 
63
        return ALLOCMEM_ERROR;
 
64
    }
 
65
    memset(pcl_buffer, 0, cur_pcl_buffer_size);
 
66
    cur_pcl_buffer_ptr = pcl_buffer;
 
67
 
 
68
    err = flushPrinterBuffer();
 
69
 
 
70
    struct    tm    *t;
 
71
    time_t    long_time;
 
72
    time(&long_time);
 
73
    t = localtime(&long_time);
 
74
 
 
75
    addToHeader(Reset, sizeof(Reset));
 
76
    addToHeader(UEL, sizeof(UEL));
 
77
 
 
78
//  Now add other header info
 
79
 
 
80
    if (jobAttrPJLAllowed())
 
81
    {
 
82
        addToHeader("@PJL SET STRINGCODESET=UTF8\012");
 
83
        addToHeader("@PJL COMMENT=\"Job Start Time: %s\"\012", m_pJA->job_start_time);
 
84
        addToHeader("@PJL JOBNAME=\"%s\"\012", m_pJA->job_title);
 
85
        addToHeader("@PJL SET JOBNAME=\"%s\"\012", m_pJA->job_title);
 
86
        addToHeader("@PJL COMMENT=\"%s; %s; %s; %s\"\012",
 
87
                    m_pJA->printer_name, m_pJA->os_name, m_pJA->driver_name, m_pJA->driver_version);
 
88
        addToHeader("@PJL COMMENT=\"Username: %s; App Filename: %s; %d-%d-%d\"\012",
 
89
                    m_pJA->user_name, m_pJA->job_title, t->tm_mon + 1, t->tm_mday, t->tm_year + 1900);
 
90
        addToHeader("@PJL SET JOBATTR=\"JobAcct1=%s\"\012", m_pJA->user_name);
 
91
        addToHeader("@PJL SET JOBATTR=\"JobAcct2=%s\"\012", m_pJA->host_name);
 
92
        addToHeader("@PJL SET JOBATTR=\"JobAcct3=%s\"\012", m_pJA->domain_name);
 
93
        addToHeader("@PJL SET JOBATTR=\"JobAcct4=%4d%02d%02d%02d%02d%02d\"\012",
 
94
                    t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
 
95
        addToHeader("@PJL SET JOBATTR=\"JobAcct5=%s\"\012", m_pJA->uuid);
 
96
 
 
97
    //  Add start of job time stamp to the header
 
98
        addToHeader("@PJL SET TIMESTAMP=%4d%02d%02d%02d%02d%02d\012",
 
99
                    t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
 
100
        addToHeader("@PJL SET JOBATTR=\"JobAcct6=Spooler Subsystem App\"\012");
 
101
        addToHeader("@PJL SET JOBATTR=\"JobAcct7=\"%s\"\012", m_pJA->job_title);
 
102
        addToHeader("@PJL SET JOBATTR=\"JobAcct8=\"%s\"\012", m_pJA->user_name);
 
103
        addToHeader("@PJL SET JOBATTR=\"JobAcct9=(null)\"\012");
 
104
 
 
105
        addToHeader("@PJL SET USERNAME=\"%s\"\012", m_pJA->user_name);
 
106
    }
 
107
 
 
108
//  Add platform specific PJL here
 
109
    addJobSettings();
 
110
 
 
111
    return err;
 
112
}
 
113
 
 
114
DRIVER_ERROR Encapsulator::Send(const BYTE *pBuffer, int length)
 
115
{
 
116
    DRIVER_ERROR    err;
 
117
//  Dont' have any buffer allocated, just send the incoming data to the device
 
118
    if (pcl_buffer == NULL) {
 
119
        return sendBuffer(pBuffer, length);
 
120
    }
 
121
 
 
122
//  Add the incoming data to the printer data buffer if there is enough room, otherwise, flush the buffer
 
123
 
 
124
    if (cur_pcl_buffer_ptr + length > (pcl_buffer + cur_pcl_buffer_size)) {
 
125
        err = sendBuffer(static_cast<const BYTE *>(pcl_buffer), (cur_pcl_buffer_ptr - pcl_buffer));
 
126
        if (err != NO_ERROR)
 
127
            return err;
 
128
        cur_pcl_buffer_ptr = pcl_buffer;
 
129
    }
 
130
 
 
131
    if (length < cur_pcl_buffer_size) {
 
132
        memcpy(cur_pcl_buffer_ptr, pBuffer, length);
 
133
        cur_pcl_buffer_ptr += length;
 
134
    }
 
135
    else {
 
136
        err = sendBuffer(pBuffer, length);
 
137
    }
 
138
    return NO_ERROR;
 
139
} // Send
 
140
 
 
141
void Encapsulator::addToHeader(const BYTE *command_string, int length)
 
142
{
 
143
    memcpy(cur_pcl_buffer_ptr, command_string, length);
 
144
    cur_pcl_buffer_ptr += length;
 
145
}
 
146
 
 
147
void Encapsulator::addToHeader(const char *fmt, ...)
 
148
{
 
149
    va_list args;
 
150
    int     n;
 
151
    va_start(args, fmt);
 
152
    int     size = cur_pcl_buffer_size - (cur_pcl_buffer_ptr - pcl_buffer);
 
153
 
 
154
    n = vsnprintf((char *) cur_pcl_buffer_ptr, size - 1, fmt, args);
 
155
    cur_pcl_buffer_ptr += n;
 
156
    va_end(args);
 
157
}
 
158
 
 
159
DRIVER_ERROR Encapsulator::sendBuffer(const BYTE *pBuffer, int length)
 
160
{
 
161
    DRIVER_ERROR    err;
 
162
    if (length == 0) {
 
163
        return NO_ERROR;
 
164
    }
 
165
    err = m_pSystemServices->Send(pBuffer, length);
 
166
    return err;
 
167
}
 
168
 
 
169
DRIVER_ERROR Encapsulator::Cleanup()
 
170
{
 
171
    DRIVER_ERROR    err = NO_ERROR;
 
172
    if (pcl_buffer && cur_pcl_buffer_ptr - pcl_buffer > 0)
 
173
    {
 
174
        err = sendBuffer(static_cast<const BYTE *>(pcl_buffer), (cur_pcl_buffer_ptr - pcl_buffer));
 
175
    }
 
176
    cur_pcl_buffer_ptr = pcl_buffer;
 
177
    return err;
 
178
}
 
179
 
 
180
DRIVER_ERROR Encapsulator::FormFeed()
 
181
{
 
182
    DRIVER_ERROR    err;
 
183
    err = this->Send((const BYTE *) "\x1B*rC\x0C", 5);
 
184
 
 
185
    return err;
 
186
}
 
187
 
 
188
DRIVER_ERROR Encapsulator::SendCAPy(int iOffset)
 
189
{
 
190
    DRIVER_ERROR    err = NO_ERROR;
 
191
    char            str[12];
 
192
    sprintf(str, "\x1b*b%dY", iOffset);
 
193
    err = this->Send ((const BYTE *) str, strlen(str));
 
194
    return err;
 
195
}
 
196
 
 
197
DRIVER_ERROR Encapsulator::EndJob()
 
198
{
 
199
    DRIVER_ERROR    err = NO_ERROR;
 
200
    err = m_pSystemServices->Send(Reset, sizeof(Reset));
 
201
    if (err == NO_ERROR)
 
202
        err = m_pSystemServices->Send(UEL, sizeof(UEL));
 
203
    return err;
 
204
}
 
205
 
 
206
void Encapsulator::CancelJob()
 
207
{
 
208
    BYTE    buffer[4098];
 
209
    memset(buffer, 0x0, sizeof(buffer));
 
210
    memcpy(buffer+4087, "\x1B%-12345X", 9);
 
211
 
 
212
//  This sequence is good for PCL3 printers. Update this for non-PCL printers.
 
213
 
 
214
    m_pSystemServices->Send((const BYTE *) buffer, 4096);
 
215
}
 
216
 
 
217
// Used only by LJMono and LJColor
 
218
 
 
219
void Encapsulator::sendJobHeader()
 
220
{
 
221
    char            szStr[256];
 
222
    int             top_margin = 0;
 
223
 
 
224
//  Set media source, type, size and quality modes.
 
225
//  Duplex and portrait mode - <ESC>&l<n>s, <ESC>&l0o
 
226
 
 
227
    addToHeader("\033&l%dh%dm%da%ds8c0o0E\033*o%dM", m_pJA->media_source, m_pQA->media_type,
 
228
                m_pMA->pcl_id, m_pJA->e_duplex_mode, m_pQA->print_quality);
 
229
 
 
230
    addToHeader("\033&u%dD\033*t%dR\033*r%dS", m_pQA->horizontal_resolution, m_pQA->vertical_resolution, m_pMA->printable_width);
 
231
 
 
232
/*
 
233
 *  Custom papersize command
 
234
 */
 
235
 
 
236
    if (m_pMA->pcl_id == CUSTOM_MEDIA_SIZE) {
 
237
        short   sWidth, sHeight;
 
238
        BYTE    b1, b2;
 
239
        sWidth  = static_cast<short>(m_pMA->physical_width);
 
240
        sHeight = static_cast<short>(m_pMA->physical_height);
 
241
        memcpy (szStr, "\x1B*o5W\x0E\x05\x00\x00\x00\x1B*o5W\x0E\x06\x00\x00\x00", 20);
 
242
        b1 = (BYTE) ((sWidth & 0xFF00) >> 8);
 
243
        b2 = (BYTE) (sWidth & 0xFF);
 
244
        szStr[8] = b1;
 
245
        szStr[9] = b2;
 
246
        b1 = (BYTE) ((sHeight & 0xFF00) >> 8);
 
247
        b2 = (BYTE) (sHeight & 0xFF);
 
248
        szStr[18] = b1;
 
249
        szStr[19] = b2;
 
250
        addToHeader((const BYTE *) szStr, 20);
 
251
    }
 
252
 
 
253
    const BYTE *pgrafMode = grafMode2;
 
254
    if (m_pJA->color_mode == 0)
 
255
    {
 
256
        configureRasterData();
 
257
        pgrafMode = grafMode3;
 
258
    }
 
259
 
 
260
    addToHeader((const BYTE *) grafStart, sizeof(grafStart));
 
261
    addToHeader((const BYTE *) pgrafMode, 5);
 
262
    addToHeader((const BYTE *) seedSame, sizeof(seedSame));
 
263
 
 
264
    top_margin = m_pMA->printable_start_y - ((m_pJA->mech_offset * m_pQA->actual_vertical_resolution)/1000);
 
265
    int left_margin = 0;
 
266
    if (m_pJA->integer_values[1] > 0)
 
267
    {
 
268
        left_margin = ((m_pJA->integer_values[1] * m_pQA->horizontal_resolution) / 100 - m_pMA->printable_width) / 2;
 
269
    }
 
270
    addToHeader("\x1b*p%dx%dY", left_margin, top_margin);
 
271
 
 
272
    return;
 
273
}
 
274