1 /*****************************************************************************\
2 dj9xxvip.cpp : Implimentation for the DJ9xxVIP 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_DJ9xxVIP
33
34 #include "header.h"
35 #include "io_defs.h"
36 #include "dj9xxvip.h"
37 #include "printerproxy.h"
38
39 APDK_BEGIN_NAMESPACE
40
41
42 #define OUR_PJL_JOBNAME "_PJL_pjl_PJL_pjl_" // this can be anything we want it to be
43 #define DRIVERWARE_JOBNAME "NEWDRIVERWARE" // don't change this - it is defined in firmware!
44
45 extern uint32_t ulMapDJ600_CCM_K[ 9 * 9 * 9 ];
46
47 const char GrayscaleSeq[]= {ESC, '*', 'o', '5', 'W', 0x0B, 0x01, 0x00, 0x00, 0x02};
48
49 const BYTE ExtraDryTime[] = "\033&b16WPML \004\000\006\001\004\001\004\001\006\010\001";
50
51 extern BYTE EscAmplCopy(BYTE *dest, int num, char end);
52 extern void AsciiHexToBinary(BYTE* dest, char* src, int count);
53 extern MediaType MediaTypeToPcl (MEDIATYPE eMediaType);
54
DJ9xxVIP(SystemServices * pSS,BOOL proto)55 DJ9xxVIP::DJ9xxVIP
56 (
57 SystemServices* pSS,
58 BOOL proto
59 ) :
60 Printer(pSS, NUM_DJ6XX_FONTS, proto),
61 PCL3acceptsDriverware(TRUE)
62 {
63
64 m_bVIPPrinter = TRUE;
65
66 if (!proto && IOMode.bDevID)
67 {
68 bCheckForCancelButton = TRUE;
69 constructor_error = VerifyPenInfo();
70 CERRCHECK;
71 }
72 else ePen = BOTH_PENS; // matches default mode
73
74 PCL3acceptsDriverware = IsPCL3DriverwareAvailable();
75
76 ModeCount = 0;
77 pMode[ModeCount++] = new GrayModeDJ990(ulMapDJ600_CCM_K,PCL3acceptsDriverware); // Grayscale K
78 pMode[ModeCount++] = new DJ990Mode(); // Automatic Color
79 pMode[ModeCount++] = new DJ990CMYGrayMode(); // Automatic Grayscale CMY
80
81 #ifdef APDK_AUTODUPLEX
82
83 /*
84 * When bidi is available, query printer for duplexer
85 * For now, this is available only on Linux which is unidi only.
86 */
87
88 bDuplexCapable = TRUE;
89 #endif
90
91 #ifdef APDK_EXTENDED_MEDIASIZE
92 pMode[ModeCount++] = new DJ990KGrayMode (); // Normal Grayscale K
93 pMode[ModeCount++] = new DJ9902400Mode (); // HiRes
94 pMode[ModeCount++] = new DJ990DraftMode (); // Draft Color
95 #endif
96 pMode[ModeCount++] = new DJ990BestMode (); // Photo Best
97 pMode[ModeCount++] = new DJ990PhotoNormalMode (); // Photo Normal
98
99 m_cExtraDryTime = 0;
100 m_iLeftOverspray = 0;
101 m_iTopOverspray = 0;
102 m_iRightOverspray = 0;
103 m_iBottomOverspray = 0;
104 }
105
GrayModeDJ990(uint32_t * map,BOOL PCL3OK)106 GrayModeDJ990::GrayModeDJ990
107 (
108 uint32_t *map,
109 BOOL PCL3OK
110 ) :
111 GrayMode(map)
112 {
113 #if defined(APDK_VIP_COLORFILTERING)
114 Config.bErnie = TRUE;
115 #endif
116
117 Config.bColorImage=FALSE;
118
119 if (!PCL3OK)
120 {
121 bFontCapable = FALSE;
122 }
123
124 #ifdef APDK_AUTODUPLEX
125 bDuplexCapable = TRUE;
126 #endif
127 #ifdef APDK_EXTENDED_MEDIASIZE
128 theQuality = qualityDraft;
129 pmQuality = QUALITY_DRAFT;
130 #endif
131 }
132
DJ990Mode()133 DJ990Mode::DJ990Mode()
134 : PrintMode(NULL)
135 {
136
137 /*
138 * The resolutions here are set to 300 for better performance from Cameras.
139 * REVISIT: Must provide a true 600 dpi printmode later.
140 * 12/21/01
141 *
142 * For now have added APDK_HIGH_RES_MODES which sets VIP_BASE_RES to 600 in dj9xxvip.h
143 * If APDK_HIGH_RES_MODES is not defined then VIP_BASE_RES is 300.
144 * 1/9/2002 - JLM
145 */
146
147 BaseResX = BaseResY = TextRes = ResolutionX[0] = ResolutionY[0] = VIP_BASE_RES;
148
149 medium = mediaAuto; // enable media-detect
150
151 #if defined(APDK_VIP_COLORFILTERING)
152 Config.bErnie = TRUE;
153 #endif
154
155 Config.bColorImage = FALSE;
156
157 #ifdef APDK_AUTODUPLEX
158 bDuplexCapable = TRUE;
159 #endif
160 } //DJ990Mode
161
162
DJ990CMYGrayMode()163 DJ990CMYGrayMode::DJ990CMYGrayMode()
164 : PrintMode(NULL)
165 {
166
167 /*
168 * See comments above regarding 300/600 dpi change
169 */
170
171 BaseResX = BaseResY = TextRes = ResolutionX[0] = ResolutionY[0] = VIP_BASE_RES;
172
173 medium = mediaAuto; // enable media-detect
174
175 #if defined(APDK_VIP_COLORFILTERING)
176 Config.bErnie = TRUE;
177 #endif
178
179 Config.bColorImage = FALSE;
180
181 #ifdef APDK_AUTODUPLEX
182 bDuplexCapable = TRUE;
183 #endif
184 pmColor = GREY_CMY;
185 bFontCapable = FALSE;
186 } //DJ990CMYGrayMode
187
188 #ifdef APDK_EXTENDED_MEDIASIZE
DJ990KGrayMode()189 DJ990KGrayMode::DJ990KGrayMode () : PrintMode (NULL)
190 {
191
192 /*
193 * See comments above regarding 300/600 dpi change.
194 */
195
196 BaseResX = BaseResY = ResolutionX[0] = ResolutionY[0] = VIP_BASE_RES;
197 medium = mediaPlain;
198 #if defined(APDK_VIP_COLORFILTERING)
199 Config.bErnie = TRUE;
200 #endif
201
202 Config.bColorImage = FALSE;
203
204 #ifdef APDK_AUTODUPLEX
205 bDuplexCapable = TRUE;
206 #endif
207 pmColor = GREY_K;
208 bFontCapable = FALSE;
209 dyeCount = 1;
210 } //DJ990KGrayMode
211
DJ9902400Mode()212 DJ9902400Mode::DJ9902400Mode () : PrintMode (NULL)
213 {
214 BaseResX =
215 BaseResY = 1200;
216 ResolutionX[0] = 1200;
217 ResolutionY[0] = 1200;
218 bFontCapable = FALSE;
219 #ifdef APDK_AUTODUPLEX
220 bDuplexCapable = FALSE;
221 #endif
222 #if defined(APDK_VIP_COLORFILTERING)
223 Config.bErnie = TRUE;
224 #endif
225
226 Config.bColorImage = FALSE;
227
228 medium = mediaHighresPhoto;
229 theQuality = qualityPresentation;
230 pmMediaType = MEDIA_PHOTO;
231 pmQuality = QUALITY_HIGHRES_PHOTO;
232 } // DJ9902400Mode
233
DJ990DraftMode()234 DJ990DraftMode::DJ990DraftMode () : PrintMode (NULL)
235 {
236 bFontCapable = FALSE;
237 #ifdef APDK_AUTODUPLEX
238 bDuplexCapable = TRUE;
239 #endif
240 #if defined(APDK_VIP_COLORFILTERING)
241 Config.bErnie = TRUE;
242 #endif
243
244 Config.bColorImage = FALSE;
245
246 medium = mediaAuto;
247 theQuality = qualityDraft;
248 pmQuality = QUALITY_DRAFT;
249 } // DJ990DraftMode
250
251 #endif // APDK_EXTENDED_MEDIASIZE
252
253 /*
254 * Some VIP printers do not have Media Sensing device. To enable
255 * selection of Photo/Best mode for these printers, use this mode.
256 */
257
DJ990BestMode()258 DJ990BestMode::DJ990BestMode () : PrintMode (NULL)
259 {
260 BaseResX = BaseResY = ResolutionX[0] = ResolutionY[0] = VIP_BASE_RES;
261
262 bFontCapable = FALSE;
263
264 #ifdef APDK_AUTODUPLEX
265 bDuplexCapable = TRUE;
266 #endif
267
268 #if defined(APDK_VIP_COLORFILTERING)
269 Config.bErnie = TRUE;
270 #endif
271
272 Config.bColorImage = FALSE;
273
274 medium = mediaGlossy;
275 theQuality = qualityPresentation;
276 pmQuality = QUALITY_BEST;
277 pmMediaType = MEDIA_PHOTO;
278 } // DJ990BestMode
279
DJ990PhotoNormalMode()280 DJ990PhotoNormalMode::DJ990PhotoNormalMode () : PrintMode (NULL)
281 {
282 BaseResX = BaseResY = ResolutionX[0] = ResolutionY[0] = VIP_BASE_RES;
283
284 bFontCapable = FALSE;
285
286 #ifdef APDK_AUTODUPLEX
287 bDuplexCapable = TRUE;
288 #endif
289
290 #if defined(APDK_VIP_COLORFILTERING)
291 Config.bErnie = TRUE;
292 #endif
293
294 Config.bColorImage = FALSE;
295
296 medium = mediaGlossy;
297 theQuality = qualityNormal;
298 pmQuality = QUALITY_NORMAL;
299 pmMediaType = MEDIA_PHOTO;
300 } // DJ990PhotoNormalMode
301
UseGUIMode(PrintMode * pPrintMode)302 BOOL DJ9xxVIP::UseGUIMode
303 (
304 PrintMode* pPrintMode
305 )
306 {
307 // The reason to change all print mode in DJ9xxVIP family to PCL3GUI mode is that
308 // the PCL3 path in VIP printers is not tested. They don't support newer CRD
309 // command. The device fint support for this group is not recommended.
310
311 return TRUE;
312 /*
313 if (pPrintMode->medium == mediaHighresPhoto)
314 {
315 return TRUE;
316 }
317 else
318 {
319 #ifdef APDK_AUTODUPLEX
320 if (pPrintMode->QueryDuplexMode() != DUPLEXMODE_NONE)
321 {
322 return TRUE;
323 }
324 #endif
325 }
326 #if defined(APDK_FONTS_NEEDED)
327 // return ((!pPrintMode->bFontCapable) && (!PCL3acceptsDriverware));
328 return (!pPrintMode->bFontCapable);
329 #else
330 return TRUE;
331 #endif
332 */
333 } //UseGUIMode
334
AddPJLHeader()335 DRIVER_ERROR DJ9xxVIP::AddPJLHeader ()
336 {
337 char *szPJLBuffer = NULL;
338 DRIVER_ERROR err = NO_ERROR;
339 int iPJLBufferSize;
340 if (((iPJLBufferSize = pSS->GetPJLHeaderBuffer (&szPJLBuffer)) > 0) && (szPJLBuffer != NULL))
341 {
342 err = Send ((const BYTE *) szPJLBuffer, iPJLBufferSize);
343 }
344 return err;
345 }
346
Mode10(SystemServices * pSys,Printer * pPrinter,unsigned int PlaneSize)347 Mode10::Mode10
348 (
349 SystemServices* pSys,
350 Printer* pPrinter,
351 unsigned int PlaneSize
352 ) :
353 Compressor(pSys, PlaneSize, TRUE),
354 thePrinter(pPrinter) // needed by Flush
355 {
356 if (constructor_error != NO_ERROR) // if error in base constructor
357 {
358 return;
359 }
360
361 // In the worst case, compression expands data by 50%
362 compressBuf = (BYTE*)pSS->AllocMem(PlaneSize + PlaneSize/2);
363 if (compressBuf == NULL)
364 constructor_error=ALLOCMEM_ERROR;
365
366 memset(SeedRow,0xFF,PlaneSize);
367 } //Mode10
368
369
~Mode10()370 Mode10::~Mode10()
371 { }
372
373
374 const BYTE ResetSeedrow[]={ESC,'*','b','0','Y'};
375
Flush()376 void Mode10::Flush()
377 // special problem here regarding white rasters: we can't just reset our seedrow to white,
378 // because if a true white raster comes next it will compress to zero, and firmware will
379 // print ITS seedrow. So when we zero our seedrow, we need to zero the firmware seedrow.
380 // The way to do this is to send ESC*b0Y. So that's what we will do here.
381 {
382 if (!seeded)
383 {
384 return;
385 }
386 compressedsize=0;
387
388 iRastersReady = 0;
389 seeded = FALSE;
390 memset(SeedRow,0xFF,inputsize);
391 thePrinter->Send(ResetSeedrow, sizeof(ResetSeedrow));
392 } //Flush
393
394
CreateCompressor(unsigned int RasterSize)395 Compressor* DJ9xxVIP::CreateCompressor(unsigned int RasterSize)
396 {
397 return new Mode10(pSS,this,RasterSize);
398 }
399
400
SelectHeader(PrintContext * pc)401 Header* DJ9xxVIP::SelectHeader(PrintContext* pc)
402 {
403 return new HeaderDJ990(this,pc);
404 }
405
406
HeaderDJ990(Printer * p,PrintContext * pc)407 HeaderDJ990::HeaderDJ990(Printer* p,PrintContext* pc)
408 : Header(p,pc)
409 {
410 SetMediaSource (pc->GetMediaSource());
411 }
412
413
ConfigureRasterData()414 DRIVER_ERROR HeaderDJ990::ConfigureRasterData()
415 // This is the more sophisticated way of setting color and resolution info.
416 //
417 // NOTE: Will need to be overridden for DJ5xx.
418 {
419
420 char buff[50]; // 20 + 3 for crdstart + 3 for ##W
421 char *out = buff;
422
423
424 // begin the CRD command
425 memcpy(out,crdStart,sizeof(crdStart) );
426 out += sizeof(crdStart);
427
428 // now set up the "#W" part, where #= number of data bytes in the command
429 // #= 20
430 // format,ID,components(2bytes),resolutions (4bytes),
431 // compresssion method, orientation, bits/component,planes/component
432 *out++ = 0x32; // "2"
433 *out++ = 0x30; // "0"
434 *out++ = 'W';
435
436 #define VIPcrdFormat 6
437 #define VIPKRGBID 0x1F
438
439 *out++ = VIPcrdFormat;
440 *out++ = VIPKRGBID;
441
442 // 2-byte component count field
443 // number of components for sRGB is 1 by defintiion
444 *out++ = 0; // leading byte
445 *out++ = 2; // 2 "component"
446
447 *out++ = ResolutionX[0]/256;
448 *out++ = ResolutionX[0]%256;
449 *out++ = ResolutionY[0]/256;
450 *out++ = ResolutionY[0]%256;
451
452 // compression method
453 *out++ = 9; // mode 9 compression
454
455 // orientation
456 *out++ = 0; // pixel major code
457
458 // bits per component
459 *out++ = 1; // 1 bits each for k
460
461 // planes per component
462 *out++ = 1; // K = one component, one "plane"
463
464 *out++ = ResolutionX[0]/256;
465 *out++ = ResolutionX[0]%256;
466 *out++ = ResolutionY[0]/256;
467 *out++ = ResolutionY[0]%256;
468
469 // compression method
470 *out++ = 10; // mode 10 compression
471
472 // orientation
473 *out++ = 1; // pixel major code
474
475 // bits per component
476 *out++ = 32; // 8 bits each for s,R,G,B
477
478 // planes per component
479 *out++ = 1; // sRGB = one component, one "plane"
480
481 return thePrinter->Send((const BYTE*) buff, out-buff);
482 } //ConfigureRasterData
483
484
ConfigureImageData()485 DRIVER_ERROR HeaderDJ990::ConfigureImageData()
486 {
487 DRIVER_ERROR err = thePrinter->Send((const BYTE*)cidStart, sizeof(cidStart));
488 ERRCHECK;
489 char sizer[3];
490 sprintf(sizer,"%dW",6);
491 err = thePrinter->Send((const BYTE*)sizer,2);
492 ERRCHECK;
493
494 BYTE colorspace = 2; // RGB
495 BYTE coding = 3;
496 BYTE bitsindex = 3; // ??
497 BYTE bitsprimary = 8;
498 BYTE CID[6];
499 CID[0] = colorspace;
500 CID[1]=coding;
501 CID[2] = bitsindex;
502 CID[3] = CID[4] = CID[5] = bitsprimary;
503
504 return thePrinter->Send((const BYTE*) CID, 6);
505 } //ConfigureImageData
506
507
Send()508 DRIVER_ERROR HeaderDJ990::Send()
509 /// ASSUMES COMPRESSION ALWAYS ON -- required by DJ990
510 {
511 DRIVER_ERROR err;
512 // PRINTMODE_VALUES *pPMV;
513 COLORMODE eColorMode = COLOR;
514 MEDIATYPE eMediaType;
515 QUALITY_MODE eQualityMode;
516 BOOL bDeviceText;
517
518 thePrintContext->GetPrintModeSettings (eQualityMode, eMediaType, eColorMode, bDeviceText);
519
520 if (eMediaType == MEDIA_CDDVD)
521 {
522 thePrintContext->SetMediaSource (sourceTrayCDDVD);
523 SetMediaSource (sourceTrayCDDVD);
524 }
525
526 StartSend();
527
528 #ifdef APDK_AUTODUPLEX
529 if (thePrintContext->QueryDuplexMode () != DUPLEXMODE_NONE)
530 {
531 err = thePrinter->Send ((const BYTE *) EnableDuplex, sizeof (EnableDuplex));
532 BYTE cDryTime;
533 cDryTime = (BYTE) ((thePrinter->GetHint (EXTRA_DRYTIME_HINT)) & 0xFF);
534 if (cDryTime != 0)
535 {
536 err = thePrinter->Send (ExtraDryTime, sizeof (ExtraDryTime) - 1);
537 err = thePrinter->Send ((const BYTE *) &cDryTime, 1);
538 ERRCHECK;
539 }
540 }
541 #endif
542
543 err = ConfigureImageData();
544 ERRCHECK;
545
546 err = ConfigureRasterData();
547 ERRCHECK;
548
549 if (thePrintMode->dyeCount == 1) // grayscale
550 {
551 err=thePrinter->Send((const BYTE*)GrayscaleSeq, sizeof(GrayscaleSeq) );
552 ERRCHECK;
553 }
554 else
555 {
556 if (eColorMode == GREY_CMY)
557 {
558 char pStr[12];
559 memcpy (pStr, GrayscaleSeq, 10);
560 pStr[9] = 0x01;
561 err = thePrinter->Send ((const BYTE *) pStr, 10);
562 }
563 }
564
565 /////////////////////////////////////////////////////////////////////////////////////
566 // unit-of-measure command --- seems to be need in DJ990 PCL3 mode
567 char uom[10];
568 sprintf(uom,"%c%c%c%d%c",ESC,'&','u',thePrintMode->ResolutionX[K],'D');
569 err = thePrinter->Send((const BYTE*)uom, strlen (uom));
570 ERRCHECK;
571
572 // another command that helps PCLviewer
573 unsigned int width=thePrintContext->OutputPixelsPerRow();
574 unsigned int digits = 1;
575 unsigned int x = width;
576 while (x > 10)
577 {
578 digits++;
579 x = x / 10;
580 }
581 sprintf(uom,"%c%c%c%d%c",ESC,'*','r', width,'S');
582 err = thePrinter->Send((const BYTE*)uom, 4 + digits );
583 ERRCHECK;
584
585 ////////////////////////////////////////////////////////////////////////////////////
586
587 /*
588 * Custom papersize command
589 */
590
591 if (thePrintContext->thePaperSize == CUSTOM_SIZE)
592 {
593 BYTE szStr[32];
594 short sWidth, sHeight;
595 BYTE b1, b2;
596 sWidth = (short) (thePrintContext->PhysicalPageSizeX () * thePrintContext->EffectiveResolutionX ());
597 sHeight = (short) (thePrintContext->PhysicalPageSizeY () * thePrintContext->EffectiveResolutionY ());
598 memcpy (szStr, "\x1B*o5W\x0E\x05\x00\x00\x00\x1B*o5W\x0E\x06\x00\x00\x00", 20);
599 b1 = (BYTE) ((sWidth & 0xFF00) >> 8);
600 b2 = (BYTE) (sWidth & 0xFF);
601 szStr[8] = b1;
602 szStr[9] = b2;
603 b1 = (BYTE) ((sHeight & 0xFF00) >> 8);
604 b2 = (BYTE) (sHeight & 0xFF);
605 szStr[18] = b1;
606 szStr[19] = b2;
607 err = thePrinter->Send ((const BYTE *) szStr, 20);
608 }
609
610 float fXOverSpray = 0.0;
611 float fYOverSpray = 0.0;
612 float fLeftOverSpray = 0.0;
613 float fTopOverSpray = 0.0;
614 FullbleedType fbType;
615 if (thePrintContext->bDoFullBleed &&
616 thePrinter->FullBleedCapable (thePrintContext->thePaperSize,
617 &fbType,
618 &fXOverSpray, &fYOverSpray,
619 &fLeftOverSpray, &fTopOverSpray))
620 {
621
622 /*
623 * To get the printer to do fullbleed printing, send the top and
624 * left overspray commands. Overspray is needed to take care of
625 * skew during paper pick. These values may be mech dependent.
626 * Currently, supported only on PhotoSmart 100. Malibu supports
627 * fullbleed printing also. The current values for overspray are
628 * 0.059 inch for top, bottom and left edges and 0.079 for right edge.
629 */
630
631 BYTE cBuf[4];
632 BYTE TopOverSpraySeq[] = {0x1b, 0x2A, 0x6F, 0x35, 0x57, 0x0E, 0x02, 0x00};
633 // "Esc*o5W 0E 02 00 00 00" Top edge overspray for full-bleed printing
634
635 BYTE LeftOverSpraySeq[] = {0x1b, 0x2A, 0x6F, 0x35, 0x57, 0x0E, 0x01, 0x00};
636 // "Esc*o5W 0E 01 00 00 00" Left edge overspray for full-bleed printing
637
638 short topspray = (short)(fTopOverSpray * thePrintContext->EffectiveResolutionY() + 0.5);
639 cBuf[1] = topspray & 0xFF;
640 cBuf[0] = topspray >> 8;
641
642 err = thePrinter->Send ((const BYTE *) TopOverSpraySeq, sizeof (TopOverSpraySeq));
643 err = thePrinter->Send ((const BYTE *) cBuf, 2);
644
645 // set the left overspray value based on resolution and global constant for horizontal overspray
646 short leftspray = (short)(fLeftOverSpray * thePrintContext->EffectiveResolutionX() + 0.5);
647 cBuf[1] = leftspray & 0xFF;
648 cBuf[0] = leftspray >> 8;
649
650 err = thePrinter->Send ((const BYTE *) LeftOverSpraySeq, sizeof (LeftOverSpraySeq));
651 err = thePrinter->Send ((const BYTE *) cBuf, 2);
652 }
653
654 // Now send media pre-load command
655 err = thePrinter->Send ((const BYTE *) "\033&l-2H", 6); // Moved from Modes(), des 3/11/03
656 ERRCHECK;
657
658 // Send speed mech command
659 thePrinter->SetHint (SPEED_MECH_HINT, 0);
660
661 // no need for compression command, it's in the CRD
662
663 err = thePrinter->Send((const BYTE*)grafStart, sizeof(grafStart) );
664 ERRCHECK;
665
666 if (!thePrinter->UseGUIMode (thePrintContext->CurrentMode) &&
667 (thePrintContext->PhysicalPageSizeX ()) < 8.0)
668 {
669
670 BYTE blankRow[40];
671 memset (blankRow, 0xFF, 40);
672 strcpy ((char *) blankRow, "\033*p0Y\033*b23W");
673 blankRow[11] = 18; // ce, 7f
674 blankRow[30] = 0xCE; blankRow[31] = 0x7F;
675 err = thePrinter->Send ((const BYTE *) blankRow, 34);
676 }
677
678 return err;
679 } //Send
680
681
StartSend()682 DRIVER_ERROR HeaderDJ990::StartSend()
683 {
684 DRIVER_ERROR err;
685
686 err = thePrinter->Send((const BYTE*)Reset,sizeof(Reset));
687 ERRCHECK;
688
689 err = thePrinter->Send((const BYTE*)UEL,sizeof(UEL));
690 ERRCHECK;
691
692 err = thePrinter->AddPJLHeader ();
693 ERRCHECK;
694
695 err = thePrinter->Send((const BYTE*)EnterLanguage,sizeof(EnterLanguage));
696 ERRCHECK;
697
698 if (!thePrinter->UseGUIMode(thePrintContext->CurrentMode))
699 {
700 err = thePrinter->Send((const BYTE*)PCL3,sizeof(PCL3));
701 }
702 else
703 {
704 err = thePrinter->Send((const BYTE*)PCLGUI,sizeof(PCLGUI));
705 }
706 ERRCHECK;
707
708
709 err = thePrinter->Send((const BYTE*)&LF,1);
710 ERRCHECK;
711
712 err = Modes (); // Set media source, type, size and quality modes.
713 ERRCHECK;
714
715 // Send media subtype if set
716 int iMediaSubtype = thePrintContext->GetMediaSubtype ();
717 if (iMediaSubtype != APDK_INVALID_VALUE)
718 {
719 BYTE szMediaSubtypeSeq[] = {0x1B, '*', 'o', '5', 'W', 0x0D, 0x03, 0x00, 0x00, 0x00};
720 szMediaSubtypeSeq[8] = (BYTE) ((iMediaSubtype & 0xFF00) >> 8);
721 szMediaSubtypeSeq[9] = (BYTE) (iMediaSubtype & 0x00FF);
722 err = thePrinter->Send ((const BYTE *) szMediaSubtypeSeq, sizeof(szMediaSubtypeSeq));
723 ERRCHECK;
724 }
725
726 if (!thePrinter->UseGUIMode(thePrintContext->CurrentMode))
727 {
728 err = Margins(); // set margins
729 }
730
731 // special GUI mode top margin set
732
733 else if ((thePrintContext->PrintableStartY ()) > 0.0)
734 {
735 CAPy = thePrintContext->GUITopMargin();
736 }
737
738 if ((thePrintContext->GetMediaSource()) == sourceTrayCDDVD)
739 {
740 err = thePrinter->Send ((const BYTE *) "\033*o5W\x0D\x03\x00\x04\x0C", 10);
741 ERRCHECK;
742 }
743
744 return err;
745 } //StartSend
746
747 /* This could replace Header::SetMediaSource in header.cpp. des 8/5/02 */
SetMediaSource(MediaSource msource)748 void HeaderDJ990::SetMediaSource(MediaSource msource)
749 // Sets value of PCL::mediasource and associated counter msrccount
750 {
751 msrccount=EscAmplCopy((BYTE*)mediasource,msource,'H');
752 if (msource == sourceTrayCDDVD)
753 {
754 SetMediaType (mediaCDDVD);
755 SetQuality (qualityPresentation);
756 return;
757 }
758 if (msource == sourceTray2 || msource > sourceTrayAuto)
759 {
760 SetMediaType (mediaPlain);
761 }
762 }
763
VerifyPenInfo()764 DRIVER_ERROR DJ9xxVIP::VerifyPenInfo()
765 {
766 DRIVER_ERROR err=NO_ERROR;
767
768 if(IOMode.bDevID == FALSE)
769 return err;
770 err = ParsePenInfo(ePen);
771
772 if(err == UNSUPPORTED_PEN) // probably Power Off - pens couldn't be read
773 {
774 DBG1("DJ9xxVIP::Need to do a POWER ON to get penIDs\n");
775
776 // have to delay or the POWER ON will be ignored
777 if (pSS->BusyWait((DWORD)2000) == JOB_CANCELED)
778 {
779 return JOB_CANCELED;
780 }
781
782 DWORD length = sizeof(DJ895_Power_On);
783 err = pSS->ToDevice(DJ895_Power_On,&length);
784 ERRCHECK;
785
786 err = pSS->FlushIO();
787 ERRCHECK;
788
789 // give the printer some time to power up
790 if (pSS->BusyWait ((DWORD) 2500) == JOB_CANCELED)
791 {
792 return JOB_CANCELED;
793 }
794
795 err = ParsePenInfo(ePen);
796 }
797
798 ERRCHECK;
799
800 // check for the normal case
801 if (ePen == BOTH_PENS || ePen == MDL_BLACK_AND_COLOR_PENS)
802 {
803 return NO_ERROR;
804 }
805
806 // Should we return NO_ERROR for MDL_BOTH also - malibu??
807
808 while ( ePen != BOTH_PENS && pSS->GetVIPVersion () == 1 )
809 {
810
811 switch (ePen)
812 {
813 case BLACK_PEN:
814 // black pen installed, need to install color pen
815 pSS->DisplayPrinterStatus(DISPLAY_NO_COLOR_PEN);
816 break;
817 case COLOR_PEN:
818 // color pen installed, need to install black pen
819 pSS->DisplayPrinterStatus(DISPLAY_NO_BLACK_PEN);
820 break;
821 case NO_PEN:
822 // neither pen installed
823 default:
824 pSS->DisplayPrinterStatus(DISPLAY_NO_PENS);
825 break;
826 }
827
828 if (pSS->BusyWait(500) == JOB_CANCELED)
829 {
830 return JOB_CANCELED;
831 }
832
833 err = ParsePenInfo(ePen);
834 ERRCHECK;
835 }
836
837 pSS->DisplayPrinterStatus(DISPLAY_PRINTING);
838
839 return NO_ERROR;
840 } //VerifyPenInfo
841
842
ParsePenInfo(PEN_TYPE & ePen,BOOL QueryPrinter)843 DRIVER_ERROR DJ9xxVIP::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
844 {
845 char* str;
846 int num_pens = 0;
847 PEN_TYPE temp_pen1 = NO_PEN;
848 BYTE penInfoBits[4];
849 int i;
850
851 /*
852 * First check if this printer's firmware version is one I know about. Currently
853 * I know upto S:04. I can't guess if the pen info nibbles have shifted in the
854 * new version. Can't tell the user about missing pens.
855 */
856
857 if ((pSS->GetVIPVersion ()) > 5)
858 {
859 ePen = BOTH_PENS;
860 return NO_ERROR;
861 }
862
863 DRIVER_ERROR err = SetPenInfo (str, QueryPrinter);
864 // ERRCHECK;
865 if (err != NO_ERROR)
866 {
867 ePen = BOTH_PENS;
868 return NO_ERROR;
869 }
870 iNumMissingPens = 0;
871
872 // the first byte indicates how many pens are supported
873 if ((str[0] >= '0') && (str[0] <= '9'))
874 {
875 num_pens = str[0] - '0';
876 }
877 else if ((str[0] >= 'A') && (str[0] <= 'F'))
878 {
879 num_pens = 10 + (str[0] - 'A');
880 }
881 else if ((str[0] >= 'a') && (str[0] <= 'f'))
882 {
883 num_pens = 10 + (str[0] - 'a');
884 }
885 else
886 {
887 return BAD_DEVICE_ID;
888 }
889
890 if ((int) strlen (str) < (num_pens * 8))
891 {
892 return BAD_DEVICE_ID;
893 }
894
895 // DJ990 style DevID
896
897 if (pSS->GetVIPVersion () == 1)
898 {
899 if (num_pens < 2)
900 {
901 return UNSUPPORTED_PEN;
902 }
903
904 // parse pen1 (should be black)
905 AsciiHexToBinary(penInfoBits, str+1, 4);
906 penInfoBits[1] &= 0xf8; // mask off ink level trigger bits
907
908 if ((penInfoBits[0] == 0xc1) && (penInfoBits[1] == 0x10))
909 {
910 temp_pen1 = BLACK_PEN;
911 }
912 else if (penInfoBits[0] == 0xc0)
913 { // missing pen
914 temp_pen1 = NO_PEN;
915 iNumMissingPens = 1;
916 }
917 else
918 {
919 return UNSUPPORTED_PEN;
920 }
921
922 // now check pen2 (should be color)
923 AsciiHexToBinary(penInfoBits, str+9, 4);
924 penInfoBits[1] &= 0xf8; // mask off ink level trigger bits
925
926 if ((penInfoBits[0] == 0xc2) && (penInfoBits[1] == 0x08))
927 { // Chinook
928 if (temp_pen1 == BLACK_PEN)
929 {
930 ePen = BOTH_PENS;
931 }
932 else
933 {
934 ePen = COLOR_PEN;
935 }
936 }
937 else if (penInfoBits[0] == 0xc0)
938 { // missing pen
939 ePen = temp_pen1;
940 iNumMissingPens = 1;
941 }
942 else
943 {
944 return UNSUPPORTED_PEN;
945 }
946
947 return NO_ERROR;
948 }
949
950 // Check for missing pens
951
952 if (*(str - 1) == '1' && *(str - 2) == '1')
953 {
954 return UNSUPPORTED_PEN;
955 }
956
957 char *p = str + 1;
958
959 /*
960 * Pen Type Info
961 *
962 Bit 31 (1 bit)
963
964 1 if these fields describe a print head
965 0 otherwise
966 Bit 30 (1 bit)
967
968 1 if these fields describe an ink supply
969 0 otherwise
970
971 Bits 29 .. 24 (6 bits) describes the pen/supply type:
972
973 0 = none
974 1 = black
975 2 = CMY
976 3 = KCM
977 4 = Cyan
978 5 = Meganta
979 6 = Yellow
980 7 = Cyan - low dye load
981 8 = Magenta - low dye load
982 9 = Yellow - low dye load (may never be used, but reserve space anyway) [def added Jun 3, 2002]
983 10 = gGK - two shades of grey plus black; g=light grey, G=medium Grey, K=black [added Sep 12, 02]
984 11 = Blue Pen
985 12 .. 62 = reserved for future use
986 63 = Unknown
987
988 Bits 23 .. 19 (5 bits) describes the pen/supply id:
989
990 0 = none
991 1 = color (Formerly N)
992 2 = black (Formerly H)
993 3 = Flash (Formerly F)
994 4 = (Formerly R -- only 6xx family)
995 5 = (Formerly C -- only 6xx family)
996 6 = (Formerly M -- only for 6xx family)
997 7 = (Cp1160 Pen)
998 8 = Europa (Jupiter Ink)
999 9 = Wax (pen/ink combo; k)
1000 10 = (pen/ink combo; cmy)
1001 11 = (pen/ink combo; kcm)
1002 12 = (pen/ink combo; k) [def added Jun 27, 2002]
1003 13 = (k) [def added Jun 27, 2002]
1004 14 = pen/ink combo; gGK) [added Sep 12, 02]
1005 15 .. 30 = reserved for future use [def added Jun 27, 2002]
1006 31 = Other/Unknown [def added Jun 27, 2002]
1007 */
1008
1009 ePen = NO_PEN;
1010
1011 if (pSS->GetVIPVersion () == 3)
1012 {
1013 for (i = 0; i < num_pens; i++, p += 4)
1014 {
1015 if (*p > 0 && *p < '5')
1016 {
1017 continue;
1018 }
1019 switch (*p)
1020 {
1021 case 0:
1022 {
1023 iNumMissingPens++;
1024 break;
1025 }
1026 case '5':
1027 {
1028 ePen = BLACK_PEN;
1029 break;
1030 }
1031 case '6':
1032 case '7':
1033 case '8':
1034 {
1035 if (ePen == BLACK_PEN)
1036 {
1037 ePen = BOTH_PENS;
1038 }
1039 else if (ePen != BOTH_PENS)
1040 {
1041 ePen = COLOR_PEN;
1042 }
1043 break;
1044 }
1045 }
1046
1047 }
1048 if (iNumMissingPens != 0)
1049 {
1050 return MISSING_PENS;
1051 }
1052 return NO_ERROR;
1053 }
1054
1055 #if 0
1056
1057 BYTE penColor;
1058
1059 /*
1060 * These printers don't need all pens to be installed to print. Parsing the pen info
1061 * is not all that useful. Also, the note about incompatible pen is not valid anymore,
1062 * it just means unknown or other pen.
1063 * Raghu - 11/17/05
1064 */
1065
1066 for (i = 0; i < num_pens; i++, p += 8)
1067 {
1068 AsciiHexToBinary (penInfoBits, p, 8);
1069
1070 if ((penInfoBits[1] & 0xf8) == 0xf8)
1071 {
1072
1073 // The high 5 bits in the 3rd and 4th nibble (second byte) identify the
1074 // installed pen. If all 5 bits are on, user has installed an incompatible pen.
1075
1076 return UNSUPPORTED_PEN;
1077 }
1078
1079 if ((penInfoBits[0] & 0x40) != 0x40) // if Bit 31 is 1, this is not a pen
1080 {
1081 continue;
1082 }
1083 penColor = penInfoBits[0] & 0x3F;
1084 switch (penColor)
1085 {
1086 case 0:
1087 {
1088 iNumMissingPens++;
1089 break;
1090 }
1091 case 1:
1092 ePen = BLACK_PEN;
1093 break;
1094 case 2:
1095 {
1096 if (ePen == BLACK_PEN)
1097 {
1098 ePen = BOTH_PENS;
1099 }
1100 else if (ePen == MDL_PEN)
1101 {
1102 ePen = MDL_BOTH;
1103 }
1104 else if (ePen == GREY_PEN)
1105 {
1106 ePen = GREY_BOTH;
1107 }
1108 else
1109 {
1110 ePen = COLOR_PEN;
1111 }
1112 break;
1113 }
1114 case 3:
1115 if (ePen == BLACK_PEN)
1116 {
1117 ePen = MDL_AND_BLACK_PENS;
1118 }
1119 else if (ePen == COLOR_PEN)
1120 {
1121 ePen = MDL_BOTH;
1122 }
1123 else if (ePen == BOTH_PENS)
1124 {
1125 ePen = MDL_BLACK_AND_COLOR_PENS;
1126 }
1127 else if (ePen == GREY_PEN)
1128 {
1129 ePen = MDL_AND_GREY_PENS;
1130 }
1131 else if (ePen == GREY_BOTH)
1132 {
1133 ePen = MDL_GREY_AND_COLOR_PENS;
1134 }
1135 else
1136 {
1137 ePen = MDL_PEN;
1138 }
1139 break;
1140 case 4: // cyan pen
1141 case 5: // magenta pen
1142 case 6: // yellow pen
1143 case 7: // low dye load cyan pen
1144 case 8: // low dye load magenta pen
1145 case 9: // low dye load yellow pen
1146 case 11: // blue pen
1147 if (ePen == BLACK_PEN || ePen == BOTH_PENS)
1148 {
1149 ePen = BOTH_PENS;
1150 }
1151 else
1152 {
1153 ePen = COLOR_PEN;
1154 }
1155 break;
1156 case 10:
1157 ePen = GREY_PEN;
1158 break;
1159 default:
1160 ePen = UNKNOWN_PEN;
1161 }
1162 }
1163 return NO_ERROR;
1164 #endif
1165
1166 ePen = BOTH_PENS;
1167 return NO_ERROR;
1168
1169 } //ParsePenInfo
1170
1171
IsPCL3DriverwareAvailable()1172 BOOL DJ9xxVIP::IsPCL3DriverwareAvailable()
1173 {
1174 #ifdef APDK_LINUX
1175 // Linux supports Bi-Di, but is not enabled at this time. See comments below.
1176 return TRUE;
1177 #else
1178
1179 BOOL pcl3driverware = TRUE; // default to TRUE since this is the case for all but some early units
1180 BOOL inAJob = FALSE;
1181 char *pStr;
1182 char *pEnd;
1183 BYTE devIDBuff[DevIDBuffSize];
1184 int maxWaitTries;
1185 int i;
1186
1187 // if don't have bidi can't check so assume driverware is ok since only certain
1188 // 990s don't handle driverware in PCL3 mode
1189 if (!IOMode.bDevID)
1190 {
1191 return TRUE;
1192 }
1193
1194 if (pSS->GetDeviceID(devIDBuff, DevIDBuffSize, TRUE) != NO_ERROR)
1195 {
1196 goto cleanup;
1197 }
1198
1199 // if printer does not have firmware based on the first 990 release
1200 // don't bother checking, can assume driverware commands are OK
1201 if (!strstr((const char*)devIDBuff+2,"MDL:DESKJET 990C") &&
1202 !strstr((const char*)devIDBuff+2,"MDL:PHOTOSMART 1215") &&
1203 !strstr((const char*)devIDBuff+2,"MDL:PHOTOSMART 1218") )
1204 {
1205 return TRUE;
1206 }
1207
1208 // high-level process to check if driverware is available in PCL3 mode:
1209 // 1. set JobName through the normal PJL command to some string X
1210 // 2. poll DeviceID until see this JobName (syncs host with printer in case
1211 // printer is still printing an earlier job etc.)
1212 // 3. go into PCL3 mode
1213 // 4. send driverware command to set JobName
1214 // 5. get the DeviceID and look at the JobName, if it is not "NEWDRIVERWARE" (what
1215 // the firmware driverware command sets it to) conclude that driverware is
1216 // not available in PCL3 mode; if the JobName is "NEWDRIVERWARE" then conclude
1217 // that driverware is available in PCL3 mode
1218 // 6. exit this "job" (send a UEL)
1219
1220
1221
1222 // set the JobName via PJL
1223 if (Flush() != NO_ERROR) goto cleanup;
1224 if (Send((const BYTE*)UEL,sizeof(UEL)) != NO_ERROR) goto cleanup;
1225 inAJob = TRUE;
1226 if (Send((const BYTE*)JobName,sizeof(JobName)) != NO_ERROR) goto cleanup;
1227 if (Send((const BYTE*)&Quote,1) != NO_ERROR) goto cleanup;
1228 if (Send((const BYTE*)OUR_PJL_JOBNAME,strlen(OUR_PJL_JOBNAME)) != NO_ERROR) goto cleanup;
1229 if (Send((const BYTE*)&Quote,1) != NO_ERROR) goto cleanup;
1230 if (Send((const BYTE*)&LF,1) != NO_ERROR) goto cleanup;
1231 if (Flush() != NO_ERROR) goto cleanup; // we flush our ::Send buffer
1232 if (pSS->FlushIO() != NO_ERROR) goto cleanup; // we flush any external I/O buffer
1233
1234 // wait for printer to see this and set JobName in the DeviceID
1235 // we know printer will respond, it is just a matter of time so wait
1236 // a while until see it since it may take a few seconds
1237 // for it to sync up with us if it is busy printing or picking
1238 //
1239 // this is a pretty long timeout but if the printer is finishing up
1240 // a preceding job we need to give it time to finish it since it won't
1241 // set the new jobname until the last job is complete
1242 // one possible enhancement would be to look at the flags in the DeviceID
1243 // to see if a job is active on more than one i/o connection
1244 maxWaitTries = 120; // wait max of 60sec
1245 for (i=0; i<maxWaitTries; i++)
1246 {
1247 if (pSS->GetDeviceID(devIDBuff, DevIDBuffSize, TRUE) != NO_ERROR) goto cleanup;
1248 if ( (pStr=(char *)strstr((const char*)devIDBuff+2,";J:")) )
1249 {
1250 pStr += 3;
1251 if ( (pEnd=(char *)strstr((const char*)pStr,";")) )
1252 {
1253 *pEnd = '\0';
1254 while (pEnd > pStr) // take out trailing spaces in JobName before compare
1255 {
1256 if (*(pEnd-1) == ' ')
1257 {
1258 *(pEnd-1) = '\0';
1259 }
1260 else
1261 {
1262 break;
1263 }
1264 pEnd--;
1265 }
1266 if (!strcmp(pStr, OUR_PJL_JOBNAME))
1267 {
1268 break;
1269 }
1270 }
1271 pSS->BusyWait((DWORD)500);
1272 }
1273 else
1274 {
1275 DBG1("JobName missing from DeviceID strings");
1276 goto cleanup;
1277 }
1278 }
1279 if (i>=maxWaitTries)
1280 {
1281 // printer didn't respond to driverware in PCL3GUI mode withing allowed timeout
1282 DBG1("Printer didn't respond to PJL\n");
1283 goto cleanup;
1284 }
1285
1286 // now printer is in sync with us so try PCL3 mode and expect it to react to command
1287 // immediately or will assume that it ignores driverware in that mode
1288 if (Send((const BYTE*)EnterLanguage,sizeof(EnterLanguage)) != NO_ERROR) goto cleanup;
1289 if (Send((const BYTE*)PCL3,sizeof(PCL3)) != NO_ERROR) goto cleanup;
1290 if (Send((const BYTE*)&LF,1) != NO_ERROR) goto cleanup;
1291 if (Send((const BYTE*)DriverwareJobName,sizeof(DriverwareJobName)) != NO_ERROR) goto cleanup;
1292 if (Flush() != NO_ERROR) goto cleanup; // we flush our ::Send buffer
1293 if (pSS->FlushIO() != NO_ERROR) goto cleanup; // we flush any external I/O buffer
1294
1295 // wait for printer to see this and set DeviceID to reflect this command
1296 // since we are sending in PCL3 mode we don't know if printer will respond
1297 // so don't wait very long
1298 maxWaitTries = 4;
1299 for (i=0; i<maxWaitTries; i++)
1300 {
1301 if (pSS->GetDeviceID(devIDBuff, DevIDBuffSize, TRUE) != NO_ERROR) goto cleanup;
1302 if ( (pStr=(char *)strstr((const char*)devIDBuff+2,";J:")) )
1303 {
1304 pStr += 3;
1305 if ( (pEnd=(char *)strstr((const char*)pStr,";")) )
1306 {
1307 *pEnd = '\0';
1308 // firmware may have garbage in remainder of JobName buffer - truncate
1309 // it to the length of the string that should be set before compare
1310 if (!strncmp(pStr, DRIVERWARE_JOBNAME, strlen(DRIVERWARE_JOBNAME)))
1311 {
1312 pcl3driverware = TRUE;
1313 break;
1314 }
1315 }
1316 pSS->BusyWait((DWORD)500);
1317 }
1318 else
1319 {
1320 DBG1("JobName missing from DeviceID string");
1321 goto cleanup;
1322 }
1323 }
1324 if (i>=maxWaitTries)
1325 {
1326 // since we haven't gotten a response assume that the printer ignores driverware
1327 // commands in PCL3 mode
1328 pcl3driverware = FALSE;
1329 }
1330
1331
1332 cleanup:
1333 if (inAJob) // send UEL in case left printer in the context of a job
1334 {
1335 if (Send((const BYTE*)UEL,sizeof(UEL)) != NO_ERROR) goto bailout;
1336 if (pSS->FlushIO() != NO_ERROR) goto bailout;
1337 }
1338
1339 bailout:
1340 return pcl3driverware;
1341
1342 #endif // APDK_LINUX
1343
1344 } //IsPCL3DriverwareAvailable
1345
1346
ParseError(BYTE status_reg)1347 DISPLAY_STATUS DJ9xxVIP::ParseError(BYTE status_reg)
1348 {
1349 DBG1("DJ9xxVIP, parsing error info\n");
1350
1351 DRIVER_ERROR err = NO_ERROR;
1352 BYTE DevIDBuffer[DevIDBuffSize];
1353 char *pStr;
1354 int iVersion = pSS->GetVIPVersion ();
1355
1356 if(IOMode.bDevID && iVersion < 6)
1357 {
1358 // If a bi-di cable was plugged in and everything was OK, let's see if it's still
1359 // plugged in and everything is OK
1360 err = pSS->GetDeviceID (DevIDBuffer, DevIDBuffSize, TRUE);
1361 if(err != NO_ERROR)
1362 {
1363 // job was bi-di but now something's messed up, probably cable unplugged
1364 return DISPLAY_COMM_PROBLEM;
1365 }
1366
1367 if ( (pStr=(char *)strstr((const char*)DevIDBuffer+2,";S:")) == NULL )
1368 {
1369 return DISPLAY_COMM_PROBLEM;
1370 }
1371
1372 // point to PrinterState
1373 BYTE b1,b2;
1374
1375 pStr+=5; // 3 for ";S:", 2 for version -- point to first byte of "printer state"
1376 b1=*pStr;
1377
1378 if (b1=='9')
1379 {
1380 return DISPLAY_TOP_COVER_OPEN;
1381 }
1382
1383 if (iVersion < 3)
1384 {
1385 pStr += 12; // point to "feature state"
1386 }
1387 else if (iVersion < 5)
1388 {
1389 pStr += 14;
1390 }
1391 else
1392 {
1393 pStr += 18;
1394 }
1395
1396 b1=*pStr++;
1397 b2=*pStr++;
1398 if ((b1=='0') && (b2=='9')) // 09 = OOP state
1399 {
1400 DBG1("Out of Paper [from Encoded DevID]\n");
1401 return DISPLAY_OUT_OF_PAPER;
1402 }
1403
1404 if (b1 == '0' && (b2 == 'c' || b2 == 'C')) // 0C - PhotoTray Mismatch
1405 {
1406
1407 /*
1408 * PhotoTray is engaged, but requested paper size is larger than A6.
1409 * It may also mean A6/Photo size is requested but photo tray is not engaged.
1410 */
1411
1412 DBG1("Photo Tray Mismatch [from Encoded DevID]\n");
1413 return DISPLAY_PHOTOTRAY_MISMATCH;
1414 }
1415
1416 // Paper Jam or Paper Stall
1417
1418 if ((b1 == '1' && b2 == '0') || // Paper Jam
1419 (b1 == '0' && (b2 == 'e' || b2 == 'E')))
1420 {
1421 return DISPLAY_PAPER_JAMMED;
1422 }
1423
1424 // Carriage Stall
1425
1426 if (b1 == '0' && (b2 == 'F' || b2 == 'f'))
1427 {
1428 return DISPLAY_ERROR_TRAP;
1429 }
1430
1431 // Job Cancelled (AIO printer turn idle after job canceled)
1432 if ((b1=='0') && (b2=='5')) // 05 = CNCL state
1433 {
1434 DBG1("Printing Canceled [from Encoded DevID]\n");
1435 return DISPLAY_PRINTING_CANCELED;
1436 }
1437
1438 // VerifyPenInfo will handle prompting the user
1439 // if this is a problem
1440 err = VerifyPenInfo ();
1441
1442 if(err != NO_ERROR)
1443 {
1444 // VerifyPenInfo returned an error, which can only happen when ToDevice
1445 // or GetDeviceID returns an error. Either way, it's BAD_DEVICE_ID or
1446 // IO_ERROR, both unrecoverable. This is probably due to the printer
1447 // being turned off during printing, resulting in us not being able to
1448 // power it back on in VerifyPenInfo, since the buffer still has a
1449 // partial raster in it and we can't send the power-on command.
1450 return DISPLAY_COMM_PROBLEM;
1451 }
1452 }
1453
1454 // check for errors we can detect from the status reg
1455 if (IOMode.bStatus)
1456 {
1457 // Although DJ8XX is OOP, printer continues taking data and BUSY bit gets
1458 // set. See IO_defs.h
1459 if ( DEVICE_IS_OOP(status_reg) )
1460 {
1461 DBG1("Out Of Paper [from status byte]\n");
1462 return DISPLAY_OUT_OF_PAPER;
1463 }
1464
1465 // DJ8XX doesn't go offline, so SELECT bit is set even when paper jammed.
1466 // See IO_defs.h
1467 if (DEVICE_PAPER_JAMMED(status_reg))
1468 {
1469 DBG1("Jammed [from status byte]\n");
1470 return DISPLAY_PAPER_JAMMED;
1471 }
1472 /*
1473 * Do not process this. Malibu printers set the NFAULT bit low when a pen is
1474 * missing, eventhough they support reserve mode printing. This causes us to
1475 * report ERROR_TRAP message. Consequence is that we may not catch carriage
1476 * stall, but should eventually result in time out.
1477 if (DEVICE_IO_TRAP(status_reg))
1478 {
1479 DBG1("Jammed or trapped [from status byte]\n");
1480 return DISPLAY_ERROR_TRAP;
1481 }
1482 */
1483 }
1484
1485 // don't know what the problem is-
1486 // Is the PrinterAlive?
1487 if (pSS->PrinterIsAlive())
1488 {
1489 iTotal_SLOW_POLL_Count += iMax_SLOW_POLL_Count;
1490 #if defined(DEBUG) && (DBG_MASK & DBG_LVL1)
1491 printf("iTotal_SLOW_POLL_Count = %d\n",iTotal_SLOW_POLL_Count);
1492 #endif
1493 // -Note that iTotal_SLOW_POLL_Count is a multiple of
1494 // iMax_SLOW_POLL_Count allowing us to check this
1495 // on an absolute time limit - not relative to the number
1496 // of times we happen to have entered ParseError.
1497 // -Also note that we have different thresholds for uni-di & bi-di.
1498 if(
1499 ((IOMode.bDevID == FALSE) && (iTotal_SLOW_POLL_Count >= 60)) ||
1500 ((IOMode.bDevID == TRUE) && (iTotal_SLOW_POLL_Count >= 120))
1501 )
1502 {
1503 return DISPLAY_BUSY;
1504 }
1505 else
1506 {
1507 return DISPLAY_PRINTING;
1508 }
1509 }
1510 else
1511 {
1512 return DISPLAY_COMM_PROBLEM;
1513 }
1514 } //ParseError
1515
1516
CleanPen()1517 DRIVER_ERROR DJ9xxVIP::CleanPen()
1518 {
1519 const BYTE DJ990_User_Output_Page[] = {ESC, '%','P','u','i','f','p','.',
1520 'm','u','l','t','i','_','b','u','t','t','o','n','_','p','u','s','h',' ','3',';',
1521 'u','d','w','.','q','u','i','t',';',ESC,'%','-','1','2','3','4','5','X' };
1522
1523 DWORD length = sizeof(PEN_CLEAN_PML);
1524 DRIVER_ERROR err = pSS->ToDevice(PEN_CLEAN_PML, &length);
1525 ERRCHECK;
1526
1527 // send this page so that the user sees some output. If you don't send this, the
1528 // pens get serviced but nothing prints out.
1529 length = sizeof(DJ990_User_Output_Page);
1530 return pSS->ToDevice(DJ990_User_Output_Page, &length);
1531 } //CleanPen
1532
1533
1534 #if defined(APDK_VIP_COLORFILTERING)
1535 /// ERNIE ////////////////////////////////////////////////////////////////
Process(RASTERDATA * ImageData)1536 BOOL TErnieFilter::Process(RASTERDATA* ImageData)
1537 {
1538 if (ImageData == NULL || (ImageData->rasterdata[COLORTYPE_COLOR] == NULL && ImageData->rasterdata[COLORTYPE_BLACK] == NULL))
1539 {
1540 return FALSE;
1541 }
1542 else
1543 {
1544 if (ImageData->rasterdata[COLORTYPE_COLOR])
1545 {
1546 submitRowToFilter(ImageData->rasterdata[COLORTYPE_COLOR]);
1547
1548 if (ImageData->rasterdata[COLORTYPE_BLACK])
1549 {
1550 memcpy(fBlackRowPtr[RowIndex], ImageData->rasterdata[COLORTYPE_BLACK], ImageData->rastersize[COLORTYPE_BLACK]);
1551 }
1552 BlackRasterSize[RowIndex++] = ImageData->rastersize[COLORTYPE_BLACK];
1553
1554 if (RowIndex == 4)
1555 RowIndex = 0;
1556
1557 // something ready after 4th time only
1558 return (fNumberOfBufferedRows == 0);
1559 }
1560 else
1561 {
1562 iRastersReady = 1;
1563 }
1564 }
1565 return TRUE;
1566 } //Process
1567
1568
GetOutputWidth(COLORTYPE rastercolor)1569 unsigned int TErnieFilter::GetOutputWidth(COLORTYPE rastercolor)
1570 {
1571 if (rastercolor == COLORTYPE_COLOR)
1572 {
1573 if (raster.rasterdata[COLORTYPE_COLOR] == NULL)
1574 return 0;
1575 else
1576 return fRowWidthInPixels * BYTES_PER_PIXEL;
1577 }
1578 else
1579 {
1580 if (raster.rasterdata[COLORTYPE_COLOR] == NULL)
1581 return raster.rastersize[rastercolor];
1582 else
1583 return BlackRasterSize[iRastersDelivered-1];
1584 }
1585 } //GetOutputWidth
1586
1587
NextOutputRaster(COLORTYPE rastercolor)1588 BYTE* TErnieFilter::NextOutputRaster(COLORTYPE rastercolor)
1589 {
1590 if (iRastersReady == 0)
1591 return (BYTE*)NULL;
1592 if (rastercolor == COLORTYPE_COLOR)
1593 {
1594 if (raster.rasterdata[COLORTYPE_COLOR] == NULL)
1595 {
1596 iRastersReady--;
1597 return (BYTE*)NULL;
1598 }
1599 else
1600 {
1601 if (iRastersReady == 0)
1602 return (BYTE*)NULL;
1603
1604 iRastersReady--;
1605
1606 return fRowPtr[iRastersDelivered++];
1607 }
1608 }
1609 else
1610 {
1611 if (raster.rasterdata[COLORTYPE_COLOR] == NULL)
1612 {
1613 return raster.rasterdata[rastercolor];
1614 }
1615 else
1616 {
1617 if (BlackRasterSize[iRastersDelivered] == 0)
1618 return NULL;
1619 else
1620 return fBlackRowPtr[iRastersDelivered];
1621 }
1622 }
1623 } //NextOutputRaster
1624
1625
Flush()1626 void TErnieFilter::Flush()
1627 {
1628 writeBufferedRows();
1629 iRastersDelivered=0;
1630 fPixelOffsetIndex = 0;
1631 iRastersReady = fNumberOfBufferedRows;
1632 fNumberOfBufferedRows = 0;
1633 } //Flush
1634
1635 #endif //APDK_VIP_COLORFILTERING
1636
get3Pixel(BYTE * pixAddress,int pixelOffset)1637 inline uint32_t Mode10::get3Pixel
1638 (
1639 BYTE* pixAddress,
1640 int pixelOffset
1641 )
1642 {
1643 pixAddress += ((pixelOffset << 1) + pixelOffset); //pixAddress += pixelOffset * 3;
1644
1645 BYTE r = *(pixAddress);
1646 BYTE g = *(pixAddress + 1);
1647 BYTE b = *(pixAddress + 2);
1648
1649 return (kWhite & ((r << 16) | (g << 8) | (b)));
1650
1651 // unsigned int toReturn = *((unsigned int*)pixAddress); // load toReturn with XRGB
1652 // toReturn &= kWhite; // Strip off unwanted X. EGW stripped lsb blue.
1653 } //get3Pixel
1654
1655
put3Pixel(BYTE * pixAddress,int pixelOffset,uint32_t pixel)1656 void Mode10::put3Pixel
1657 (
1658 BYTE* pixAddress,
1659 int pixelOffset,
1660 uint32_t pixel
1661 )
1662 {
1663 pixAddress += ((pixelOffset << 1) + pixelOffset); //pixAddress += pixelOffset * 3;
1664
1665 unsigned int temp = (pixel & kWhite);
1666
1667 *(pixAddress) = ((temp >> 16) & 0x000000FF);
1668 *(pixAddress + 1) = ((temp >> 8) & 0x000000FF);
1669 *(pixAddress + 2) = (temp & 0x000000FF);
1670
1671 } //put3Pixel
1672
1673
ShortDelta(uint32_t lastPixel,uint32_t lastUpperPixel)1674 unsigned short Mode10::ShortDelta
1675 (
1676 uint32_t lastPixel,
1677 uint32_t lastUpperPixel
1678 )
1679 {
1680 int dr,dg,db;
1681 int result;
1682
1683 dr = GetRed(lastPixel) - GetRed(lastUpperPixel);
1684 dg = GetGreen(lastPixel) - GetGreen(lastUpperPixel);
1685 db = GetBlue(lastPixel) - GetBlue(lastUpperPixel);
1686
1687 if ((dr <= 15) && (dr >= -16) && (dg <= 15) && (dg >= -16) && (db <= 30) && (db >= -32))
1688 { // Note db is divided by 2 to double it's range from -16..15 to -32..30
1689 result = ((dr << 10) & 0x007C00) | (((dg << 5) & 0x0003E0) | ((db >> 1) & 0x01F) | 0x8000); // set upper bit to signify short delta
1690 }
1691 else
1692 {
1693 result = 0; // upper bit is zero to signify delta won't work
1694 }
1695
1696 return result;
1697 }
1698
Process(RASTERDATA * input)1699 BOOL Mode10::Process
1700 (
1701 RASTERDATA* input
1702 )
1703 /****************************************************************************
1704 Initially written by Elden Wood
1705 August 1998
1706
1707 Similar to mode 9, though tailored for pixel data.
1708 For more information see the Bert Compression Format document.
1709
1710 This function compresses a single row per call.
1711 ****************************************************************************/
1712 {
1713 if (input==NULL ||
1714 (input->rasterdata[COLORTYPE_COLOR]==NULL && input->rasterdata[COLORTYPE_BLACK]==NULL)) // flushing pipeline
1715 {
1716 Flush();
1717 return FALSE;
1718 }
1719
1720 if (myplane == COLORTYPE_BLACK || input->rasterdata[COLORTYPE_COLOR]==NULL)
1721 {
1722 iRastersReady = 1;
1723 compressedsize = 0;
1724 if (seeded)
1725 {
1726 thePrinter->Send(ResetSeedrow, sizeof(ResetSeedrow));
1727 memset(SeedRow,0xFF,inputsize);
1728 seeded = FALSE;
1729 }
1730 return TRUE;
1731 }
1732 unsigned int originalsize = input->rastersize[myplane];
1733 unsigned int size = input->rastersize[myplane];
1734
1735 unsigned char *seedRowPtr = (unsigned char*)SeedRow;
1736
1737 unsigned char *compressedDataPtr = compressBuf;
1738 unsigned char *curRowPtr = (unsigned char*)input->rasterdata[myplane];
1739 unsigned int rowWidthInBytes = size;
1740
1741 ASSERT(curRowPtr);
1742 ASSERT(seedRowPtr);
1743 ASSERT(compressedDataPtr);
1744 ASSERT(rowWidthInBytes >= BYTES_PER_PIXEL);
1745 ASSERT((rowWidthInBytes % BYTES_PER_PIXEL) == 0);
1746
1747 unsigned char *compressedDataStart = compressedDataPtr;
1748 unsigned int lastPixel = (rowWidthInBytes / BYTES_PER_PIXEL) - 1;
1749
1750 // Setup sentinal value to replace last pixel of curRow. Simplifies future end condition checking.
1751 uint32_t realLastPixel = getPixel(curRowPtr, lastPixel);
1752
1753 uint32_t newLastPixel = realLastPixel;
1754 while ((getPixel(curRowPtr, lastPixel-1) == newLastPixel) ||
1755 (getPixel(seedRowPtr, lastPixel) == newLastPixel))
1756 {
1757 putPixel(curRowPtr, lastPixel, newLastPixel += 0x100); // add one to green.
1758 }
1759
1760 unsigned int curPixel = 0;
1761 unsigned int seedRowPixelCopyCount;
1762 unsigned int cachedColor = kWhite;
1763
1764 do // all pixels in row
1765 {
1766 unsigned char CMDByte = 0;
1767 int replacementCount;
1768
1769 // Find seedRowPixelCopyCount for upcoming copy
1770 seedRowPixelCopyCount = curPixel;
1771 while (getPixel(seedRowPtr, curPixel) == getPixel(curRowPtr, curPixel))
1772 {
1773 curPixel++;
1774 }
1775
1776 seedRowPixelCopyCount = curPixel - seedRowPixelCopyCount;
1777 ASSERT (curPixel <= lastPixel);
1778
1779 int pixelSource = 0;
1780
1781 if (curPixel == lastPixel) // On last pixel of row. RLE could also leave us on the last pixel of the row from the previous iteration.
1782 {
1783 putPixel(curRowPtr, lastPixel, realLastPixel);
1784
1785 if (getPixel(seedRowPtr, curPixel) == realLastPixel)
1786 {
1787 goto mode10rtn;
1788 }
1789 else // code last pix as a literal
1790 {
1791
1792 CMDByte = eLiteral;
1793 pixelSource = eeNewPixel;
1794 replacementCount = 1;
1795 curPixel++;
1796 }
1797 }
1798 else // prior to last pixel of row
1799 {
1800 ASSERT(curPixel < lastPixel);
1801
1802 replacementCount = curPixel;
1803 uint32_t RLERun = getPixel(curRowPtr, curPixel);
1804
1805 curPixel++; // Adjust for next pixel.
1806 while (RLERun == getPixel(curRowPtr, curPixel)) // RLE
1807 {
1808 curPixel++;
1809 }
1810 curPixel--; // snap back to current.
1811 replacementCount = curPixel - replacementCount;
1812 ASSERT(replacementCount >= 0);
1813
1814 if (replacementCount > 0) // Adjust for total occurance and move to next pixel to do.
1815 {
1816 curPixel++;
1817 replacementCount++;
1818
1819 if (cachedColor == RLERun)
1820 {
1821 pixelSource = eeCachedColor;
1822 }
1823 else if (getPixel(seedRowPtr, curPixel-replacementCount+1) == RLERun)
1824 {
1825 pixelSource = eeNEPixel;
1826 }
1827 else if ((curPixel-replacementCount > 0) && (getPixel(curRowPtr, curPixel-replacementCount-1) == RLERun))
1828 {
1829 pixelSource = eeWPixel;
1830 }
1831 else
1832 {
1833 pixelSource = eeNewPixel;
1834 cachedColor = RLERun;
1835 }
1836
1837 CMDByte = eRLE; // Set default for later.
1838
1839 }
1840
1841 if (curPixel == lastPixel)
1842 {
1843 ASSERT(replacementCount > 0); // Already found some RLE pixels
1844
1845 if (realLastPixel == RLERun) // Add to current RLE. Otherwise it'll be part of the literal from the seedrow section above on the next iteration.
1846 {
1847 putPixel(curRowPtr, lastPixel, realLastPixel);
1848 replacementCount++;
1849 curPixel++;
1850 }
1851 }
1852
1853 if (0 == replacementCount) // no RLE so it's a literal by default.
1854 {
1855 uint32_t tempPixel = getPixel(curRowPtr, curPixel);
1856
1857 ASSERT(tempPixel != getPixel(curRowPtr, curPixel+1)); // not RLE
1858 ASSERT(tempPixel != getPixel(seedRowPtr, curPixel)); // not seedrow copy
1859
1860 CMDByte = eLiteral;
1861
1862 if (cachedColor == tempPixel)
1863 {
1864 pixelSource = eeCachedColor;
1865
1866 }
1867 else if (getPixel(seedRowPtr, curPixel+1) == tempPixel)
1868 {
1869 pixelSource = eeNEPixel;
1870
1871 }
1872 else if ((curPixel > 0) && (getPixel(curRowPtr, curPixel-1) == tempPixel))
1873 {
1874 pixelSource = eeWPixel;
1875
1876 }
1877 else
1878 {
1879
1880 pixelSource = eeNewPixel;
1881 cachedColor = tempPixel;
1882 }
1883
1884 replacementCount = curPixel;
1885 uint32_t cachePixel;
1886 uint32_t nextPixel = getPixel(curRowPtr, curPixel+1);
1887 do
1888 {
1889 if (++curPixel == lastPixel)
1890 {
1891 putPixel(curRowPtr, lastPixel, realLastPixel);
1892 curPixel++;
1893 break;
1894 }
1895 cachePixel = nextPixel;
1896 }
1897 while ((cachePixel != (nextPixel = getPixel(curRowPtr, curPixel+1))) &&
1898 (cachePixel != getPixel(seedRowPtr, curPixel)));
1899
1900 replacementCount = curPixel - replacementCount;
1901
1902 ASSERT(replacementCount > 0);
1903 }
1904 }
1905
1906 ASSERT(seedRowPixelCopyCount >= 0);
1907
1908 // Write out compressed data next.
1909 if (eLiteral == CMDByte)
1910 {
1911 ASSERT(replacementCount >= 1);
1912
1913 replacementCount -= 1; // normalize it
1914
1915 CMDByte |= pixelSource; // Could put this directly into CMDByte above.
1916 CMDByte |= MIN(3, seedRowPixelCopyCount) << 3;
1917 CMDByte |= MIN(7, replacementCount);
1918
1919 *compressedDataPtr++ = CMDByte;
1920
1921 if (seedRowPixelCopyCount >= 3)
1922 {
1923 outputVLIBytesConsecutively(seedRowPixelCopyCount - 3, compressedDataPtr);
1924 }
1925
1926 replacementCount += 1; // denormalize it
1927
1928 int totalReplacementCount = replacementCount;
1929 int upwardPixelCount = 1;
1930
1931 if (eeNewPixel != pixelSource)
1932 {
1933 replacementCount -= 1; // Do not encode 1st pixel of run since it comes from an alternate location.
1934 upwardPixelCount = 2;
1935 }
1936
1937 for ( ; upwardPixelCount <= totalReplacementCount; upwardPixelCount++)
1938 {
1939 ASSERT(totalReplacementCount >= upwardPixelCount);
1940
1941 unsigned short compressedPixel = ShortDelta( getPixel(curRowPtr, curPixel-replacementCount),
1942 getPixel(seedRowPtr, curPixel-replacementCount));
1943 if (compressedPixel)
1944 {
1945 *compressedDataPtr++ = compressedPixel >> 8;
1946 *compressedDataPtr++ = (unsigned char)compressedPixel;
1947
1948 }
1949 else
1950 {
1951 uint32_t uncompressedPixel = getPixel(curRowPtr, curPixel-replacementCount);
1952
1953 uncompressedPixel >>= 1; // Lose the lsb of blue and zero out the msb of the 3 bytes.
1954
1955 *compressedDataPtr++ = (BYTE)(uncompressedPixel >> 16);
1956 *compressedDataPtr++ = (BYTE)(uncompressedPixel >> 8);
1957 *compressedDataPtr++ = (BYTE)(uncompressedPixel);
1958
1959 }
1960
1961 if (((upwardPixelCount-8) % 255) == 0) // See if it's time to spill a single VLI byte.
1962 {
1963 *compressedDataPtr++ = MIN(255, totalReplacementCount - upwardPixelCount);
1964 }
1965
1966 replacementCount--;
1967 }
1968 }
1969 else // RLE
1970 {
1971 ASSERT(eRLE == CMDByte);
1972 ASSERT(replacementCount >= 2);
1973
1974 replacementCount -= 2; // normalize it
1975
1976 CMDByte |= pixelSource; // Could put this directly into CMDByte above.
1977 CMDByte |= MIN(3, seedRowPixelCopyCount) << 3;
1978 CMDByte |= MIN(7, replacementCount);
1979
1980 *compressedDataPtr++ = CMDByte;
1981
1982 if (seedRowPixelCopyCount >= 3)
1983 {
1984 outputVLIBytesConsecutively(seedRowPixelCopyCount - 3, compressedDataPtr);
1985 }
1986
1987 replacementCount += 2; // denormalize it
1988
1989 if (eeNewPixel == pixelSource)
1990 {
1991 unsigned short compressedPixel = ShortDelta(getPixel(curRowPtr, curPixel - replacementCount),
1992 getPixel(seedRowPtr, curPixel - replacementCount));
1993 if (compressedPixel)
1994 {
1995 *compressedDataPtr++ = compressedPixel >> 8;
1996 *compressedDataPtr++ = (unsigned char)compressedPixel;
1997 }
1998 else
1999 {
2000 uint32_t uncompressedPixel = getPixel(curRowPtr, curPixel - replacementCount);
2001
2002 uncompressedPixel >>= 1;
2003
2004 *compressedDataPtr++ = (BYTE)(uncompressedPixel >> 16);
2005 *compressedDataPtr++ = (BYTE)(uncompressedPixel >> 8);
2006 *compressedDataPtr++ = (BYTE)(uncompressedPixel);
2007 }
2008 }
2009
2010 if (replacementCount-2 >= 7) outputVLIBytesConsecutively(replacementCount - (7+2), compressedDataPtr);
2011 }
2012 } while (curPixel <= lastPixel);
2013
2014 mode10rtn:
2015 size = compressedDataPtr - compressedDataStart; // return # of compressed bytes.
2016 compressedsize = size;
2017 memcpy(SeedRow, input->rasterdata[myplane], originalsize);
2018 seeded = TRUE;
2019 iRastersReady = 1;
2020 return TRUE;
2021 } //Process
2022
NextOutputRaster(COLORTYPE color)2023 BYTE* Mode10::NextOutputRaster(COLORTYPE color)
2024 // since we return 1-for-1, just return result first call
2025 {
2026 if (iRastersReady==0)
2027 return (BYTE*)NULL;
2028
2029 if (color == COLORTYPE_BLACK)
2030 {
2031 return raster.rasterdata[color];
2032 }
2033 else
2034 {
2035 iRastersReady=0;
2036 if (raster.rasterdata[color] != NULL)
2037 {
2038 return compressBuf;
2039 }
2040 else
2041 {
2042 return raster.rasterdata[color];
2043 }
2044 }
2045 }
2046
PhotoTrayStatus(BOOL bQueryPrinter)2047 BYTE DJ9xxVIP::PhotoTrayStatus
2048 (
2049 BOOL bQueryPrinter
2050 )
2051 {
2052 DRIVER_ERROR err;
2053 char* pStr;
2054
2055 BYTE bDevIDBuff[DevIDBuffSize];
2056
2057 if (!IOMode.bDevID)
2058 {
2059 bQueryPrinter = FALSE;
2060 }
2061
2062 err = pSS->GetDeviceID(bDevIDBuff, DevIDBuffSize, bQueryPrinter);
2063 if (err!=NO_ERROR)
2064 {
2065 return 0;
2066 }
2067
2068 if ( (pStr=(char *)strstr((const char*)bDevIDBuff+2,";S:")) == NULL )
2069 {
2070 return 0;
2071 }
2072
2073 // skip over ";S:<version=2bytes><topcover><inklid><duplexer>"
2074 pStr += 8;
2075 BYTE b = *pStr;
2076 return b;
2077 } //PhotoTrayStatus
2078
2079
PhotoTrayPresent(BOOL bQueryPrinter)2080 BOOL DJ9xxVIP::PhotoTrayPresent
2081 (
2082 BOOL bQueryPrinter
2083 )
2084 {
2085 // for phototray present == 8
2086 return ((PhotoTrayStatus(bQueryPrinter) & 8) == 8);
2087 } //PhotoTrayInstalled
2088
2089
PhotoTrayEngaged(BOOL bQueryPrinter)2090 PHOTOTRAY_STATE DJ9xxVIP::PhotoTrayEngaged
2091 (
2092 BOOL bQueryPrinter
2093 )
2094 {
2095
2096 /*
2097 * When you add any new printer models to this class, make sure that the printer
2098 * has the phototray sensor and reports the phototray state correctly.
2099 */
2100 // for phototray present and engaged == 9
2101 return ((PHOTOTRAY_STATE) ((PhotoTrayStatus(bQueryPrinter) & 9) == 9));
2102 } //PhotoTrayEngaged
2103
2104
MandatoryPaperSize()2105 PAPER_SIZE DJ9xxVIP::MandatoryPaperSize()
2106 {
2107 if (PhotoTrayEngaged (TRUE))
2108 return PHOTO_SIZE;
2109 else return UNSUPPORTED_SIZE; // code for "nothing mandatory"
2110 } //MandatoryPaperSize
2111
2112
CheckInkLevel()2113 DRIVER_ERROR DJ9xxVIP::CheckInkLevel()
2114 {
2115 DRIVER_ERROR err;
2116 char *pStr;
2117 int i;
2118
2119 // BYTE bDevIDBuff[DevIDBuffSize];
2120
2121 if (!IOMode.bDevID)
2122 {
2123 return NO_ERROR;
2124 }
2125
2126 #if 0
2127 /*
2128 * Check for unknown device id version.
2129 */
2130
2131 if ((pSS->GetVIPVersion ()) > 5)
2132 {
2133 return NO_ERROR;
2134 }
2135
2136 err = pSS->GetDeviceID(bDevIDBuff, DevIDBuffSize, TRUE);
2137 if (err!=NO_ERROR)
2138 {
2139 return err;
2140 }
2141
2142 if ( (pStr=(char *)strstr((const char*)bDevIDBuff+2,";S:")) == NULL )
2143 {
2144 return NO_ERROR;
2145 }
2146 #endif
2147
2148 // Skip to pen-count field
2149
2150 err = SetPenInfo (pStr, FALSE);
2151 if (err != NO_ERROR)
2152 {
2153 return NO_ERROR;
2154 }
2155
2156 /*
2157 * VIPVersion = DevID Version + 1 - DevID Version no is 2 bytes following ;S:
2158 * Version 00 and 01 report 12 bytes for status info
2159 * Version 02 and onwards, report two additional bytes before pen info
2160 */
2161
2162 if (pSS->GetVIPVersion () == 1)
2163 {
2164
2165 // DJ990 style DeviceID
2166
2167 // Next 3 should be 2C1
2168 // meaning 2 pens, first field is head/supply for K
2169
2170 // pStr += 19;
2171 BYTE b1,b2,b3;
2172 b1=*pStr++; b2=*pStr++; b3=*pStr++;
2173 if ( (b1 != '2') || (b2 != 'C') || (b3 != '1'))
2174 {
2175 return NO_ERROR;
2176 }
2177
2178 // black pen
2179 pStr++; // skip pen identifier
2180 BYTE blackink = *pStr - 48; // convert from ascii
2181 // only look at low 3 bits
2182 blackink = blackink & 7;
2183
2184 // skip into color field
2185 pStr += 8;
2186 BYTE colorink = *pStr - 48;
2187 // only look at low 3 bits
2188 colorink = colorink & 7;
2189
2190 if ((blackink<5) && (colorink<5))
2191 {
2192 return NO_ERROR;
2193 }
2194
2195 if ((blackink>4) && (colorink>4))
2196 {
2197 return WARN_LOW_INK_BOTH_PENS;
2198 }
2199 if (blackink>4)
2200 {
2201 return WARN_LOW_INK_BLACK;
2202 }
2203 else
2204 {
2205 return WARN_LOW_INK_COLOR;
2206 }
2207 }
2208
2209 #if 0
2210 pStr += 21;
2211 if (pSS->GetVIPVersion () > 4)
2212 {
2213 pStr += 4;
2214 }
2215 #endif
2216
2217 int numPens = 0;
2218 if (*pStr > '0' && *pStr < '9')
2219 {
2220 numPens = *pStr - '0';
2221 }
2222 else if (*pStr > 'A' && *pStr < 'F')
2223 {
2224 numPens = *pStr - 'A';
2225 }
2226 else if (*pStr > 'a' && *pStr < 'f')
2227 {
2228 numPens = *pStr - 'a';
2229 }
2230
2231 pStr++;
2232
2233 err = NO_ERROR;
2234 if (pSS->GetVIPVersion () == 3)
2235 {
2236 for (i = 0; i < numPens; i++, pStr += 4)
2237 {
2238 switch (*pStr)
2239 {
2240 case '5':
2241 {
2242 if ((*(pStr+1) & 0xf3) > 1)
2243 {
2244 if (err != NO_ERROR)
2245 {
2246 err = WARN_LOW_INK_MULTIPLE_PENS;
2247 }
2248 else
2249 {
2250 err = WARN_LOW_INK_BLACK;
2251 }
2252 }
2253 break;
2254 }
2255 case '6':
2256 {
2257 if ((*(pStr+1) & 0xf3) > 1)
2258 {
2259 if (err != NO_ERROR)
2260 {
2261 err = WARN_LOW_INK_MULTIPLE_PENS;
2262 }
2263 else
2264 {
2265 err = WARN_LOW_INK_CYAN;
2266 }
2267 }
2268 break;
2269 }
2270 case '7':
2271 {
2272 if ((*(pStr+1) & 0xf3) > 1)
2273 {
2274 if (err != NO_ERROR)
2275 {
2276 err = WARN_LOW_INK_MULTIPLE_PENS;
2277 }
2278 else
2279 {
2280 err = WARN_LOW_INK_MAGENTA;
2281 }
2282 }
2283
2284 break;
2285 }
2286 case '8':
2287 {
2288 if ((*(pStr+1) & 0xf3) > 1)
2289 {
2290 if (err != NO_ERROR)
2291 {
2292 err = WARN_LOW_INK_MULTIPLE_PENS;
2293 }
2294 else
2295 {
2296 err = WARN_LOW_INK_YELLOW;
2297 }
2298 }
2299 break;
2300 }
2301 }
2302 }
2303 return err;
2304 }
2305
2306 BYTE penInfoBits[4];
2307 BYTE blackink = 0;
2308 BYTE colorink = 0;
2309 BYTE photoink = 0;
2310 BYTE greyink = 0;
2311
2312 for (i = 0; i < numPens; i++, pStr += 8)
2313 {
2314 AsciiHexToBinary (penInfoBits, pStr, 8);
2315
2316 if ((penInfoBits[0] & 0x40) != 0x40) // if Bit 31 is 1, this is not a pen
2317 {
2318 continue;
2319 }
2320 int penColor = penInfoBits[0] & 0x3F;
2321 switch (penColor)
2322 {
2323 case 1:
2324 blackink = penInfoBits[1] & 0x7;
2325 break;
2326 case 2:
2327 colorink = penInfoBits[1] & 0x7;
2328 break;
2329 case 3:
2330 photoink = penInfoBits[1] & 0x7;
2331 break;
2332 case 10:
2333 greyink = penInfoBits[1] & 0x7;
2334 break;
2335 case 4:
2336 case 5:
2337 case 6:
2338 case 7:
2339 case 8:
2340 case 9:
2341 colorink = penInfoBits[1] & 0x7; // REVISIT: these are C, M, Y respectively
2342 break;
2343 default:
2344 break;
2345 }
2346 }
2347 if (blackink < 2 && colorink < 2 && photoink < 2 && greyink < 2)
2348 {
2349 return NO_ERROR;
2350 }
2351 else if (blackink > 1 && colorink > 1 && photoink > 1)
2352 {
2353 return WARN_LOW_INK_COLOR_BLACK_PHOTO;
2354 }
2355 else if (greyink > 1 && colorink > 1 && photoink > 1)
2356 {
2357 return WARN_LOW_INK_COLOR_GREY_PHOTO;
2358 }
2359 else if (blackink > 1 && colorink > 1)
2360 {
2361 return WARN_LOW_INK_BOTH_PENS;
2362 }
2363 else if (blackink > 1 && photoink > 1)
2364 {
2365 return WARN_LOW_INK_BLACK_PHOTO;
2366 }
2367 else if (greyink > 1 && colorink > 1)
2368 {
2369 return WARN_LOW_INK_COLOR_GREY;
2370 }
2371 else if (greyink > 1 && photoink > 1)
2372 {
2373 return WARN_LOW_INK_GREY_PHOTO;
2374 }
2375 else if (colorink > 1 && photoink > 1)
2376 {
2377 return WARN_LOW_INK_COLOR_PHOTO;
2378 }
2379 else if (blackink > 1)
2380 {
2381 return WARN_LOW_INK_BLACK;
2382 }
2383 else if (colorink > 1)
2384 {
2385 return WARN_LOW_INK_COLOR;
2386 }
2387 else if (photoink > 1)
2388 {
2389 return WARN_LOW_INK_PHOTO;
2390 }
2391 else if (greyink > 1)
2392 {
2393 return WARN_LOW_INK_GREY;
2394 }
2395 else if (colorink > 1)
2396 {
2397 return WARN_LOW_INK_COLOR;
2398 }
2399 else
2400 {
2401 return NO_ERROR;
2402 }
2403 } //CheckInkLevel
2404
2405 APDK_END_NAMESPACE
2406
2407 #endif //APDK_DJ9xxVIP
2408