Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpijs / ljcolor.cpp
1 /*****************************************************************************\
2   ljcolor.cpp : Implimentation for the LJColor class
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
31
32 #ifdef APDK_LJCOLOR
33
34 #include "header.h"
35 #include "io_defs.h"
36 #include "ljcolor.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 extern uint32_t ulMapGRAY_K_6x6x1[9 * 9 * 9];
44
45 LJColor::LJColor (SystemServices* pSS, int numfonts, BOOL proto)
46     : Printer(pSS, numfonts, proto)
47 {
48
49     if ((!proto) && (IOMode.bDevID))
50     {
51         constructor_error = VerifyPenInfo();
52         CERRCHECK;
53     }
54     else ePen = BOTH_PENS;    // matches default mode
55
56     pMode[GRAYMODE_INDEX]      = new LJColorGrayMode ();
57     pMode[DEFAULTMODE_INDEX]   = new LJColor300DPIMode ();
58     pMode[SPECIALMODE_INDEX]   = new LJColor600DPIMode ();
59     pMode[SPECIALMODE_INDEX+1] = new LJColor150DPIMode ();
60     pMode[SPECIALMODE_INDEX+2] = new LJColorKDraftMode ();
61     ModeCount = 5;
62
63
64     CMYMap = NULL;
65     m_bJobStarted = FALSE;
66 #ifdef  APDK_AUTODUPLEX
67     m_bRotateBackPage = FALSE;  // Lasers don't require back side image to be rotated
68 #endif
69 #ifdef APDK_EXTENDED_MEDIASIZE
70     pMode[SPECIALMODE_INDEX+3] = new LJColorPlainBestMode ();
71     ModeCount = 6;
72 #endif
73     m_pCompressor = NULL;
74     m_iYPos = 0;
75
76     DBG1("LJColor created\n");
77 }
78
79 LJColor::~LJColor ()
80 {
81     DISPLAY_STATUS  eDispStatus;
82     if (IOMode.bStatus && m_bJobStarted)
83     {
84         for (int i = 0; i < 5; i++)
85         {
86             pSS->BusyWait (2000);
87             eDispStatus = ParseError (0);
88             if (eDispStatus == DISPLAY_PRINTING_COMPLETE)
89             {
90                 pSS->DisplayPrinterStatus (eDispStatus);
91                 break;
92             }
93         }
94     }
95 }
96
97 LJColorKDraftMode::LJColorKDraftMode ()
98 : GrayMode (ulMapDJ600_CCM_K)
99 {
100     theQuality = qualityDraft;
101     pmQuality  = QUALITY_DRAFT;
102     pmColor    = GREY_K;
103 #ifdef APDK_AUTODUPLEX
104     bDuplexCapable = TRUE;
105 #endif
106 }
107
108 LJColorGrayMode::LJColorGrayMode () : GrayMode (ulMapGRAY_K_6x6x1)
109 {
110         ResolutionX[0] = 
111         ResolutionY[0] = 
112         BaseResX =
113         BaseResY = 600;
114     pmColor = GREY_K;
115 #ifdef APDK_AUTODUPLEX
116     bDuplexCapable = TRUE;
117 #endif
118 }
119
120 LJColor150DPIMode::LJColor150DPIMode ()
121 : PrintMode (NULL)
122 {
123     ResolutionX[0] = ResolutionY[0] = 150;
124     BaseResX = BaseResY = 150;
125         TextRes = 150;
126         Config.bColorImage = FALSE;
127         theQuality = qualityDraft;
128         pmQuality  = QUALITY_DRAFT;
129 #ifdef APDK_AUTODUPLEX
130     bDuplexCapable = TRUE;
131 #endif
132 }
133
134 LJColor300DPIMode::LJColor300DPIMode ()
135 : PrintMode (NULL)
136 {
137     ResolutionX[0] = 300;
138     ResolutionY[0] = 300;
139     BaseResX = BaseResY = 300;
140
141     Config.bColorImage = FALSE;
142         theQuality = qualityNormal;
143
144     bFontCapable = TRUE;
145     pmQuality = QUALITY_NORMAL;
146         Config.bColorImage = FALSE;
147 #ifdef APDK_AUTODUPLEX
148     bDuplexCapable = TRUE;
149 #endif
150 }
151
152 LJColor600DPIMode::LJColor600DPIMode ()
153 : PrintMode (NULL)
154 {
155     ResolutionX[0] = 600;
156     ResolutionY[0] = 600;
157     BaseResX = BaseResY = 600;
158     Config.bColorImage = FALSE;
159         theQuality = qualityPresentation;
160     bFontCapable = TRUE;
161     pmQuality   = QUALITY_BEST;
162     pmMediaType = MEDIA_PHOTO;
163 #ifdef APDK_AUTODUPLEX
164     bDuplexCapable = TRUE;
165 #endif
166 }
167
168 #ifdef  APDK_EXTENDED_MEDIASIZE
169 LJColorPlainBestMode::LJColorPlainBestMode ()
170 : PrintMode (NULL)
171 {
172     ResolutionX[0] = 600;
173     ResolutionY[0] = 600;
174     BaseResX = BaseResY = 600;
175
176     Config.bColorImage = FALSE;
177         theQuality = qualityPresentation;
178     bFontCapable = TRUE;
179     pmQuality   = QUALITY_BEST;
180 #ifdef APDK_AUTODUPLEX
181     bDuplexCapable = TRUE;
182 #endif
183 }
184 #endif
185
186 HeaderLJColor::HeaderLJColor (Printer* p, PrintContext* pc)
187     : Header(p,pc)
188 { }
189
190 DRIVER_ERROR HeaderLJColor::Send ()
191 {
192     DRIVER_ERROR err;
193     char    uom[12];
194
195     COLORMODE       eC = COLOR;
196     MEDIATYPE       eM;
197     QUALITY_MODE    eQ;
198     BOOL            bD;
199
200     ((LJColor *)thePrinter)->bGrey_K = FALSE;
201     if ((thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD)) == NO_ERROR &&
202         eC == GREY_K)
203     {
204         ((LJColor *)thePrinter)->bGrey_K = TRUE;
205     }
206
207     StartSend ();
208
209     if (eC != GREY_K)
210     {
211
212 /*
213  *      Configure image data - ESC*v#W - # = 6 bytes
214  *      02 - RGB colorspace (00 - Device RGB)
215  *      03 - Direct pixel
216  *      08 - bits per index - ignored for direct pixel
217  *      08, 08, 08 - bits per primary each
218  */
219
220         err = thePrinter->Send ((const BYTE *) "\033*v6W\00\03\010\010\010\010", 11);
221         ERRCHECK;
222
223 //      Continues tone dither
224 //      Logical operation - 0
225
226 //      err = thePrinter->Send ((const BYTE *) "\033*t18J\033*l204O", 13);
227         err = thePrinter->Send ((const BYTE *) "\033*t18J", 6);
228
229         ERRCHECK;
230
231 /*
232  *      Driver Configuration Command - ESC*#W - # = 3 bytes
233  *      device id - 6 = color HP LaserJet Printer
234  *      func index - 4 = Select Colormap
235  *      argument - 2   = Vivid Graphics
236  */
237
238         err = thePrinter->Send ((const BYTE *) "\033*o3W\06\04\06", 8);
239         ERRCHECK;
240
241 /*
242  *      Program color palette entries
243  */
244         err = thePrinter->Send ((const BYTE *) "\033*v255A\033*v255B\033*v255C\033*v0I", 26);
245         ERRCHECK;
246
247         err = thePrinter->Send ((const BYTE *) "\033*v255A\033*v0B\033*v0C\033*v6I", 22);
248         ERRCHECK;
249         err = thePrinter->Send ((const BYTE *) "\033*v0A\033*v255B\033*v0C\033*v5I", 22);
250         ERRCHECK;
251         err = thePrinter->Send ((const BYTE *) "\033*v0A\033*v0B\033*v255C\033*v3I", 22);
252         ERRCHECK;
253         err = thePrinter->Send ((const BYTE *) "\033*v255A\033*v255B\033*v0C\033*v4I", 24);
254         ERRCHECK;
255         err = thePrinter->Send ((const BYTE *) "\033*v255A\033*v0B\033*v255C\033*v2I", 24);
256         ERRCHECK;
257         err = thePrinter->Send ((const BYTE *) "\033*v0A\033*v255B\033*v255C\033*v1I", 24);
258         ERRCHECK;
259         err = thePrinter->Send ((const BYTE *) "\033*v0A\033*v0B\033*v0C\033*v7I", 20);
260         ERRCHECK;
261     }
262
263     sprintf (uom, "\033*r%dS", thePrintContext->OutputPixelsPerRow ());
264     err = thePrinter->Send ((const BYTE*)uom, strlen (uom));
265     ERRCHECK;
266
267     err = Graphics ();     // start raster graphics and set compression mode
268
269     return err;
270 }
271
272 DRIVER_ERROR HeaderLJColor::StartSend ()
273 {
274     DRIVER_ERROR err;
275     char    res[72];
276     int     iRes;
277
278     iRes = thePrintContext->EffectiveResolutionY ();
279
280     err = thePrinter->Send ((const BYTE*)UEL,sizeof(UEL));
281     ERRCHECK;
282
283     sprintf (res, "@PJL SET PAGEPROTECT=AUTO@PJL SET RESOLUTION=%d\015\012", iRes);
284     err = thePrinter->Send ((const BYTE *) res, strlen (res));
285     ERRCHECK;
286
287     if (thePrinter->IOMode.bStatus)
288     {
289         sprintf (res, "@PJL JOB NAME = \"%ld\"\015\012", (long) (thePrinter));
290         err = thePrinter->Send ((const BYTE *) res, strlen (res));
291         ERRCHECK;
292     }
293
294     QUALITY_MODE    eQ = QUALITY_NORMAL;
295     COLORMODE       eC;
296     MEDIATYPE       eM;
297     BOOL            bD;
298
299     thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD);
300
301     if (eQ == QUALITY_DRAFT)
302     {
303         strcpy (res, "@PJL SET RET=OFF\015\012@PJL SET ECONOMODE=ON\015\012");
304         err = thePrinter->Send ((const BYTE *) res, strlen (res));
305         ERRCHECK;
306     }
307
308     if (thePrinter->IOMode.bStatus)
309     {
310         strcpy (res, "@PJL USTATUSOFF\015\012@PJL USTATUS DEVICE = ON\015\012@PJL USTATUS JOB = ON\015\012");
311         err = thePrinter->Send ((const BYTE *) res, strlen (res));
312         ERRCHECK;
313     }
314
315 //  Duplexing directive
316
317     strcpy (res, "@PJL SET DUPLEX=OFF\015\012");
318
319 #ifdef APDK_AUTODUPLEX
320     DUPLEXMODE  dupmode = thePrintContext->QueryDuplexMode ();\r
321     if (dupmode != DUPLEXMODE_NONE)\r
322     {\r
323         strcpy (res, "@PJL SET DUPLEX=ON\015\012@PJL SET BINDING=");\r
324         if (dupmode == DUPLEXMODE_BOOK)\r
325             strcat (res, "LONGEDGE\015\012");\r
326         else\r
327             strcat (res, "SHORTEDGE\015\012");\r
328     }\r
329 #endif
330
331     err = thePrinter->Send ((const BYTE *) res, strlen (res));
332
333
334     err = thePrinter->Send ((const BYTE*) EnterLanguage, sizeof (EnterLanguage));
335     ERRCHECK;
336
337     err = thePrinter->Send ((const BYTE*) "PCL\015\012", 5);
338     ERRCHECK;
339
340     err = thePrinter->Send ((const BYTE*) Reset,sizeof (Reset));
341     ERRCHECK;
342
343     sprintf (res, "\033&l%dH", thePrintContext->GetMediaSource ());
344     err = thePrinter->Send ((const BYTE *) res, strlen (res));          // Source
345     ERRCHECK;
346
347 //  Media size, vertical spacing between lines and top margin
348
349     memcpy (res, mediasize, mscount - 1);
350     strcpy (res+mscount-1, "a8c0E");
351     err = thePrinter->Send ((const BYTE *) res, strlen (res));
352     ERRCHECK;
353
354         sprintf (res, "\033*t%dR\033&u%dD", iRes, iRes);
355     err=thePrinter->Send ((const BYTE*) res, strlen (res));
356     ERRCHECK;
357
358     err = Margins ();
359     ERRCHECK;
360     CAPy = 0;
361
362 //  Default is single sided printing
363
364     strcpy (res, "\033&l0S");
365
366 #ifdef APDK_AUTODUPLEX
367     DUPLEXMODE  eDupMode = thePrintContext->QueryDuplexMode ();
368     if (eDupMode != DUPLEXMODE_NONE)
369     {
370         sprintf (res, "\033&l%dS", (eDupMode == DUPLEXMODE_BOOK) ? 1 : 2);
371     }
372 #endif
373     err = thePrinter->Send ((const BYTE *) res, strlen (res));
374     ERRCHECK;
375
376 /*
377  *  Set orientation to Portrait. APDK supports printing in Portrait mode only.
378  *  If users desire Landscape printing, application/gluecode will have to
379  *  rearrange the rasters appropriately.
380  */
381
382     err = thePrinter->Send ((const BYTE *) "\033&l0O", 5);
383
384     // Number of copies
385     sprintf (res, "\033&l%dX", thePrintContext->GetCopyCount ());
386     err = thePrinter->Send ((const BYTE *) res, strlen (res));
387     ERRCHECK;
388
389     return err;
390 }
391
392 DRIVER_ERROR HeaderLJColor::Graphics ()
393 {
394
395     DRIVER_ERROR err;
396     err = thePrinter->Send ((const BYTE*) grafStart, sizeof (grafStart));
397     ERRCHECK;
398
399     if (((LJColor *) thePrinter)->bGrey_K)
400     {
401         err = thePrinter->Send ((const BYTE*) "\033*b2M", 5);
402         ERRCHECK;
403     }
404     else
405     {
406         err = thePrinter->Send ((const BYTE*) "\033*b3M", 5);
407     }
408
409     return err;
410 }
411
412 DRIVER_ERROR HeaderLJColor::EndJob ()
413 {
414     char    szBuff[128];
415     DRIVER_ERROR    err = NO_ERROR;
416     if (thePrinter->IOMode.bStatus)
417     {
418         sprintf (szBuff, "\033E\033%%-12345X@PJL EOJ NAME = \"%ld\"\015\012@PJL RESET\015\012",
419                  (long) (thePrinter));
420         err = thePrinter->Send ((const BYTE *) szBuff, strlen (szBuff));
421         ERRCHECK;
422     }
423     strcpy (szBuff, "\033%-12345X");
424     err = thePrinter->Send ((const BYTE *) szBuff, strlen (szBuff));
425
426     return err;
427 }
428
429 DRIVER_ERROR HeaderLJColor::FormFeed ()
430 {
431     ((LJColor *)thePrinter)->bFGColorSet = FALSE;
432     ((LJColor *)thePrinter)->m_iYPos = 0;
433
434     return (thePrinter->Send ((const BYTE *) "\014", 1));
435 }
436
437 DRIVER_ERROR HeaderLJColor::SendCAPy (unsigned int iAbsY)
438 {
439     if (iAbsY == 0)
440     {
441         return thePrinter->Send ((const BYTE *) "\033*p0Y", 5);
442     }
443     return NO_ERROR;
444 }
445
446 DRIVER_ERROR LJColor::Encapsulate (const RASTERDATA* InputRaster, BOOL bLastPlane)
447 {
448     char    szScratchStr[16];
449     DRIVER_ERROR    err;
450     m_iYPos++;
451     if (bFGColorSet == FALSE)
452     {
453         Send ((const BYTE *) "\033*v7S", 5);
454         bFGColorSet = TRUE;
455     }
456     sprintf (szScratchStr, "\033*b%uW", InputRaster->rastersize[COLORTYPE_COLOR]);
457     err = Send ((const BYTE *) szScratchStr, strlen (szScratchStr));
458     if (err == NO_ERROR)
459     {
460         err = Send (InputRaster->rasterdata[COLORTYPE_COLOR], InputRaster->rastersize[COLORTYPE_COLOR]);
461     }
462
463 /*
464  *  Printers with low memory (64 MB or less) can run out of memory during decompressing
465  *  the image data and will abort the job. To prevent this, restart raster command.
466  *  Raghu
467  */
468
469     if (!bGrey_K &&
470         m_iYResolution == 600 &&
471         m_iYPos % 1200 == 0)
472     {
473         SkipRasters (0);
474         err = Send ((const BYTE *) "\033*rC\033*r1A\033*b3M", 14);
475     }
476
477     return err;
478 }
479
480 DRIVER_ERROR LJColor::SkipRasters (int nBlankRasters)
481 {
482     char    szScratchStr[16];
483     DRIVER_ERROR    err = NO_ERROR;
484     if (m_pCompressor)
485     {
486         m_pCompressor->Flush ();
487     }
488     if (nBlankRasters > 0)
489     {
490         m_iYPos += nBlankRasters;
491         sprintf (szScratchStr, "\033*p%dY", m_iYPos);
492         err = Send ((const BYTE *) szScratchStr, strlen (szScratchStr));
493     }
494     return err;
495 }
496
497
498 Header* LJColor::SelectHeader (PrintContext *pc)
499 {
500     m_iYResolution = pc->EffectiveResolutionY ();
501     return new HeaderLJColor (this, pc);
502 }
503
504 DRIVER_ERROR LJColor::VerifyPenInfo()
505 {
506
507     DRIVER_ERROR err = NO_ERROR;
508
509     if(IOMode.bDevID == FALSE)
510     {
511         return err;
512     }
513
514     ePen = BOTH_PENS;
515     return NO_ERROR;
516 }
517
518 DRIVER_ERROR LJColor::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
519 {
520 //    char* str;
521 //    DRIVER_ERROR err = SetPenInfo(str, QueryPrinter);
522 //    ERRCHECK;
523
524     ePen = BOTH_PENS;
525
526     return NO_ERROR;
527 }
528
529 Compressor* LJColor::CreateCompressor (unsigned int RasterSize)
530 {
531     bFGColorSet = FALSE;
532     if (bGrey_K)
533         return new Mode2 (pSS, RasterSize);
534
535     m_pCompressor = new Mode3 (pSS, this, RasterSize);
536     return m_pCompressor;
537 }
538
539 /*
540  *  Function name: ParseError
541  *
542  *  Owner: Darrell Walker
543  *
544  *  Purpose:  To determine what error state the printer is in.
545  *
546  *  Called by: Send()
547  *
548  *  Parameters on entry: status_reg is the contents of the centronics
549  *                      status register (at the time the error was
550  *                      detected)
551  *
552  *  Parameters on exit: unchanged
553  *
554  *  Return Values: The proper DISPLAY_STATUS to reflect the printer
555  *              error state.
556  *
557  */
558
559 /*  We have to override the base class's (Printer) ParseError function due
560     to the fact that the 8XX series returns a status byte of F8 when it's out of
561     paper.  Unfortunately, the 600 series returns F8 when they're turned off.
562     The way things are structured in Printer::ParseError, we used to check only
563     for DEVICE_IS_OOP.  This would return true even if we were connected to a
564     600 series printer that was turned off, causing the Out of paper status
565     message to be displayed.  This change also reflects a corresponding change
566     in IO_defs.h, where I split DEVICE_IS_OOP into DEVICE_IS_OOP, DJ400_IS_OOP, and
567     DJ8XX_IS_OOP and we now check for DJ8XX_IS_OOP in the DJ8xx class's
568     ParseError function below.  05/11/99 DGC.
569 */
570
571 DISPLAY_STATUS LJColor::ParseError(BYTE status_reg)
572 {
573     DBG1("LJColor: parsing error info\n");
574
575     DRIVER_ERROR err = NO_ERROR;
576     BYTE    szReadBuff[256];
577     DWORD   iReadCount = 256;
578     DISPLAY_STATUS  eStatus = (DISPLAY_STATUS) status_reg;
579     char    *tmpStr;
580     int     iErrorCode;
581
582     if (!IOMode.bDevID)
583         return eStatus;
584
585     memset (szReadBuff, 0, 256);
586     err = pSS->FromDevice (szReadBuff, &iReadCount);
587     if (err == NO_ERROR && iReadCount == 0)
588         return eStatus;
589
590     if (strstr ((char *) szReadBuff, "JOB"))
591     {
592         if (!(tmpStr = strstr ((char *) szReadBuff, "NAME")))
593             return DISPLAY_PRINTING;
594         tmpStr += 6;
595         while (*tmpStr < '0' || *tmpStr > '9')
596             tmpStr++;
597         sscanf (tmpStr, "%d", &iErrorCode);
598         if (iErrorCode != (long) (this))
599             return DISPLAY_PRINTING;
600     }
601
602     if (strstr ((char *) szReadBuff, "END"))
603     {
604         return DISPLAY_PRINTING_COMPLETE;
605     }
606
607
608     if (strstr ((char *) szReadBuff, "CANCEL"))
609         return DISPLAY_PRINTING_CANCELED;
610
611     if (!(tmpStr = strstr ((char *) szReadBuff, "CODE")))
612         return eStatus;
613
614     tmpStr += 4;
615     while (*tmpStr < '0' || *tmpStr > '9')
616         tmpStr++;
617     sscanf (tmpStr, "%d", &iErrorCode);
618
619     if (iErrorCode < 32000)
620         return DISPLAY_PRINTING;
621
622     if (iErrorCode == 40010 || iErrorCode == 40020)
623         return DISPLAY_NO_PENS;     // Actually, out of toner
624
625     if (iErrorCode == 40021)
626         return DISPLAY_TOP_COVER_OPEN;
627
628     if ((iErrorCode / 100) == 419)
629         return DISPLAY_OUT_OF_PAPER;
630
631     if ((iErrorCode / 1000) == 42 || iErrorCode == 40022)
632     {
633         DBG1("Paper Jammed\n");
634         return DISPLAY_PAPER_JAMMED;
635     }
636
637     if (iErrorCode > 40049 && iErrorCode < 41000)
638     {
639         DBG1("IO trap\n");
640         return DISPLAY_ERROR_TRAP;
641     }
642
643     if (iErrorCode == 40079)
644         return DISPLAY_OFFLINE;
645
646     return DISPLAY_ERROR_TRAP;
647 }
648
649 APDK_END_NAMESPACE
650
651 #endif  // defined APDK_LJCOLOR