1 /*****************************************************************************\
2   ljmono.cpp : Implimentation for the LJMono class
3 
4   Copyright (c) 1996 - 2015, HP 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 HP 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 
31 
32 #ifdef APDK_LJMONO
33 
34 #include "header.h"
35 #include "io_defs.h"
36 #include "ljmono.h"
37 #include "printerproxy.h"
38 #include "resources.h"
39 
40 APDK_BEGIN_NAMESPACE
41 
42 extern uint32_t ulMapDJ600_CCM_K[ 9 * 9 * 9 ];
43 
LJMono(SystemServices * pSS,int numfonts,BOOL proto)44 LJMono::LJMono (SystemServices* pSS, int numfonts, BOOL proto)
45     : Printer(pSS, numfonts, proto)
46 {
47 
48     if ((!proto) && (IOMode.bDevID))
49     {
50         constructor_error = VerifyPenInfo ();
51         CERRCHECK;
52     }
53     else ePen = BLACK_PEN;    // matches default mode
54 
55     pMode[GRAYMODE_INDEX]    = new LJMonoDraftMode ();
56     pMode[DEFAULTMODE_INDEX] = new LJMonoNormalMode ();
57     pMode[SPECIALMODE_INDEX] = new LJMonoBestMode ();
58     ModeCount = 3;
59 
60     CMYMap = NULL;
61     m_bJobStarted = FALSE;
62 #ifdef  APDK_AUTODUPLEX
63     m_bRotateBackPage = FALSE;  // Lasers don't require back side image to be rotated
64 #endif
65 
66     DBG1("LJMono created\n");
67 }
68 
~LJMono()69 LJMono::~LJMono ()
70 {
71     DISPLAY_STATUS  eDispStatus;
72     if (IOMode.bStatus && m_bJobStarted)
73     {
74         for (int i = 0; i < 5; i++)
75         {
76             pSS->BusyWait (2000);
77             eDispStatus = ParseError (0);
78             if (eDispStatus == DISPLAY_PRINTING_COMPLETE)
79             {
80                 pSS->DisplayPrinterStatus (eDispStatus);
81                 break;
82             }
83         }
84     }
85 }
86 
LJMonoDraftMode()87 LJMonoDraftMode::LJMonoDraftMode ()
88 : GrayMode(ulMapDJ600_CCM_K)
89 {
90 
91 //  By default, this is 150 dpi because LJ_BASE_RES is defined to be 300
92 //  unless APDK_HIGH_RES_MODES is defined, then VIP_BASE_RES will be 600
93 
94     ResolutionX[0] =
95     ResolutionY[0] = LJ_BASE_RES;
96     BaseResX =
97     BaseResY = LJ_BASE_RES;
98     MixedRes = FALSE;
99     bFontCapable = TRUE;
100     theQuality = qualityDraft;
101     pmQuality = QUALITY_DRAFT;
102 #ifdef APDK_AUTODUPLEX
103     bDuplexCapable = TRUE;
104 #endif
105 }
106 
LJMonoNormalMode()107 LJMonoNormalMode::LJMonoNormalMode ()
108 : GrayMode(ulMapDJ600_CCM_K)
109 {
110 
111 //  300 or 600 dpi depending on LJ_BASE_RES value, which in turn is affected by APDK_HIGH_RES_MODES
112 
113     ResolutionX[0] =
114     ResolutionY[0] = LJ_BASE_RES * 2;
115     BaseResX =
116     BaseResY = LJ_BASE_RES * 2;
117 	TextRes  = LJ_BASE_RES * 2;
118     MixedRes = FALSE;
119     bFontCapable = TRUE;
120 #ifdef APDK_AUTODUPLEX
121     bDuplexCapable = TRUE;
122 #endif
123 }
124 
LJMonoBestMode()125 LJMonoBestMode::LJMonoBestMode ()
126 : GrayMode(ulMapDJ600_CCM_K)
127 {
128     ResolutionX[0] = ResolutionY[0] = 600;
129     BaseResX = BaseResY = 600;
130     TextRes = 600;
131     MixedRes = FALSE;
132     bFontCapable = TRUE;
133 	pmQuality = QUALITY_BEST;
134 #ifdef APDK_AUTODUPLEX
135     bDuplexCapable = TRUE;
136 #endif
137 }
138 
HeaderLJMono(Printer * p,PrintContext * pc)139 HeaderLJMono::HeaderLJMono (Printer* p,PrintContext* pc)
140     : Header(p,pc)
141 { }
142 
Send()143 DRIVER_ERROR HeaderLJMono::Send ()
144 {
145     DRIVER_ERROR err;
146 
147     StartSend ();
148 
149     err = Graphics ();     // start raster graphics and set compression mode
150 
151     return err;
152 }
153 
StartSend()154 DRIVER_ERROR HeaderLJMono::StartSend ()
155 {
156     DRIVER_ERROR err;
157     char    res[96];
158     int     iRes;
159 
160     iRes = thePrintContext->EffectiveResolutionY ();
161 
162     err = thePrinter->Send((const BYTE*)UEL,sizeof(UEL));
163     ERRCHECK;
164 
165     sprintf (res, "@PJL SET PAGEPROTECT=AUTO\015\012@PJL SET RESOLUTION=%d\015\012", iRes);
166     err = thePrinter->Send ((const BYTE *) res, strlen (res));
167     ERRCHECK;
168 
169    err = thePrinter->Send ((const BYTE *) "@PJL SET DENSITY=5\015\012", 20); // for lj1100, des 8/7/02
170    ERRCHECK;
171 
172     QUALITY_MODE    eQ = QUALITY_NORMAL;
173     COLORMODE       eC;
174     MEDIATYPE       eM;
175     BOOL            bD;
176 
177     thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD);
178 
179     if (eQ == QUALITY_DRAFT)
180     {
181         strcpy (res, "@PJL SET RET=OFF\015\012@PJL SET ECONOMODE=ON\015\012");
182         err = thePrinter->Send ((const BYTE *) res, strlen (res));
183         ERRCHECK;
184     }
185 
186     if (thePrinter->IOMode.bStatus)
187     {
188         sprintf (res, "@PJL JOB NAME = \"%ld\"\015\012", (long) (thePrinter));
189         err = thePrinter->Send ((const BYTE *) res, strlen (res));
190         ERRCHECK;
191 
192         strcpy (res, "@PJL USTATUSOFF\015\012@PJL USTATUS DEVICE = ON\015\012@PJL USTATUS JOB = ON\015\012");
193         err = thePrinter->Send ((const BYTE *) res, strlen (res));
194         ERRCHECK;
195     }
196 
197 //  Duplexing directive
198 
199     strcpy (res, "@PJL SET DUPLEX=OFF\015\012");
200 
201 #ifdef APDK_AUTODUPLEX
202     DUPLEXMODE  dupmode = thePrintContext->QueryDuplexMode ();
203     if (dupmode != DUPLEXMODE_NONE)
204     {
205         strcpy (res, "@PJL SET DUPLEX=ON\015\012@PJL SET BINDING=");
206         if (dupmode == DUPLEXMODE_BOOK)
207             strcat (res, "LONGEDGE\015\012");
208         else
209             strcat (res, "SHORTEDGE\015\012");
210     }
211 #endif
212     err = thePrinter->Send ((const BYTE *) res, strlen (res));
213     ERRCHECK;
214 
215     err = thePrinter->Send ((const BYTE*) EnterLanguage, sizeof (EnterLanguage));
216     ERRCHECK;
217 
218     err = thePrinter->Send ((const BYTE*) "PCL\015\012", 5);
219     ERRCHECK;
220 
221     err = thePrinter->Send ((const BYTE*)Reset,sizeof(Reset));
222     ERRCHECK;
223 
224     sprintf (res, "\033&l%dH", thePrintContext->GetMediaSource());
225     err = thePrinter->Send ((const BYTE *) res, strlen (res));      // Source
226     ERRCHECK;
227 
228 //  Media size, vertical spacing between lines and top margin
229 
230     memcpy (res, mediasize, mscount - 1);
231     strcpy (res+mscount-1, "a8c0E");
232     err = thePrinter->Send ((const BYTE *) res, strlen (res));
233     ERRCHECK;
234 
235     sprintf (res, "\033*t%dR\033&u%dD", iRes, iRes);
236     err = thePrinter->Send ((const BYTE *) res, 14);
237     ERRCHECK;
238 
239     err = Margins ();
240     ERRCHECK;
241     CAPy = 0;
242 
243 //  Default is single sided printing
244 
245     strcpy (res, "\033&l0S");
246 #ifdef APDK_AUTODUPLEX
247     DUPLEXMODE  eDupMode = thePrintContext->QueryDuplexMode ();
248     if (eDupMode != DUPLEXMODE_NONE)
249     {
250         sprintf (res, "\033&l%dS", (eDupMode == DUPLEXMODE_BOOK) ? 1 : 2);
251     }
252 #endif
253     err = thePrinter->Send ((const BYTE *) res, strlen (res));
254     ERRCHECK;
255 
256 /*
257  *  Set orientation to Portrait. APDK supports printing in Portrait mode only.
258  *  If users desire Landscape printing, application/gluecode will have to
259  *  rearrange the rasters appropriately.
260  */
261 
262     err = thePrinter->Send ((const BYTE *) "\033&l0O", 5);
263 
264     // Number of copies
265     sprintf (res, "\033&l%dX", thePrintContext->GetCopyCount ());
266     err = thePrinter->Send ((const BYTE *) res, strlen (res));
267     ERRCHECK;
268 
269     return err;
270 }
271 
Graphics()272 DRIVER_ERROR HeaderLJMono::Graphics ()
273 {
274     DRIVER_ERROR error = thePrinter->Send ((const BYTE*)grafStart, sizeof (grafStart) );
275     if (error!=NO_ERROR)
276         return error;
277 
278     error= thePrinter->Send((const BYTE*) grafMode2, sizeof (grafMode2) );
279 
280     if (error!=NO_ERROR)
281         return error;
282 
283     return error;
284 }
285 
EndJob()286 DRIVER_ERROR HeaderLJMono::EndJob ()
287 {
288     char    szBuff[128];
289     DRIVER_ERROR    err = NO_ERROR;
290     if (thePrinter->IOMode.bStatus)
291     {
292         sprintf (szBuff, "\033E\033%%-12345X@PJL EOJ NAME = \"%ld\"\015\012@PJL RESET\015\012",
293                 (long) (thePrinter));
294         err = thePrinter->Send ((const BYTE *) szBuff, strlen (szBuff));
295     }
296 
297     strcpy (szBuff, "\033%-12345X");
298     err = thePrinter->Send ((const BYTE *) szBuff, strlen (szBuff));
299 
300     return err;
301 }
302 
SelectHeader(PrintContext * pc)303 Header* LJMono::SelectHeader (PrintContext* pc)
304 {
305     m_bJobStarted = TRUE;
306     return new HeaderLJMono (this,pc);
307 }
308 
VerifyPenInfo()309 DRIVER_ERROR LJMono::VerifyPenInfo()
310 {
311 
312     DRIVER_ERROR err = NO_ERROR;
313 
314     if(IOMode.bDevID == FALSE)
315     {
316         return err;
317     }
318 
319     ePen = BLACK_PEN;
320     return NO_ERROR;
321 }
322 
ParsePenInfo(PEN_TYPE & ePen,BOOL QueryPrinter)323 DRIVER_ERROR LJMono::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
324 {
325 
326     ePen = BLACK_PEN;
327 
328     return NO_ERROR;
329 }
330 
CreateCompressor(unsigned int RasterSize)331 Compressor* LJMono::CreateCompressor (unsigned int RasterSize)
332 {
333     return new Mode2 (pSS,RasterSize);
334 }
335 
ParseError(BYTE status_reg)336 DISPLAY_STATUS LJMono::ParseError (BYTE status_reg)
337 {
338     DBG1("LJMono: parsing error info\n");
339 
340     DRIVER_ERROR err = NO_ERROR;
341     BYTE    szReadBuff[256];
342     DWORD   iReadCount = 256;
343     DISPLAY_STATUS  eStatus = (DISPLAY_STATUS) status_reg;
344     char    *tmpStr;
345     int     iErrorCode;
346 
347     if (!IOMode.bDevID)
348         return eStatus;
349 
350     memset (szReadBuff, 0, 256);
351     err = pSS->FromDevice (szReadBuff, &iReadCount);
352     if (err == NO_ERROR && iReadCount == 0)
353         return eStatus;
354 
355     if (strstr ((char *) szReadBuff, "JOB"))
356     {
357         if (!(tmpStr = strstr ((char *) szReadBuff, "NAME")))
358             return DISPLAY_PRINTING;
359         tmpStr += 6;
360         while (*tmpStr < '0' || *tmpStr > '9')
361             tmpStr++;
362         sscanf (tmpStr, "%d", &iErrorCode);
363         if (iErrorCode != (long) (this))
364             return DISPLAY_PRINTING;
365     }
366 
367     if (strstr ((char *) szReadBuff, "END"))
368     {
369         return DISPLAY_PRINTING_COMPLETE;
370     }
371 
372 
373     if (strstr ((char *) szReadBuff, "CANCEL"))
374         return DISPLAY_PRINTING_CANCELED;
375 
376     if (!(tmpStr = strstr ((char *) szReadBuff, "CODE")))
377         return eStatus;
378 
379     tmpStr += 4;
380     while (*tmpStr < '0' || *tmpStr > '9')
381         tmpStr++;
382     sscanf (tmpStr, "%d", &iErrorCode);
383 
384     if (iErrorCode < 32000)
385         return DISPLAY_PRINTING;
386 
387     if (iErrorCode == 40010 || iErrorCode == 40020)
388         return DISPLAY_NO_PENS;     // Actually, out of toner
389 
390     if (iErrorCode == 40021)
391         return DISPLAY_TOP_COVER_OPEN;
392 
393     if ((iErrorCode / 100) == 419)
394         return DISPLAY_OUT_OF_PAPER;
395 
396     if ((iErrorCode / 1000) == 42 || iErrorCode == 40022)
397     {
398         DBG1("Paper Jammed\n");
399         return DISPLAY_PAPER_JAMMED;
400     }
401 
402     if (iErrorCode > 40049 && iErrorCode < 41000)
403     {
404         DBG1("IO trap\n");
405         return DISPLAY_ERROR_TRAP;
406     }
407 
408     if (iErrorCode == 40079)
409         return DISPLAY_OFFLINE;
410 
411     return DISPLAY_ERROR_TRAP;
412 }
413 
414 APDK_END_NAMESPACE
415 
416 #endif  // defined APDK_LJMono
417