Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpijs / dj850.cpp
1 /*****************************************************************************\
2   dj850.cpp : Implimentation for the DJ850 class
3
4   Copyright (c) 1996 - 2002, 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 #if defined(APDK_DJ850)
32
33 #include "header.h"
34 #include "io_defs.h"
35 #include "dj850.h"
36 #include "printerproxy.h"
37
38 APDK_BEGIN_NAMESPACE
39 extern BYTE* GetHT3x3_4();
40 extern BYTE* GetHT6x6_4();
41 APDK_END_NAMESPACE
42
43 APDK_BEGIN_NAMESPACE
44
45 extern uint32_t ulMapDJ600_CCM_K[ 9 * 9 * 9 ];
46 extern uint32_t ulMapDJ850_Normal_KCMY[9 * 9 * 9];
47 extern uint32_t ulMapDJ600_CCM_K[ 9 * 9 * 9 ];
48 extern uint32_t ulMapGRAY_K_6x6x1[9 * 9 * 9];
49
50 DJ850Mode1::DJ850Mode1()    // Normal Color
51 : PrintMode(ulMapDJ850_Normal_KCMY)
52 // 600x600x1 K
53 // 300x300x2 CMY
54 {
55     ColorDepth[K]=1;  // 600x600x1 K
56
57     for (int i=1; i < 4; i++)
58         ColorDepth[i]=2;    // 300x300x2 CMY
59
60     ResolutionX[K]=ResolutionY[K]=600;
61     MixedRes = TRUE;
62
63     ColorFEDTable = GetHT3x3_4();
64
65 }
66
67 DJ850Mode3::DJ850Mode3()    // Draft Color
68 : PrintMode(ulMapDJ850_Normal_KCMY)
69 // 300x300x1 KCMY
70 {
71     theQuality = qualityDraft;
72     pmQuality = QUALITY_DRAFT;
73 }
74
75 DJ850Mode4::DJ850Mode4()    // Draft Gray K
76 : GrayMode(ulMapDJ600_CCM_K)
77 // 300x300x1 K
78 {
79     theQuality = qualityDraft;
80     pmQuality = QUALITY_DRAFT;
81 }
82
83 DJ850Mode5::DJ850Mode5()    // Normal Gray K
84 : GrayMode(ulMapGRAY_K_6x6x1)
85 // 600x600x1 K
86 {
87     BaseResX = BaseResY = 600;
88     ResolutionX[K]=ResolutionY[K]=600;
89 }
90
91 DJ850::DJ850(SystemServices* pSS,
92                        int numfonts, BOOL proto)
93     : Printer(pSS, numfonts, proto)
94 {
95     if ((!proto) && (IOMode.bDevID))
96     {
97         constructor_error = VerifyPenInfo();
98         CERRCHECK;
99     }
100     else ePen=BOTH_PENS;    // matches default mode
101
102     pMode[GRAYMODE_INDEX]      = new DJ850Mode5 ();   // Normal Gray K
103     pMode[DEFAULTMODE_INDEX]   = new DJ850Mode1 ();   // Normal Color
104     pMode[SPECIALMODE_INDEX] = new DJ850Mode3 ();   // Draft Color
105     pMode[SPECIALMODE_INDEX+1] = new DJ850Mode4 ();   // Draft Gray K
106     ModeCount = 4;
107
108     CMYMap = ulMapDJ850_Normal_KCMY;
109
110     DBG1("DJ850 created\n");
111 }
112
113 Header850::Header850(Printer* p,PrintContext* pc)
114     : Header895(p,pc)
115 { }
116
117 Header* DJ850::SelectHeader(PrintContext* pc)
118 {
119     return new Header850(this,pc);
120 }
121
122 DRIVER_ERROR Header850::StartSend()
123 // common items gathered for code savings
124 {
125     DRIVER_ERROR err;
126
127     err = thePrinter->Send((const BYTE*)Reset,sizeof(Reset));
128     ERRCHECK;
129 #if 0
130     err = thePrinter->Send((const BYTE*)UEL,sizeof(UEL));
131     ERRCHECK;
132
133     err = thePrinter->Send((const BYTE*)EnterLanguage,sizeof(EnterLanguage));
134     ERRCHECK;
135
136     if (!thePrinter->UseGUIMode(thePrintContext->CurrentMode))
137         err = thePrinter->Send((const BYTE*)PCL3,sizeof(PCL3));
138     else
139         err = thePrinter->Send((const BYTE*)PCLGUI,sizeof(PCLGUI));
140     ERRCHECK;
141
142     err = thePrinter->Send((const BYTE*)&LF,1);
143     ERRCHECK;
144 #endif
145     err=Modes();            // Set media source, type, size and quality modes.
146     ERRCHECK;
147
148 //  Now send media pre-load command
149     err = thePrinter->Send ((const BYTE *) "\033&l-2H", 6);   
150     ERRCHECK;
151
152     char uom[10];
153     sprintf(uom,"%c%c%c%d%c",ESC,'&','u',thePrintContext->EffectiveResolutionY(),'D');
154     err=thePrinter->Send((const BYTE*)uom, strlen (uom));
155     ERRCHECK;
156
157     if (!thePrinter->UseGUIMode(thePrintContext->CurrentMode))
158         err=Margins();          // set margins
159
160     else    // special GUI mode top margin set
161     {
162         CAPy = thePrintContext->GUITopMargin();
163     }
164
165     return err;
166 }
167
168 DRIVER_ERROR DJ850::VerifyPenInfo()
169 {
170
171     DRIVER_ERROR err = NO_ERROR;
172
173     if(IOMode.bDevID == FALSE)
174     {
175         return err;
176     }
177
178     err = ParsePenInfo(ePen);
179
180     ERRCHECK;
181
182     // check for the normal case
183     if (ePen == BOTH_PENS)
184     {
185         return NO_ERROR;
186     }
187
188     while ( ePen != BOTH_PENS   )
189     {
190
191         switch (ePen)
192         {
193             case BLACK_PEN:
194                 // black pen installed, need to install color pen
195                 pSS->DisplayPrinterStatus(DISPLAY_NO_COLOR_PEN);
196                 break;
197             case COLOR_PEN:
198                 // color pen installed, need to install black pen
199                 pSS->DisplayPrinterStatus(DISPLAY_NO_BLACK_PEN);
200                 break;
201             case NO_PEN:
202                 // neither pen installed
203             default:
204                 pSS->DisplayPrinterStatus(DISPLAY_NO_PENS);
205                 break;
206         }
207
208         if (pSS->BusyWait(500) == JOB_CANCELED)
209         {
210             return JOB_CANCELED;
211         }
212
213         err =  ParsePenInfo(ePen);
214         ERRCHECK;
215     }
216
217     pSS->DisplayPrinterStatus(DISPLAY_PRINTING);
218
219     return NO_ERROR;
220 }
221
222 DRIVER_ERROR DJ850::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
223 {
224     char* str;
225     DRIVER_ERROR err = SetPenInfo (str, QueryPrinter);
226     ERRCHECK;
227
228     if (*str != '$')
229     {
230         return BAD_DEVICE_ID;
231     }
232
233     // parse penID
234     PEN_TYPE temp_pen1;
235     // check pen1, assume it is black, pen2 is color
236     switch (str[1])
237     {
238         case 'H': // (H)obbes
239       case 'L': // (L)inus
240       case 'Z': // (Z)orro
241       {
242          temp_pen1 = BLACK_PEN;
243          break;
244       }
245         case 'X': return UNSUPPORTED_PEN;
246         default:  temp_pen1 = NO_PEN; break;
247     }
248
249     // now check pen2
250
251     int i = 2;
252     while ((i < DevIDBuffSize) && str[i] != '$') i++; // handles variable length penIDs
253     if (i == DevIDBuffSize)
254     {
255         return BAD_DEVICE_ID;
256     }
257
258     i++;
259
260     // Check for (M)onet color pen, note (X)Undefined, (A)Missing.
261     if(str[i] == 'M')
262     // check what pen1 was
263     {
264         if (temp_pen1 == BLACK_PEN)
265         {
266             ePen = BOTH_PENS;
267         }
268         else
269         {
270             ePen = COLOR_PEN;
271         }
272     }
273     else // no color pen, just set what pen1 was
274     {
275         ePen = temp_pen1;
276     }
277
278     return NO_ERROR;
279 }
280
281
282 Compressor* DJ850::CreateCompressor(unsigned int RasterSize)
283 {
284     DBG1("Compression = Mode2\n");
285     return new Mode2(pSS,RasterSize);
286 }
287
288 BOOL DJ850::UseGUIMode(PrintMode* pPrintMode)
289 {
290     return (!pPrintMode->bFontCapable);
291 }
292
293
294 /*
295  *  Function name: ParseError
296  *
297  *  Owner: Darrell Walker
298  *
299  *  Purpose:  To determine what error state the printer is in.
300  *
301  *  Called by: Send()
302  *
303  *  Parameters on entry: status_reg is the contents of the centronics
304  *                      status register (at the time the error was
305  *                      detected)
306  *
307  *  Parameters on exit: unchanged
308  *
309  *  Return Values: The proper DISPLAY_STATUS to reflect the printer
310  *              error state.
311  *
312  */
313
314 /*  We have to override the base class's (Printer) ParseError function due
315     to the fact that the 8XX series returns a status byte of F8 when it's out of
316     paper.  Unfortunately, the 600 series returns F8 when they're turned off.
317     The way things are structured in Printer::ParseError, we used to check only
318     for DEVICE_IS_OOP.  This would return true even if we were connected to a
319     600 series printer that was turned off, causing the Out of paper status
320     message to be displayed.  This change also reflects a corresponding change
321     in IO_defs.h, where I split DEVICE_IS_OOP into DEVICE_IS_OOP, DJ400_IS_OOP, and
322     DJ8XX_IS_OOP and we now check for DJ8XX_IS_OOP in the DJ8xx class's
323     ParseError function below.  05/11/99 DGC.
324 */
325
326 DISPLAY_STATUS DJ850::ParseError(BYTE status_reg)
327 {
328     DBG1("DJ850: parsing error info\n");
329
330     DRIVER_ERROR err = NO_ERROR;
331     BYTE DevIDBuffer[DevIDBuffSize];
332
333     if(IOMode.bDevID)
334     {
335         // If a bi-di cable was plugged in and everything was OK, let's see if it's still
336         // plugged in and everything is OK
337         err = pSS->GetDeviceID(DevIDBuffer, DevIDBuffSize, TRUE);
338         if(err != NO_ERROR)
339             // job was bi-di but now something's messed up, probably cable unplugged
340             return DISPLAY_COMM_PROBLEM;
341
342         if ( TopCoverOpen(status_reg) )
343         {
344             DBG1("Top Cover Open\n");
345             return DISPLAY_TOP_COVER_OPEN;
346         }
347
348         // VerifyPenInfo will handle prompting the user
349         // if this is a problem
350         err = VerifyPenInfo();
351
352         if(err != NO_ERROR)
353             // VerifyPenInfo returned an error, which can only happen when ToDevice
354             // or GetDeviceID returns an error. Either way, it's BAD_DEVICE_ID or
355             // IO_ERROR, both unrecoverable.  This is probably due to the printer
356             // being turned off during printing, resulting in us not being able to
357             // power it back on in VerifyPenInfo, since the buffer still has a
358             // partial raster in it and we can't send the power-on command.
359             return DISPLAY_COMM_PROBLEM;
360     }
361
362     // check for errors we can detect from the status reg
363     if (IOMode.bStatus)
364     {
365         if ( DEVICE_IS_OOP(status_reg) )
366         {
367             DBG1("Out Of Paper\n");
368             return DISPLAY_OUT_OF_PAPER;
369         }
370
371       if (DEVICE_PAPER_JAMMED(status_reg))
372       {
373          DBG1("Paper Jammed\n");
374          return DISPLAY_PAPER_JAMMED;
375       }
376
377       if (DEVICE_IO_TRAP(status_reg))
378         {
379             DBG1("IO trap\n");
380             return DISPLAY_ERROR_TRAP;
381         }
382     }
383
384     // don't know what the problem is-
385     //  Is the PrinterAlive?
386     if (pSS->PrinterIsAlive())
387     {
388         iTotal_SLOW_POLL_Count += iMax_SLOW_POLL_Count;
389 #if defined(DEBUG) && (DBG_MASK & DBG_LVL1)
390         printf("iTotal_SLOW_POLL_Count = %d\n",iTotal_SLOW_POLL_Count);
391 #endif
392         // -Note that iTotal_SLOW_POLL_Count is a multiple of
393         //  iMax_SLOW_POLL_Count allowing us to check this
394         //  on an absolute time limit - not relative to the number
395         //  of times we happen to have entered ParseError.
396         // -Also note that we have different thresholds for uni-di & bi-di.
397         if(
398             ((IOMode.bDevID == FALSE) && (iTotal_SLOW_POLL_Count >= 60)) ||
399             ((IOMode.bDevID == TRUE)  && (iTotal_SLOW_POLL_Count >= 120))
400           )
401         {
402             return DISPLAY_BUSY;
403         }
404         else
405         {
406             return DISPLAY_PRINTING;
407         }
408     }
409     else
410     {
411         return DISPLAY_COMM_PROBLEM;
412     }
413 }
414
415 APDK_END_NAMESPACE
416
417 #endif  // defined APDK_DJ850