1 /*****************************************************************************\
2 dj8xx.cpp : Implimentation for the DJ8xx class
4 Copyright (c) 1996 - 2001, Hewlett-Packard Co.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
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.
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 \*****************************************************************************/
32 #if defined(APDK_DJ8xx)|| defined(APDK_DJ9xx)
37 #include "printerproxy.h"
40 extern BYTE* GetHT3x3_4();
41 extern BYTE* GetHT6x6_4();
46 extern uint32_t ulMapDJ895_KCMY[ 9 * 9 * 9 ];
47 extern uint32_t ulMapDJ600_CCM_K[ 9 * 9 * 9 ];
48 extern uint32_t ulMapDJ895_HB_KCMY[ 9 * 9 * 9 ];
49 extern uint32_t ulMapDJ895_Binary_KCMY[ 9 * 9 * 9 ];
50 extern uint32_t ulMapGRAY_K_6x6x1[9 * 9 * 9];
52 DJ895Mode1::DJ895Mode1() // Normal Color
53 : PrintMode(ulMapDJ895_KCMY)
58 ColorDepth[K]=1; // 600x600x1 K
60 for (int i=1; i < 4; i++)
61 ColorDepth[i]=2; // 300x300x2 CMY
63 ResolutionX[K]=ResolutionY[K]=600;
67 ColorFEDTable = GetHT3x3_4();
69 bFontCapable = FALSE; // DJ895 can't do fonts and hifipe at same time
72 DJ895Mode2::DJ895Mode2() // Photo
73 : PrintMode(ulMapDJ895_HB_KCMY)
78 ColorDepth[K]=1; // 600x600x1 K
81 ColorDepth[i]=2; // 600x600x2 CMY
84 ResolutionX[i]=ResolutionY[i]=600;
86 BaseResX = BaseResY = 600;
90 theQuality = qualityPresentation;
92 ColorFEDTable = GetHT6x6_4();
94 bFontCapable = FALSE; // DJ895 can't do fonts and hifipe at same time
96 // strcpy(ModeName, "Photo");
98 pmQuality = QUALITY_BEST;
99 pmMediaType = MEDIA_PHOTO;
102 DJ895Mode3::DJ895Mode3() // Draft Color
103 : PrintMode(ulMapDJ895_Binary_KCMY)
107 theQuality = qualityDraft;
108 // strcpy(ModeName,"Draft");
109 pmQuality = QUALITY_DRAFT;
112 DJ895Mode4::DJ895Mode4() // Draft Gray K
113 : GrayMode(ulMapDJ600_CCM_K)
116 theQuality = qualityDraft;
117 pmQuality = QUALITY_DRAFT;
120 #ifdef APDK_EXTENDED_MEDIASIZE
121 DJ895Mode5::DJ895Mode5() // Normal Gray K
122 : GrayMode(ulMapGRAY_K_6x6x1)
125 BaseResX = BaseResY = 600;
126 ResolutionX[K]=ResolutionY[K]=600;
127 bFontCapable = FALSE;
131 DJ8xx::DJ8xx(SystemServices* pSS,
132 int numfonts, BOOL proto)
133 : Printer(pSS, numfonts, proto)
136 if ((!proto) && (IOMode.bDevID))
138 constructor_error = VerifyPenInfo();
141 else ePen=BOTH_PENS; // matches default mode
143 #ifdef APDK_EXTENDED_MEDIASIZE
144 pMode[GRAYMODE_INDEX] = new DJ895Mode5 (); // Normal Gray K
146 pMode[GRAYMODE_INDEX] = new GrayMode (ulMapDJ600_CCM_K); // Normal Gray K
148 pMode[DEFAULTMODE_INDEX] = new DJ895Mode1 (); // Normal Color
149 pMode[SPECIALMODE_INDEX] = new DJ895Mode2 (); // Photo
150 pMode[SPECIALMODE_INDEX+1] = new DJ895Mode3 (); // Draft Color
151 pMode[SPECIALMODE_INDEX+2] = new DJ895Mode4 (); // Draft Gray K
154 CMYMap = ulMapDJ895_Binary_KCMY;
156 DBG1("DJ8xx created\n");
160 Header895::Header895(Printer* p,PrintContext* pc)
164 DRIVER_ERROR Header895::Send()
169 err = ConfigureRasterData();
172 err=Graphics(); // start raster graphics and set compression mode
174 // this is the pre-pick command but it doesn't work. hmm...
175 // err = thePrinter->Send((const BYTE*)DJ895_Pre_Pick,sizeof(DJ895_Pre_Pick));
180 DRIVER_ERROR Header895::StartSend()
181 // common items gathered for code savings
185 err = thePrinter->Send((const BYTE*)Reset,sizeof(Reset));
188 err = thePrinter->Send((const BYTE*)UEL,sizeof(UEL));
191 err = thePrinter->Send((const BYTE*)EnterLanguage,sizeof(EnterLanguage));
194 if (!thePrinter->UseGUIMode(thePrintContext->CurrentMode))
195 err = thePrinter->Send((const BYTE*)PCL3,sizeof(PCL3));
197 err = thePrinter->Send((const BYTE*)PCLGUI,sizeof(PCLGUI));
200 err = thePrinter->Send((const BYTE*)&LF,1);
203 err=Modes(); // Set media source, type, size and quality modes.
206 // Now send media pre-load command
207 err = thePrinter->Send ((const BYTE *) "\033&l-2H", 6);
211 sprintf(uom,"%c%c%c%d%c",ESC,'&','u',thePrintContext->EffectiveResolutionY(),'D');
212 err=thePrinter->Send((const BYTE*)uom, strlen (uom));
215 if (!thePrinter->UseGUIMode(thePrintContext->CurrentMode))
216 err=Margins(); // set margins
218 else // special GUI mode top margin set
220 CAPy = thePrintContext->GUITopMargin();
226 extern BYTE EscAmplCopy(BYTE *dest, int num, char end);
229 DRIVER_ERROR Header895::Graphics()
230 // variant due to compression problems
232 DRIVER_ERROR error= thePrinter->Send((const BYTE*)grafStart, sizeof(grafStart) );
236 if (thePrintMode->Config.bCompress)
238 error= thePrinter->Send((const BYTE*)grafMode2, sizeof(grafMode2) );
244 error= thePrinter->Send((const BYTE*)grafMode0, sizeof(grafMode0) );
247 #define GRAPHICSIZE (sizeof(grafStart)+sizeof(grafMode9)+sizeof(SeedSame))
251 Header* DJ8xx::SelectHeader(PrintContext* pc)
253 return new Header895(this,pc);
256 DRIVER_ERROR DJ8xx::VerifyPenInfo()
259 DRIVER_ERROR err = NO_ERROR;
261 if(IOMode.bDevID == FALSE)
266 err = ParsePenInfo(ePen);
268 if(err == UNSUPPORTED_PEN) // probably Power Off - pens couldn't be read
270 DBG1("DJ8xx::Need to do a POWER ON to get penIDs\n");
272 // have to delay the POWER ON will be ignored
273 if (pSS->BusyWait((DWORD)2000) == JOB_CANCELED)
278 DWORD length = sizeof(DJ895_Power_On);
279 err = pSS->ToDevice(DJ895_Power_On,&length);
282 err = pSS->FlushIO();
285 // give the printer some time to power up
286 if (pSS->BusyWait ((DWORD) 2500) == JOB_CANCELED)
291 err = ParsePenInfo(ePen);
296 // check for the normal case
297 if (ePen == BOTH_PENS)
302 while ( ePen != BOTH_PENS )
308 // black pen installed, need to install color pen
309 pSS->DisplayPrinterStatus(DISPLAY_NO_COLOR_PEN);
312 // color pen installed, need to install black pen
313 pSS->DisplayPrinterStatus(DISPLAY_NO_BLACK_PEN);
316 // neither pen installed
318 pSS->DisplayPrinterStatus(DISPLAY_NO_PENS);
322 if (pSS->BusyWait(500) == JOB_CANCELED)
327 err = ParsePenInfo(ePen);
331 pSS->DisplayPrinterStatus(DISPLAY_PRINTING);
336 DRIVER_ERROR DJ8xx::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
339 DRIVER_ERROR err = SetPenInfo (str, QueryPrinter);
344 return BAD_DEVICE_ID;
349 // check pen1, assume it is black, pen2 is color
352 case 'H': // (H)obbes
356 temp_pen1 = BLACK_PEN;
359 case 'X': return UNSUPPORTED_PEN;
360 default: temp_pen1 = NO_PEN; break;
366 while ((i < DevIDBuffSize) && str[i] != '$') i++; // handles variable length penIDs
367 if (i == DevIDBuffSize)
369 return BAD_DEVICE_ID;
374 // need to be more forgiving of the color pen type because of
375 // the unknown chinookID for DJ970
376 // we can't guarantee the (F)lash color pen, but we can make sure
377 // the pen is not (X)Undefined, (A)Missing or (M)onet
378 if(str[i] != 'X' && str[i] != 'A' && str[i] != 'M')
379 // check what pen1 was
381 if (temp_pen1 == BLACK_PEN)
390 else // no color pen, just set what pen1 was
399 Compressor* DJ8xx::CreateCompressor(unsigned int RasterSize)
401 DBG1("Compression = Mode2\n");
402 return new Mode2(pSS,RasterSize);
405 BOOL DJ8xx::UseGUIMode(PrintMode* pPrintMode)
407 return (!pPrintMode->bFontCapable);
410 DRIVER_ERROR DJ8xx::CleanPen()
412 const BYTE DJ895_Diag_Page[] = {ESC, '%','P','u','i','f','p','.',
413 'm','u','l','t','i','_','b','u','t','t','o','n','_','p','u','s','h',' ','4',';',
414 'u','d','w','.','q','u','i','t',';',ESC,'%','-','1','2','3','4','5','X' };
416 const BYTE PEN_CLEAN_PML[]={0x1B,0x45,0x1B,0x26,0x62,0x31,0x36,0x57,
417 0x50,0x4D,0x4C,0x20, // EscE Esc&b16WPML{space}
418 0x04,0x00,0x06,0x01,0x04,0x01,0x05,0x01,
419 0x01,0x04,0x01,0x64}; // PML Marking-Agent-Maintenance=100
421 DWORD length = sizeof(DJ895_Power_On);
422 DRIVER_ERROR Error = pSS->ToDevice(DJ895_Power_On,&length);
424 pSS->BusyWait((DWORD)1000);
426 length = sizeof(PEN_CLEAN_PML);
427 Error = pSS->ToDevice(PEN_CLEAN_PML,&length);
429 length = sizeof(DJ895_Diag_Page);
430 return pSS->ToDevice(DJ895_Diag_Page,&length);
437 * Function name: ParseError
439 * Owner: Darrell Walker
441 * Purpose: To determine what error state the printer is in.
445 * Parameters on entry: status_reg is the contents of the centronics
446 * status register (at the time the error was
449 * Parameters on exit: unchanged
451 * Return Values: The proper DISPLAY_STATUS to reflect the printer
456 /* We have to override the base class's (Printer) ParseError function due
457 to the fact that the 8XX series returns a status byte of F8 when it's out of
458 paper. Unfortunately, the 600 series returns F8 when they're turned off.
459 The way things are structured in Printer::ParseError, we used to check only
460 for DEVICE_IS_OOP. This would return true even if we were connected to a
461 600 series printer that was turned off, causing the Out of paper status
462 message to be displayed. This change also reflects a corresponding change
463 in IO_defs.h, where I split DEVICE_IS_OOP into DEVICE_IS_OOP, DJ400_IS_OOP, and
464 DJ8XX_IS_OOP and we now check for DJ8XX_IS_OOP in the DJ8xx class's
465 ParseError function below. 05/11/99 DGC.
468 DISPLAY_STATUS DJ8xx::ParseError(BYTE status_reg)
470 DBG1("DJ8xx: parsing error info\n");
472 DRIVER_ERROR err = NO_ERROR;
473 BYTE DevIDBuffer[DevIDBuffSize];
478 // If a bi-di cable was plugged in and everything was OK, let's see if it's still
479 // plugged in and everything is OK
480 err = pSS->GetDeviceID(DevIDBuffer, DevIDBuffSize, TRUE);
482 // job was bi-di but now something's messed up, probably cable unplugged
483 return DISPLAY_COMM_PROBLEM;
485 if ( TopCoverOpen(status_reg) )
487 DBG1("Top Cover Open\n");
488 return DISPLAY_TOP_COVER_OPEN;
492 if ( (pStr=(char *)strstr((const char*)DevIDBuffer+2,"VSTATUS:")) == NULL )
494 return DISPLAY_COMM_PROBLEM;
497 pStr+=8; // skip "VSTATUS:"
498 // Paper Jam or Paper Stall
499 if (strstr((char*)pStr,"PAJM") || strstr((char*)pStr,"PAPS"))
501 return DISPLAY_PAPER_JAMMED;
504 // Power down or printing turning off
505 if (strstr((char*)pStr,"PWDN") || strstr((char*)pStr,"OFFF"))
507 return DISPLAY_OFFLINE;
511 // VerifyPenInfo will handle prompting the user
512 // if this is a problem
513 err = VerifyPenInfo();
516 // VerifyPenInfo returned an error, which can only happen when ToDevice
517 // or GetDeviceID returns an error. Either way, it's BAD_DEVICE_ID or
518 // IO_ERROR, both unrecoverable. This is probably due to the printer
519 // being turned off during printing, resulting in us not being able to
520 // power it back on in VerifyPenInfo, since the buffer still has a
521 // partial raster in it and we can't send the power-on command.
522 return DISPLAY_COMM_PROBLEM;
525 // check for errors we can detect from the status reg
528 if ( DEVICE_IS_OOP(status_reg) )
530 DBG1("Out Of Paper\n");
531 return DISPLAY_OUT_OF_PAPER;
534 if (DEVICE_PAPER_JAMMED(status_reg))
536 DBG1("Paper Jammed\n");
537 return DISPLAY_PAPER_JAMMED;
540 if (DEVICE_IO_TRAP(status_reg))
543 return DISPLAY_ERROR_TRAP;
547 // don't know what the problem is-
548 // Is the PrinterAlive?
549 if (pSS->PrinterIsAlive())
551 iTotal_SLOW_POLL_Count += iMax_SLOW_POLL_Count;
552 #if defined(DEBUG) && (DBG_MASK & DBG_LVL1)
553 printf("iTotal_SLOW_POLL_Count = %d\n",iTotal_SLOW_POLL_Count);
555 // -Note that iTotal_SLOW_POLL_Count is a multiple of
556 // iMax_SLOW_POLL_Count allowing us to check this
557 // on an absolute time limit - not relative to the number
558 // of times we happen to have entered ParseError.
559 // -Also note that we have different thresholds for uni-di & bi-di.
561 ((IOMode.bDevID == FALSE) && (iTotal_SLOW_POLL_Count >= 60)) ||
562 ((IOMode.bDevID == TRUE) && (iTotal_SLOW_POLL_Count >= 120))
569 return DISPLAY_PRINTING;
574 return DISPLAY_COMM_PROBLEM;
580 #endif // defined APDK_DJ8xx or APDK_9xx