1 /*****************************************************************************\
2 Copyright (c) 2002 - 2002, Hewlett-Packard Co.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. Neither the name of Hewlett-Packard nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 \*****************************************************************************/
28 // PrinterFactory.cpp - Morpheus component code base
32 #include "printerfactory.h"
36 PrinterFactory* PrinterFactory::s_Instance = NULL; // enforce the singleton
37 PrinterFactory::ProxyListElement* PrinterFactory::s_ProxyList = NULL;
38 unsigned int PrinterFactory::s_uFamilyCount = 0;
39 unsigned int PrinterFactory::s_uPrinterCount = 0;
41 extern void HP_strcat(char* str1, const char* str2);
44 //! Constructor for PrinterFactory
46 ******************************************************************************/
47 PrinterFactory::PrinterFactory
52 // the static factory is coming on-line, do what you need here.
53 TRACE("PF - static factory construction complete\n");
58 //! Destructor for PrinterFactory
60 ******************************************************************************/
61 PrinterFactory::~PrinterFactory
65 TRACE("PF::~PF - static factory destructing\n");
66 ProxyListElement* t_ListEntry;
69 TRACE(" - deleting %s from factory list\n", s_ProxyList->printerProxyElement->GetFamilyName());
70 t_ListEntry = s_ProxyList;
71 s_ProxyList = t_ListEntry->next;
74 s_Instance = NULL; // factory is gone
75 TRACE("finished PF::~PF\n");
80 //! Register proxy classes for printer families
82 This method is used by the constuctor of the PrinterProxy subclasses to
83 register themselves with the factory. They call Register(this) to pass
84 themselves to the factory.
85 ******************************************************************************/
86 void PrinterFactory::Register
88 const PrinterProxy* thePrinterProxy //!< [in]pointer to the PrinterProxy
91 // use the first registration of a printer proxy to force the instantiation
92 // of the only PrinterFactory
93 if (s_Instance == NULL)
95 TRACE("PF::Register - asking for new factory\n");
96 // create the singleton
97 s_Instance = new PrinterFactory;
100 TRACE("PF::Register\n");
101 // we know we'll need an entry in the list so create it first
102 ProxyListElement* t_ListEntry = new(ProxyListElement);
103 if (t_ListEntry == NULL)
105 // we have a problem - the driver is not running yet
106 // the RTL is registering these static printer proxy servers and
107 // the main code hasn't started yet.
110 // this list works so simply because we don't care about the order
111 // and we always insert the next entry before the current head.
112 t_ListEntry->printerProxyElement = thePrinterProxy;
113 t_ListEntry->next = s_ProxyList;
114 s_ProxyList = t_ListEntry;
116 s_uPrinterCount += thePrinterProxy->GetModelCount();
118 TRACE("PF::Register %s registered with PrinterFactory\n", thePrinterProxy->GetFamilyName());
119 TRACE("Printers supported by class are:\n");
120 MODEL_HANDLE myHandle = thePrinterProxy->StartModelNameEnum();
121 const char* printerName;
122 while ((printerName = thePrinterProxy->GetNextModelName(myHandle)))
124 TRACE(" %s\n", printerName);
130 //! UnRegister proxy classes for printer families
132 PrinterProxy subclasses use this to unregister themselves with their destuctor
134 ******************************************************************************/
135 void PrinterFactory::UnRegister
137 const PrinterProxy* thePrinterProxy //!< [in]pointer to the PrinterProxy to unregister
140 // use the first registration of a printer proxy to force the instantiation
141 // of the only PrinterFactory
142 if (s_Instance == NULL)
144 TRACE("Unregistering a PrinterProxy when factory does not exist\n");
148 TRACE("PF::UnRegister %s\n", thePrinterProxy->GetFamilyName());
149 if (s_ProxyList == NULL)
151 TRACE("PF::UnRegister - Printer Factory printer list is empty!\n");
154 ProxyListElement* prevListEntry = NULL;
155 ProxyListElement* t_ListEntry = s_ProxyList;
158 while ((t_ListEntry) && (!bFound))
160 if (t_ListEntry->printerProxyElement == thePrinterProxy)
162 TRACE("We found the matching proxy by address\n");
164 if (prevListEntry != NULL) //somewhere in list
166 prevListEntry->next = t_ListEntry->next;
168 else // at head of list
170 s_ProxyList = t_ListEntry->next;
174 s_uPrinterCount -= thePrinterProxy->GetModelCount();
176 prevListEntry = t_ListEntry;
177 t_ListEntry = t_ListEntry->next;
179 TRACE("PF::UnRegister removed %s from PrinterFactory\n", thePrinterProxy->GetFamilyName());
180 TRACE("PF::UnRegister - factory now supports %d families and %d printers\n",
184 if (s_ProxyList == NULL)
186 TRACE("PF::UnRegister asking for deletion of empty Factory\n");
187 delete PrinterFactory::GetInstance();
193 //! return the next familiy name that is in the factory
195 Move to the next family in the factory and then return the name of that family.
196 This moved to the next family first!
197 FAMILY_HANDLE is changed to the next family. If there are no more families in
198 the factory then FAMILY_HANDLE will be NULL.
201 name of the next family in the factory<br>
202 NULL if there are no more families in the factory
203 ******************************************************************************/
204 const char* PrinterFactory::GetNextFamilyName
206 FAMILY_HANDLE& theFamilyHandle //!< [in][out]handle to the current family
209 TRACE("PF::GetNextFamilyName()\n");
210 if (nextFamily(theFamilyHandle))
212 return getPrinterProxy(theFamilyHandle)->GetFamilyName();
218 } //GetNextFamilyName
222 //! return the family namne that supports the printer
225 the name of the family that supports the printer name passed in. May be NULL
226 if there is no family in the factory that supports the printer name.
227 ******************************************************************************/
228 const char* PrinterFactory::GetFamilyName
230 const char* thePrinterName //!< [in] name of the printer model
233 const char* szFamilyName = NULL;
234 FAMILY_HANDLE myFamilyHandle = FindDevIdMatch(thePrinterName);
237 szFamilyName = getPrinterProxy(myFamilyHandle)->GetFamilyName();
243 //! return the next model name for the current family that is in the factory
245 MODEL_HANDLE is updated durint this processes
247 Name of the next model that this family supports. Will be NULL at the end of
249 ******************************************************************************/
250 const char* PrinterFactory::GetNextModelName
252 FAMILY_HANDLE theFamilyHandle, //!< [in] handle to the current family
253 MODEL_HANDLE& theModelHandle //!< [in][out] handle to the current model
256 TRACE("PF::GetNextModelName()\n");
257 const char* szModelName = NULL;
258 if (theFamilyHandle == NULL)
260 theModelHandle = NULL;
264 szModelName = getPrinterProxy(theFamilyHandle)->GetNextModelName(theModelHandle);
271 //! return the next printer name in the factory
273 This returns the next printer (model) name supported in the factory. This
274 iterates over the whole factory without regard to families. PRINTER_HANDLE is
275 updated during this process.
278 Name of the printer in the factory. Will be NULL after all the printers in the
279 factory have been enumerated.
280 ******************************************************************************/
281 const char* PrinterFactory::GetNextPrinterName
283 PRINTER_HANDLE& thePrinterHandle //!< [in][out] handle to the printer
286 TRACE("PF::GetNextPrinterName()\n");
287 static FAMILY_HANDLE familyHandle;
288 nextPrinter(familyHandle, thePrinterHandle);
289 return reinterpret_cast<const char*>(thePrinterHandle);
290 } //GetNextPrinterName
294 //! moves the family handle to the next family in the factory
296 updates the FAMILY_HANDLE to the next family in the factory. After the last
297 family in the factory the FAMILY_HANDLE will be NULL.
300 true - there was another family in the factory (ie FAMILY_HANDLE is not NULL)<br>
301 false - there were no more families in the factory (ie FAMILY_HANDLE is NULL)
302 ******************************************************************************/
303 bool PrinterFactory::nextFamily
305 FAMILY_HANDLE& theFamilyHandle //!< [in][out] handle to the family
308 TRACE("PF::nextFamily()\n");
310 const ProxyListElement* proxyList = getProxyListElement(theFamilyHandle);
311 if (proxyList == NULL)
313 TRACE("PF::nextFamily - reset to head of list\n");
314 theFamilyHandle = s_ProxyList;
318 TRACE("PF::nextFamily - next element\n");
319 theFamilyHandle = proxyList->next;
321 if (theFamilyHandle == NULL)
323 TRACE("PF::nextFamily - NULL (end of list)\n");
331 //! moves the family handle to the next family in the factory
333 updates the FAMILY_HANDLE to the next family in the factory. After the last
334 family in the factory the FAMILY_HANDLE will be NULL.
337 true - there was another family in the factory (ie FAMILY_HANDLE is not NULL)<br>
338 false - there were no more families in the factory (ie FAMILY_HANDLE is NULL)
339 ******************************************************************************/
340 const PRINTER_TYPE PrinterFactory::EnumDevices
342 FAMILY_HANDLE& theFamilyHandle
345 TRACE("PF::EnumDevices()\n");
346 if (nextFamily(theFamilyHandle))
348 return getPrinterProxy(theFamilyHandle)->GetPrinterType();
357 //! determines of there is another printer in the factory
358 /*! moves the modle handle to the next model in the family. If there are no more
359 models in the family then it moves the family handle to the next family and the
360 model handle to the start of that families model list.
361 both the family and model handels can be updated during this process. Both will
362 be NULL if there are no more printers in this iteration of the factory.
365 true - there was another printer in the factory and the family/model handle references it<br>
366 false - there were no more printers in the factory and both handles are NULL
367 ******************************************************************************/
368 bool PrinterFactory::nextPrinter
370 FAMILY_HANDLE& theFamilyHandle, //!< [in][out] current family handle
371 MODEL_HANDLE& theModelHandle //!< [in][out] current model handle
374 TRACE("PF::nextPrinter(,)\n");
376 if (theFamilyHandle == NULL) //this is the first time through
378 theFamilyHandle = StartFamilyNameEnum();
379 if (nextFamily(theFamilyHandle))
381 theModelHandle = StartModelNameEnum(theFamilyHandle);
385 bMore = false; // no families in the list
389 if (GetNextModelName(theFamilyHandle, theModelHandle) == NULL) //end of model list
391 if(nextFamily(theFamilyHandle))
393 theModelHandle = StartModelNameEnum(theFamilyHandle);
394 if (GetNextModelName(theFamilyHandle, theModelHandle) == NULL)
413 //! Find a match for a Device ID string in the factory
415 The device ID string can be a device ID string retrived from a printer or it
416 can be a simple model name or family name. This will walk through each family
417 in the factory and will check to see if it is a simple family or model string
418 and if not then will check for a valid device ID string.
421 A family handle based on the device ID string passed in.<br>
422 NULL if there is no match.
423 ******************************************************************************/
424 const FAMILY_HANDLE PrinterFactory::FindDevIdMatch
426 const char* szDevIdString //!< [in] well formed device id string
429 TRACE("PF::FindDevIdMatch(%s)\n", szDevIdString);
430 FAMILY_HANDLE myFamilyHandle = StartFamilyNameEnum();
432 bool bDevIDString = TRUE;
433 if ((!strstr(szDevIdString, "MFG:") &&
434 !strstr(szDevIdString+2, "MFG:") &&
435 !strstr(szDevIdString, "MANUFACTURER:") &&
436 !strstr(szDevIdString+2, "MANUFACTURER:")) ||
437 (!strstr(szDevIdString, "MDL:") &&
438 !strstr(szDevIdString+2, "MDL:") &&
439 !strstr(szDevIdString, "MODEL:") &&
440 !strstr(szDevIdString+2, "MODEL:")) ||
441 ((szDevIdString[0] == '\0') && (szDevIdString[1] == '\0')))
443 bDevIDString = FALSE;
446 while (nextFamily(myFamilyHandle))
450 // check to see if a full device ID String match
451 if (getPrinterProxy(myFamilyHandle)->DeviceMatchQuery(szDevIdString))
458 // check the family and see if they passed a simple model string
459 if (getPrinterProxy(myFamilyHandle)->ModelMatchQuery(szDevIdString))
465 // if we never had a match (i.e. did the break) then myFamilyHandle is NULL
466 return myFamilyHandle;
470 //! Get the bitwise return based on the registered family
474 A bitwise int based on the family registered.<br
475 0 if there is no printer registered.
476 ******************************************************************************/
477 const unsigned int PrinterFactory::GetModelBits
482 TRACE("PF::GetModelBits\n");
483 FAMILY_HANDLE myFamilyHandle = StartFamilyNameEnum();
485 while (nextFamily(myFamilyHandle))
489 bits = bits | getPrinterProxy(myFamilyHandle)->GetModelBit();
496 //! Get the bitwise return based on the registered family
500 concatnated string based on the family registered.<br
501 null string if there is no printer registered.
502 ******************************************************************************/
503 const void PrinterFactory::GetModelString
512 TRACE("PF::GetModelString\n");
513 FAMILY_HANDLE myFamilyHandle = StartFamilyNameEnum();
516 while (nextFamily(myFamilyHandle))
518 p = getPrinterProxy(myFamilyHandle)->GetFamilyName();
\r
519 i += strlen(p) + 1;
\r
520 if (i > mresult_length) break;
521 HP_strcat(mresult, p);
522 HP_strcat(mresult, " ");
\r