Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1253 lines
42 KiB

  1. //-----------------------------------------------------------------------------
  2. // This files contains the module name for this mini driver. Each mini driver
  3. // must have a unique module name. The module name is used to obtain the
  4. // module handle of this Mini Driver. The module handle is used by the
  5. // generic library to load in tables from the Mini Driver.
  6. // It also contains Install() for upgrading 3.0 driver to 3.1.
  7. //
  8. //-----------------------------------------------------------------------------
  9. #include "strings.h"
  10. char *rgchModuleName = "PCL5MSC";
  11. char szNone[]="";
  12. // The following are defined to ensure that we upgrade correctly from the
  13. // HPPCL5a, HPPCL5e and Win 3.11 HPPCL5MS drivers
  14. #define MAX_LJ4_MBMEMSETTING 68 // from HP tech specification
  15. #define KB_THRESHOLD 200 // kb range check,needed for conversion
  16. #define PRINTDRIVER
  17. #include <print.h>
  18. #include "gdidefs.inc"
  19. #include "mdevice.h"
  20. #include "unidrv.h"
  21. #include "minidriv.h"
  22. #ifndef _INC_WINDOWSX
  23. #include <windowsx.h>
  24. #endif
  25. #ifndef WINNT
  26. short NEAR PASCAL MakeAppName(LPSTR,LPCSTR,short);
  27. // typedef for atom stuff--what a nuisance!
  28. typedef struct tagSFNODE
  29. {
  30. WORD wIndex;
  31. ATOM atom;
  32. } SFNODE, FAR *LPSFNODE;
  33. // Typedef for Font Installer procedure
  34. typedef int (FAR * PASCAL SOFTFONTPROC)(HWND,LPSTR,LPSTR,BOOL,int,int);
  35. HINSTANCE hInst;
  36. #define DEFAULT_INT 32767
  37. #define SOFT_FONT_THRES 25 // build font summary, if over this limit
  38. #define MAX_CART_INDEX 12
  39. #define TMPSIZE 256
  40. // Define these so they happily use the same values as the HPPCL5E driver.
  41. #define GS_PHOTO 0
  42. #define GS_LINEART 1
  43. #define GS_SCANJET 2
  44. // map old HPPCL5a's cartindex to unidrv's FONTCART index for newer cartridges.
  45. // This mapping table is created based on the old HPPCL5a .rc file.
  46. // Note that we do not have "International Collection" cartridge and we
  47. // map it to index 0 (arbitrarily).
  48. int rgNewCartMap[12] = {0, 8, 7, 2, 3, 0, 5, 6, 1, 4, 9, 10};
  49. // String to determine if we have a member of the LaserJet 4 family
  50. char szLJ4[]="HP LaserJet 4";
  51. // Stuff needed for mapping old facenames to new versions
  52. #ifndef NOFONTMAP
  53. typedef struct tagFACEMAP
  54. {
  55. char szOldFace[LF_FACESIZE];
  56. char szNewFace[LF_FACESIZE];
  57. } FACEMAP, NEAR * NPFACEMAP;
  58. typedef struct tagFACEINDEX
  59. {
  60. BYTE cFirstChar;
  61. BYTE bIndex;
  62. } FACEINDEX, NEAR * NPFACEINDEX;
  63. FACEMAP FaceMap[]={{"Albertus (W\x01)", "Albertus Medium"},
  64. {"Albertus Xb (W\x01)", "Albertus Extra Bold"},
  65. {"Antique Olv (W\x01)", "Antique Olive"},
  66. {"Antique Olv Cmpct (W\x01)","Antique Olive Compact"},
  67. {"CG Bodoni (W\x01)", "CG Bodoni"},
  68. {"CG Cent Schl (W\x01)", "CG Century Schoolbook"},
  69. {"CG Omega (W\x01)", "CG Omega"},
  70. {"CG Palacio (W\x01)", "CG Palacio"},
  71. {"CG Times (W\x01)", "CG Times"},
  72. {"Clarendon Cd (W\x01)", "Clarendon Condensed"},
  73. {"Cooper Blk (W\x01)", "Cooper Black"},
  74. {"Coronet (W\x01)", "Coronet"},
  75. {"Courier (W\x01)", "Courier"},
  76. {"Garmond (W\x01)", "Garamond"},
  77. {"ITC Benguat (W\x01)", "ITC Benguiat"},
  78. {"ITC Bookman Db (W\x01)", "ITC Bookman Demi"},
  79. {"ITC Bookman Lt (W\x01)", "ITC Bookman Light"},
  80. {"ITC Souvenir Db (W\x01)", "ITC Souvenir Demi"},
  81. {"ITC Souvenir Lt (W\x01)", "ITC Souvenir Light"},
  82. {"Letter Gothic (W\x01)", "Letter Gothic"},
  83. {"Marigold (W\x01)", "Marigold"},
  84. {"Revue Lt (W\x01)", "Revue Light"},
  85. {"Shannon (W\x01)", "Shannon"},
  86. {"Shannon Xb (W\x01)", "Shannon Extra Bold"},
  87. {"Stymie (W\x01)", "Stymie"},
  88. {"Univers (W\x01)", "Univers"},
  89. {"Univers Cd (W\x01)", "Univers Condensed"}};
  90. FACEINDEX FaceIndex[]={{'A',0},
  91. {'C',4},
  92. {'G',13},
  93. {'I',14},
  94. {'L',19},
  95. {'M',20},
  96. {'R',21},
  97. {'S',22},
  98. {'U',25},
  99. {(BYTE)'\xFF',27}}; // Provide an upper limit
  100. // to the search for 'U'.
  101. #endif
  102. //------------------------------------------------------------------------
  103. // Function: LibMain(hInstance,wDataSeg,cbHeapSize,lpszCmdLine)
  104. //
  105. // Action: Save the hInstance for this DLL
  106. //
  107. // Return: 1
  108. //------------------------------------------------------------------------
  109. int WINAPI LibMain (HANDLE hInstance,
  110. WORD wDataSeg,
  111. WORD cbHeapSize,
  112. LPSTR lpszCmdLine)
  113. {
  114. hInst=hInstance;
  115. return 1;
  116. }
  117. //--------------------------*MakeAppName*---------------------------------------
  118. // Action: compose the <printer,port> name for reading the profile data
  119. // Return the length of the actual application name. Return -1 if fails.
  120. //
  121. //------------------------------------------------------------------------------
  122. short NEAR PASCAL MakeAppName(LPSTR lpAppName,
  123. LPCSTR lpPortName,
  124. short max)
  125. {
  126. short length, count;
  127. LPCSTR lpTmp;
  128. LPCSTR lpLastColon = NULL;
  129. length = lstrlen(lpAppName);
  130. if (!lpPortName)
  131. return length;
  132. if (length == 0 || length > max - lstrlen(lpPortName))
  133. return -1;
  134. // insert the comma
  135. lpAppName[length++] = ',';
  136. // append the port name but do not want the last ':', if any.
  137. for (lpTmp = lpPortName ; *lpTmp; lpTmp++)
  138. if (*lpTmp == ':')
  139. lpLastColon = lpTmp;
  140. if (lpLastColon && lpLastColon == lpTmp - 1)
  141. count = lpLastColon - lpPortName;
  142. else
  143. count = lpTmp - lpPortName;
  144. lstrcpy((LPSTR)&lpAppName[length], lpPortName);
  145. length += count;
  146. lpAppName[length]='\0';
  147. return length;
  148. }
  149. #define KEY_BUF_SIZE 256
  150. //---------------------------------------------------------------------------
  151. // Function: GetInt(lpSection,lpKey,lpnValue,nDefault,bRemove)
  152. //
  153. // Action: Load the appropriate string from the resources, then get the
  154. // specified integer from the section. Remove the old entry if
  155. // it exists and it bRemove is TRUE.
  156. //
  157. // Return: TRUE if we actually found a value, FALSE if not.
  158. //---------------------------------------------------------------------------
  159. BOOL NEAR PASCAL GetInt(LPSTR lpSection,
  160. LPCSTR lpKey,
  161. LPINT lpnValue,
  162. int nDefault,
  163. BOOL bRemove)
  164. {
  165. char szKeyName[60];
  166. int nTest;
  167. if(!HIWORD(lpKey))
  168. {
  169. if(LoadString(hInst,LOWORD(lpKey),szKeyName,sizeof(szKeyName)))
  170. lpKey=szKeyName;
  171. else
  172. return FALSE;
  173. }
  174. nTest=GetProfileInt(lpSection,szKeyName,DEFAULT_INT);
  175. if(DEFAULT_INT != nTest)
  176. {
  177. *lpnValue=nTest;
  178. if(bRemove)
  179. WriteProfileString(lpSection,szKeyName,NULL);
  180. return TRUE;
  181. }
  182. // Section doesn't exist--use default
  183. *lpnValue=nDefault;
  184. return FALSE;
  185. }
  186. //-------------------------------------------------------------------------
  187. // Function: WriteInt(lpSection,lpKey,nValue)
  188. //
  189. // Action: Write an integer value to the specified section of win.ini.
  190. //
  191. // Return: TRUE if successful, FALSE if not.
  192. //-------------------------------------------------------------------------
  193. BOOL NEAR PASCAL WriteInt(LPSTR lpSection,
  194. LPCSTR lpKey,
  195. int nValue)
  196. {
  197. char szKeyName[60];
  198. char szValue[10];
  199. if(!HIWORD(lpKey))
  200. {
  201. if(LoadString(hInst,LOWORD(lpKey),szKeyName,sizeof(szKeyName)))
  202. lpKey=szKeyName;
  203. else
  204. return FALSE;
  205. }
  206. wsprintf(szValue,"%u",nValue);
  207. return WriteProfileString(lpSection,szKeyName,szValue);
  208. }
  209. //---------------------------*MergeFontLists*-----------------------------
  210. // Action: Merge the old and new soft fonts. In most cases when we get
  211. // called, we really don't do much of anything, because the
  212. // font lists are identical. However, we have to do some fun
  213. // stuff to merge the lists if they're different.
  214. // We know how many soft font entries exist in each section,
  215. // via the "SoftFonts" int, but the entries may be non-consecutive.
  216. //
  217. // Note: This stomps all over the passed in buffer
  218. //
  219. // Return: TRUE if successfully conpleted, FALSE if not
  220. //------------------------------------------------------------------------
  221. BOOL NEAR PASCAL MergeFontLists(LPSTR lpOldSec,
  222. LPSTR lpNewSec,
  223. LPSTR lpTmp)
  224. {
  225. WORD wOldFonts;
  226. WORD wNewFonts;
  227. LPSFNODE lpFonts;
  228. WORD wMergedFonts=0;
  229. WORD wLoop;
  230. WORD wFound;
  231. WORD wNewIndex;
  232. BYTE szKey[20];
  233. // Get these values outside of the if statement, otherwise the compiler
  234. // may optimize out the assignment of wNewFonts
  235. GetInt(lpOldSec,MAKEINTRESOURCE(IDS_SOFTFONTS),&wOldFonts,0,FALSE);
  236. GetInt(lpNewSec,MAKEINTRESOURCE(IDS_SOFTFONTS),&wNewFonts,0,FALSE);
  237. if(wOldFonts || wNewFonts)
  238. {
  239. char szFormat[30];
  240. // Get a block big enough for the worst case--no common fonts
  241. if(!(lpFonts=(LPSFNODE)GlobalAllocPtr(GHND,
  242. (DWORD)(wOldFonts+wNewFonts)*sizeof(SFNODE))))
  243. {
  244. return FALSE;
  245. }
  246. // We need a formatting string
  247. LoadString(hInst,IDS_SOFTFONTFORMAT,szFormat,sizeof(szFormat));
  248. // Put fonts from lpNew Sec first in the list. This way, if we have
  249. // already updated at least one driver from 5A to 5MS and the soft
  250. // fonts haven't changed, our old font summary file is still valid.
  251. // Unidrv will automatically recreate the font summary file if it
  252. // sees that the number of soft fonts has changed. Even though we
  253. // know how many soft font entries exist, we don't know that they
  254. // will be sequential. (They may not be if one was added, then
  255. // deleted). Keep track of the original offset. Even though the
  256. // font installer seems to be 1-based, start looking at 0, just
  257. // to be safe.
  258. for(wLoop=0,wFound=0;wFound<wNewFonts;wLoop++)
  259. {
  260. wsprintf(lpTmp,szFormat,wLoop);
  261. if(GetProfileString(lpNewSec,lpTmp,szNone,lpTmp,TMPSIZE))
  262. {
  263. lpFonts[wMergedFonts].wIndex=wLoop;
  264. lpFonts[wMergedFonts++].atom=GlobalAddAtom(lpTmp);
  265. wFound++;
  266. }
  267. }
  268. // Remember where we left off in numbering the entries
  269. wNewIndex=wLoop;
  270. // Read fonts from lpOldSec--create atoms for new entries
  271. for(wLoop=0,wFound=0;wFound<wOldFonts;wLoop++)
  272. {
  273. wsprintf(lpTmp,szFormat,wLoop);
  274. if(GetProfileString(lpOldSec,lpTmp,szNone,lpTmp,TMPSIZE))
  275. {
  276. wFound++;
  277. if(!GlobalFindAtom(lpTmp))
  278. {
  279. lpFonts[wMergedFonts].wIndex=wLoop;
  280. lpFonts[wMergedFonts++].atom=GlobalAddAtom(lpTmp);
  281. }
  282. }
  283. }
  284. // Write out the list of atoms--do the entries from lpNewSec first
  285. WriteInt(lpNewSec,MAKEINTRESOURCE(IDS_SOFTFONTS),wMergedFonts);
  286. for(wLoop=0;wLoop<wNewFonts;wLoop++)
  287. {
  288. GlobalGetAtomName(lpFonts[wLoop].atom,lpTmp,TMPSIZE);
  289. wsprintf(szKey,szFormat,lpFonts[wLoop].wIndex);
  290. WriteProfileString(lpNewSec,szKey,lpTmp);
  291. GlobalDeleteAtom(lpFonts[wLoop].atom);
  292. }
  293. // Now write out the entries that were in lpOldSec but not in lpNewSec.
  294. // Since the actual numbering of these entries is arbitrary, just
  295. // start numbering them at wNewIndex and increment each time.
  296. for(wLoop=wNewFonts;wLoop<wMergedFonts;wLoop++)
  297. {
  298. GlobalGetAtomName(lpFonts[wLoop].atom,lpTmp,TMPSIZE);
  299. wsprintf(szKey,szFormat,wNewIndex);
  300. WriteProfileString(lpNewSec,szKey,lpTmp);
  301. GlobalDeleteAtom(lpFonts[wLoop].atom);
  302. wNewIndex++;
  303. }
  304. GlobalFreePtr(lpFonts);
  305. }
  306. return TRUE;
  307. }
  308. //----------------------*AddMissingEntries*-----------------------------
  309. // Action: Copy any entries that appear in lpOldSec but not lpNewSec to
  310. // lpNewSec, but don't copy any entries relevant to soft fonts
  311. // (These entries will be copied in MergeFontSections).
  312. //
  313. // Return: TRUE if successful, FALSE if not
  314. //----------------------------------------------------------------------
  315. BOOL NEAR PASCAL AddMissingEntries(LPSTR lpOldSec,
  316. LPSTR lpNewSec,
  317. LPSTR lpTmp)
  318. {
  319. WORD wSize;
  320. LPSTR lpBuf;
  321. LPSTR lpWork;
  322. char szTest2[30];
  323. char szTest1[30];
  324. int nLength;
  325. // Get the key names into buffers
  326. wSize=KEY_BUF_SIZE;
  327. if(!(lpBuf=GlobalAllocPtr(GHND,(DWORD)wSize)))
  328. return FALSE;
  329. while((WORD)GetProfileString(lpOldSec,NULL,szNone,lpBuf,wSize)==wSize-2)
  330. {
  331. wSize*=2;
  332. if(lpWork=GlobalReAllocPtr(lpBuf,(DWORD)wSize,GHND))
  333. lpBuf=lpWork;
  334. else
  335. {
  336. GlobalFreePtr(lpBuf);
  337. return FALSE;
  338. }
  339. }
  340. // Load some strings
  341. LoadString(hInst,IDS_FONTSUMMARY,szTest1,sizeof(szTest1));
  342. nLength=LoadString(hInst,IDS_SOFTFONTTEST,szTest2,sizeof(szTest2));
  343. // Now examine each entry, copy it if we want to keep it, and return TRUE
  344. // There are two cases where we don't want to copy the file--the key
  345. // named FontSummary and all keys that begin with "SoftFont"
  346. lpWork=lpBuf;
  347. while(wSize=(WORD)lstrlen(lpWork))
  348. {
  349. // Font Summary?
  350. if(lstrcmpi(lpWork,szTest1))
  351. {
  352. // Soft Font Entry?
  353. lstrcpy(lpTmp,lpWork);
  354. lpTmp[nLength]='\0';
  355. if(lstrcmpi(lpTmp,szTest2))
  356. {
  357. // Add this entry if it doesn't already exist in the new section
  358. if(!GetProfileString(lpNewSec,lpWork,szNone,lpTmp,TMPSIZE))
  359. {
  360. GetProfileString(lpOldSec,lpWork,szNone,lpTmp,TMPSIZE);
  361. WriteProfileString(lpNewSec,lpWork,lpTmp);
  362. }
  363. }
  364. }
  365. lpWork+=(wSize+1);
  366. }
  367. GlobalFreePtr(lpBuf);
  368. return TRUE;
  369. }
  370. //---------------------------*HandleSoftFonts*---------------------------
  371. // Action: Transfer the soft fonts between old and new entries. First we
  372. // copy any entries that don't already exist in the new section,
  373. // with the exception of soft font information. Then we go ahead
  374. // and merge the soft fonts, so the end result in the new section
  375. // is the union of the old and new soft fonts.
  376. //
  377. // Return: TRUE if success, FALSE if not
  378. //-----------------------------------------------------------------------
  379. BOOL NEAR PASCAL HandleSoftFonts(LPSTR lpszOldSec,
  380. LPSTR lpszNewSec)
  381. {
  382. char szTmp[TMPSIZE];
  383. if(AddMissingEntries(lpszOldSec,lpszNewSec,szTmp))
  384. return MergeFontLists(lpszOldSec,lpszNewSec,szTmp);
  385. return FALSE;
  386. }
  387. //------------------------------------------------------------------------
  388. // Function: ConvertStraight(lpSection,nOldID,nNewID)
  389. //
  390. // Action: Convert a section setting without translation
  391. //
  392. // Return: TRUE if the old setting existed
  393. //------------------------------------------------------------------------
  394. BOOL NEAR PASCAL ConvertStraight(LPSTR lpSection,
  395. int nOldID,
  396. int nNewID)
  397. {
  398. int nValue;
  399. if(GetInt(lpSection,MAKEINTRESOURCE(nOldID),&nValue,0,TRUE))
  400. {
  401. WriteInt(lpSection,MAKEINTRESOURCE(nNewID),nValue);
  402. return TRUE;
  403. }
  404. return FALSE;
  405. }
  406. //------------------------------------------------------------------------
  407. // Function: ConvertBool(lpSection,nOldID,nNewID,nNewValue)
  408. //
  409. // Action: Convert a section with minimal translation. If the old section
  410. // existed and was non-zero, write nNewValue to the new section.
  411. // If the old section existed and was 0, write 0 to the new section.
  412. //
  413. // Return: TRUE if the old setting existed
  414. //------------------------------------------------------------------------
  415. BOOL NEAR PASCAL ConvertBool(LPSTR lpSection,
  416. int nOldID,
  417. int nNewID,
  418. int nNewValue)
  419. {
  420. int nOldValue;
  421. if(GetInt(lpSection,MAKEINTRESOURCE(nOldID),&nOldValue,0,TRUE))
  422. {
  423. WriteInt(lpSection,MAKEINTRESOURCE(nNewID),nOldValue?nNewValue:0);
  424. return TRUE;
  425. }
  426. return FALSE;
  427. }
  428. //------------------------------------------------------------------------
  429. // Function: ConvertVectorMode(lpSection)
  430. //
  431. // Action: Convert the graphics mode setting
  432. // Cannot do straight conversion as defaults dont match
  433. //
  434. // Return: TRUE if the old section existed
  435. //------------------------------------------------------------------------
  436. BOOL NEAR PASCAL ConvertVectorMode(LPSTR lpSection)
  437. {
  438. int nValue;
  439. GetInt(lpSection,MAKEINTRESOURCE(IDS_OLDVECTORMODE),&nValue,1,TRUE);
  440. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWVECTORMODE),nValue);
  441. return TRUE;
  442. }
  443. //------------------------------------------------------------------------
  444. // Function: ConvertResolution(lpSection,lpModel)
  445. //
  446. // Action: Convert the old resolution section to the new one
  447. //
  448. // Return: TRUE if the old section existed
  449. //------------------------------------------------------------------------
  450. BOOL NEAR PASCAL ConvertResolution(LPSTR lpSection,
  451. LPSTR lpModel)
  452. {
  453. int nValue;
  454. if(GetInt(lpSection,MAKEINTRESOURCE(IDS_OLD_5A_RESOLUTION),&nValue,0,TRUE))
  455. {
  456. LPSTR lpLJ4=szLJ4;
  457. LPSTR lpCheck=lpModel;
  458. BOOL bLJ4=TRUE;
  459. nValue=300/(1<<nValue);
  460. // Compare the passed-in model to szLJ4. If lpModel begins with the
  461. // substring "HP LaserJet 4", then lpLJ4 will point to NULL when we
  462. // exit the loop.
  463. while(*lpLJ4 == *lpCheck)
  464. {
  465. lpLJ4++;
  466. lpCheck++;
  467. }
  468. if(!*lpLJ4)
  469. {
  470. // This is in the LJ4 family--check if it's a 4L or 4ML
  471. if(lstrcmp(lpCheck,"L") && lstrcmp(lpCheck,"ML"))
  472. {
  473. int nTest;
  474. // Device is capable of 600 dpi--check the value for
  475. // "printerres".
  476. GetInt(lpSection,MAKEINTRESOURCE(IDS_OLD_5E_RESOLUTION),
  477. &nTest,600,TRUE);
  478. if(600==nTest)
  479. nValue<<=1;
  480. }
  481. }
  482. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWRESOLUTION),nValue);
  483. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWYRESOLUTION),nValue);
  484. return TRUE;
  485. }
  486. return FALSE;
  487. }
  488. //-------------------------------------------------------------------------
  489. // Function: WriteHalfTone(lpSection,nIndex)
  490. //
  491. // Action: Write the halftoning data to win.ini
  492. //
  493. // Return: VOID
  494. //-------------------------------------------------------------------------
  495. VOID NEAR PASCAL WriteHalfTone(LPSTR lpSection,
  496. int nIndex)
  497. {
  498. int nBrush;
  499. int nIntensity;
  500. switch(nIndex)
  501. {
  502. case GS_LINEART:
  503. nBrush=RES_DB_LINEART;
  504. nIntensity=100;
  505. break;
  506. case GS_SCANJET:
  507. nBrush=RES_DB_COARSE;
  508. nIntensity=150;
  509. break;
  510. case GS_PHOTO:
  511. default:
  512. nBrush=RES_DB_COARSE;
  513. nIntensity=100;
  514. break;
  515. }
  516. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWBRUSH),nBrush);
  517. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWINTENSITY),nIntensity);
  518. }
  519. //-------------------------------------------------------------------------
  520. // Function: Convert5aHalfTone(lpSection)
  521. //
  522. // Action: Convert the 5A halftoning settings
  523. //
  524. // Return: TRUE if the old section existed, FALSE if not
  525. //-------------------------------------------------------------------------
  526. BOOL NEAR PASCAL Convert5aHalfTone(LPSTR lpSection)
  527. {
  528. int nIndex;
  529. int nGray;
  530. int nBright;
  531. BOOL bGrayScale;
  532. BOOL bBrightness;
  533. // See if either setting exists...
  534. bGrayScale=GetInt(lpSection,MAKEINTRESOURCE(IDS_OLDGRAYSCALE),&nGray,
  535. 1,TRUE);
  536. bBrightness=GetInt(lpSection,MAKEINTRESOURCE(IDS_OLDBRIGHTNESS),&nBright,
  537. 0,TRUE);
  538. if(bGrayScale || bBrightness)
  539. {
  540. if(1==nBright)
  541. nIndex=GS_SCANJET;
  542. else if(0==nGray)
  543. nIndex=GS_LINEART;
  544. else
  545. nIndex=GS_PHOTO;
  546. WriteHalfTone(lpSection,nIndex);
  547. return TRUE;
  548. }
  549. return FALSE;
  550. }
  551. //-----------------------------------------------------------------------
  552. // Function: Convert5eHalfTone(LPSTR lpSection)
  553. //
  554. // Action: Convert the 5E halftoning settings
  555. //
  556. // Return: TRUE if successful, FALSE if not
  557. //-----------------------------------------------------------------------
  558. BOOL NEAR PASCAL Convert5eHalfTone(LPSTR lpSection)
  559. {
  560. int nValue;
  561. if(GetInt(lpSection,MAKEINTRESOURCE(IDS_OLD_5E_HALFTONE),&nValue,
  562. 0,TRUE))
  563. {
  564. WriteHalfTone(lpSection,nValue);
  565. return TRUE;
  566. }
  567. return FALSE;
  568. }
  569. //-----------------------------------------------------------------------
  570. // Function: Convert5aMemory(lpSection)
  571. //
  572. // Action: Convert the memory settings from the old to the new values
  573. //
  574. // Return: TRUE if the old section existed, FALSE if not
  575. //-----------------------------------------------------------------------
  576. BOOL NEAR PASCAL Convert5aMemory(LPSTR lpSection)
  577. {
  578. int nValue;
  579. int nPrinterMB;
  580. // Get memory settings--extract from prtindex.
  581. // Values range from 0 to 28, where 0-4 are the LaserJet III,
  582. // 5-9 are the LaserJet IIID, 10-14 are the LaserJet IIIP, and
  583. // 15-28 are the LaserJet IIISi. For indices less than 20, the
  584. // total MB is the index mod 5, + 1. For indices 20 and above, the
  585. // total MB is the index - 14, except for 26, 27, and 28, which
  586. // require special handling because of the increments that memory
  587. // can be added to the IIISi.
  588. // The formula used to calculate the settings is derived directly
  589. // from the values used in the hppcl5a driver. Specifically,
  590. // AM = 945 * TM - 245, where TM is the total memory in MB, and
  591. // AM is the available printer memory.
  592. if(GetInt(lpSection,MAKEINTRESOURCE(IDS_OLDMEMORY),&nValue,1,TRUE))
  593. {
  594. if(nValue<20)
  595. nPrinterMB=nValue%5 + 1;
  596. else
  597. {
  598. nPrinterMB=nValue-14;
  599. if(nValue>25)
  600. {
  601. nPrinterMB++; // 25=11MB, 26=13MB, so add an extra MB.
  602. if(nValue==28)
  603. nPrinterMB+=2; // 27=14MB, 28=17MB, so add 2 extra MB.
  604. }
  605. }
  606. nValue=945*nPrinterMB-245;
  607. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWMEMORY),nValue);
  608. return TRUE;
  609. }
  610. return FALSE;
  611. }
  612. //-----------------------------------------------------------------------
  613. // Function: Convert5eMemory(lpSection)
  614. //
  615. // Action: Convert the HPPCL5E memory settings from the old to the new values
  616. //
  617. // Conversion code has to check the win.ini mem setting so that we upgrade
  618. // mem setting correctly
  619. //
  620. // Return: TRUE if the old section existed, FALSE if not
  621. //-----------------------------------------------------------------------
  622. BOOL NEAR PASCAL Convert5eMemory(LPSTR lpSection)
  623. {
  624. unsigned nValue;
  625. if(GetInt(lpSection,MAKEINTRESOURCE(IDS_NEWMEMORY),&nValue,1,FALSE))
  626. {
  627. if (nValue <= KB_THRESHOLD )
  628. {
  629. if (nValue > MAX_LJ4_MBMEMSETTING)
  630. nValue = MAX_LJ4_MBMEMSETTING; // force it to max value
  631. nValue=900*nValue - 450; // convert to KB, using HP formula
  632. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWMEMORY),nValue);
  633. return TRUE;
  634. }
  635. }
  636. return FALSE;
  637. }
  638. //-----------------------------------------------------------------------
  639. // Function: Convert5MSMemory(lpSection)
  640. //
  641. // Action: Convert the WFW HPPCL5MS memory settings from the old to the new
  642. // values
  643. //
  644. // Conversion code has to check the win.ini mem setting so that we upgrade
  645. // mem setting correctly
  646. //
  647. // Added for backward compatability
  648. //
  649. // Return: TRUE if the old section existed, FALSE if not
  650. //-----------------------------------------------------------------------
  651. BOOL NEAR PASCAL Convert5MSMemory(LPSTR lpSection)
  652. {
  653. unsigned nValue;
  654. if(GetInt(lpSection,MAKEINTRESOURCE(IDS_NEWMEMORY),&nValue,1,TRUE))
  655. {
  656. nValue = nValue / 900; // convert to MB value
  657. nValue = 945*nValue - 245; // formula used in hppcl5a driver
  658. // used to convert to available mem
  659. WriteInt(lpSection,MAKEINTRESOURCE(IDS_NEWMEMORY),nValue);
  660. return TRUE;
  661. }
  662. return FALSE;
  663. }
  664. //------------------------------------------------------------------------
  665. // Function: HandleFontCartridges(lpSection,lpOldDrvSec,lpNewDrvSec)
  666. //
  667. // Action: Handle font cartridge data
  668. //
  669. // Return: VOID
  670. //------------------------------------------------------------------------
  671. VOID NEAR PASCAL HandleFontCartridges(LPSTR lpSection,
  672. LPSTR lpOldDrvSec,
  673. LPSTR lpNewDrvSec)
  674. {
  675. int nCount;
  676. // Get the count of cartridges--if there are no cartridges, do nothing.
  677. if(GetInt(lpSection,MAKEINTRESOURCE(IDS_CARTRIDGECOUNT),&nCount,0,TRUE))
  678. {
  679. char szOldCartKey[16];
  680. char szNewCartKey[16];
  681. short nCart = 0;
  682. short i;
  683. short index;
  684. int nLength1;
  685. int nLength2;
  686. nLength1=LoadString(hInst,IDS_CARTINDEX,szOldCartKey,
  687. sizeof(szOldCartKey));
  688. nLength2=LoadString(hInst,IDS_CARTRIDGE,szNewCartKey,
  689. sizeof(szNewCartKey));
  690. for (i = 0; i < nCount; i++)
  691. {
  692. if (i > 0)
  693. wsprintf(szOldCartKey+nLength1,"%d",i);
  694. // compose cartridge keyname for current driver
  695. wsprintf(szNewCartKey+nLength2,"%d",i+1);
  696. if ((index = GetProfileInt(lpNewDrvSec, szOldCartKey, 0)) > 0)
  697. {
  698. WriteProfileString(lpNewDrvSec, szOldCartKey, NULL);
  699. nCart++;
  700. if (index <= MAX_CART_INDEX)
  701. WriteInt(lpSection,szNewCartKey,rgNewCartMap[index-1]);
  702. else
  703. // external cartridges. Simply copy the id over.
  704. WriteInt(lpSection,szNewCartKey,index);
  705. }
  706. }
  707. // Save the # of cartridges
  708. WriteInt(lpSection,MAKEINTRESOURCE(IDS_CARTRIDGECOUNT),nCart);
  709. }
  710. }
  711. //--------------------------------------------------------------------------
  712. // Function: HandleFonts(lpSection,lpDevName,lpPort)
  713. //
  714. // Action: Deal with soft fonts & font cartridges
  715. //
  716. // Return: VOID
  717. //--------------------------------------------------------------------------
  718. VOID NEAR PASCAL HandleFonts(LPSTR lpSection,
  719. LPSTR lpDevName,
  720. LPSTR lpPort)
  721. {
  722. char szOldDrvSec[64]; // HPPCL5A,<port> or HPPCL5E,<port>
  723. char szNewDrvSec[64]; // HPPCL5MS,<port>
  724. int nCount;
  725. BOOL bOldExists=FALSE; // Does old section exist?
  726. LoadString(hInst,IDS_OLD_5E_DRIVERNAME,szOldDrvSec,sizeof(szOldDrvSec));
  727. MakeAppName((LPSTR)szOldDrvSec,lpPort,sizeof(szOldDrvSec));
  728. // See if the old section exists at all. Temporarily borrow szNewDrvSec.
  729. if(GetProfileString(szOldDrvSec,NULL,szNone,szNewDrvSec,
  730. sizeof(szNewDrvSec)))
  731. {
  732. bOldExists=TRUE;
  733. }
  734. else
  735. {
  736. // Try the HPPCL5E driver...
  737. LoadString(hInst,IDS_OLD_5A_DRIVERNAME,szOldDrvSec,sizeof(szOldDrvSec));
  738. MakeAppName((LPSTR)szOldDrvSec,lpPort,sizeof(szOldDrvSec));
  739. if(GetProfileString(szOldDrvSec,NULL,szNone,szNewDrvSec,
  740. sizeof(szNewDrvSec)))
  741. {
  742. bOldExists=TRUE;
  743. }
  744. }
  745. lstrcpy(szNewDrvSec,rgchModuleName);
  746. MakeAppName((LPSTR)szNewDrvSec,lpPort,sizeof(szNewDrvSec));
  747. if(bOldExists)
  748. {
  749. HandleSoftFonts(szOldDrvSec,szNewDrvSec);
  750. HandleFontCartridges(lpSection,szOldDrvSec,szNewDrvSec);
  751. }
  752. // create UNIDRV's font summary file, if there are many soft fonts.
  753. GetInt(szNewDrvSec,MAKEINTRESOURCE(IDS_SOFTFONTS),&nCount,0,FALSE);
  754. if(nCount>SOFT_FONT_THRES)
  755. {
  756. HDC hIC;
  757. if(hIC=CreateIC(rgchModuleName,lpDevName,lpPort,NULL))
  758. DeleteDC(hIC);
  759. }
  760. }
  761. //-------------------------*DevInstall*---------------------------------------
  762. // Action: De-install, upgrade or install a device.
  763. //
  764. //----------------------------------------------------------------------------
  765. int FAR PASCAL DevInstall(HWND hWnd,
  766. LPSTR lpDevName,
  767. LPSTR lpOldPort,
  768. LPSTR lpNewPort)
  769. {
  770. char szDevSec[64]; // [<device>,<port>] section name
  771. if (!lpDevName)
  772. return -1;
  773. if (!lpOldPort)
  774. {
  775. char szBuf[10];
  776. if (!lpNewPort)
  777. return 0;
  778. // install a device for the first time. Convert old HPPCL5a settings,
  779. // which are still under [<device>,<port>], into equivalent new
  780. // UNIDRV settings under [<device>,<port>], if applicable.
  781. // Delete old settings that are linked to the device name, but don't
  782. // delete old settings that are liked to the driver and port (softfonts)
  783. lstrcpy(szDevSec,lpDevName);
  784. MakeAppName((LPSTR)szDevSec,lpNewPort,sizeof(szDevSec));
  785. // check if old settings exist at all
  786. if(GetProfileString(szDevSec,NULL,NULL,szBuf,sizeof(szBuf)))
  787. {
  788. // Do the straight conversions
  789. ConvertStraight(szDevSec,IDS_OLDPAPERSIZE,IDS_NEWPAPERSIZE);
  790. ConvertStraight(szDevSec,IDS_OLDPAPERSOURCE,IDS_NEWPAPERSOURCE);
  791. ConvertStraight(szDevSec,IDS_OLDORIENTATION,IDS_NEWORIENTATION);
  792. ConvertStraight(szDevSec,IDS_OLDTRUETYPE,IDS_NEWTRUETYPE);
  793. ConvertStraight(szDevSec,IDS_OLDSEPARATION,IDS_NEWSEPARATION);
  794. // Convert the simple translations
  795. ConvertBool(szDevSec,IDS_OLDPAGEPROTECT,IDS_NEWPAGEPROTECT,1);
  796. ConvertBool(szDevSec,IDS_OLDOUTPUT,IDS_NEWOUTPUT,259);
  797. // Do the stuff that requires more complicated conversion
  798. ConvertResolution(szDevSec,lpDevName);
  799. if(!Convert5eHalfTone(szDevSec))
  800. Convert5aHalfTone(szDevSec);
  801. if(!Convert5eMemory(szDevSec))
  802. {
  803. if(!Convert5MSMemory(szDevSec))
  804. Convert5aMemory(szDevSec);
  805. }
  806. ConvertVectorMode(szDevSec);
  807. // Handle soft fonts & cartridges
  808. HandleFonts(szDevSec,lpDevName,lpNewPort);
  809. }
  810. // Flush the cached settings from win.ini
  811. WriteProfileString(NULL,NULL,NULL);
  812. }
  813. else
  814. {
  815. int nCount;
  816. // move device settings from the old port to the new port, or
  817. // de-install a device, i.e. remove its device setttings in order
  818. // to compress the profile.
  819. // First, check if there is any soft font installed under the
  820. // old port. If so, warn the user to copy them over.
  821. lstrcpy(szDevSec,rgchModuleName);
  822. MakeAppName((LPSTR)szDevSec,lpOldPort,sizeof(szDevSec));
  823. if(GetInt(szDevSec,MAKEINTRESOURCE(IDS_SOFTFONTS),&nCount,0,FALSE)
  824. && nCount && lpNewPort)
  825. {
  826. NPSTR npTemp;
  827. if(npTemp=(NPSTR)LocalAlloc(LPTR,TMPSIZE))
  828. {
  829. if(LoadString(hInst,IDS_SOFTFONTWARNING,npTemp,TMPSIZE))
  830. {
  831. // Use this API so that the M Box is set to the Foreground
  832. MSGBOXPARAMS mbp;
  833. mbp.cbSize = sizeof(mbp);
  834. mbp.hwndOwner = hWnd;
  835. mbp.hInstance = hInst;
  836. mbp.lpszText = npTemp;
  837. mbp.lpszCaption = lpOldPort;
  838. mbp.dwStyle = MB_SETFOREGROUND | MB_OK | MB_ICONEXCLAMATION;
  839. mbp.lpszIcon = NULL;
  840. mbp.dwContextHelpId = 0L;
  841. mbp.lpfnMsgBoxCallback = NULL;
  842. MessageBoxIndirect(&mbp);
  843. }
  844. LocalFree((HLOCAL)npTemp);
  845. }
  846. }
  847. }
  848. return UniDevInstall(hWnd,lpDevName,lpOldPort,lpNewPort);
  849. }
  850. // the following 3 definitions MUST be compatible with the
  851. // HPPCL font installer
  852. #define CLASS_LASERJET 0
  853. #define CLASS_DESKJET 1
  854. #define CLASS_DESKJET_PLUS 2
  855. //---------------------------*InstallExtFonts*---------------------------------
  856. // Action: call the specific font installer to add/delete/modify soft fonts
  857. // and/or external cartridges.
  858. //
  859. // Parameters:
  860. // HWND hWnd; handle to the parent windows.
  861. // LPSTR lpDeviceName; long pointer to the printer name.
  862. // LPSTR lpPortName; long pointer to the associated port name.
  863. // BOOL bSoftFonts; flag if supporting soft fonts or not.
  864. //
  865. // Return Value:
  866. // > 0 : if the font information has changed;
  867. // == 0 : if nothing has changed;
  868. // == -1 : if intending to use the universal font installer
  869. // (not available now).
  870. //-------------------------------------------------------------------------
  871. int FAR PASCAL InstallExtFonts(HWND hWnd,
  872. LPSTR lpDeviceName,
  873. LPSTR lpPortName,
  874. BOOL bSoftFonts)
  875. {
  876. int fsVers;
  877. HANDLE hFIlib;
  878. SOFTFONTPROC lpFIns;
  879. if ((hFIlib = LoadLibrary((LPSTR)"FINSTALL.DLL")) < 32 ||
  880. !(lpFIns = (SOFTFONTPROC)GetProcAddress(hFIlib,"InstallSoftFont")))
  881. {
  882. if (hFIlib >= 32)
  883. FreeLibrary(hFIlib);
  884. #ifdef DEBUG
  885. MessageBox(0,
  886. "Can't load FINSTAL.DLL or can't get InstallSoftFont",
  887. NULL, MB_OK);
  888. #endif
  889. return TRUE;
  890. }
  891. // FINSTALL.DLL was loaded properly. Now call InstallSoftFont().
  892. // We choose to ignore the returned "fvers". No use of it.
  893. fsVers = (*lpFIns)(hWnd,rgchModuleName,lpPortName,
  894. (GetKeyState(VK_SHIFT)<0 && GetKeyState(VK_CONTROL)<0),
  895. 1, // dummy value for "fvers".
  896. bSoftFonts?CLASS_LASERJET:256);
  897. FreeLibrary(hFIlib);
  898. return fsVers;
  899. }
  900. // -------------------------------------------------------------------
  901. //
  902. // Special case control functions wrt SETCHARSET escape. This is necessary
  903. // to avoid breaking Winword and Pagemaker. (note that we don't actually
  904. // do anything with SETCHARSET, but apps break unless we say that we do)
  905. //
  906. // --------------------------------------------------------------------
  907. int FAR PASCAL Control(LPDV lpdv,
  908. short function,
  909. LPSTR lpInData,
  910. LPSTR lpOutData)
  911. {
  912. // Tell app that SETCHARSET is supported
  913. if(QUERYESCSUPPORT == function && *((LPWORD)lpInData) == SETCHARSET)
  914. return 1;
  915. // Special case SETCHARSET
  916. if(SETCHARSET == function)
  917. return 1;
  918. // General case
  919. return UniControl(lpdv, function, lpInData, lpOutData);
  920. }
  921. #ifndef NOFONTMAP
  922. //----------------------------------------------------------------------
  923. // Function: MapFaceName(lplfOld,lplfNew)
  924. //
  925. // Action: Map old face names to their new counterparts. Do as little
  926. // work as we possibly can, since this function gets called
  927. // often & we don't want to impact performance. Optimize
  928. // the whole search to the case where we don't find a match,
  929. // as this will be the most common scenario.
  930. //
  931. // Return: A pointer to the LOGFONT to actually hand to Unidrv. Cast
  932. // the return to a LPSTR, just so the compiler is happy.
  933. //----------------------------------------------------------------------
  934. LPSTR NEAR PASCAL MapFaceName(LPLOGFONT lplfOld,
  935. LPLOGFONT lplfNew)
  936. {
  937. LPLOGFONT lpReturn=lplfOld; // By default
  938. NPFACEINDEX pIndex;
  939. LPSTR lpFace=lplfOld->lfFaceName;
  940. BYTE cTest=*lpFace++;
  941. // Determine range of possible matches in the table. Since the
  942. // table is sorted alphabetically, we may be able to bail out
  943. // before we reach the end of the table.
  944. for(pIndex=FaceIndex;cTest > pIndex->cFirstChar;pIndex++)
  945. ;
  946. // Only proceed if the first character matches and this isn't the
  947. // firewall (cTest = \xFF).
  948. if(cTest==pIndex->cFirstChar && ('\xFF' != cTest))
  949. {
  950. WORD wStartIndex=(WORD)(pIndex->bIndex);
  951. WORD wStopIndex=(WORD)((pIndex+1)->bIndex);
  952. WORD wLoop=wStartIndex;
  953. NPSTR npMapFace=&(FaceMap[wStartIndex].szOldFace[1]);
  954. BYTE cMapFace;
  955. // Check the rest of the string against the table entries.
  956. // This search routine takes advantage of the fact that
  957. // the old face names in the table are fully sorted alphabetically.
  958. // This search routine takes advantage of the fact that our table
  959. // is fully sorted, and doesn't do a full string comparison until
  960. // we actually think we have a match. Once we think there's a match,
  961. // we'll double-check the entire string to prevent false triggering.
  962. while(wLoop < wStopIndex)
  963. {
  964. // Look for a match. At this point, match a wildcard to
  965. // anything--we'll do a more stringent check later on, if we
  966. // think we have a match. Stop if cTest is NULL.
  967. while((((cTest=*lpFace)==(cMapFace=*npMapFace)) ||
  968. ('\x01'==cMapFace)) && cTest)
  969. {
  970. npMapFace++;
  971. lpFace++;
  972. }
  973. // We arrive here via two conditions: (1) we've reached the
  974. // end of lpFace and cTest is NULL, or (2) cMapFace and cTest
  975. // failed to compare. We should only continue searching if
  976. // cMapFace is non-NULL and cTest is larger than cMapFace (take
  977. // advantage of the fact that FaceMap is sorted alphabetically).
  978. // For overall performance, check for the no match case first.
  979. // Move to the next table entry as long as there's still a
  980. // chance to find a match.
  981. if(cTest > cMapFace)
  982. {
  983. npMapFace+=sizeof(FACEMAP);
  984. wLoop++;
  985. continue; // Go to the next iteration
  986. }
  987. // if cTest is non-NULL, then the sorting of the table guarantees
  988. // that there are no matches. Bail out now.
  989. if(cTest)
  990. goto MFN_exit;
  991. // cTest is NULL, so we will not make another iteration. The
  992. // only thing left to decide is whether or not we have a match
  993. // with the current string.
  994. if(cMapFace)
  995. goto MFN_exit;
  996. // The guards above ensure that we only arrive here if both
  997. // cTest and cMapFace are NULL, which means that if we're
  998. // going to find a match, this string is it. We took shortcuts
  999. // in the comparisons above, so do a stringent comparison now
  1000. // to be sure that this is really a match. The only characters
  1001. // to match wildcards are '1' and 'N', since these are the only
  1002. // ones used in previous versions of the driver.
  1003. for(lpFace=lplfOld->lfFaceName,npMapFace=FaceMap[wLoop].szOldFace;
  1004. (cMapFace=*npMapFace) && (cTest=*lpFace);
  1005. npMapFace++,lpFace++)
  1006. {
  1007. if(!((cTest==cMapFace) ||
  1008. (('\x01'==cMapFace)&&(('1'==cTest)||('N'==cTest)))))
  1009. {
  1010. // False trigger--bail out without changing facename
  1011. goto MFN_exit;
  1012. }
  1013. }
  1014. // We now know that this really is a match--keep the requested
  1015. // attributes & change just the face name.
  1016. *lplfNew=*lplfOld;
  1017. lstrcpy(lplfNew->lfFaceName,FaceMap[wLoop].szNewFace);
  1018. lpReturn=lplfNew;
  1019. goto MFN_exit;
  1020. }
  1021. }
  1022. MFN_exit:
  1023. return (LPSTR)lpReturn;
  1024. }
  1025. #endif
  1026. //----------------------------------------------------------------------
  1027. // Function: RealizeObject(lpdv,sStyle,lpInObj,lpOutObj,lpTextXForm)
  1028. //
  1029. // Action: Hook this out to enable font substitution. If the object isn't
  1030. // a font, do absolutely nothing.
  1031. //
  1032. // Return: Save as UniRealizeObject().
  1033. //----------------------------------------------------------------------
  1034. DWORD FAR PASCAL RealizeObject(LPDV lpdv,
  1035. short sStyle,
  1036. LPSTR lpInObj,
  1037. LPSTR lpOutObj,
  1038. LPTEXTXFORM lpTextXForm)
  1039. {
  1040. #ifndef NOFONTMAP
  1041. LOGFONT lfNew;
  1042. if(OBJ_FONT==sStyle)
  1043. lpInObj=MapFaceName((LPLOGFONT)lpInObj,&lfNew);
  1044. #endif
  1045. return UniRealizeObject(lpdv, sStyle, lpInObj, lpOutObj, lpTextXForm);
  1046. }
  1047. #endif //!WINNT
  1048.