1 /*****************************************************************************\
2 registry.cpp : Implimentation for the DeviceRegistry 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 // The purpose of this file is to facilitate addition and subtraction
33 // of supported devices from the system.
36 #include "printerfactory.h"
39 #include "apollo2xxx.h"
40 #include "apollo21xx.h"
41 #include "apollo2560.h"
42 #include "apollo2xxx.h"
65 #include "djgenericvip.h"
67 #include "ojprokx50.h"
73 #include "ljjetready.h"
74 #include "ljfastraster.h"
75 #if defined (APDK_LJZJS_MONO) || defined (APDK_LJZJS_COLOR) || defined (APDK_LJM1005)
78 #ifdef APDK_LJZJS_MONO
79 #include "ljzjsmono.h"
81 #ifdef APDK_LJZJS_COLOR
82 #include "ljzjscolor.h"
89 #ifdef APDK_QUICKCONNECT
90 #include "quickconnect.h"
96 PScriptProxy DeviceRegistry::s_PScriptProxy;
100 LJMonoProxy DeviceRegistry::s_LJMonoProxy;
104 LJColorProxy DeviceRegistry::s_LJColorProxy;
107 #ifdef APDK_LJJETREADY
108 LJJetReadyProxy DeviceRegistry::s_LJJetReadyProxy;
111 #ifdef APDK_LJFASTRASTER
112 LJFastRasterProxy DeviceRegistry::s_LJFastRasterProxy;
115 #ifdef APDK_LJZJS_MONO
116 LJZjsMonoProxy DeviceRegistry::s_LJZjsMonoProxy;
119 #ifdef APDK_LJZJS_COLOR
120 LJZjsColorProxy DeviceRegistry::s_LJZjsColorProxy;
124 LJM1005Proxy DeviceRegistry::s_LJM1005Proxy;
125 LJP1XXXProxy DeviceRegistry::s_LJP1XXXProxy;
128 #if defined(APDK_PSP100) && defined (APDK_DJ9xxVIP)
129 PSP100Proxy DeviceRegistry::s_PSP100Proxy;
130 PSP470Proxy DeviceRegistry::s_PSP470Proxy;
133 #if defined(APDK_DJGENERICVIP) && defined (APDK_DJ9xxVIP)
134 DJGenericVIPProxy DeviceRegistry::s_DJGenericVIPProxy;
135 DJ55xxProxy DeviceRegistry::s_DJ55xxProxy;
139 DJ9xxProxy DeviceRegistry::s_DJ9xxProxy;
143 DJ9xxVIPProxy DeviceRegistry::s_DJ9xxVIPProxy;
144 OJProKx50Proxy DeviceRegistry::s_OJProKx50Proxy;
147 #if defined(APDK_DJ8xx)|| defined(APDK_DJ9xx)
148 DJ8xxProxy DeviceRegistry::s_DJ8xxProxy;
151 #if defined(APDK_DJ8xx)|| defined(APDK_DJ9xx)
153 DJ8x5Proxy DeviceRegistry::s_DJ8x5Proxy;
157 #if defined(APDK_DJ890)
158 DJ890Proxy DeviceRegistry::s_DJ890Proxy;
161 #if defined(APDK_DJ850)
162 DJ850Proxy DeviceRegistry::s_DJ850Proxy;
165 #ifdef APDK_DJ6xxPhoto
166 DJ6xxPhotoProxy DeviceRegistry::s_DJ6xxPhotoProxy;
170 DJ660Proxy DeviceRegistry::s_DJ660Proxy;
174 DJ630Proxy DeviceRegistry::s_DJ630Proxy;
178 DJ600Proxy DeviceRegistry::s_DJ600Proxy;
182 DJ540Proxy DeviceRegistry::s_DJ540Proxy;
186 DJ400Proxy DeviceRegistry::s_DJ400Proxy;
190 DJ350Proxy DeviceRegistry::s_DJ350Proxy;
193 #if defined(APDK_DJ3600) && defined (APDK_DJ3320)
194 DJ3600Proxy DeviceRegistry::s_DJ3600Proxy;
195 DJ4100Proxy DeviceRegistry::s_DJ4100Proxy;
196 DJD2600Proxy DeviceRegistry::s_DJD2600Proxy;
199 #if defined (APDK_DJ3320)
200 DJ3320Proxy DeviceRegistry::s_DJ3320Proxy;
203 #ifdef APDK_APOLLO2560
204 Apollo2560Proxy DeviceRegistry::s_Apollo2560Proxy;
207 #ifdef APDK_APOLLO21XX
208 Apollo21xxProxy DeviceRegistry::s_Apollo21xxProxy;
211 #ifdef APDK_APOLLO2XXX
212 Apollo2xxxProxy DeviceRegistry::s_Apollo2xxxProxy;
215 #ifdef APDK_QUICKCONNECT
216 QuickConnectProxy DeviceRegistry::s_QuickConnectProxy;
219 DeviceRegistry::DeviceRegistry()
220 : device(UNSUPPORTED)
225 DeviceRegistry::~DeviceRegistry()
227 DBG1("deleting DeviceRegistry\n");
231 DRIVER_ERROR DeviceRegistry::SelectDevice(const PRINTER_TYPE Model)
233 if (Model > MAX_PRINTER_TYPE)
234 return UNSUPPORTED_PRINTER;
241 DRIVER_ERROR DeviceRegistry::SelectDevice(char* model, int *pVIPVersion, char* pens, SystemServices* pSS)
242 // used by PrintContext constructor
243 // based on this 'model' string, we will search for the enum'd value
244 // and set this enum'd value in 'device'
247 #if defined(DEBUG) && (DBG_MASK & DBG_LVL1)
248 printf("DR::SelectDevice: model= '%s'\n",model);
249 printf("DR::SelectDevice: VIPver= %d\n",*pVIPVersion);
250 printf("DR::SelectDevice: pens= '%s'\n",pens);
254 char pen1 = '\0'; // black/color(for CCM)/photo(for 690) pen
255 char pen2 = '\0'; // color/non-existent(for CCM) pen
259 DRIVER_ERROR err = NO_ERROR;
261 FAMILY_HANDLE familyHandle = pPFI->FindDevIdMatch(model);
262 if (familyHandle != NULL)
264 device = pPFI->GetFamilyType(familyHandle);
268 if (!match) // see if printer supports VIP, if so set compatible device
270 if (*pVIPVersion == 1)
275 else if (*pVIPVersion > 1)
278 device = eDJGenericVIP; // eDJ9xxVIP;
283 * See if this is a sleek (LIDIL) printer, or PostScript printer
288 BYTE DevIDBuffer[DevIDBuffSize];
290 err = pSS->GetDeviceID(DevIDBuffer, DevIDBuffSize, FALSE);
291 ERRCHECK; // should be either NO_ERROR or BAD_DEVICE_ID
293 char *cmdStr = (char *) strstr ((const char *) DevIDBuffer+2, "CMD:");
295 if ((strstr((const char *) DevIDBuffer+2,"CMD:LDL")))
300 if (!match && cmdStr && (cmdStrEnd = (char *) strstr (cmdStr, ";")))
303 if (strstr (cmdStr, "LDL"))
310 if (!match && !cmdStr)
312 cmdStr = (char *) strstr ((const char *) DevIDBuffer+2, "COMMAND SET:");
314 if (!match && cmdStr && (strstr ((const char *) cmdStr+4, "POSTSCRIPT") ||
315 strstr ((const char *) cmdStr+4, "PostScript") ||
316 strstr ((const char *) cmdStr+4, "Postscript") ||
317 strstr ((const char *) cmdStr+4, "postscript") ))
326 // The devID model string did not have a match for a known printer
327 // and the printer doesn't support VIP so let's look at the pen info for clues
329 // if we don't have pen info (VSTATUS) it's presumably
330 // either sleek, DJ4xx or non-HP
331 device = UNSUPPORTED;
332 if ( pens[0] != '\0' )
334 // DJ8xx (and DJ970?) printers return penID $X0$X0
338 DBG1("DR:(Unknown Model) Need to do a POWER ON to get penIDs\n");
340 DWORD length=sizeof(DJ895_Power_On);
341 err = pSS->ToDevice(DJ895_Power_On, &length);
344 err = pSS->FlushIO();
347 // give the printer some time to power up
348 if (pSS->BusyWait((DWORD)1000) == JOB_CANCELED)
351 // we must re-query the devID
352 err=GetPrinterModel(model,pVIPVersion,pens,pSS);
356 // Arggghh. The pen(s) COULD be missing
360 // Is this binary-encoded format?
367 // get pen1 - penID format is $HB0$FC0
370 // get pen2 - if it exists
372 BOOL NO_PEN2 = FALSE;
373 while(pens[j] != '$') // handles variable length penIDs
376 if ( pens[j] == '\0' )
377 // never found a pen2
384 if (NO_PEN2 == FALSE)
390 if(pen1 == 'A' || pen2 == 'A')
394 // 2-pen printer with both pens missing
396 pSS->DisplayPrinterStatus(DISPLAY_NO_PENS);
398 // 1-pen printer with missing pen
399 else if(pen2 == '\0')
400 pSS->DisplayPrinterStatus(DISPLAY_NO_PEN_DJ600);
402 // may be one-pen DJ8xx derivative
403 else if (pen2 == 'F')
408 // 2-pen printer with BLACK missing
409 else pSS->DisplayPrinterStatus(DISPLAY_NO_BLACK_PEN);
411 // 2-pen printer with COLOR missing
415 // possibly DJ8x5 derivative
417 if (pen1 == 'H' || pen1 == 'Z' || pen1 == 'L')
422 pSS->DisplayPrinterStatus(DISPLAY_NO_COLOR_PEN);
425 if (pSS->BusyWait(500) == JOB_CANCELED)
428 // we must re-query the devID
429 err=GetPrinterModel(model,pVIPVersion,pens,pSS);
433 } while(pen1 == 'A' || pen2 == 'A');
435 // now that we have pens to look at, let's do the logic
436 // to instantiate the 'best-fit' driver
438 if (pen1 == 'H' || pen1 == 'Z' || pen1 == 'L') // (BLACK)
440 // check for a 850/855/870
443 else if (strncmp (model,"DESKJET 890",11) == 0)
444 device=eDJ890; // 890 has same pens as DJ895!
445 else if (pen2 == 'N') // (COLOR)
447 // It must be a DJ8xx derivative or will hopefully at
448 // least recognize a DJ8xx print mode
452 else if(pen1 == 'C') // (BLACK)
454 // check for 1-pen printer
455 if (pen2 == '\0') device = eDJ600;
456 // must be a 2-pen 6xx-derivative
457 else device = eDJ6xx;
459 else if(pen1 == 'M') // Multi-dye load
461 // must be a 690-derivative
462 device = eDJ6xxPhoto;
465 // check for 540-style pens?
466 // D = color, E = black
468 // else device=UNSUPPORTED;
473 // Early DJ8xx printer do not yet have full bi-di so check
474 // the model to avoid a communication problem.
475 if ( ( (strncmp(model,"DESKJET 81",10) == 0)
476 || (strncmp(model,"DESKJET 83",10) == 0)
477 || (strncmp(model,"DESKJET 88",10) == 0)
478 || (strncmp(model,"DESKJET 895",11) == 0)
480 && (pSS->IOMode.bUSB)
483 DBG1("This printer has limited USB status\n");
484 pSS->IOMode.bStatus = FALSE;
485 pSS->IOMode.bDevID = FALSE;
488 if ( ( (strncmp(model,"DESKJET 63",10) == 0)
489 || (strncmp(model,"DESKJET 64",10) == 0)
491 && (pSS->IOMode.bUSB)
494 DBG1("This printer has limited USB status, but we did get DeviceIDString\n");
495 pSS->IOMode.bStatus = FALSE;
498 if (device == UNSUPPORTED) return UNSUPPORTED_PRINTER;
499 else return NO_ERROR;
502 DRIVER_ERROR DeviceRegistry::SelectDevice(const char* sDevID, SystemServices* pSS)
504 char strModel[DevIDBuffSize]; // to contain the MODEL (MDL) from the DevID
505 char strPens[64]; // to contain the VSTATUS penID from the DevID
506 int VIPVersion; // VIP version from the DevID
508 DRIVER_ERROR err = ParseDevIDString(sDevID, strModel, &VIPVersion, strPens);
511 return UNSUPPORTED_PRINTER;
514 return SelectDevice(strModel, &VIPVersion, strPens, pSS);
517 DRIVER_ERROR DeviceRegistry::InstantiatePrinter(Printer*& p, SystemServices* pSS)
518 // Instantiate a printer object and return a pointer p based on the previously
519 // set 'device' variable
521 //ASSERT(p == NULL); // if it's not then we're going to loose memory
523 FAMILY_HANDLE familyHandle = pPFI->FindDevIdMatch(ModelName[device]);
524 if (familyHandle == NULL)
526 ASSERT(familyHandle);
527 DBG1("DR::InstantiatePrinter - no family match\n");
528 return UNSUPPORTED_PRINTER;
530 p = pPFI->CreatePrinter(pSS, familyHandle);
532 return p->constructor_error;
533 } //InstantiatePrinter
537 DRIVER_ERROR DeviceRegistry::GetPrinterModel(char* strModel, int *pVIPVersion, char* strPens, SystemServices* pSS)
540 BYTE DevIDBuffer[DevIDBuffSize];
542 err = pSS->GetDeviceID(DevIDBuffer, DevIDBuffSize, TRUE);
543 ERRCHECK; // should be either NO_ERROR or BAD_DEVICE_ID
545 return ParseDevIDString((const char*)DevIDBuffer, strModel, pVIPVersion, strPens);
549 #define HEXTOINT(x, p) if (x >= '0' && x <= '9') *p |= x - '0'; \
550 else if (x >= 'A' && x <= 'F') *p |= 0xA + x - 'A'; \
551 else if (x >= 'a' && x <= 'f') *p |= 0xA + x - 'a'
555 //! Parse a device id string
557 Enter a full description of the method here. This will be the API doc.
559 ******************************************************************************/
560 DRIVER_ERROR DeviceRegistry::ParseDevIDString(const char* sDevID, char* strModel, int *pVIPVersion, char* strPens)
562 int i; // simple counter
563 char* pStr = NULL; // string pointer used in parsing DevID
565 // get the model name
566 // - note: I'm setting pStr to the return of strstr
567 // so I need to increment past my search string
568 if ( (pStr = (char *)strstr(sDevID+2,"MODEL:")) )
571 if ( (pStr=(char *)strstr(sDevID+2,"MDL:")) )
573 else return BAD_DEVICE_ID;
575 // my own version of strtok to pull out the model string here
577 while ( (pStr[i] != ';') && (pStr[i] != '\0') && (i < DevIDBuffSize))
579 strModel[i] = pStr[i];
585 // see if this printer support VIP or not
586 if ( (pStr=(char *)strstr(sDevID+2,";S:00")) ) // binary encoded device ID status (version 0)
588 pStr += 15; // get to the VIP support field (version of 0 == doesn't support VIP)
589 if ((*pStr >= '0') && (*pStr <= '9'))
591 *pVIPVersion = *pStr - '0';
593 else if ((*pStr >= 'A') && (*pStr <= 'F'))
595 *pVIPVersion = 10 + (*pStr - 'A');
604 * DevID string has changed starting with Jupiter.
605 * Following ";S:", two nibbles for Version Number
606 * 12 nibbles for Status Information, the last nibble
607 * is reserved for future use, the second from last
608 * indicates whether the printer has VIP support.
610 * Actually, four nibbles were added.
611 * The first fourteen nibbles contain feature state info.
612 * So, starting with version 02 of device id, following ":S:" there are
613 * 2 nibbles for version number
614 * 14 nibbles for feature state (the 15th nibble from ';' is the vip flag
615 * 2 nibbles for printer status
617 * Crystal added 4 more nibbles to the option field.
620 else if ((pStr = (char *)strstr (sDevID+2, ";S:")))
623 HEXTOINT (*(pStr+3), pVIPVersion);
624 *pVIPVersion = *pVIPVersion << 4;
625 HEXTOINT (*(pStr+4), pVIPVersion);
626 if (*(pStr + 15) == '1')
641 // now get the pen info
642 if( (pStr=(char *)strstr(sDevID+2,"VSTATUS:")) )
646 while ( (pStr[i] != ',') && (pStr[i] != ';') && (pStr[i] != '\0') )
648 strPens[i] = pStr[i];
653 else if ( (pStr = (char *)strstr(sDevID + 2, ";S:00")) || // binary encoded device ID status (version 0)
654 (pStr = (char *)strstr (sDevID + 2, ";S:"))) // Jupiter and later style
658 HEXTOINT (*(pStr+3), &iVersion);
659 iVersion = iVersion << 4;
660 HEXTOINT (*(pStr+4), &iVersion);
663 pStr += 19; // get to the number of pens field
665 else if (iVersion < 4)
674 // each supported pen has a block of 8 bytes of info so copy the number of pens byte
675 // plus 8 bytes for each supported ped
676 if ((*pStr >= '0') && (*pStr <= '9'))
678 i = 1 + ((*pStr-'0')*8);
680 else if ((*pStr >= 'A') && (*pStr <= 'F'))
682 i = 1 + ((10 + (*pStr-'A')) * 8);
685 { // bogus number of pens field
688 memcpy(strPens, pStr, i);
691 else // no VSTATUS for 400 and sleek printers