Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpcups / Encapsulator.cpp
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     if (err == NO_ERROR) {
185         return Cleanup();
186     }
187     return err;
188 }
189
190 DRIVER_ERROR Encapsulator::SendCAPy(int iOffset)
191 {
192     DRIVER_ERROR    err = NO_ERROR;
193     char            str[12];
194     sprintf(str, "\x1b*b%dY", iOffset);
195     err = this->Send ((const BYTE *) str, strlen(str));
196     return err;
197 }
198
199 DRIVER_ERROR Encapsulator::EndJob()
200 {
201     DRIVER_ERROR    err = NO_ERROR;
202     err = m_pSystemServices->Send(Reset, sizeof(Reset));
203     if (err == NO_ERROR)
204         err = m_pSystemServices->Send(UEL, sizeof(UEL));
205     return err;
206 }
207
208 void Encapsulator::CancelJob()
209 {
210     BYTE    buffer[4098];
211     memset(buffer, 0x0, sizeof(buffer));
212     memcpy(buffer+4087, "\x1B%-12345X", 9);
213
214 //  This sequence is good for PCL3 printers. Update this for non-PCL printers.
215
216     m_pSystemServices->Send((const BYTE *) buffer, 4096);
217 }
218
219 // Used only by LJMono and LJColor
220
221 void Encapsulator::sendJobHeader()
222 {
223     char            szStr[256];
224     int             top_margin = 0;
225
226 //  Set media source, type, size and quality modes.
227 //  Duplex and portrait mode - <ESC>&l<n>s, <ESC>&l0o
228
229     addToHeader("\033&l%dh%dm%da%ds8c0o0E\033*o%dM", m_pJA->media_source, m_pQA->media_type,
230                 m_pMA->pcl_id, m_pJA->e_duplex_mode, m_pQA->print_quality);
231
232     addToHeader("\033&u%dD\033*t%dR\033*r%dS", m_pQA->horizontal_resolution, m_pQA->vertical_resolution, m_pMA->printable_width);
233
234 /*
235  *  Custom papersize command
236  */
237
238     if (m_pMA->pcl_id == CUSTOM_MEDIA_SIZE) {
239         short   sWidth, sHeight;
240         BYTE    b1, b2;
241         sWidth  = static_cast<short>(m_pMA->physical_width);
242         sHeight = static_cast<short>(m_pMA->physical_height);
243         memcpy (szStr, "\x1B*o5W\x0E\x05\x00\x00\x00\x1B*o5W\x0E\x06\x00\x00\x00", 20);
244         b1 = (BYTE) ((sWidth & 0xFF00) >> 8);
245         b2 = (BYTE) (sWidth & 0xFF);
246         szStr[8] = b1;
247         szStr[9] = b2;
248         b1 = (BYTE) ((sHeight & 0xFF00) >> 8);
249         b2 = (BYTE) (sHeight & 0xFF);
250         szStr[18] = b1;
251         szStr[19] = b2;
252         addToHeader((const BYTE *) szStr, 20);
253     }
254
255     const BYTE *pgrafMode = grafMode2;
256     if (m_pJA->color_mode == 0)
257     {
258         configureRasterData();
259         pgrafMode = grafMode3;
260     }
261
262     addToHeader((const BYTE *) grafStart, sizeof(grafStart));
263     addToHeader((const BYTE *) pgrafMode, 5);
264     addToHeader((const BYTE *) seedSame, sizeof(seedSame));
265
266     top_margin = m_pMA->printable_start_y - ((m_pJA->mech_offset * m_pQA->actual_vertical_resolution)/1000);
267     int left_margin = 0;
268     if (m_pJA->integer_values[1] > 0)
269     {
270         left_margin = ((m_pJA->integer_values[1] * m_pQA->horizontal_resolution) / 100 - m_pMA->printable_width) / 2;
271     }
272     addToHeader("\x1b*p%dx%dY", left_margin, top_margin);
273
274     return;
275 }
276
277
278 DRIVER_ERROR Encapsulator::preProcessRasterData(cups_raster_t **cups_raster, cups_page_header2_t* firstpage_cups_header, char* pSwapedPagesFileName)
279 {
280         dbglog ("DEBUG: Encapsulator::preProcessRasterData.............. \n");
281         return NO_ERROR;
282 }
283